Permalink
Browse files

vehicles: enable amphibious vehicles

stop treating boat boards as wheels and doing weird things with wheel
area traction calculations.  Instead, check if a vehicle is mostly in
the water, and if it is, whether it can float, or if it isn't, whether
it has sufficient wheels.  Now that these are entirely separate concepts,
a vehicle can be amphibious by giving it wheels and enough boat boards.

Revise the drag test to consistently give correct results and include
water drag numbers.
  • Loading branch information...
mlangsdorf committed Dec 22, 2018
1 parent 4316d6e commit 1254ea05efb54858c036fa66d3fbda243fa1fb76
@@ -1,6 +1,6 @@
[
{
"type":"WHEEL",
"type": "GENERIC",
"id": "inflatable_section",
"symbol": "o",
"color": "green",
@@ -13,8 +13,6 @@
"volume": 50,
"bashing": 8,
"to_hit": -1,
"diameter": 30,
"width": 4,
"category": "veh_parts"
},{
"type":"GENERIC",
@@ -32,7 +30,7 @@
"category" : "veh_parts",
"price" : 9000
},{
"type":"WHEEL",
"type": "GENERIC",
"id": "inflatable_airbag",
"symbol": "o",
"color": "dark_gray",
@@ -45,8 +43,6 @@
"volume": 50,
"bashing": 8,
"to_hit": -1,
"diameter": 30,
"width": 4,
"category": "veh_parts"
}
]
@@ -1,20 +1,18 @@
[
{
"type": "WHEEL",
"type": "GENERIC",
"id": "boat_board",
"symbol": "o",
"color": "brown",
"name": "boat board",
"name_plural": "boat board",
"description": "A wooden board that keeps the boat afloat. To change a vehicle into a boat, place as you would wheels on a car. Then attach oars or a motor to get the boat to move.",
"description": "A wooden board that keeps the boat afloat. Add boat boards to a vehicle until it floats. Then attach oars or a motor to get the boat to move.",
"price": 8000,
"material": [ "wood" ],
"weight": 3000,
"volume": 50,
"bashing": 8,
"to_hit": -1,
"diameter": 30,
"width": 4,
"category": "veh_parts"
}
]
@@ -3,7 +3,7 @@
"type" : "vehicle_part",
"id" : "boat_board",
"name" : "boat board",
"description": "A wooden board that keeps the boat afloat. To change a vehicle into a boat, place as you would wheels on a car. Then attach oars or a motor to get the boat to move.",
"description": "A wooden board that keeps the boat afloat. Add boat boards to a vehicle until it floats. Then attach oars or a motor to get the boat to move.",
"symbol" : "o",
"color" : "brown",
"broken_symbol" : "x",
@@ -277,7 +277,7 @@ bool game::dump_stats( const std::string &what, dump_mode mode,
r.push_back( to_string( veh_fueled.coeff_rolling_drag() ) );
r.push_back( to_string( veh_fueled.static_drag( false ) ) );
r.push_back( to_string( static_cast<int>( 50 *
veh_fueled.k_traction( veh_fueled.wheel_area( false ) ) ) ) );
veh_fueled.k_traction( veh_fueled.wheel_area() ) ) ) );
rows.push_back( r );
};
for( auto &e : vehicle_prototype::get_all() ) {
@@ -64,12 +64,12 @@ bool game::grabbed_veh_move( const tripoint &dp )
// (Roughly 1.1K kg = danger zone; cube vans are about the max)
if( str_req > 45 ) {
add_msg( m_info, _( "The %s is too bulky for you to move by hand." ),
grabbed_vehicle->name.c_str() );
grabbed_vehicle->name );
return true; // No shoving around an RV.
}

