Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move vehicle flyability to a flag, allow modifying flying vehicles #40509

Merged
merged 1 commit into from
May 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/json/vehicleparts/rotor.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"color": "light_blue",
"broken_symbol": "O",
"broken_color": "light_gray",
"flags": [ "ROTOR", "NO_INSTALL_PLAYER", "NO_UNINSTALL", "NO_REPAIR", "NO_MODIFY_VEHICLE" ],
"flags": [ "ROTOR", "NO_INSTALL_PLAYER", "NO_UNINSTALL", "NO_REPAIR" ],
"description": "A set of aerofoil helicopter rotors, when spun at high speed, they generate thrust via lift."
},
{
Expand Down
36 changes: 18 additions & 18 deletions data/json/vehicleparts/vehicle_parts.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "15 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "SEAT", "BOARDABLE", "CARGO", "BELTABLE" ],
"flags": [ "SEAT", "BOARDABLE", "CARGO", "BELTABLE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_seat",
"damage_reduction": { "all": 2 }
},
Expand Down Expand Up @@ -162,7 +162,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "15 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "BED", "SEAT", "BOARDABLE", "BELTABLE", "CARGO" ],
"flags": [ "BED", "SEAT", "BOARDABLE", "BELTABLE", "CARGO", "SIMPLE_PART" ],
"breaks_into": "ig_vp_seat",
"damage_reduction": { "all": 3 }
},
Expand Down Expand Up @@ -589,7 +589,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "OBSTACLE", "OPENABLE", "BOARDABLE", "WINDOW" ],
"flags": [ "CARGO", "OBSTACLE", "OPENABLE", "BOARDABLE", "WINDOW", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 21 }
},
Expand All @@ -613,7 +613,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "OBSTACLE", "OPAQUE", "OPENABLE", "BOARDABLE" ],
"flags": [ "CARGO", "OBSTACLE", "OPAQUE", "OPENABLE", "BOARDABLE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 28 }
},
Expand All @@ -637,7 +637,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "OBSTACLE", "OPENABLE", "BOARDABLE", "WINDOW" ],
"flags": [ "CARGO", "OBSTACLE", "OPENABLE", "BOARDABLE", "WINDOW", "SIMPLE_PART" ],
"breaks_into": "ig_vp_hdframe",
"damage_reduction": { "all": 68 }
},
Expand All @@ -661,7 +661,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "OBSTACLE", "OPAQUE", "OPENABLE", "BOARDABLE" ],
"flags": [ "CARGO", "OBSTACLE", "OPAQUE", "OPENABLE", "BOARDABLE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_hdframe",
"damage_reduction": { "all": 75 }
},
Expand All @@ -684,7 +684,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "OBSTACLE", "OPAQUE", "OPENABLE", "ROOF", "BOARDABLE" ],
"flags": [ "OBSTACLE", "OPAQUE", "OPENABLE", "ROOF", "BOARDABLE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 28 }
},
Expand All @@ -708,7 +708,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_weld_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED" ],
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 30 }
},
Expand All @@ -732,7 +732,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_weld_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED", "OPAQUE" ],
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED", "OPAQUE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 34 }
},
Expand All @@ -756,7 +756,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_weld_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 4 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED" ],
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED", "SIMPLE_PART" ],
"breaks_into": "ig_vp_hdframe",
"damage_reduction": { "all": 78 }
},
Expand All @@ -780,7 +780,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_weld_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 4 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED", "OPAQUE" ],
"flags": [ "CARGO", "LOCKABLE_CARGO", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "COVERED", "OPAQUE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_hdframe",
"damage_reduction": { "all": 80 }
},
Expand Down Expand Up @@ -1154,7 +1154,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_weld_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 2 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "LOCKABLE_CARGO", "COVERED", "BOARDABLE" ],
"flags": [ "CARGO", "LOCKABLE_CARGO", "COVERED", "BOARDABLE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 30 }
},
Expand Down Expand Up @@ -2628,7 +2628,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "LOW_FINAL_AIR_DRAG", "NO_ROOF_NEEDED", "WINDOW" ],
"flags": [ "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "LOW_FINAL_AIR_DRAG", "NO_ROOF_NEEDED", "WINDOW", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 25 }
},
Expand All @@ -2651,7 +2651,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "LOW_FINAL_AIR_DRAG", "WINDOW" ],
"flags": [ "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "LOW_FINAL_AIR_DRAG", "WINDOW", "SIMPLE_PART" ],
"breaks_into": "ig_vp_hdframe",
"damage_reduction": { "all": 78 }
},
Expand All @@ -2674,7 +2674,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "OPAQUE", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE" ],
"flags": [ "OPAQUE", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_sheet_metal",
"damage_reduction": { "all": 24 }
},
Expand All @@ -2697,7 +2697,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_bolt", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE" ],
"flags": [ "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE", "SIMPLE_PART" ],
"breaks_into": "ig_vp_frame",
"damage_reduction": { "all": 26 }
},
Expand Down Expand Up @@ -3044,7 +3044,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "15 m", "using": [ [ "vehicle_nail_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "30 m", "using": [ [ "adhesive", 2 ] ] }
},
"flags": [ "OBSTACLE", "OPENABLE", "BOARDABLE", "WINDOW" ],
"flags": [ "OBSTACLE", "OPENABLE", "BOARDABLE", "WINDOW", "SIMPLE_PART" ],
"breaks_into": [ { "item": "splinter", "count": [ 7, 9 ] } ],
"damage_reduction": { "all": 8 }
},
Expand All @@ -3067,7 +3067,7 @@
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "15 m", "using": [ [ "vehicle_nail_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 3 ] ], "time": "30 m", "using": [ [ "adhesive", 2 ] ] }
},
"flags": [ "OBSTACLE", "OPENABLE", "BOARDABLE", "OPAQUE" ],
"flags": [ "OBSTACLE", "OPENABLE", "BOARDABLE", "OPAQUE", "SIMPLE_PART" ],
"breaks_into": [ { "item": "splinter", "count": [ 7, 9 ] } ],
"damage_reduction": { "all": 12 }
},
Expand Down
1 change: 1 addition & 0 deletions src/activity_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum class do_activity_reason : int {
ALREADY_WORKING, // somebody is already working there
NEEDS_VEH_DECONST, // There is a vehicle part there that we can deconstruct, given the right tools.
NEEDS_VEH_REPAIR, // There is a vehicle part there that can be repaired, given the right tools.
WOULD_PREVENT_VEH_FLYING, // Attempting to perform this activity on a vehicle would prevent it from flying
NEEDS_MINING, // This spot can be mined, if the right tool is present.
NEEDS_FISHING // This spot can be fished, if the right tool is present.
};
Expand Down
8 changes: 8 additions & 0 deletions src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,10 @@ static activity_reason_info can_do_activity_there( const activity_id &act, playe
if( vpindex == -1 || !veh->can_unmount( vpindex ) ) {
continue;
}
// If removing this part would make the vehicle non-flyable, avoid it
if( veh->would_prevent_flyable( vpinfo ) ) {
return activity_reason_info::fail( do_activity_reason::WOULD_PREVENT_VEH_FLYING );
}
// this is the same part that somebody else wants to work on, or already is.
if( std::find( already_working_indexes.begin(), already_working_indexes.end(),
vpindex ) != already_working_indexes.end() ) {
Expand Down Expand Up @@ -1174,6 +1178,10 @@ static activity_reason_info can_do_activity_there( const activity_id &act, playe
part_elem->info().repair_requirements().is_empty() ) {
continue;
}
// If repairing this part would make the vehicle non-flyable, avoid it
if( veh->would_prevent_flyable( vpinfo ) ) {
return activity_reason_info::fail( do_activity_reason::WOULD_PREVENT_VEH_FLYING );
}
if( std::find( already_working_indexes.begin(), already_working_indexes.end(),
vpindex ) != already_working_indexes.end() ) {
continue;
Expand Down
20 changes: 13 additions & 7 deletions src/handle_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,19 @@ static void pldrive( const tripoint &p )
return;
}
}
if( p.z != 0 && !u.has_trait( trait_PROF_HELI_PILOT ) ) {
u.add_msg_if_player( m_info, _( "You have no idea how to make the vehicle fly." ) );
return;
}
if( p.z != 0 && !g->m.has_zlevels() ) {
u.add_msg_if_player( m_info, _( "This vehicle doesn't look very airworthy." ) );
return;
if( p.z != 0 ) {
if( !u.has_trait( trait_PROF_HELI_PILOT ) ) {
u.add_msg_if_player( m_info, _( "You have no idea how to make the vehicle fly." ) );
return;
}
if( !veh->is_flyable() ) {
u.add_msg_if_player( m_info, _( "This vehicle doesn't look very airworthy." ) );
return;
}
if( !g->m.has_zlevels() ) {
u.add_msg_if_player( m_info, _( "This vehicle cannot be flown without z levels." ) );
return;
}
}
if( p.z == -1 ) {
if( veh->check_heli_descend( u ) ) {
Expand Down
2 changes: 2 additions & 0 deletions src/savegame_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2692,6 +2692,7 @@ void vehicle::deserialize( JsonIn &jsin )
data.read( "is_following", is_following );
data.read( "is_patrolling", is_patrolling );
data.read( "autodrive_local_target", autodrive_local_target );
data.read( "airworthy", flyable );
data.read( "summon_time_limit", summon_time_limit );
data.read( "magic", magic );
// Need to manually backfill the active item cache since the part loader can't call its vehicle.
Expand Down Expand Up @@ -2854,6 +2855,7 @@ void vehicle::serialize( JsonOut &json ) const
json.member( "is_following", is_following );
json.member( "is_patrolling", is_patrolling );
json.member( "autodrive_local_target", autodrive_local_target );
json.member( "airworthy", flyable );
json.member( "summon_time_limit", summon_time_limit );
json.member( "magic", magic );
json.end_object();
Expand Down
35 changes: 34 additions & 1 deletion src/veh_interact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,16 @@ bool veh_interact::do_install( std::string &msg )
default:
break;
}
// Modifying a vehicle with rotors will make in not flightworthy (until we've got a better model)
// It can only be the player doing this - an npc won't work well with query_yn
if( veh->would_prevent_flyable( *sel_vpart_info ) ) {
if( query_yn(
_( "Installing this part will mean that this vehicle is no longer flightworthy. Continue?" ) ) ) {
veh->set_flyable( false );
} else {
return false;
}
}
if( veh->is_foldable() && !sel_vpart_info->has_flag( "FOLDABLE" ) &&
!query_yn( _( "Installing this part will make the vehicle unfoldable. Continue?" ) ) ) {
return true;
Expand Down Expand Up @@ -1182,7 +1192,8 @@ bool veh_interact::do_repair( std::string &msg )

std::string nmsg;

bool ok;
// this will always be set, but the gcc thinks that sometimes it won't be
bool ok = true;
if( pt.is_broken() ) {
ok = format_reqs( nmsg, vp.install_requirements(), vp.install_skills, vp.install_time( g->u ) );
} else {
Expand All @@ -1193,6 +1204,17 @@ bool veh_interact::do_repair( std::string &msg )
} else if( veh->has_part( "NO_MODIFY_VEHICLE" ) && !vp.has_flag( "SIMPLE_PART" ) ) {
nmsg += colorize( _( "This vehicle cannot be repaired.\n" ), c_light_red );
ok = false;
} else if( veh->would_prevent_flyable( vp ) ) {
// Modifying a vehicle with rotors will make in not flightworthy (until we've got a better model)
// It can only be the player doing this - an npc won't work well with query_yn
if( query_yn(
_( "Repairing this part will mean that this vehicle is no longer flightworthy. Continue?" ) ) ) {
veh->set_flyable( false );
} else {
nmsg += colorize( _( "You chose not to install this part to keep the vehicle flyable.\n" ),
c_light_red );
ok = false;
}
} else {
ok = format_reqs( nmsg, vp.repair_requirements() * pt.base.damage_level( 4 ), vp.repair_skills,
vp.repair_time( g->u ) * pt.base.damage() / pt.base.max_damage() );
Expand Down Expand Up @@ -1862,6 +1884,17 @@ bool veh_interact::do_remove( std::string &msg )
default:
break;
}

// Modifying a vehicle with rotors will make in not flightworthy (until we've got a better model)
// It can only be the player doing this - an npc won't work well with query_yn
if( veh->would_prevent_flyable( veh->parts[part].info() ) ) {
if( query_yn(
_( "Removing this part will mean that this vehicle is no longer flightworthy. Continue?" ) ) ) {
veh->set_flyable( false );
} else {
return false;
}
}
const std::vector<npc *> helpers = g->u.get_crafting_helpers();
for( const npc *np : helpers ) {
add_msg( m_info, _( "%s helps with this task…" ), np->name );
Expand Down
8 changes: 6 additions & 2 deletions src/veh_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static const std::unordered_map<std::string, vpart_bitflags> vpart_bitflag_map =
{ "SEATBELT", VPFLAG_SEATBELT },
{ "WHEEL", VPFLAG_WHEEL },
{ "ROTOR", VPFLAG_ROTOR },
{ "ROTOR_SIMPLE", VPFLAG_ROTOR_SIMPLE },
{ "FLOATS", VPFLAG_FLOATS },
{ "DOME_LIGHT", VPFLAG_DOME_LIGHT },
{ "AISLE_LIGHT", VPFLAG_AISLE_LIGHT },
Expand Down Expand Up @@ -421,7 +422,7 @@ void vpart_info::load( const JsonObject &jo, const std::string &src )
load_wheel( def.wheel_info, jo );
}

if( def.has_flag( "ROTOR" ) ) {
if( def.has_flag( "ROTOR" ) || def.has_flag( "ROTOR_SIMPLE" ) ) {
load_rotor( def.rotor_info, jo );
}

Expand Down Expand Up @@ -892,7 +893,10 @@ float vpart_info::wheel_or_rating() const

int vpart_info::rotor_diameter() const
{
return has_flag( VPFLAG_ROTOR ) ? rotor_info->rotor_diameter : 0;
if( has_flag( VPFLAG_ROTOR ) || has_flag( VPFLAG_ROTOR_SIMPLE ) ) {
return rotor_info->rotor_diameter;
}
return 0;
}

const cata::optional<vpslot_workbench> &vpart_info::get_workbench_info() const
Expand Down
1 change: 1 addition & 0 deletions src/veh_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ enum vpart_bitflags : int {
VPFLAG_COOLER,
VPFLAG_WHEEL,
VPFLAG_ROTOR,
VPFLAG_ROTOR_SIMPLE,
VPFLAG_MOUNTABLE,
VPFLAG_FLOATS,
VPFLAG_DOME_LIGHT,
Expand Down
21 changes: 19 additions & 2 deletions src/vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3933,6 +3933,7 @@ double vehicle::coeff_air_drag() const
d_check_max( drag[ col ].panel, pa, pa.info().has_flag( "SOLAR_PANEL" ) );
d_check_max( drag[ col ].windmill, pa, pa.info().has_flag( "WIND_TURBINE" ) );
d_check_max( drag[ col ].rotor, pa, pa.info().has_flag( "ROTOR" ) );
d_check_max( drag[ col ].rotor, pa, pa.info().has_flag( "ROTOR_SIMPLE" ) );
d_check_max( drag[ col ].sail, pa, pa.info().has_flag( "WIND_POWERED" ) );
d_check_max( drag[ col ].exposed, pa, d_exposed( pa ) );
d_check_min( drag[ col ].last, pa, pa.info().has_flag( "LOW_FINAL_AIR_DRAG" ) ||
Expand Down Expand Up @@ -4094,14 +4095,30 @@ bool vehicle::has_sufficient_rotorlift() const

bool vehicle::is_rotorcraft() const
{
return has_part( "ROTOR" ) && has_sufficient_rotorlift() && player_in_control( g->u );
return ( has_part( "ROTOR" ) || has_part( "ROTOR_SIMPLE" ) ) && has_sufficient_rotorlift() &&
player_in_control( g->u );
}

bool vehicle::is_flyable() const
{
return flyable;
}

void vehicle::set_flyable( bool val )
{
flyable = val;
}

int vehicle::get_z_change() const
{
return requested_z_change;
}

bool vehicle::would_prevent_flyable( const vpart_info &vpinfo ) const
{
return is_flyable() && has_part( "ROTOR" ) && !vpinfo.has_flag( "SIMPLE_PART" );
}

bool vehicle::is_flying_in_air() const
{
return is_flying;
Expand Down Expand Up @@ -5502,7 +5519,7 @@ void vehicle::refresh()
if( vpi.has_flag( VPFLAG_SOLAR_PANEL ) ) {
solar_panels.push_back( p );
}
if( vpi.has_flag( VPFLAG_ROTOR ) ) {
if( vpi.has_flag( VPFLAG_ROTOR ) || vpi.has_flag( VPFLAG_ROTOR_SIMPLE ) ) {
rotors.push_back( p );
}
if( vpi.has_flag( "WIND_TURBINE" ) ) {
Expand Down
Loading