Skip to content

Commit

Permalink
Reins controls for horse-powered vehicles (#37148)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidpwbrown authored and ZhilkinSerg committed Jan 19, 2020
1 parent 8c365a3 commit da23951
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 6 deletions.
16 changes: 16 additions & 0 deletions data/json/items/vehicle/controls.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@
"category": "veh_parts",
"price": 40000
},
{
"id": "reins_tackle",
"type": "GENERIC",
"name": { "str": "rein and tackle", "str_pl": "reins and tackles" },
"category": "veh_parts",
"description": "A set of leather bindings to control a mountable creature.",
"weight": "500 g",
"volume": "1200 ml",
"price": 30000,
"bashing": 1,
"to_hit": -2,
"material": [ "leather" ],
"symbol": "W",
"color": "light_gray",
"looks_like": "rope_6"
},
{
"type": "GENERIC",
"id": "vehicle_dashboard",
Expand Down
14 changes: 14 additions & 0 deletions data/json/recipes/recipe_vehicle.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@
"qualities": [ { "id": "HAMMER", "level": 2 } ],
"components": [ [ [ "sheet_metal", 3 ] ] ]
},
{
"result": "reins_tackle",
"type": "recipe",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_VEHICLE",
"skill_used": "tailor",
"difficulty": 3,
"time": "120 m",
"using": [ [ "sewing_standard", 100 ] ],
"components": [
[ [ "leather", 12 ], [ "tanned_hide", 2 ], [ "fur", 12 ], [ "tanned_pelt", 2 ] ],
[ [ "cordage_superior", 2, "LIST" ] ]
]
},
{
"result": "yoke_harness",
"type": "recipe",
Expand Down
22 changes: 22 additions & 0 deletions data/json/vehicleparts/vehicle_parts.json
Original file line number Diff line number Diff line change
Expand Up @@ -1627,6 +1627,28 @@
"breaks_into": [ { "item": "splinter", "count": [ 2, 4 ] } ],
"damage_reduction": { "all": 5 }
},
{
"type": "vehicle_part",
"id": "reins_tackle",
"name": "reins and tackle",
"symbol": "W",
"color": "light_gray",
"broken_symbol": "X",
"broken_color": "red",
"durability": 80,
"description": "A set of leather bindings to control a creature pulling a vehicle, such as a cart.",
"bonus": 10,
"damage_modifier": 5,
"item": "reins_tackle",
"folded_volume": 1,
"requirements": {
"install": { "skills": [ [ "mechanics", 1 ] ], "time": "6 m", "using": [ [ "vehicle_nail_install", 1 ] ] },
"removal": { "skills": [ [ "mechanics", 1 ] ], "time": "3 m", "using": [ [ "vehicle_nail_removal", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 1 ] ], "time": "6 m", "using": [ [ "adhesive", 2 ] ] }
},
"flags": [ "CONTROL_ANIMAL", "FOLDABLE" ],
"breaks_into": [ { "item": "leather", "count": [ 1, 2 ] } ]
},
{
"type": "vehicle_part",
"id": "controls",
Expand Down
1 change: 1 addition & 0 deletions doc/JSON_FLAGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,7 @@ Those flags are added by the game code to specific items (that specific welder,
- ```CIRCLE_LIGHT``` Projects a circular radius of light when turned on.
- ```CONE_LIGHT``` Projects a cone of light when turned on.
- ```CONTROLS``` Can be used to control the vehicle.
- ```CONTROL_ANIMAL``` These controls can only be used to control a vehicle pulled by an animal (such as reins etc).
- ```COOLER``` There is separate command to toggle this part.
- ```COVERED``` Prevents items in cargo parts from emitting any light.
- ```CRAFTRIG``` Acts as a dehydrator, vacuum sealer and reloading press for crafting purposes. Potentially to include additional tools in the future.
Expand Down
15 changes: 12 additions & 3 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5103,6 +5103,7 @@ void game::moving_vehicle_dismount( const tripoint &dest_loc )

void game::control_vehicle()
{
static const itype_id fuel_type_animal( "animal" );
int veh_part = -1;
vehicle *veh = remoteveh();
if( veh == nullptr ) {
Expand All @@ -5111,9 +5112,16 @@ void game::control_vehicle()
veh_part = vp->part_index();
}
}
if( veh != nullptr && veh->player_in_control( u ) ) {
if( veh != nullptr && veh->player_in_control( u ) &&
veh->avail_part_with_feature( veh_part, "CONTROLS", true ) >= 0 ) {
veh->use_controls( u.pos() );
} else if( veh && veh->avail_part_with_feature( veh_part, "CONTROLS", true ) >= 0 &&
} else if( veh && veh->player_in_control( u ) &&
veh->avail_part_with_feature( veh_part, "CONTROL_ANIMAL", true ) >= 0 ) {
u.controlling_vehicle = false;
add_msg( m_info, _( "You let go of the reins." ) );
} else if( veh && ( veh->avail_part_with_feature( veh_part, "CONTROLS", true ) >= 0 ||
( veh->avail_part_with_feature( veh_part, "CONTROL_ANIMAL", true ) >= 0 &&
veh->has_engine_type( fuel_type_animal, false ) && veh->has_harnessed_animal() ) ) &&
u.in_vehicle ) {
if( !veh->interact_vehicle_locked() ) {
veh->handle_potential_theft( dynamic_cast<player &>( u ) );
Expand Down Expand Up @@ -9383,7 +9391,8 @@ point game::place_player( const tripoint &dest_loc )
}
}

if( vp1.part_with_feature( "CONTROLS", true ) && u.in_vehicle && !u.is_mounted() ) {
if( ( vp1.part_with_feature( "CONTROL_ANIMAL", true ) ||
vp1.part_with_feature( "CONTROLS", true ) ) && u.in_vehicle && !u.is_mounted() ) {
add_msg( _( "There are vehicle controls here." ) );
if( !u.has_trait( trait_id( "WAYFARER" ) ) ) {
add_msg( m_info, _( "%s to drive." ), press_x( ACTION_CONTROL_VEHICLE ) );
Expand Down
12 changes: 10 additions & 2 deletions src/handle_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,19 @@ static void pldrive( int x, int y )
return;
}
if( !remote ) {
int pctr = veh->part_with_feature( part, "CONTROLS", true );
if( pctr < 0 ) {
static const itype_id fuel_type_animal( "animal" );
const bool has_animal_controls = veh->part_with_feature( part, "CONTROL_ANIMAL", true ) >= 0;
const bool has_controls = veh->part_with_feature( part, "CONTROLS", true ) >= 0;
const bool has_animal = veh->has_engine_type( fuel_type_animal, false ) &&
veh->has_harnessed_animal();
if( !has_controls && !has_animal_controls ) {
add_msg( m_info, _( "You can't drive the vehicle from here. You need controls!" ) );
u.controlling_vehicle = false;
return;
} else if( !has_controls && has_animal_controls && !has_animal ) {
add_msg( m_info, _( "You can't drive this vehicle without an animal to pull it." ) );
u.controlling_vehicle = false;
return;
}
} else {
if( empty( veh->get_avail_parts( "REMOTE_CONTROLS" ) ) ) {
Expand Down
5 changes: 4 additions & 1 deletion src/vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,10 @@ bool vehicle::player_in_control( const player &p ) const

const optional_vpart_position vp = g->m.veh_at( p.pos() );
if( vp && &vp->vehicle() == this &&
part_with_feature( vp->part_index(), VPFLAG_CONTROLS, false ) >= 0 && p.controlling_vehicle ) {
( ( part_with_feature( vp->part_index(), "CONTROL_ANIMAL", true ) >= 0 &&
has_engine_type( fuel_type_animal, false ) && has_harnessed_animal() ) ||
( part_with_feature( vp->part_index(), VPFLAG_CONTROLS, false ) >= 0 ) ) &&
p.controlling_vehicle ) {
return true;
}

Expand Down
1 change: 1 addition & 0 deletions src/vehicle.h
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,7 @@ class vehicle
//true if an engine exists with specified type
//If enabled true, this engine must be enabled to return true
bool has_engine_type( const itype_id &ft, bool enabled ) const;
bool has_harnessed_animal() const;
//true if an engine exists without the specified type
//If enabled true, this engine must be enabled to return true
bool has_engine_type_not( const itype_id &ft, bool enabled ) const;
Expand Down
14 changes: 14 additions & 0 deletions src/vehicle_move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,20 @@ void vehicle::handle_trap( const tripoint &p, int part )
}
}

bool vehicle::has_harnessed_animal() const
{
for( size_t e = 0; e < parts.size(); e++ ) {
const vehicle_part &vp = parts[ e ];
if( vp.info().fuel_type == fuel_type_animal ) {
monster *mon = get_pet( e );
if( mon && mon->has_effect( effect_harnessed ) && mon->has_effect( effect_pet ) ) {
return true;
}
}
}
return false;
}

void vehicle::autodrive( int x, int y )
{
// for now, autodriving is only possible when pulled by an animal
Expand Down

0 comments on commit da23951

Please sign in to comment.