From e94fc70d0c141d5b5d4d542d58d6d965873b8892 Mon Sep 17 00:00:00 2001 From: The Force <2040992+TheForce172@users.noreply.github.com> Date: Fri, 24 Apr 2026 21:39:58 +0100 Subject: [PATCH 1/5] Fix C4709 Warnings on latest VS --- code/ai/aicode.cpp | 46 +++++++++++++++---------- code/hud/hudsquadmsg.cpp | 5 +-- code/missionui/missionbrief.cpp | 2 +- code/missionui/missionshipchoice.cpp | 4 ++- code/model/animation/modelanimation.cpp | 5 +-- code/model/modelread.cpp | 11 ++++-- code/network/multimsgs.cpp | 2 +- code/object/collideshipship.cpp | 10 +++--- code/object/object.cpp | 6 ++-- code/parse/sexp.cpp | 4 ++- code/ship/ship.cpp | 19 ++++++---- code/ship/ship.h | 40 ++++++++++++++++----- code/ship/shiphit.cpp | 3 +- code/weapon/weapon.h | 27 +++++++++++---- code/weapon/weapons.cpp | 5 +-- qtfred/src/mission/EditorViewport.cpp | 4 +-- 16 files changed, 133 insertions(+), 60 deletions(-) diff --git a/code/ai/aicode.cpp b/code/ai/aicode.cpp index 04d0625f783..48c2eed51d2 100644 --- a/code/ai/aicode.cpp +++ b/code/ai/aicode.cpp @@ -1399,7 +1399,7 @@ void ai_turn_towards_vector(const vec3d* dest, object* objp, const vec3d* slide_ } // Don't allow a ship to turn if it's prevented from turning. - if ( objp->flags[Object::Object_Flags::Dont_change_orientation, Object::Object_Flags::Immobile] ) { + if (objp->flags[Object::Object_Flags::Dont_change_orientation] || objp->flags[Object::Object_Flags::Immobile]) { return; } @@ -2146,7 +2146,8 @@ float get_wing_lowest_av_ab_speed(object *objp) ai_info *oaip = &Ai_info[oshipp->ai_index]; ship_info *osip = &Ship_info[oshipp->ship_info_index]; - if ((oaip->mode == AIM_WAYPOINTS) && (oshipp->wingnum == wingnum) && (oaip->ai_flags[AI::AI_Flags::Formation_object, AI::AI_Flags::Formation_wing])) { + if ((oaip->mode == AIM_WAYPOINTS) && (oshipp->wingnum == wingnum) && + (oaip->ai_flags[AI::AI_Flags::Formation_object] || oaip->ai_flags[AI::AI_Flags::Formation_wing])) { float cur_max; if ((oshipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(osip->flags[Ship::Info_Flags::Afterburner]) || (o->phys_info.afterburner_max_vel.xyz.z <= o->phys_info.max_vel.xyz.z) || !(oaip->ai_flags[AI::AI_Flags::Free_afterburner_use] || oaip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) { @@ -6650,7 +6651,8 @@ void ai_maybe_announce_shockwave_weapon(object *firing_objp, int weapon_index) ai_info *aip = &Ai_info[Ships[A->instance].ai_index]; // AL 1-5-98: only avoid shockwave if not docked or repairing - if ( !object_is_docked(A) && !(aip->ai_flags[AI::AI_Flags::Repairing, AI::AI_Flags::Being_repaired]) ) { + if (!object_is_docked(A) && + !(aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Being_repaired])) { aip->ai_flags.set(AI::AI_Flags::Avoid_shockwave_weapon); } } @@ -12318,7 +12320,8 @@ void ai_process_subobjects(int objnum) // (previously in ship_evaluate_ai (previously in ship_process_post)) // Cyborg -- Unfortunately Ai info is not reliable and should just not be accessed here. // It will have no real effect on gameplay, since the server decides when turrets fire - if (!MULTIPLAYER_CLIENT && (aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair])) + if (!MULTIPLAYER_CLIENT && + (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair])) { if (aip->support_ship_objnum >= 0) { @@ -13167,7 +13170,7 @@ void ai_do_repair_frame(object *objp, ai_info *aip, float frametime) static bool rearm_eta_found=false; - if (aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair]) { + if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) { if (Ships[objp->instance].team == Iff_traitor) { ai_abort_rearm_request(objp); return; @@ -13534,7 +13537,8 @@ void ai_maybe_evade_locked_missile(object *objp, ai_info *aip) return; } - if (aip->ai_flags[AI::AI_Flags::No_dynamic, AI::AI_Flags::Kamikaze]) { // If not allowed to pursue dynamic objectives, don't evade. Dumb? Maybe change. -- MK, 3/15/98 + if (aip->ai_flags[AI::AI_Flags::No_dynamic] || aip->ai_flags[AI::AI_Flags::Kamikaze]) { // If not allowed to pursue dynamic objectives, don't evade. Dumb? + //Maybe change. -- MK, 3/15/98 return; } @@ -13589,7 +13593,7 @@ void ai_maybe_evade_locked_missile(object *objp, ai_info *aip) } break; case AIM_DOCK: // Ships in dock mode can evade iif they are not currently repairing or docked. - if (object_is_docked(objp) || (aip->ai_flags[AI::AI_Flags::Repairing, AI::AI_Flags::Being_repaired])) + if (object_is_docked(objp) || (aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Being_repaired])) break; FALLTHROUGH; case AIM_GUARD: @@ -13739,7 +13743,8 @@ void maybe_evade_dumbfire_weapon(ai_info *aip) case AIM_WAYPOINTS: case AIM_FLY_TO_SHIP: case AIM_SAFETY: - if (!(aip->ai_flags[AI::AI_Flags::No_dynamic, AI::AI_Flags::Kamikaze]) && Ship_info[Ships[aip->shipnum].ship_info_index].is_small_ship()) { + if (!(aip->ai_flags[AI::AI_Flags::No_dynamic] || aip->ai_flags[AI::AI_Flags::Kamikaze]) && + Ship_info[Ships[aip->shipnum].ship_info_index].is_small_ship()) { aip->active_goal = AI_ACTIVE_GOAL_DYNAMIC; aip->previous_mode = aip->mode; aip->previous_submode = aip->submode; @@ -14417,7 +14422,8 @@ int num_allies_rearming(object *objp) continue; if (Ships[A->instance].team == team) { - if (Ai_info[Ships[A->instance].ai_index].ai_flags[AI::AI_Flags::Repairing, AI::AI_Flags::Awaiting_repair]) { + if (Ai_info[Ships[A->instance].ai_index].ai_flags[AI::AI_Flags::Repairing] || + Ai_info[Ships[A->instance].ai_index].ai_flags[AI::AI_Flags::Awaiting_repair]) { count++; } } @@ -14449,7 +14455,7 @@ int maybe_request_support(object *objp) return 0; // A ship that is currently awaiting does not need support! - if (aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair]) + if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) return 0; if (!timestamp_elapsed(aip->next_rearm_request_timestamp)) @@ -14773,7 +14779,8 @@ void ai_announce_ship_dying(object *dying_objp) ai_info *aip = &Ai_info[Ships[A->instance].ai_index]; // AL 1-5-98: only avoid shockwave if not docked or repairing - if ( !object_is_docked(A) && !(aip->ai_flags[AI::AI_Flags::Repairing, AI::AI_Flags::Being_repaired]) ) { + if (!object_is_docked(A) && + !(aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Being_repaired])) { aip->ai_flags.set(AI::AI_Flags::Avoid_shockwave_ship); } } @@ -15104,7 +15111,7 @@ int ai_avoid_shockwave(object *objp, ai_info *aip) // Return true if this ship is close to being repaired, else return false. int ai_await_repair_frame(object *objp, ai_info *aip) { - if (!(aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair])) + if (!(aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair])) return 0; if (aip->support_ship_objnum == -1) @@ -15364,11 +15371,12 @@ void ai_frame(int objnum) ai_process_mission_orders( objnum, aip ); // Avoid a shockwave, if necessary. If a shockwave and rearming, stop rearming. - if (aip->mode != AIM_PLAY_DEAD && aip->ai_flags[AI::AI_Flags::Avoid_shockwave_ship, AI::AI_Flags::Avoid_shockwave_weapon]) { + if (aip->mode != AIM_PLAY_DEAD && + (aip->ai_flags[AI::AI_Flags::Avoid_shockwave_ship] || aip->ai_flags[AI::AI_Flags::Avoid_shockwave_weapon])) { if (ai_avoid_shockwave(Pl_objp, aip)) { aip->ai_flags.remove(AI::AI_Flags::Big_ship_collide_recover_1); aip->ai_flags.remove(AI::AI_Flags::Big_ship_collide_recover_2); - if (aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair]) + if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) ai_abort_rearm_request(Pl_objp); return; } @@ -15553,7 +15561,7 @@ void ai_frame(int objnum) aip->target_time += flFrametime; int in_formation = 0; - if (aip->ai_flags[AI::AI_Flags::Formation_object, AI::AI_Flags::Formation_wing]) { + if (aip->ai_flags[AI::AI_Flags::Formation_object] || aip->ai_flags[AI::AI_Flags::Formation_wing]) { in_formation = !ai_formation(); } @@ -16497,11 +16505,13 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, const vec3d *hit_normal) aip->last_hit_time = Missiontime; - if (aip->ai_flags[AI::AI_Flags::No_dynamic, AI::AI_Flags::Kamikaze]) // If not allowed to pursue dynamic objectives, don't evade. Dumb? Maybe change. -- MK, 3/15/98 + if (aip->ai_flags[AI::AI_Flags::No_dynamic] || + aip->ai_flags[AI::AI_Flags::Kamikaze]) // If not allowed to pursue dynamic objectives, don't evade. Dumb? + //Maybe change. -- MK, 3/15/98 return; // If this ship is awaiting repair, abort! - if (aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair]) { + if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) { if (get_hull_pct(objp_ship) < 0.3f) { // Note, only abort if hull below a certain level. aip->next_rearm_request_timestamp = timestamp(NEXT_REARM_TIMESTAMP/2); // Might request again after 15 seconds. @@ -16794,7 +16804,7 @@ int ai_abort_rearm_request(object *requester_objp) } requester_aip = &Ai_info[requester_shipp->ai_index]; - if (requester_aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair]){ + if (requester_aip->ai_flags[AI::AI_Flags::Being_repaired] || requester_aip->ai_flags[AI::AI_Flags::Awaiting_repair]){ // support objnum is always valid once a rearm repair has been requested. It points to the // ship that is coming to repair me. diff --git a/code/hud/hudsquadmsg.cpp b/code/hud/hudsquadmsg.cpp index e67e15c902f..ba6206bd017 100644 --- a/code/hud/hudsquadmsg.cpp +++ b/code/hud/hudsquadmsg.cpp @@ -394,7 +394,7 @@ bool hud_squadmsg_wing_valid(wing *wingp) // a couple of special cases to account for before adding to count (or to menu). Don't count // wings that are leaving or left. - if ( wingp->flags[Ship::Wing_Flags::Gone, Ship::Wing_Flags::Departing] ) + if ( wingp->flags[Ship::Wing_Flags::Gone] || wingp->flags[Ship::Wing_Flags::Departing] ) return false; // Goober5000 - instead of checking wing leader, let's check all ships in wing; @@ -1842,7 +1842,8 @@ void hud_squadmsg_type_select( ) // check to see if the player is awaiting repair or being repaired. Active the abort and inactive the repair items // check to see if the player is scheduled to be repaired by incoming ship - if ( Ai_info[Ships[Player_obj->instance].ai_index].ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair] ) { + if (Ai_info[Ships[Player_obj->instance].ai_index].ai_flags[AI::AI_Flags::Being_repaired] || + Ai_info[Ships[Player_obj->instance].ai_index].ai_flags[AI::AI_Flags::Awaiting_repair]) { MsgItems[TYPE_REPAIR_REARM_ITEM].active = 0; MsgItems[TYPE_REPAIR_REARM_ABORT_ITEM].active = 1; } diff --git a/code/missionui/missionbrief.cpp b/code/missionui/missionbrief.cpp index e9579c51b2e..7d91cb7b74e 100644 --- a/code/missionui/missionbrief.cpp +++ b/code/missionui/missionbrief.cpp @@ -2098,7 +2098,7 @@ int brief_only_allow_briefing() return 1; } - if ( The_mission.flags[Mission::Mission_Flags::Scramble, Mission::Mission_Flags::Red_alert] ) { + if (The_mission.flags[Mission::Mission_Flags::Scramble] || The_mission.flags[Mission::Mission_Flags::Red_alert]) { return 1; } diff --git a/code/missionui/missionshipchoice.cpp b/code/missionui/missionshipchoice.cpp index d9748cdba2c..f09af2118c6 100644 --- a/code/missionui/missionshipchoice.cpp +++ b/code/missionui/missionshipchoice.cpp @@ -1976,7 +1976,9 @@ commit_pressed_status commit_pressed(bool API_Access) // Any incomplete loadouts that make it through the loadout screen will be condensed so that gaps are moved to the bottom. This check adds that responsibility to the player. // Note: don't check for training, scramble, or red-alert missions // Note2: don't check missions without briefings either - if (check_for_gaps_in_weapon_slots() && !(The_mission.game_type & MISSION_TYPE_TRAINING) && !The_mission.flags[Mission::Mission_Flags::Scramble, Mission::Mission_Flags::Red_alert, Mission::Mission_Flags::No_briefing]) + if (check_for_gaps_in_weapon_slots() && !(The_mission.game_type & MISSION_TYPE_TRAINING) && + !(The_mission.flags[Mission::Mission_Flags::Scramble] || The_mission.flags[Mission::Mission_Flags::Red_alert] || + The_mission.flags[Mission::Mission_Flags::No_briefing])) { popup(PF_USE_AFFIRMATIVE_ICON, 1, diff --git a/code/model/animation/modelanimation.cpp b/code/model/animation/modelanimation.cpp index 0dd6a6ee7cf..9770e66ac3d 100644 --- a/code/model/animation/modelanimation.cpp +++ b/code/model/animation/modelanimation.cpp @@ -224,7 +224,8 @@ namespace animation { if (m_flags[Animation_Flags::Random_starting_phase]) { instanceData.time = util::Random::next() * util::Random::INV_F_MAX_VALUE * instanceData.duration; //Check if we might be on the way backwards - if (m_flags[Animation_Flags::Loop, Animation_Flags::Auto_Reverse] && !m_flags[Animation_Flags::Reset_at_completion] && util::Random::flip_coin()) { + if ((m_flags[Animation_Flags::Loop] || m_flags[Animation_Flags::Auto_Reverse]) && + !m_flags[Animation_Flags::Reset_at_completion] && util::Random::flip_coin()) { prevTime = instanceData.duration; instanceData.canonicalDirection = ModelAnimationDirection::RWD; } @@ -1378,7 +1379,7 @@ namespace animation { if (Animation_types.find(type)->second.second) { //This is a type where the code does not reset the animation. The animation is expected to auto-reset in one way or another. //If it doesn't, nothing will crash, but the result is most likely unintended. - if (!animation->m_flags[Animation_Flags::Auto_Reverse, Animation_Flags::Reset_at_completion]) { + if (!(animation->m_flags[Animation_Flags::Auto_Reverse] || animation->m_flags[Animation_Flags::Reset_at_completion])) { error_display(0, "Animation trigger type %s expects an auto-reset flag to be set.", atype); } diff --git a/code/model/modelread.cpp b/code/model/modelread.cpp index 416edf37c15..93afbd30983 100644 --- a/code/model/modelread.cpp +++ b/code/model/modelread.cpp @@ -2093,7 +2093,10 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, // Genghis: if we have a thruster and none of the collision // properties were provided, then set "nocollide_this_only". - if (sm->flags[Model::Submodel_flags::Is_thruster] && !(sm->flags[Model::Submodel_flags::No_collisions, Model::Submodel_flags::Nocollide_this_only, Model::Submodel_flags::Collide_invisible]) ) + if (sm->flags[Model::Submodel_flags::Is_thruster] && + !(sm->flags[Model::Submodel_flags::No_collisions] || + sm->flags[Model::Submodel_flags::Nocollide_this_only] || + sm->flags[Model::Submodel_flags::Collide_invisible])) { sm->flags.set(Model::Submodel_flags::Nocollide_this_only); } @@ -3445,7 +3448,11 @@ int model_load(const char* filename, ship_info* sip, ErrorType error_type, bool dl2 = SCP_tolower(sm2->name[first_diff]) - 'a'; // Handle LODs named "detail0/1/2/etc" too (as opposed to "detaila/b/c/etc") - if (sm1->parent == -1 && sm2->parent == -1 && !sm1->flags[Model::Submodel_flags::Is_damaged, Model::Submodel_flags::Is_live_debris] && !sm2->flags[Model::Submodel_flags::Is_damaged, Model::Submodel_flags::Is_live_debris]) { + if (sm1->parent == -1 && sm2->parent == -1 && + !(sm1->flags[Model::Submodel_flags::Is_damaged] || + sm1->flags[Model::Submodel_flags::Is_live_debris]) && + !(sm2->flags[Model::Submodel_flags::Is_damaged] || + sm2->flags[Model::Submodel_flags::Is_live_debris])) { dl2 = dl2 - dl1; dl1 = 0; } diff --git a/code/network/multimsgs.cpp b/code/network/multimsgs.cpp index ecd5c77bdf3..9a0d14f1837 100644 --- a/code/network/multimsgs.cpp +++ b/code/network/multimsgs.cpp @@ -7612,7 +7612,7 @@ void process_homing_weapon_info( ubyte *data, header *hinfo ) if ( homing_object->type == OBJ_WEAPON ) { auto flags_check = Weapon_info[Weapons[homing_object->instance].weapon_info_index].wi_flags; - if ( !((flags_check[Weapon::Info_Flags::Bomb, Weapon::Info_Flags::Cmeasure])) ) { + if (!((flags_check[Weapon::Info_Flags::Bomb] || flags_check[Weapon::Info_Flags::Cmeasure]))) { nprintf(("Network", "Homing object is invalid for homing update\n")); return; } diff --git a/code/object/collideshipship.cpp b/code/object/collideshipship.cpp index 1fd1d69cfa9..19e5146c668 100644 --- a/code/object/collideshipship.cpp +++ b/code/object/collideshipship.cpp @@ -803,7 +803,8 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_ // We will try not to worry about the left over time in the frame // heavy's position unchanged by collision // light's position is heavy's position plus relative position from heavy - if (should_collide && !lighter->flags[Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile]){ + if (should_collide && !(lighter->flags[Object::Object_Flags::Dont_change_position] || + lighter->flags[Object::Object_Flags::Immobile])) { vm_vec_add(&lighter->pos, &heavy->pos, &ship_ship_hit_info->light_collision_cm_pos); } @@ -821,7 +822,8 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_ } if (should_collide){ - if (!heavy->flags[Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile]) { + if (!(heavy->flags[Object::Object_Flags::Dont_change_position] || + heavy->flags[Object::Object_Flags::Immobile])) { Assert(!vm_is_vec_nan(&direction_light)); vm_vec_scale_add2(&heavy->pos, &direction_light, 0.2f * (1.0f - heavy_light_mass_ratio)); vm_vec_scale_add2(&heavy->pos, &ship_ship_hit_info->collision_normal, -0.1f * (1.0f - heavy_light_mass_ratio)); @@ -840,8 +842,8 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_ //For landings, we want minimal movement on the light ship (just enough to keep the collision detection honest) if (ship_ship_hit_info->is_landing) { vm_vec_scale_add2(&lighter->pos, &ship_ship_hit_info->collision_normal, LANDING_POS_OFFSET); - } - else if (!lighter->flags[Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile]) { + } else if (!(lighter->flags[Object::Object_Flags::Dont_change_position] || + lighter->flags[Object::Object_Flags::Immobile])) { vm_vec_scale_add2(&lighter->pos, &direction_light, -0.2f * heavy_light_mass_ratio); vm_vec_scale_add2(&lighter->pos, &ship_ship_hit_info->collision_normal, 0.1f * heavy_light_mass_ratio); } diff --git a/code/object/object.cpp b/code/object/object.cpp index 06bbf7cb240..1d98b01e175 100644 --- a/code/object/object.cpp +++ b/code/object/object.cpp @@ -1641,8 +1641,10 @@ void obj_move_all(float frametime) } // Goober5000 - accommodate objects that aren't supposed to move in some way (at least until they're destroyed) - bool dont_change_position = objp->flags[Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile] && objp->hull_strength > 0.0f; - bool dont_change_orientation = objp->flags[Object::Object_Flags::Dont_change_orientation, Object::Object_Flags::Immobile] && objp->hull_strength > 0.0f; + bool dont_change_position = (objp->flags[Object::Object_Flags::Dont_change_position] || objp->flags[Object::Object_Flags::Immobile]) && objp->hull_strength > 0.0f; + bool dont_change_orientation = (objp->flags[Object::Object_Flags::Dont_change_orientation] || + objp->flags[Object::Object_Flags::Immobile]) && + objp->hull_strength > 0.0f; // skip the physics if we're totally immobile if (!dont_change_position || !dont_change_orientation) { diff --git a/code/parse/sexp.cpp b/code/parse/sexp.cpp index e1698eb3c4e..adbfd669977 100644 --- a/code/parse/sexp.cpp +++ b/code/parse/sexp.cpp @@ -4298,7 +4298,9 @@ int check_sexp_potential_issues(int node, int *bad_node, SCP_string &issue_msg) for (const auto so : list_range(&Ship_obj_list)) { const auto &obj = Objects[so->objnum]; - if (obj.flags[Object::Object_Flags::Immobile, Object::Object_Flags::Dont_change_position, Object::Object_Flags::Dont_change_orientation]) + if (obj.flags[Object::Object_Flags::Immobile] || + obj.flags[Object::Object_Flags::Dont_change_position] || + obj.flags[Object::Object_Flags::Dont_change_orientation]) { issue_msg = "At least one ship ("; issue_msg += Ships[obj.instance].ship_name; diff --git a/code/ship/ship.cpp b/code/ship/ship.cpp index 561a6f883d3..1c2f29b280f 100644 --- a/code/ship/ship.cpp +++ b/code/ship/ship.cpp @@ -9120,7 +9120,7 @@ void wing_maybe_cleanup( wing *wingp, int team ) // waves so we can mark the wing as gone and no other ships arrive // Goober5000 - also if it's departing... this is sort of, but not exactly, what :V: did; // but it seems to be consistent with how it should behave - if (wingp->flags[Ship::Wing_Flags::Departing, Ship::Wing_Flags::Departure_ordered]) + if (wingp->flags[Ship::Wing_Flags::Departing] || wingp->flags[Ship::Wing_Flags::Departure_ordered]) wingp->current_wave = wingp->num_waves; // Goober5000 - some changes for clarity and closing holes @@ -13385,7 +13385,9 @@ int ship_fire_primary(object * obj, int force, bool rollback_shot) int effective_primary_banks = 0; for (int it = 0; it < num_primary_banks; it++) { - if ((it == bank_to_fire) || !(Weapon_info[swp->primary_bank_weapons[it]].wi_flags[Weapon::Info_Flags::Nolink, Weapon::Info_Flags::No_linked_penalty])) + if ((it == bank_to_fire) || + !(Weapon_info[swp->primary_bank_weapons[it]].wi_flags[Weapon::Info_Flags::Nolink] || + Weapon_info[swp->primary_bank_weapons[it]].wi_flags[Weapon::Info_Flags::No_linked_penalty])) effective_primary_banks++; } Assert(effective_primary_banks >= 1); @@ -16863,7 +16865,8 @@ int ship_find_repair_ship( object *requester_obj, object **ship_we_found ) dist = vm_vec_dist_quick(&objp->pos, &requester_obj->pos); - if (aip->ai_flags[AI::AI_Flags::Repairing, AI::AI_Flags::Awaiting_repair, AI::AI_Flags::Being_repaired]) + if (aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Awaiting_repair] || + aip->ai_flags[AI::AI_Flags::Being_repaired]) { // support ship is already busy, track the one that will be // done soonest by estimating how many seconds it will take for the support ship @@ -22315,15 +22318,17 @@ bool ship::is_arriving(ship::warpstage stage, bool dock_leader_or_single) const { if (stage == ship::warpstage::BOTH) { if (!dock_leader_or_single) { - return flags[Ship::Ship_Flags::Arriving_stage_1, Ship::Ship_Flags::Arriving_stage_1_dock_follower, Ship::Ship_Flags::Arriving_stage_2, Ship::Ship_Flags::Arriving_stage_2_dock_follower]; + return flags[Ship::Ship_Flags::Arriving_stage_1] || + flags[Ship::Ship_Flags::Arriving_stage_1_dock_follower] || + flags[Ship::Ship_Flags::Arriving_stage_2] || flags[Ship::Ship_Flags::Arriving_stage_2_dock_follower]; } else { - return flags[Ship::Ship_Flags::Arriving_stage_1, Ship::Ship_Flags::Arriving_stage_2]; + return flags[Ship::Ship_Flags::Arriving_stage_1] || flags[Ship::Ship_Flags::Arriving_stage_2]; } } else if (stage == ship::warpstage::STAGE1) { if (!dock_leader_or_single) { - return flags[Ship::Ship_Flags::Arriving_stage_1, Ship::Ship_Flags::Arriving_stage_1_dock_follower]; + return flags[Ship::Ship_Flags::Arriving_stage_1] || flags[Ship::Ship_Flags::Arriving_stage_1_dock_follower]; } else { return flags[Ship::Ship_Flags::Arriving_stage_1]; @@ -22331,7 +22336,7 @@ bool ship::is_arriving(ship::warpstage stage, bool dock_leader_or_single) const } if (stage == ship::warpstage::STAGE2) { if (!dock_leader_or_single) { - return flags[Ship::Ship_Flags::Arriving_stage_2, Ship::Ship_Flags::Arriving_stage_2_dock_follower]; + return flags[Ship::Ship_Flags::Arriving_stage_2] || flags[Ship::Ship_Flags::Arriving_stage_2_dock_follower]; } else { return flags[Ship::Ship_Flags::Arriving_stage_2]; diff --git a/code/ship/ship.h b/code/ship/ship.h index 636084b9186..6cca86bf254 100644 --- a/code/ship/ship.h +++ b/code/ship/ship.h @@ -855,8 +855,11 @@ class ship //Helper functions bool is_arriving(ship::warpstage stage = ship::warpstage::BOTH, bool dock_leader_or_single = false) const; - inline bool is_departing() const { return flags[Ship::Ship_Flags::Depart_warp, Ship::Ship_Flags::Depart_dockbay]; } - inline bool cannot_warp_flags() const { return flags[Ship::Ship_Flags::Warp_broken, Ship::Ship_Flags::Warp_never, Ship::Ship_Flags::Disabled, Ship::Ship_Flags::No_subspace_drive]; } + inline bool is_departing() const + { + return flags[Ship::Ship_Flags::Depart_warp] || flags[Ship::Ship_Flags::Depart_dockbay]; + } + inline bool cannot_warp_flags() const { return flags[Ship::Ship_Flags::Warp_broken] || flags[Ship::Ship_Flags::Warp_never]|| flags[Ship::Ship_Flags::Disabled] || flags[Ship::Ship_Flags::No_subspace_drive]; } inline bool is_dying_or_departing() const { return is_departing() || flags[Ship::Ship_Flags::Dying]; } const char* get_display_name() const; @@ -1521,13 +1524,34 @@ class ship_info //Helper functions - inline bool is_small_ship() const { return flags[Ship::Info_Flags::Fighter, Ship::Info_Flags::Bomber, Ship::Info_Flags::Support, Ship::Info_Flags::Escapepod]; } - inline bool is_big_ship() const { return flags[Ship::Info_Flags::Cruiser, Ship::Info_Flags::Freighter, Ship::Info_Flags::Transport, Ship::Info_Flags::Corvette, Ship::Info_Flags::Gas_miner, Ship::Info_Flags::Awacs]; } - inline bool is_huge_ship() const { return flags[Ship::Info_Flags::Capital, Ship::Info_Flags::Supercap, Ship::Info_Flags::Drydock, Ship::Info_Flags::Knossos_device]; } - inline bool is_flyable() const { return !(flags[Ship::Info_Flags::Cargo, Ship::Info_Flags::Navbuoy, Ship::Info_Flags::Sentrygun]); } // AL 11-24-97: this useful to know for targeting reasons -// note: code that previously used is_harmless() / SIF_HARMLESS now uses several flags defined in objecttypes.tbl + inline bool is_small_ship() const + { + return flags[Ship::Info_Flags::Fighter] || flags[Ship::Info_Flags::Bomber] || flags[Ship::Info_Flags::Support] + || flags[Ship::Info_Flags::Escapepod]; + } + inline bool is_big_ship() const + { + return flags[Ship::Info_Flags::Cruiser] || flags[Ship::Info_Flags::Freighter] || + flags[Ship::Info_Flags::Transport] || + flags[Ship::Info_Flags::Corvette] || + flags[Ship::Info_Flags::Gas_miner] || flags[Ship::Info_Flags::Awacs]; + } + inline bool is_huge_ship() const + { + return flags[Ship::Info_Flags::Capital] || flags[Ship::Info_Flags::Supercap] || + flags[Ship::Info_Flags::Drydock] || flags[Ship::Info_Flags::Knossos_device]; + } + inline bool is_flyable() const + { + return !( + flags[Ship::Info_Flags::Cargo] || flags[Ship::Info_Flags::Navbuoy] || flags[Ship::Info_Flags::Sentrygun]); + } // AL 11-24-97: this useful to know for targeting reasons + // note: code that previously used is_harmless() / SIF_HARMLESS now uses several flags defined in objecttypes.tbl // inline bool is_harmless() const { return flags[Ship::Info_Flags::Cargo, Ship::Info_Flags::Navbuoy, Ship::Info_Flags::Escapepod]; } // AL 12-3-97: ships that are not a threat - inline bool is_fighter_bomber() const { return flags[Ship::Info_Flags::Fighter, Ship::Info_Flags::Bomber]; } + inline bool is_fighter_bomber() const + { + return flags[Ship::Info_Flags::Fighter] || flags[Ship::Info_Flags::Bomber]; + } inline bool is_big_or_huge() const { return is_big_ship() || is_huge_ship(); } inline bool avoids_shockwaves() const { return is_small_ship(); } diff --git a/code/ship/shiphit.cpp b/code/ship/shiphit.cpp index 2721bd0ab00..931c82f06a4 100755 --- a/code/ship/shiphit.cpp +++ b/code/ship/shiphit.cpp @@ -179,7 +179,8 @@ void do_subobj_destroyed_stuff( ship *ship_p, ship_subsys *subsys, const vec3d* } // create fireballs when subsys destroy for large ships. - if (!(subsys->flags[Ship::Subsystem_Flags::Vanished, Ship::Subsystem_Flags::No_disappear]) && !no_explosion) { + if (!(subsys->flags[Ship::Subsystem_Flags::Vanished] || subsys->flags[Ship::Subsystem_Flags::No_disappear]) && + !no_explosion) { vec3d center_to_subsys; vm_vec_sub(¢er_to_subsys, &g_subobj_pos, &ship_objp->pos); diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index d8d7fa07250..77deeed7968 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -946,12 +946,27 @@ struct weapon_info inline bool is_beam() const { return subtype == WP_BEAM || wi_flags[Weapon::Info_Flags::Beam]; } inline bool is_non_beam_primary() const { return subtype == WP_LASER && !wi_flags[Weapon::Info_Flags::Beam]; } - inline bool is_homing() const { return wi_flags[Weapon::Info_Flags::Homing_heat, Weapon::Info_Flags::Homing_aspect, Weapon::Info_Flags::Homing_javelin]; } - inline bool is_locked_homing() const { return wi_flags[Weapon::Info_Flags::Homing_aspect, Weapon::Info_Flags::Homing_javelin]; } - inline bool hurts_big_ships() const { return wi_flags[Weapon::Info_Flags::Bomb, Weapon::Info_Flags::Beam, Weapon::Info_Flags::Huge, Weapon::Info_Flags::Big_only]; } - inline bool is_interceptable() const { return wi_flags[Weapon::Info_Flags::Fighter_Interceptable, Weapon::Info_Flags::Turret_Interceptable]; } - inline bool is_mine() const { return wi_flags[Weapon::Info_Flags::Mine]; } - + inline bool is_homing() const + { + return wi_flags[Weapon::Info_Flags::Homing_heat] || wi_flags[Weapon::Info_Flags::Homing_aspect] || + wi_flags[Weapon::Info_Flags::Homing_javelin]; + } + inline bool is_locked_homing() const + { + return wi_flags[Weapon::Info_Flags::Homing_aspect] || wi_flags[Weapon::Info_Flags::Homing_javelin]; + } + inline bool hurts_big_ships() const + { + return wi_flags[Weapon::Info_Flags::Bomb] || wi_flags[Weapon::Info_Flags::Beam] || + wi_flags[Weapon::Info_Flags::Huge] || wi_flags[Weapon::Info_Flags::Big_only]; + } + inline bool is_interceptable() const + { + return wi_flags[Weapon::Info_Flags::Fighter_Interceptable] || + wi_flags[Weapon::Info_Flags::Turret_Interceptable]; + } + inline bool is_mine() const { return wi_flags[Weapon::Info_Flags::Mine]; } + const char* get_display_name() const; bool has_display_name() const; diff --git a/code/weapon/weapons.cpp b/code/weapon/weapons.cpp index 450ca52a604..90e409112f6 100644 --- a/code/weapon/weapons.cpp +++ b/code/weapon/weapons.cpp @@ -4147,7 +4147,8 @@ int parse_weapon(int subtype, bool replace, const char *filename) if (optional_string("$Weapon Hitpoints:")) { stuff_int(&wip->weapon_hitpoints); - } else if (first_time && (wip->wi_flags[Weapon::Info_Flags::Turret_Interceptable, Weapon::Info_Flags::Fighter_Interceptable, Weapon::Info_Flags::Mine])) { + } else if (first_time && (wip->wi_flags[Weapon::Info_Flags::Turret_Interceptable] || + wip->wi_flags[Weapon::Info_Flags::Fighter_Interceptable] || wip->wi_flags[Weapon::Info_Flags::Mine])) { wip->weapon_hitpoints = wip->is_mine() ? 50 : 25; // mines are tankier by default, like bombs } @@ -5517,7 +5518,7 @@ void find_homing_object(object *weapon_objp, int num) else if (objp->type == OBJ_WEAPON) { //don't attempt to home on weapons if the weapon is a huge weapon or is a javelin homing weapon. - if (wip->wi_flags[Weapon::Info_Flags::Huge, Weapon::Info_Flags::Homing_javelin]) + if (wip->wi_flags[Weapon::Info_Flags::Huge] || wip->wi_flags[Weapon::Info_Flags::Homing_javelin]) continue; //don't look for local ssms that are gone for the time being diff --git a/qtfred/src/mission/EditorViewport.cpp b/qtfred/src/mission/EditorViewport.cpp index 3d25ddc4b9a..638d58f46ff 100644 --- a/qtfred/src/mission/EditorViewport.cpp +++ b/qtfred/src/mission/EditorViewport.cpp @@ -282,7 +282,7 @@ void EditorViewport::select_objects(const Marking_box& box) { ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { valid = 1; - if (ptr->flags[Object::Object_Flags::Hidden, Object::Object_Flags::Locked_from_editing]) { + if (ptr->flags[Object::Object_Flags::Hidden] || ptr->flags[Object::Object_Flags::Locked_from_editing]) { valid = 0; } if (!isObjectVisibleInLayer(ptr)) { @@ -705,7 +705,7 @@ int EditorViewport::object_check_collision(object* objp, vec3d* p0, vec3d* p1, v return 0; } - if (objp->flags[Object::Object_Flags::Hidden, Object::Object_Flags::Locked_from_editing]) { + if (objp->flags[Object::Object_Flags::Hidden] || objp->flags[Object::Object_Flags::Locked_from_editing]) { return 0; } if (!isObjectVisibleInLayer(objp)) { From a77eb99dd9050c3bca9eb07f06e882755566bd9c Mon Sep 17 00:00:00 2001 From: The Force <2040992+TheForce172@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:13:12 +0100 Subject: [PATCH 2/5] more --- code/cutscene/cutscenes.cpp | 3 ++- code/particle/volumes/ModelSurfaceVolume.cpp | 4 +++- code/scripting/api/objs/ship.cpp | 2 +- code/scripting/api/objs/techroom.cpp | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/cutscene/cutscenes.cpp b/code/cutscene/cutscenes.cpp index 29ca15b1800..469e4456bbf 100644 --- a/code/cutscene/cutscenes.cpp +++ b/code/cutscene/cutscenes.cpp @@ -537,7 +537,8 @@ void cutscenes_screen_init() int u = 0; for (auto cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut, ++u) { - if (cut->flags[Cutscene::Cutscene_Flags::Viewable, Cutscene::Cutscene_Flags::Always_viewable] && !cut->flags[Cutscene::Cutscene_Flags::Never_viewable]) + if ((cut->flags[Cutscene::Cutscene_Flags::Viewable] || cut->flags[Cutscene::Cutscene_Flags::Always_viewable]) && + !cut->flags[Cutscene::Cutscene_Flags::Never_viewable]) { Cutscene_list.push_back(u); } diff --git a/code/particle/volumes/ModelSurfaceVolume.cpp b/code/particle/volumes/ModelSurfaceVolume.cpp index 13b66032588..944feb699c5 100644 --- a/code/particle/volumes/ModelSurfaceVolume.cpp +++ b/code/particle/volumes/ModelSurfaceVolume.cpp @@ -21,7 +21,9 @@ vec3d ModelSurfaceVolume::sampleRandomPoint(const matrix &orientation, decltype( if (submodel < 0) { SCP_vector eligible_submodels; for (int i = 0; i < pm->n_models; ++i) { - if (!pm->submodel[i].flags[Model::Submodel_flags::Is_lod, Model::Submodel_flags::Is_damaged, Model::Submodel_flags::Is_live_debris]) + if (!pm->submodel[i].flags[Model::Submodel_flags::Is_lod] || + !pm->submodel[i].flags[Model::Submodel_flags::Is_damaged] || + !pm->submodel[i].flags[Model::Submodel_flags::Is_live_debris]) eligible_submodels.emplace_back(i); } diff --git a/code/scripting/api/objs/ship.cpp b/code/scripting/api/objs/ship.cpp index 537a3f8c150..8ee33ca80e5 100644 --- a/code/scripting/api/objs/ship.cpp +++ b/code/scripting/api/objs/ship.cpp @@ -1654,7 +1654,7 @@ ADE_FUNC(callSupport, return ADE_RETURN_FALSE; } - if (aip->ai_flags[AI::AI_Flags::Being_repaired, AI::AI_Flags::Awaiting_repair]) { + if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) { return ADE_RETURN_FALSE; } diff --git a/code/scripting/api/objs/techroom.cpp b/code/scripting/api/objs/techroom.cpp index 54b12203bc4..453d35baf9f 100644 --- a/code/scripting/api/objs/techroom.cpp +++ b/code/scripting/api/objs/techroom.cpp @@ -182,7 +182,8 @@ ADE_VIRTVAR(isVisible, current.getScene()->flags.set(Cutscene::Cutscene_Flags::Viewable, visible); Pilot.save_savefile(); } - if (current.getScene()->flags[Cutscene::Cutscene_Flags::Viewable, Cutscene::Cutscene_Flags::Always_viewable] && + if ((current.getScene()->flags[Cutscene::Cutscene_Flags::Viewable] || + current.getScene()->flags[Cutscene::Cutscene_Flags::Always_viewable]) && !current.getScene()->flags[Cutscene::Cutscene_Flags::Never_viewable]) { return ade_set_args(L, "b", true); From 4608ac9f057f8b414bbbf01680926fa5cf956aa9 Mon Sep 17 00:00:00 2001 From: The Force <2040992+TheForce172@users.noreply.github.com> Date: Tue, 7 Jul 2026 21:02:11 +0100 Subject: [PATCH 3/5] suppress false positive --- code/ai/aicode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ai/aicode.cpp b/code/ai/aicode.cpp index 48c2eed51d2..112f581b5c8 100644 --- a/code/ai/aicode.cpp +++ b/code/ai/aicode.cpp @@ -12320,7 +12320,7 @@ void ai_process_subobjects(int objnum) // (previously in ship_evaluate_ai (previously in ship_process_post)) // Cyborg -- Unfortunately Ai info is not reliable and should just not be accessed here. // It will have no real effect on gameplay, since the server decides when turrets fire - if (!MULTIPLAYER_CLIENT && + if (!MULTIPLAYER_CLIENT && // NOLINT(readability-simplify-boolean-expr) (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair])) { if (aip->support_ship_objnum >= 0) From c08d4fd5d689c3aba190a8aecf2b1938a09a2b9c Mon Sep 17 00:00:00 2001 From: The Force <2040992+TheForce172@users.noreply.github.com> Date: Wed, 8 Jul 2026 20:09:01 +0100 Subject: [PATCH 4/5] Switch to using any/none_of --- code/ai/aicode.cpp | 38 ++++++++++---------- code/cutscene/cutscenes.cpp | 2 +- code/globalincs/flagset.h | 13 +++++++ code/hud/hudsquadmsg.cpp | 5 ++- code/missionui/missionbrief.cpp | 2 +- code/missionui/missionshipchoice.cpp | 3 +- code/model/animation/modelanimation.cpp | 4 +-- code/model/modelread.cpp | 10 ++---- code/network/multimsgs.cpp | 2 +- code/object/collideshipship.cpp | 9 ++--- code/object/object.cpp | 10 +++--- code/parse/sexp.cpp | 4 +-- code/particle/volumes/ModelSurfaceVolume.cpp | 4 +-- code/scripting/api/objs/ship.cpp | 2 +- code/scripting/api/objs/techroom.cpp | 4 +-- code/ship/ship.cpp | 19 +++++----- code/ship/ship.h | 4 +-- code/ship/shiphit.cpp | 2 +- code/weapon/weapon.h | 11 +++--- code/weapon/weapons.cpp | 5 ++- fred2/fredrender.cpp | 2 +- fred2/fredview.cpp | 2 +- qtfred/src/mission/EditorViewport.cpp | 4 +-- 23 files changed, 77 insertions(+), 84 deletions(-) diff --git a/code/ai/aicode.cpp b/code/ai/aicode.cpp index 112f581b5c8..520c7cac4e0 100644 --- a/code/ai/aicode.cpp +++ b/code/ai/aicode.cpp @@ -1399,7 +1399,7 @@ void ai_turn_towards_vector(const vec3d* dest, object* objp, const vec3d* slide_ } // Don't allow a ship to turn if it's prevented from turning. - if (objp->flags[Object::Object_Flags::Dont_change_orientation] || objp->flags[Object::Object_Flags::Immobile]) { + if (objp->flags.any_of(Object::Object_Flags::Dont_change_orientation,Object::Object_Flags::Immobile)) { return; } @@ -2147,7 +2147,7 @@ float get_wing_lowest_av_ab_speed(object *objp) ship_info *osip = &Ship_info[oshipp->ship_info_index]; if ((oaip->mode == AIM_WAYPOINTS) && (oshipp->wingnum == wingnum) && - (oaip->ai_flags[AI::AI_Flags::Formation_object] || oaip->ai_flags[AI::AI_Flags::Formation_wing])) { + (oaip->ai_flags.any_of(AI::AI_Flags::Formation_object,AI::AI_Flags::Formation_wing))) { float cur_max; if ((oshipp->flags[Ship::Ship_Flags::Afterburner_locked]) || !(osip->flags[Ship::Info_Flags::Afterburner]) || (o->phys_info.afterburner_max_vel.xyz.z <= o->phys_info.max_vel.xyz.z) || !(oaip->ai_flags[AI::AI_Flags::Free_afterburner_use] || oaip->ai_profile_flags[AI::Profile_Flags::Free_afterburner_use])) { @@ -6652,7 +6652,7 @@ void ai_maybe_announce_shockwave_weapon(object *firing_objp, int weapon_index) // AL 1-5-98: only avoid shockwave if not docked or repairing if (!object_is_docked(A) && - !(aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Being_repaired])) { + aip->ai_flags.none_of(AI::AI_Flags::Repairing,AI::AI_Flags::Being_repaired)) { aip->ai_flags.set(AI::AI_Flags::Avoid_shockwave_weapon); } } @@ -12321,7 +12321,7 @@ void ai_process_subobjects(int objnum) // Cyborg -- Unfortunately Ai info is not reliable and should just not be accessed here. // It will have no real effect on gameplay, since the server decides when turrets fire if (!MULTIPLAYER_CLIENT && // NOLINT(readability-simplify-boolean-expr) - (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair])) + (aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair))) { if (aip->support_ship_objnum >= 0) { @@ -13170,7 +13170,7 @@ void ai_do_repair_frame(object *objp, ai_info *aip, float frametime) static bool rearm_eta_found=false; - if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) { + if (aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)) { if (Ships[objp->instance].team == Iff_traitor) { ai_abort_rearm_request(objp); return; @@ -13537,7 +13537,7 @@ void ai_maybe_evade_locked_missile(object *objp, ai_info *aip) return; } - if (aip->ai_flags[AI::AI_Flags::No_dynamic] || aip->ai_flags[AI::AI_Flags::Kamikaze]) { // If not allowed to pursue dynamic objectives, don't evade. Dumb? + if (aip->ai_flags.any_of(AI::AI_Flags::No_dynamic,AI::AI_Flags::Kamikaze)) { // If not allowed to pursue dynamic objectives, don't evade. Dumb? //Maybe change. -- MK, 3/15/98 return; } @@ -13593,7 +13593,7 @@ void ai_maybe_evade_locked_missile(object *objp, ai_info *aip) } break; case AIM_DOCK: // Ships in dock mode can evade iif they are not currently repairing or docked. - if (object_is_docked(objp) || (aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Being_repaired])) + if (object_is_docked(objp) || (aip->ai_flags.any_of(AI::AI_Flags::Repairing,AI::AI_Flags::Being_repaired))) break; FALLTHROUGH; case AIM_GUARD: @@ -13743,7 +13743,7 @@ void maybe_evade_dumbfire_weapon(ai_info *aip) case AIM_WAYPOINTS: case AIM_FLY_TO_SHIP: case AIM_SAFETY: - if (!(aip->ai_flags[AI::AI_Flags::No_dynamic] || aip->ai_flags[AI::AI_Flags::Kamikaze]) && + if (aip->ai_flags.none_of(AI::AI_Flags::No_dynamic,AI::AI_Flags::Kamikaze) && Ship_info[Ships[aip->shipnum].ship_info_index].is_small_ship()) { aip->active_goal = AI_ACTIVE_GOAL_DYNAMIC; aip->previous_mode = aip->mode; @@ -14422,8 +14422,7 @@ int num_allies_rearming(object *objp) continue; if (Ships[A->instance].team == team) { - if (Ai_info[Ships[A->instance].ai_index].ai_flags[AI::AI_Flags::Repairing] || - Ai_info[Ships[A->instance].ai_index].ai_flags[AI::AI_Flags::Awaiting_repair]) { + if (Ai_info[Ships[A->instance].ai_index].ai_flags.any_of(AI::AI_Flags::Repairing,AI::AI_Flags::Awaiting_repair)) { count++; } } @@ -14455,7 +14454,7 @@ int maybe_request_support(object *objp) return 0; // A ship that is currently awaiting does not need support! - if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) + if (aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)) return 0; if (!timestamp_elapsed(aip->next_rearm_request_timestamp)) @@ -14780,7 +14779,7 @@ void ai_announce_ship_dying(object *dying_objp) // AL 1-5-98: only avoid shockwave if not docked or repairing if (!object_is_docked(A) && - !(aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Being_repaired])) { + aip->ai_flags.none_of(AI::AI_Flags::Repairing,AI::AI_Flags::Being_repaired)) { aip->ai_flags.set(AI::AI_Flags::Avoid_shockwave_ship); } } @@ -15111,7 +15110,7 @@ int ai_avoid_shockwave(object *objp, ai_info *aip) // Return true if this ship is close to being repaired, else return false. int ai_await_repair_frame(object *objp, ai_info *aip) { - if (!(aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair])) + if (aip->ai_flags.none_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)) return 0; if (aip->support_ship_objnum == -1) @@ -15372,11 +15371,11 @@ void ai_frame(int objnum) // Avoid a shockwave, if necessary. If a shockwave and rearming, stop rearming. if (aip->mode != AIM_PLAY_DEAD && - (aip->ai_flags[AI::AI_Flags::Avoid_shockwave_ship] || aip->ai_flags[AI::AI_Flags::Avoid_shockwave_weapon])) { + aip->ai_flags.any_of(AI::AI_Flags::Avoid_shockwave_ship,AI::AI_Flags::Avoid_shockwave_weapon)) { if (ai_avoid_shockwave(Pl_objp, aip)) { aip->ai_flags.remove(AI::AI_Flags::Big_ship_collide_recover_1); aip->ai_flags.remove(AI::AI_Flags::Big_ship_collide_recover_2); - if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) + if (aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)) ai_abort_rearm_request(Pl_objp); return; } @@ -15561,7 +15560,7 @@ void ai_frame(int objnum) aip->target_time += flFrametime; int in_formation = 0; - if (aip->ai_flags[AI::AI_Flags::Formation_object] || aip->ai_flags[AI::AI_Flags::Formation_wing]) { + if (aip->ai_flags.any_of(AI::AI_Flags::Formation_object,AI::AI_Flags::Formation_wing)) { in_formation = !ai_formation(); } @@ -16505,13 +16504,12 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, const vec3d *hit_normal) aip->last_hit_time = Missiontime; - if (aip->ai_flags[AI::AI_Flags::No_dynamic] || - aip->ai_flags[AI::AI_Flags::Kamikaze]) // If not allowed to pursue dynamic objectives, don't evade. Dumb? + if (aip->ai_flags.any_of(AI::AI_Flags::No_dynamic,AI::AI_Flags::Kamikaze)) // If not allowed to pursue dynamic objectives, don't evade. Dumb? //Maybe change. -- MK, 3/15/98 return; // If this ship is awaiting repair, abort! - if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) { + if (aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)) { if (get_hull_pct(objp_ship) < 0.3f) { // Note, only abort if hull below a certain level. aip->next_rearm_request_timestamp = timestamp(NEXT_REARM_TIMESTAMP/2); // Might request again after 15 seconds. @@ -16804,7 +16802,7 @@ int ai_abort_rearm_request(object *requester_objp) } requester_aip = &Ai_info[requester_shipp->ai_index]; - if (requester_aip->ai_flags[AI::AI_Flags::Being_repaired] || requester_aip->ai_flags[AI::AI_Flags::Awaiting_repair]){ + if (requester_aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)){ // support objnum is always valid once a rearm repair has been requested. It points to the // ship that is coming to repair me. diff --git a/code/cutscene/cutscenes.cpp b/code/cutscene/cutscenes.cpp index 469e4456bbf..32609c792fc 100644 --- a/code/cutscene/cutscenes.cpp +++ b/code/cutscene/cutscenes.cpp @@ -537,7 +537,7 @@ void cutscenes_screen_init() int u = 0; for (auto cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut, ++u) { - if ((cut->flags[Cutscene::Cutscene_Flags::Viewable] || cut->flags[Cutscene::Cutscene_Flags::Always_viewable]) && + if ((cut->flags.any_of(Cutscene::Cutscene_Flags::Viewable,Cutscene::Cutscene_Flags::Always_viewable)) && !cut->flags[Cutscene::Cutscene_Flags::Never_viewable]) { Cutscene_list.push_back(u); diff --git a/code/globalincs/flagset.h b/code/globalincs/flagset.h index 69c0f68de9b..1e336f61f50 100644 --- a/code/globalincs/flagset.h +++ b/code/globalincs/flagset.h @@ -23,7 +23,20 @@ class flagset { set(val); } } + template + bool any_of(T first, Ts... rest) const + { + static_assert((std::is_same::value && ...), + "All arguments to any_of() must be flags of the same enum type"); + return (*this)[first] || ((*this)[rest] || ...); + } + // Returns true if none of the given flags are set. + template + bool none_of(T first, Ts... rest) const + { + return !any_of(first, rest...); + } bool operator[](const T idx) const { return values[(static_cast < size_t >(idx))]; }; template diff --git a/code/hud/hudsquadmsg.cpp b/code/hud/hudsquadmsg.cpp index ba6206bd017..7d793d7116f 100644 --- a/code/hud/hudsquadmsg.cpp +++ b/code/hud/hudsquadmsg.cpp @@ -394,7 +394,7 @@ bool hud_squadmsg_wing_valid(wing *wingp) // a couple of special cases to account for before adding to count (or to menu). Don't count // wings that are leaving or left. - if ( wingp->flags[Ship::Wing_Flags::Gone] || wingp->flags[Ship::Wing_Flags::Departing] ) + if ( wingp->flags.any_of(Ship::Wing_Flags::Gone,Ship::Wing_Flags::Departing) ) return false; // Goober5000 - instead of checking wing leader, let's check all ships in wing; @@ -1842,8 +1842,7 @@ void hud_squadmsg_type_select( ) // check to see if the player is awaiting repair or being repaired. Active the abort and inactive the repair items // check to see if the player is scheduled to be repaired by incoming ship - if (Ai_info[Ships[Player_obj->instance].ai_index].ai_flags[AI::AI_Flags::Being_repaired] || - Ai_info[Ships[Player_obj->instance].ai_index].ai_flags[AI::AI_Flags::Awaiting_repair]) { + if (Ai_info[Ships[Player_obj->instance].ai_index].ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)) { MsgItems[TYPE_REPAIR_REARM_ITEM].active = 0; MsgItems[TYPE_REPAIR_REARM_ABORT_ITEM].active = 1; } diff --git a/code/missionui/missionbrief.cpp b/code/missionui/missionbrief.cpp index 7d91cb7b74e..b68d2a850fb 100644 --- a/code/missionui/missionbrief.cpp +++ b/code/missionui/missionbrief.cpp @@ -2098,7 +2098,7 @@ int brief_only_allow_briefing() return 1; } - if (The_mission.flags[Mission::Mission_Flags::Scramble] || The_mission.flags[Mission::Mission_Flags::Red_alert]) { + if (The_mission.flags.any_of(Mission::Mission_Flags::Scramble,Mission::Mission_Flags::Red_alert)) { return 1; } diff --git a/code/missionui/missionshipchoice.cpp b/code/missionui/missionshipchoice.cpp index f09af2118c6..197fd027b21 100644 --- a/code/missionui/missionshipchoice.cpp +++ b/code/missionui/missionshipchoice.cpp @@ -1977,8 +1977,7 @@ commit_pressed_status commit_pressed(bool API_Access) // Note: don't check for training, scramble, or red-alert missions // Note2: don't check missions without briefings either if (check_for_gaps_in_weapon_slots() && !(The_mission.game_type & MISSION_TYPE_TRAINING) && - !(The_mission.flags[Mission::Mission_Flags::Scramble] || The_mission.flags[Mission::Mission_Flags::Red_alert] || - The_mission.flags[Mission::Mission_Flags::No_briefing])) + The_mission.flags.none_of(Mission::Mission_Flags::Scramble,Mission::Mission_Flags::Red_alert,Mission::Mission_Flags::No_briefing)) { popup(PF_USE_AFFIRMATIVE_ICON, 1, diff --git a/code/model/animation/modelanimation.cpp b/code/model/animation/modelanimation.cpp index 9770e66ac3d..b98eebdda8b 100644 --- a/code/model/animation/modelanimation.cpp +++ b/code/model/animation/modelanimation.cpp @@ -224,7 +224,7 @@ namespace animation { if (m_flags[Animation_Flags::Random_starting_phase]) { instanceData.time = util::Random::next() * util::Random::INV_F_MAX_VALUE * instanceData.duration; //Check if we might be on the way backwards - if ((m_flags[Animation_Flags::Loop] || m_flags[Animation_Flags::Auto_Reverse]) && + if (m_flags.any_of(Animation_Flags::Loop,Animation_Flags::Auto_Reverse) && !m_flags[Animation_Flags::Reset_at_completion] && util::Random::flip_coin()) { prevTime = instanceData.duration; instanceData.canonicalDirection = ModelAnimationDirection::RWD; @@ -1379,7 +1379,7 @@ namespace animation { if (Animation_types.find(type)->second.second) { //This is a type where the code does not reset the animation. The animation is expected to auto-reset in one way or another. //If it doesn't, nothing will crash, but the result is most likely unintended. - if (!(animation->m_flags[Animation_Flags::Auto_Reverse] || animation->m_flags[Animation_Flags::Reset_at_completion])) { + if (animation->m_flags.none_of(Animation_Flags::Auto_Reverse,Animation_Flags::Reset_at_completion)) { error_display(0, "Animation trigger type %s expects an auto-reset flag to be set.", atype); } diff --git a/code/model/modelread.cpp b/code/model/modelread.cpp index 93afbd30983..d4a92c94595 100644 --- a/code/model/modelread.cpp +++ b/code/model/modelread.cpp @@ -2094,9 +2094,7 @@ modelread_status read_model_file_no_subsys(polymodel * pm, const char* filename, // Genghis: if we have a thruster and none of the collision // properties were provided, then set "nocollide_this_only". if (sm->flags[Model::Submodel_flags::Is_thruster] && - !(sm->flags[Model::Submodel_flags::No_collisions] || - sm->flags[Model::Submodel_flags::Nocollide_this_only] || - sm->flags[Model::Submodel_flags::Collide_invisible])) + sm->flags.none_of(Model::Submodel_flags::No_collisions,Model::Submodel_flags::Nocollide_this_only,Model::Submodel_flags::Collide_invisible)) { sm->flags.set(Model::Submodel_flags::Nocollide_this_only); } @@ -3449,10 +3447,8 @@ int model_load(const char* filename, ship_info* sip, ErrorType error_type, bool // Handle LODs named "detail0/1/2/etc" too (as opposed to "detaila/b/c/etc") if (sm1->parent == -1 && sm2->parent == -1 && - !(sm1->flags[Model::Submodel_flags::Is_damaged] || - sm1->flags[Model::Submodel_flags::Is_live_debris]) && - !(sm2->flags[Model::Submodel_flags::Is_damaged] || - sm2->flags[Model::Submodel_flags::Is_live_debris])) { + sm1->flags.none_of(Model::Submodel_flags::Is_damaged, Model::Submodel_flags::Is_live_debris) && + sm2->flags.none_of(Model::Submodel_flags::Is_damaged, Model::Submodel_flags::Is_live_debris)) { dl2 = dl2 - dl1; dl1 = 0; } diff --git a/code/network/multimsgs.cpp b/code/network/multimsgs.cpp index 9a0d14f1837..0dc6a20a9e2 100644 --- a/code/network/multimsgs.cpp +++ b/code/network/multimsgs.cpp @@ -7612,7 +7612,7 @@ void process_homing_weapon_info( ubyte *data, header *hinfo ) if ( homing_object->type == OBJ_WEAPON ) { auto flags_check = Weapon_info[Weapons[homing_object->instance].weapon_info_index].wi_flags; - if (!((flags_check[Weapon::Info_Flags::Bomb] || flags_check[Weapon::Info_Flags::Cmeasure]))) { + if (flags_check.none_of(Weapon::Info_Flags::Bomb, Weapon::Info_Flags::Cmeasure)) { nprintf(("Network", "Homing object is invalid for homing update\n")); return; } diff --git a/code/object/collideshipship.cpp b/code/object/collideshipship.cpp index 19e5146c668..47a46a8ff78 100644 --- a/code/object/collideshipship.cpp +++ b/code/object/collideshipship.cpp @@ -803,8 +803,7 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_ // We will try not to worry about the left over time in the frame // heavy's position unchanged by collision // light's position is heavy's position plus relative position from heavy - if (should_collide && !(lighter->flags[Object::Object_Flags::Dont_change_position] || - lighter->flags[Object::Object_Flags::Immobile])) { + if (should_collide && lighter->flags.none_of(Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile)) { vm_vec_add(&lighter->pos, &heavy->pos, &ship_ship_hit_info->light_collision_cm_pos); } @@ -822,8 +821,7 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_ } if (should_collide){ - if (!(heavy->flags[Object::Object_Flags::Dont_change_position] || - heavy->flags[Object::Object_Flags::Immobile])) { + if (heavy->flags.none_of(Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile)) { Assert(!vm_is_vec_nan(&direction_light)); vm_vec_scale_add2(&heavy->pos, &direction_light, 0.2f * (1.0f - heavy_light_mass_ratio)); vm_vec_scale_add2(&heavy->pos, &ship_ship_hit_info->collision_normal, -0.1f * (1.0f - heavy_light_mass_ratio)); @@ -842,8 +840,7 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_ //For landings, we want minimal movement on the light ship (just enough to keep the collision detection honest) if (ship_ship_hit_info->is_landing) { vm_vec_scale_add2(&lighter->pos, &ship_ship_hit_info->collision_normal, LANDING_POS_OFFSET); - } else if (!(lighter->flags[Object::Object_Flags::Dont_change_position] || - lighter->flags[Object::Object_Flags::Immobile])) { + } else if (lighter->flags.none_of(Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile)) { vm_vec_scale_add2(&lighter->pos, &direction_light, -0.2f * heavy_light_mass_ratio); vm_vec_scale_add2(&lighter->pos, &ship_ship_hit_info->collision_normal, 0.1f * heavy_light_mass_ratio); } diff --git a/code/object/object.cpp b/code/object/object.cpp index 1d98b01e175..44eeb967f4b 100644 --- a/code/object/object.cpp +++ b/code/object/object.cpp @@ -1641,10 +1641,12 @@ void obj_move_all(float frametime) } // Goober5000 - accommodate objects that aren't supposed to move in some way (at least until they're destroyed) - bool dont_change_position = (objp->flags[Object::Object_Flags::Dont_change_position] || objp->flags[Object::Object_Flags::Immobile]) && objp->hull_strength > 0.0f; - bool dont_change_orientation = (objp->flags[Object::Object_Flags::Dont_change_orientation] || - objp->flags[Object::Object_Flags::Immobile]) && - objp->hull_strength > 0.0f; + bool dont_change_position = + objp->flags.any_of(Object::Object_Flags::Dont_change_position, Object::Object_Flags::Immobile) && + objp->hull_strength > 0.0f; + bool dont_change_orientation = + objp->flags.any_of(Object::Object_Flags::Dont_change_orientation, Object::Object_Flags::Immobile) && + objp->hull_strength > 0.0f; // skip the physics if we're totally immobile if (!dont_change_position || !dont_change_orientation) { diff --git a/code/parse/sexp.cpp b/code/parse/sexp.cpp index adbfd669977..3f82142d176 100644 --- a/code/parse/sexp.cpp +++ b/code/parse/sexp.cpp @@ -4298,9 +4298,7 @@ int check_sexp_potential_issues(int node, int *bad_node, SCP_string &issue_msg) for (const auto so : list_range(&Ship_obj_list)) { const auto &obj = Objects[so->objnum]; - if (obj.flags[Object::Object_Flags::Immobile] || - obj.flags[Object::Object_Flags::Dont_change_position] || - obj.flags[Object::Object_Flags::Dont_change_orientation]) + if (obj.flags.any_of(Object::Object_Flags::Immobile,Object::Object_Flags::Dont_change_position,Object::Object_Flags::Dont_change_orientation)) { issue_msg = "At least one ship ("; issue_msg += Ships[obj.instance].ship_name; diff --git a/code/particle/volumes/ModelSurfaceVolume.cpp b/code/particle/volumes/ModelSurfaceVolume.cpp index 944feb699c5..f02dcd96943 100644 --- a/code/particle/volumes/ModelSurfaceVolume.cpp +++ b/code/particle/volumes/ModelSurfaceVolume.cpp @@ -21,9 +21,7 @@ vec3d ModelSurfaceVolume::sampleRandomPoint(const matrix &orientation, decltype( if (submodel < 0) { SCP_vector eligible_submodels; for (int i = 0; i < pm->n_models; ++i) { - if (!pm->submodel[i].flags[Model::Submodel_flags::Is_lod] || - !pm->submodel[i].flags[Model::Submodel_flags::Is_damaged] || - !pm->submodel[i].flags[Model::Submodel_flags::Is_live_debris]) + if (pm->submodel[i].flags.none_of(Model::Submodel_flags::Is_lod,Model::Submodel_flags::Is_damaged,Model::Submodel_flags::Is_live_debris)) eligible_submodels.emplace_back(i); } diff --git a/code/scripting/api/objs/ship.cpp b/code/scripting/api/objs/ship.cpp index 8ee33ca80e5..9cd6b9dd867 100644 --- a/code/scripting/api/objs/ship.cpp +++ b/code/scripting/api/objs/ship.cpp @@ -1654,7 +1654,7 @@ ADE_FUNC(callSupport, return ADE_RETURN_FALSE; } - if (aip->ai_flags[AI::AI_Flags::Being_repaired] || aip->ai_flags[AI::AI_Flags::Awaiting_repair]) { + if (aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair)) { return ADE_RETURN_FALSE; } diff --git a/code/scripting/api/objs/techroom.cpp b/code/scripting/api/objs/techroom.cpp index 453d35baf9f..bc74e54c19d 100644 --- a/code/scripting/api/objs/techroom.cpp +++ b/code/scripting/api/objs/techroom.cpp @@ -182,8 +182,8 @@ ADE_VIRTVAR(isVisible, current.getScene()->flags.set(Cutscene::Cutscene_Flags::Viewable, visible); Pilot.save_savefile(); } - if ((current.getScene()->flags[Cutscene::Cutscene_Flags::Viewable] || - current.getScene()->flags[Cutscene::Cutscene_Flags::Always_viewable]) && + if (current.getScene()->flags.any_of(Cutscene::Cutscene_Flags::Viewable, + Cutscene::Cutscene_Flags::Always_viewable) && !current.getScene()->flags[Cutscene::Cutscene_Flags::Never_viewable]) { return ade_set_args(L, "b", true); diff --git a/code/ship/ship.cpp b/code/ship/ship.cpp index 1c2f29b280f..f3d69d5b72e 100644 --- a/code/ship/ship.cpp +++ b/code/ship/ship.cpp @@ -9120,7 +9120,7 @@ void wing_maybe_cleanup( wing *wingp, int team ) // waves so we can mark the wing as gone and no other ships arrive // Goober5000 - also if it's departing... this is sort of, but not exactly, what :V: did; // but it seems to be consistent with how it should behave - if (wingp->flags[Ship::Wing_Flags::Departing] || wingp->flags[Ship::Wing_Flags::Departure_ordered]) + if (wingp->flags.any_of(Ship::Wing_Flags::Departing,Ship::Wing_Flags::Departure_ordered)) wingp->current_wave = wingp->num_waves; // Goober5000 - some changes for clarity and closing holes @@ -13386,8 +13386,8 @@ int ship_fire_primary(object * obj, int force, bool rollback_shot) for (int it = 0; it < num_primary_banks; it++) { if ((it == bank_to_fire) || - !(Weapon_info[swp->primary_bank_weapons[it]].wi_flags[Weapon::Info_Flags::Nolink] || - Weapon_info[swp->primary_bank_weapons[it]].wi_flags[Weapon::Info_Flags::No_linked_penalty])) + Weapon_info[swp->primary_bank_weapons[it]] + .wi_flags.none_of(Weapon::Info_Flags::Nolink, Weapon::Info_Flags::No_linked_penalty)) effective_primary_banks++; } Assert(effective_primary_banks >= 1); @@ -16865,8 +16865,7 @@ int ship_find_repair_ship( object *requester_obj, object **ship_we_found ) dist = vm_vec_dist_quick(&objp->pos, &requester_obj->pos); - if (aip->ai_flags[AI::AI_Flags::Repairing] || aip->ai_flags[AI::AI_Flags::Awaiting_repair] || - aip->ai_flags[AI::AI_Flags::Being_repaired]) + if (aip->ai_flags.any_of(AI::AI_Flags::Repairing,AI::AI_Flags::Awaiting_repair,AI::AI_Flags::Being_repaired)) { // support ship is already busy, track the one that will be // done soonest by estimating how many seconds it will take for the support ship @@ -22318,17 +22317,15 @@ bool ship::is_arriving(ship::warpstage stage, bool dock_leader_or_single) const { if (stage == ship::warpstage::BOTH) { if (!dock_leader_or_single) { - return flags[Ship::Ship_Flags::Arriving_stage_1] || - flags[Ship::Ship_Flags::Arriving_stage_1_dock_follower] || - flags[Ship::Ship_Flags::Arriving_stage_2] || flags[Ship::Ship_Flags::Arriving_stage_2_dock_follower]; + return flags.any_of(Ship::Ship_Flags::Arriving_stage_1,Ship::Ship_Flags::Arriving_stage_1_dock_follower,Ship::Ship_Flags::Arriving_stage_2,Ship::Ship_Flags::Arriving_stage_2_dock_follower); } else { - return flags[Ship::Ship_Flags::Arriving_stage_1] || flags[Ship::Ship_Flags::Arriving_stage_2]; + return flags.any_of(Ship::Ship_Flags::Arriving_stage_1,Ship::Ship_Flags::Arriving_stage_2); } } else if (stage == ship::warpstage::STAGE1) { if (!dock_leader_or_single) { - return flags[Ship::Ship_Flags::Arriving_stage_1] || flags[Ship::Ship_Flags::Arriving_stage_1_dock_follower]; + return flags.any_of(Ship::Ship_Flags::Arriving_stage_1,Ship::Ship_Flags::Arriving_stage_1_dock_follower); } else { return flags[Ship::Ship_Flags::Arriving_stage_1]; @@ -22336,7 +22333,7 @@ bool ship::is_arriving(ship::warpstage stage, bool dock_leader_or_single) const } if (stage == ship::warpstage::STAGE2) { if (!dock_leader_or_single) { - return flags[Ship::Ship_Flags::Arriving_stage_2] || flags[Ship::Ship_Flags::Arriving_stage_2_dock_follower]; + return flags.any_of(Ship::Ship_Flags::Arriving_stage_2,Ship::Ship_Flags::Arriving_stage_2_dock_follower); } else { return flags[Ship::Ship_Flags::Arriving_stage_2]; diff --git a/code/ship/ship.h b/code/ship/ship.h index 6cca86bf254..6107f7df89f 100644 --- a/code/ship/ship.h +++ b/code/ship/ship.h @@ -857,9 +857,9 @@ class ship bool is_arriving(ship::warpstage stage = ship::warpstage::BOTH, bool dock_leader_or_single = false) const; inline bool is_departing() const { - return flags[Ship::Ship_Flags::Depart_warp] || flags[Ship::Ship_Flags::Depart_dockbay]; + return flags.any_of(Ship::Ship_Flags::Depart_warp, Ship::Ship_Flags::Depart_dockbay); } - inline bool cannot_warp_flags() const { return flags[Ship::Ship_Flags::Warp_broken] || flags[Ship::Ship_Flags::Warp_never]|| flags[Ship::Ship_Flags::Disabled] || flags[Ship::Ship_Flags::No_subspace_drive]; } + inline bool cannot_warp_flags() const { return flags.any_of(Ship::Ship_Flags::Warp_broken,Ship::Ship_Flags::Warp_never,Ship::Ship_Flags::Disabled,Ship::Ship_Flags::No_subspace_drive); } inline bool is_dying_or_departing() const { return is_departing() || flags[Ship::Ship_Flags::Dying]; } const char* get_display_name() const; diff --git a/code/ship/shiphit.cpp b/code/ship/shiphit.cpp index 931c82f06a4..50ee1c8cb8a 100755 --- a/code/ship/shiphit.cpp +++ b/code/ship/shiphit.cpp @@ -179,7 +179,7 @@ void do_subobj_destroyed_stuff( ship *ship_p, ship_subsys *subsys, const vec3d* } // create fireballs when subsys destroy for large ships. - if (!(subsys->flags[Ship::Subsystem_Flags::Vanished] || subsys->flags[Ship::Subsystem_Flags::No_disappear]) && + if (subsys->flags.none_of(Ship::Subsystem_Flags::Vanished,Ship::Subsystem_Flags::No_disappear) && !no_explosion) { vec3d center_to_subsys; vm_vec_sub(¢er_to_subsys, &g_subobj_pos, &ship_objp->pos); diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index 77deeed7968..1c067b4bf62 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -948,22 +948,19 @@ struct weapon_info inline bool is_homing() const { - return wi_flags[Weapon::Info_Flags::Homing_heat] || wi_flags[Weapon::Info_Flags::Homing_aspect] || - wi_flags[Weapon::Info_Flags::Homing_javelin]; + return wi_flags.any_of(Weapon::Info_Flags::Homing_heat,Weapon::Info_Flags::Homing_aspect,Weapon::Info_Flags::Homing_javelin); } inline bool is_locked_homing() const { - return wi_flags[Weapon::Info_Flags::Homing_aspect] || wi_flags[Weapon::Info_Flags::Homing_javelin]; + return wi_flags.any_of(Weapon::Info_Flags::Homing_aspect,Weapon::Info_Flags::Homing_javelin); } inline bool hurts_big_ships() const { - return wi_flags[Weapon::Info_Flags::Bomb] || wi_flags[Weapon::Info_Flags::Beam] || - wi_flags[Weapon::Info_Flags::Huge] || wi_flags[Weapon::Info_Flags::Big_only]; + return wi_flags.any_of(Weapon::Info_Flags::Bomb,Weapon::Info_Flags::Beam,Weapon::Info_Flags::Huge,Weapon::Info_Flags::Big_only); } inline bool is_interceptable() const { - return wi_flags[Weapon::Info_Flags::Fighter_Interceptable] || - wi_flags[Weapon::Info_Flags::Turret_Interceptable]; + return wi_flags.any_of(Weapon::Info_Flags::Fighter_Interceptable,Weapon::Info_Flags::Turret_Interceptable); } inline bool is_mine() const { return wi_flags[Weapon::Info_Flags::Mine]; } diff --git a/code/weapon/weapons.cpp b/code/weapon/weapons.cpp index 90e409112f6..b373b7645d1 100644 --- a/code/weapon/weapons.cpp +++ b/code/weapon/weapons.cpp @@ -4147,8 +4147,7 @@ int parse_weapon(int subtype, bool replace, const char *filename) if (optional_string("$Weapon Hitpoints:")) { stuff_int(&wip->weapon_hitpoints); - } else if (first_time && (wip->wi_flags[Weapon::Info_Flags::Turret_Interceptable] || - wip->wi_flags[Weapon::Info_Flags::Fighter_Interceptable] || wip->wi_flags[Weapon::Info_Flags::Mine])) { + } else if (first_time && (wip->wi_flags.any_of(Weapon::Info_Flags::Turret_Interceptable,Weapon::Info_Flags::Fighter_Interceptable,Weapon::Info_Flags::Mine))) { wip->weapon_hitpoints = wip->is_mine() ? 50 : 25; // mines are tankier by default, like bombs } @@ -5518,7 +5517,7 @@ void find_homing_object(object *weapon_objp, int num) else if (objp->type == OBJ_WEAPON) { //don't attempt to home on weapons if the weapon is a huge weapon or is a javelin homing weapon. - if (wip->wi_flags[Weapon::Info_Flags::Huge] || wip->wi_flags[Weapon::Info_Flags::Homing_javelin]) + if (wip->wi_flags.any_of(Weapon::Info_Flags::Huge,Weapon::Info_Flags::Homing_javelin)) continue; //don't look for local ssms that are gone for the time being diff --git a/fred2/fredrender.cpp b/fred2/fredrender.cpp index 19f4af3e86b..26edb834b43 100644 --- a/fred2/fredrender.cpp +++ b/fred2/fredrender.cpp @@ -1426,7 +1426,7 @@ int object_check_collision(object *objp, vec3d *p0, vec3d *p1, vec3d *hitpos) { // PROP HERE? - if (objp->flags[Object::Object_Flags::Hidden, Object::Object_Flags::Locked_from_editing]) + if (objp->flags.any_of(Object::Object_Flags::Hidden, Object::Object_Flags::Locked_from_editing)) return 0; if ((Show_ship_models || Show_outlines) && (objp->type == OBJ_SHIP)) { diff --git a/fred2/fredview.cpp b/fred2/fredview.cpp index 89efcc5bfbf..0bc4d3fae51 100644 --- a/fred2/fredview.cpp +++ b/fred2/fredview.cpp @@ -1463,7 +1463,7 @@ void select_objects() ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { valid = 1; - if (ptr->flags[Object::Object_Flags::Hidden, Object::Object_Flags::Locked_from_editing]) + if (ptr->flags.any_of(Object::Object_Flags::Hidden, Object::Object_Flags::Locked_from_editing)) valid = 0; Assert(ptr->type != OBJ_NONE); diff --git a/qtfred/src/mission/EditorViewport.cpp b/qtfred/src/mission/EditorViewport.cpp index 638d58f46ff..dfbf5d5f08d 100644 --- a/qtfred/src/mission/EditorViewport.cpp +++ b/qtfred/src/mission/EditorViewport.cpp @@ -282,7 +282,7 @@ void EditorViewport::select_objects(const Marking_box& box) { ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { valid = 1; - if (ptr->flags[Object::Object_Flags::Hidden] || ptr->flags[Object::Object_Flags::Locked_from_editing]) { + if (ptr->flags.any_of(Object::Object_Flags::Hidden,Object::Object_Flags::Locked_from_editing)) { valid = 0; } if (!isObjectVisibleInLayer(ptr)) { @@ -705,7 +705,7 @@ int EditorViewport::object_check_collision(object* objp, vec3d* p0, vec3d* p1, v return 0; } - if (objp->flags[Object::Object_Flags::Hidden] || objp->flags[Object::Object_Flags::Locked_from_editing]) { + if (objp->flags.any_of(Object::Object_Flags::Hidden,Object::Object_Flags::Locked_from_editing)) { return 0; } if (!isObjectVisibleInLayer(objp)) { From 61cf6b1e6f68502adf1e899d760d636fbae8acce Mon Sep 17 00:00:00 2001 From: The Force <2040992+TheForce172@users.noreply.github.com> Date: Fri, 10 Jul 2026 03:21:02 +0100 Subject: [PATCH 5/5] Address Feedback --- code/ai/aicode.cpp | 8 +- code/globalincs/flagset.h | 1 + code/ship/ship.h | 36 ++----- code/weapon/weapon.h | 22 +---- test/src/globalincs/test_flagset.cpp | 134 +++++++++++++-------------- 5 files changed, 82 insertions(+), 119 deletions(-) diff --git a/code/ai/aicode.cpp b/code/ai/aicode.cpp index 520c7cac4e0..5569a9b554a 100644 --- a/code/ai/aicode.cpp +++ b/code/ai/aicode.cpp @@ -12320,7 +12320,7 @@ void ai_process_subobjects(int objnum) // (previously in ship_evaluate_ai (previously in ship_process_post)) // Cyborg -- Unfortunately Ai info is not reliable and should just not be accessed here. // It will have no real effect on gameplay, since the server decides when turrets fire - if (!MULTIPLAYER_CLIENT && // NOLINT(readability-simplify-boolean-expr) + if (!MULTIPLAYER_CLIENT && (aip->ai_flags.any_of(AI::AI_Flags::Being_repaired,AI::AI_Flags::Awaiting_repair))) { if (aip->support_ship_objnum >= 0) @@ -13537,8 +13537,7 @@ void ai_maybe_evade_locked_missile(object *objp, ai_info *aip) return; } - if (aip->ai_flags.any_of(AI::AI_Flags::No_dynamic,AI::AI_Flags::Kamikaze)) { // If not allowed to pursue dynamic objectives, don't evade. Dumb? - //Maybe change. -- MK, 3/15/98 + if (aip->ai_flags.any_of(AI::AI_Flags::No_dynamic,AI::AI_Flags::Kamikaze)) { // If not allowed to pursue dynamic objectives, don't evade. Dumb? //Maybe change. -- MK, 3/15/98 return; } @@ -16504,8 +16503,7 @@ void ai_ship_hit(object *objp_ship, object *hit_objp, const vec3d *hit_normal) aip->last_hit_time = Missiontime; - if (aip->ai_flags.any_of(AI::AI_Flags::No_dynamic,AI::AI_Flags::Kamikaze)) // If not allowed to pursue dynamic objectives, don't evade. Dumb? - //Maybe change. -- MK, 3/15/98 + if (aip->ai_flags.any_of(AI::AI_Flags::No_dynamic,AI::AI_Flags::Kamikaze)) // If not allowed to pursue dynamic objectives, don't evade. Dumb? //Maybe change. -- MK, 3/15/98 return; // If this ship is awaiting repair, abort! diff --git a/code/globalincs/flagset.h b/code/globalincs/flagset.h index 1e336f61f50..7c03779efeb 100644 --- a/code/globalincs/flagset.h +++ b/code/globalincs/flagset.h @@ -23,6 +23,7 @@ class flagset { set(val); } } + // Returns true if any of the given flags are set. template bool any_of(T first, Ts... rest) const { diff --git a/code/ship/ship.h b/code/ship/ship.h index 6107f7df89f..1f0f2785d4f 100644 --- a/code/ship/ship.h +++ b/code/ship/ship.h @@ -855,10 +855,7 @@ class ship //Helper functions bool is_arriving(ship::warpstage stage = ship::warpstage::BOTH, bool dock_leader_or_single = false) const; - inline bool is_departing() const - { - return flags.any_of(Ship::Ship_Flags::Depart_warp, Ship::Ship_Flags::Depart_dockbay); - } + inline bool is_departing() const { return flags.any_of(Ship::Ship_Flags::Depart_warp,Ship::Ship_Flags::Depart_dockbay); } inline bool cannot_warp_flags() const { return flags.any_of(Ship::Ship_Flags::Warp_broken,Ship::Ship_Flags::Warp_never,Ship::Ship_Flags::Disabled,Ship::Ship_Flags::No_subspace_drive); } inline bool is_dying_or_departing() const { return is_departing() || flags[Ship::Ship_Flags::Dying]; } @@ -1524,34 +1521,13 @@ class ship_info //Helper functions - inline bool is_small_ship() const - { - return flags[Ship::Info_Flags::Fighter] || flags[Ship::Info_Flags::Bomber] || flags[Ship::Info_Flags::Support] - || flags[Ship::Info_Flags::Escapepod]; - } - inline bool is_big_ship() const - { - return flags[Ship::Info_Flags::Cruiser] || flags[Ship::Info_Flags::Freighter] || - flags[Ship::Info_Flags::Transport] || - flags[Ship::Info_Flags::Corvette] || - flags[Ship::Info_Flags::Gas_miner] || flags[Ship::Info_Flags::Awacs]; - } - inline bool is_huge_ship() const - { - return flags[Ship::Info_Flags::Capital] || flags[Ship::Info_Flags::Supercap] || - flags[Ship::Info_Flags::Drydock] || flags[Ship::Info_Flags::Knossos_device]; - } - inline bool is_flyable() const - { - return !( - flags[Ship::Info_Flags::Cargo] || flags[Ship::Info_Flags::Navbuoy] || flags[Ship::Info_Flags::Sentrygun]); - } // AL 11-24-97: this useful to know for targeting reasons + inline bool is_small_ship() const { return flags.any_of(Ship::Info_Flags::Fighter,Ship::Info_Flags::Bomber,Ship::Info_Flags::Support,Ship::Info_Flags::Escapepod); } + inline bool is_big_ship() const { return flags.any_of(Ship::Info_Flags::Cruiser,Ship::Info_Flags::Freighter,Ship::Info_Flags::Transport,Ship::Info_Flags::Corvette,Ship::Info_Flags::Gas_miner,Ship::Info_Flags::Awacs); } + inline bool is_huge_ship() const { return flags.any_of(Ship::Info_Flags::Capital,Ship::Info_Flags::Supercap,Ship::Info_Flags::Drydock,Ship::Info_Flags::Knossos_device); } + inline bool is_flyable() const { return flags.none_of(Ship::Info_Flags::Cargo,Ship::Info_Flags::Navbuoy,Ship::Info_Flags::Sentrygun); } // AL 11-24-97: this useful to know for targeting reasons // note: code that previously used is_harmless() / SIF_HARMLESS now uses several flags defined in objecttypes.tbl // inline bool is_harmless() const { return flags[Ship::Info_Flags::Cargo, Ship::Info_Flags::Navbuoy, Ship::Info_Flags::Escapepod]; } // AL 12-3-97: ships that are not a threat - inline bool is_fighter_bomber() const - { - return flags[Ship::Info_Flags::Fighter] || flags[Ship::Info_Flags::Bomber]; - } + inline bool is_fighter_bomber() const { return flags.any_of(Ship::Info_Flags::Fighter,Ship::Info_Flags::Bomber); } inline bool is_big_or_huge() const { return is_big_ship() || is_huge_ship(); } inline bool avoids_shockwaves() const { return is_small_ship(); } diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index 1c067b4bf62..ed59726b94f 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -946,23 +946,11 @@ struct weapon_info inline bool is_beam() const { return subtype == WP_BEAM || wi_flags[Weapon::Info_Flags::Beam]; } inline bool is_non_beam_primary() const { return subtype == WP_LASER && !wi_flags[Weapon::Info_Flags::Beam]; } - inline bool is_homing() const - { - return wi_flags.any_of(Weapon::Info_Flags::Homing_heat,Weapon::Info_Flags::Homing_aspect,Weapon::Info_Flags::Homing_javelin); - } - inline bool is_locked_homing() const - { - return wi_flags.any_of(Weapon::Info_Flags::Homing_aspect,Weapon::Info_Flags::Homing_javelin); - } - inline bool hurts_big_ships() const - { - return wi_flags.any_of(Weapon::Info_Flags::Bomb,Weapon::Info_Flags::Beam,Weapon::Info_Flags::Huge,Weapon::Info_Flags::Big_only); - } - inline bool is_interceptable() const - { - return wi_flags.any_of(Weapon::Info_Flags::Fighter_Interceptable,Weapon::Info_Flags::Turret_Interceptable); - } - inline bool is_mine() const { return wi_flags[Weapon::Info_Flags::Mine]; } + inline bool is_homing() const { return wi_flags.any_of(Weapon::Info_Flags::Homing_heat,Weapon::Info_Flags::Homing_aspect,Weapon::Info_Flags::Homing_javelin); } + inline bool is_locked_homing() const { return wi_flags.any_of(Weapon::Info_Flags::Homing_aspect,Weapon::Info_Flags::Homing_javelin); } + inline bool hurts_big_ships() const { return wi_flags.any_of(Weapon::Info_Flags::Bomb,Weapon::Info_Flags::Beam,Weapon::Info_Flags::Huge,Weapon::Info_Flags::Big_only); } + inline bool is_interceptable() const { return wi_flags.any_of(Weapon::Info_Flags::Fighter_Interceptable,Weapon::Info_Flags::Turret_Interceptable); } + inline bool is_mine() const { return wi_flags[Weapon::Info_Flags::Mine]; } const char* get_display_name() const; bool has_display_name() const; diff --git a/test/src/globalincs/test_flagset.cpp b/test/src/globalincs/test_flagset.cpp index 7bc68e32cfa..fa3377aba3f 100644 --- a/test/src/globalincs/test_flagset.cpp +++ b/test/src/globalincs/test_flagset.cpp @@ -1,67 +1,67 @@ - -#include - -#include - -FLAG_LIST(TestFlags) -{ - First = 0, - Second, - Another, - AndAnother, - One, - Two, - - NUM_VALUES -}; - -TEST(FlagsetTests, initializer_list) { - { - flagset flags{}; - - ASSERT_FALSE(flags[TestFlags::First]); - ASSERT_FALSE(flags[TestFlags::Second]); - ASSERT_FALSE(flags[TestFlags::Another]); - ASSERT_FALSE(flags[TestFlags::AndAnother]); - } - { - flagset flags{ TestFlags::First}; - - ASSERT_TRUE(flags[TestFlags::First]); - ASSERT_FALSE(flags[TestFlags::Second]); - ASSERT_FALSE(flags[TestFlags::Another]); - ASSERT_FALSE(flags[TestFlags::AndAnother]); - } -} - -TEST(FlagsetTests, two_flags) { - { - flagset flags{ TestFlags::First, TestFlags::Second }; - - ASSERT_TRUE((flags[TestFlags::First, TestFlags::Second])); - ASSERT_TRUE((flags[TestFlags::First, TestFlags::Another])); - ASSERT_FALSE((flags[TestFlags::AndAnother, TestFlags::Another])); - } -} - -TEST(FlagsetTests, three_flags) { - { - flagset flags{ TestFlags::First, TestFlags::Second, TestFlags::Another }; - - ASSERT_TRUE((flags[TestFlags::First, TestFlags::Second, TestFlags::Another])); - ASSERT_FALSE((flags[TestFlags::One, TestFlags::Two, TestFlags::AndAnother])); - } -} - -TEST(FlagsetTests, numeric_conversion) { - { - flagset base{ TestFlags::First, TestFlags::Second, TestFlags::Another }; - - flagset converted; - - converted.from_u64(base.to_u64()); - - ASSERT_TRUE(base == converted); - } -} - + +#include + +#include + +FLAG_LIST(TestFlags) +{ + First = 0, + Second, + Another, + AndAnother, + One, + Two, + + NUM_VALUES +}; + +TEST(FlagsetTests, initializer_list) { + { + flagset flags{}; + + ASSERT_FALSE(flags[TestFlags::First]); + ASSERT_FALSE(flags[TestFlags::Second]); + ASSERT_FALSE(flags[TestFlags::Another]); + ASSERT_FALSE(flags[TestFlags::AndAnother]); + } + { + flagset flags{ TestFlags::First}; + + ASSERT_TRUE(flags[TestFlags::First]); + ASSERT_FALSE(flags[TestFlags::Second]); + ASSERT_FALSE(flags[TestFlags::Another]); + ASSERT_FALSE(flags[TestFlags::AndAnother]); + } +} + +TEST(FlagsetTests, two_flags) { + { + flagset flags{ TestFlags::First, TestFlags::Second }; + + ASSERT_TRUE((flags.any_of(TestFlags::First, TestFlags::Second))); + ASSERT_TRUE((flags.any_of(TestFlags::First, TestFlags::Another))); + ASSERT_FALSE((flags.any_of(TestFlags::AndAnother, TestFlags::Another))); + } +} + +TEST(FlagsetTests, three_flags) { + { + flagset flags{ TestFlags::First, TestFlags::Second, TestFlags::Another }; + + ASSERT_TRUE((flags.any_of(TestFlags::First, TestFlags::Second, TestFlags::Another))); + ASSERT_FALSE((flags.any_of(TestFlags::One, TestFlags::Two, TestFlags::AndAnother))); + } +} + +TEST(FlagsetTests, numeric_conversion) { + { + flagset base{ TestFlags::First, TestFlags::Second, TestFlags::Another }; + + flagset converted; + + converted.from_u64(base.to_u64()); + + ASSERT_TRUE(base == converted); + } +} +