const auto &wheel_indices = grabbed_vehicle->wheelcache;
if( grabbed_vehicle->valid_wheel_config( false ) ) {
if( grabbed_vehicle->valid_wheel_config() ) {
//determine movecost for terrain touching wheels
const tripoint vehpos = grabbed_vehicle->global_pos3();
for( int p : wheel_indices ) {
@@ -372,7 +372,7 @@ bool map::vehproceed()
if( cur_veh == nullptr ) {
for( auto &vehs_v : vehs ) {
vehicle &cveh = *vehs_v.v;
if( cveh.falling ) {
if( cveh.is_falling ) {
cur_veh = vehs_v.v;
break;
}
@@ -386,29 +386,6 @@ bool map::vehproceed()
return cur_veh->act_on_map();
}

float map::vehicle_buoyancy( const vehicle &veh ) const
{
const auto &float_indices = veh.floating;
const int num = float_indices.size();
int moored = 0;
float total_wheel_area = 0.0f;
for( int w = 0; w < num; w++ ) {
const int p = float_indices[w];
const tripoint pp = veh.global_part_pos3( p );
total_wheel_area += veh.parts[ p ].wheel_width() * veh.parts[ p ].wheel_diameter();

if( !has_flag( "SWIMMABLE", pp ) ) {
moored++;
}
}

if( moored > num - 1 ) {
return 0.0f;
}

return total_wheel_area;
}

static bool sees_veh( const Creature &c, vehicle &veh, bool force_recalc )
{
const auto &veh_points = veh.get_points( force_recalc );
@@ -517,7 +494,7 @@ void map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &facing
}

// If not enough wheels, mess up the ground a bit.
if( !vertical && !veh.valid_wheel_config( veh.is_in_water() ) ) {
if( !vertical && !veh.valid_wheel_config() && !veh.is_in_water() ) {
veh.velocity += veh.velocity < 0 ? 2000 : -2000;
for( const auto &p : veh.get_points() ) {
const ter_id &pter = ter( p );
@@ -1076,9 +1053,7 @@ vehicle *map::displace_vehicle( tripoint &p, const tripoint &dp )
g->setremoteveh( veh );
}

if( !veh->falling ) {
veh->falling = vehicle_falling( *veh );
}
veh->check_falling_or_floating();

//global positions of vehicle loot zones have changed.
veh->zones_dirty = true;
@@ -2018,7 +1993,7 @@ void map::drop_vehicle( const tripoint &p )
return;
}

vp->vehicle().falling = true;
vp->vehicle().is_falling = true;
}

void map::drop_fields( const tripoint &p )
@@ -531,14 +531,6 @@ class map
// TODO: Remove the ugly sinking vehicle hack
float vehicle_wheel_traction( const vehicle &veh ) const;

// Like traction, except for water
// TODO: Actually implement (this is a stub)
// TODO: Test for it when the vehicle sinks rather than when it has VP_FLOATS
float vehicle_buoyancy( const vehicle &veh ) const;

// Returns if the vehicle should fall down a z-level
bool vehicle_falling( vehicle &veh );

// Executes vehicle-vehicle collision based on vehicle::collision results
// Returns impulse of the executed collision
// If vector contains collisions with vehicles other than veh2, they will be ignored
@@ -2160,7 +2160,8 @@ void vehicle::deserialize( JsonIn &jsin )
data.read( "moveDir", mdir );
data.read( "turn_dir", turn_dir );
data.read( "velocity", velocity );
data.read( "falling", falling );
data.read( "falling", is_falling );
data.read( "floating", is_floating );
data.read( "cruise_velocity", cruise_velocity );
data.read( "vertical_velocity", vertical_velocity );
data.read( "cruise_on", cruise_on );
@@ -2276,7 +2277,8 @@ void vehicle::serialize( JsonOut &json ) const
json.member( "moveDir", move.dir() );
json.member( "turn_dir", turn_dir );
json.member( "velocity", velocity );
json.member( "falling", falling );
json.member( "falling", is_falling );
json.member( "floating", is_floating );
json.member( "cruise_velocity", cruise_velocity );
json.member( "vertical_velocity", vertical_velocity );
json.member( "cruise_on", cruise_on );
@@ -1965,13 +1965,13 @@ void veh_interact::display_veh ()
static std::string wheel_state_description( const vehicle &veh )
{
bool is_boat = !veh.floating.empty();
bool is_land = !veh.wheelcache.empty();
bool is_land = !veh.wheelcache.empty() || !is_boat;

bool suf_land = veh.sufficient_wheel_config( false );
bool bal_land = veh.balanced_wheel_config( false );
bool suf_land = veh.sufficient_wheel_config();
bool bal_land = veh.balanced_wheel_config();

bool suf_boat = veh.can_float();

bool suf_boat = veh.sufficient_wheel_config( true );
bool bal_boat = veh.balanced_wheel_config( true );
float steer = veh.steering_effectiveness();

std::string wheel_status;
@@ -1994,21 +1994,19 @@ static std::string wheel_state_description( const vehicle &veh )
std::string boat_status;
if( !suf_boat ) {
boat_status = _( "<color_light_red>leaks</color>" );
} else if( !bal_boat ) {
boat_status = _( "<color_light_red>unbalanced</color>" );
} else {
boat_status = _( "<color_blue>swims</color>" );
}

if( is_boat && is_land ) {
return string_format( _( "Wheels/boat: %s/%s" ), wheel_status.c_str(), boat_status.c_str() );
return string_format( _( "Wheels/boat: %s/%s" ), wheel_status, boat_status );
}

if( is_boat ) {
return string_format( _( "Boat: %s" ), boat_status.c_str() );
return string_format( _( "Boat: %s" ), boat_status );
}

return string_format( _( "Wheels: %s" ), wheel_status.c_str() );
return string_format( _( "Wheels: %s" ), wheel_status );
}

/**
@@ -2049,13 +2047,14 @@ void veh_interact::display_stats() const
}

bool is_boat = !veh->floating.empty();
bool is_ground = !veh->wheelcache.empty() || !is_boat;

const auto vel_to_int = []( const double vel ) {
return static_cast<int>( convert_velocity( vel, VU_VEHICLE ) );
};

int i = 0;
if( !is_boat ) {
if( is_ground ) {
fold_and_print( w_stats, y[i], x[i], w[i], c_light_gray,
_( "Safe/Top Speed: <color_light_green>%3d</color>/<color_light_red>%3d</color> %s" ),
vel_to_int( veh->safe_ground_velocity( false ) ),
@@ -2152,7 +2151,7 @@ void veh_interact::display_stats() const
}
i += 1;

if( !is_boat ) {
if( is_ground ) {
fold_and_print( w_stats, y[i], x[i], w[i], c_light_gray,
_( "Rolling drag: <color_light_blue>%5.2f</color>"),
veh->coeff_rolling_drag() );
@@ -2166,8 +2165,7 @@ void veh_interact::display_stats() const

fold_and_print( w_stats, y[i], x[i], w[i], c_light_gray,
_( "Offroad: <color_light_blue>%4d</color>%%" ),
static_cast<int>( veh->k_traction( veh->wheel_area( is_boat ) *
0.5f ) * 100 ) );
static_cast<int>( veh->k_traction( veh->wheel_area() * 0.5f ) * 100 ) );
i += 1;

if( is_boat ) {
Oops, something went wrong.

0 comments on commit 1254ea0

Please sign in to comment.