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

[WIP]Hot air balloons #37935

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 17 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
59 changes: 59 additions & 0 deletions data/json/items/vehicle/balloons.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
[
{
"id": "small_hot_air_balloon",
"type": "GENERIC",
"category": "veh_parts",
"name": "small hot air balloon envelope",
"description": "A small folded up nylon envelope for use in a hot air balloon.",
"price": 600,
"weight": "45359 g",
"volume": "45359 ml",
"looks_like": "tarp",
"material": [ "nylon" ],
"symbol": "O",
"color": "dark_gray"
},
{
"id": "medium_hot_air_balloon",
"type": "GENERIC",
"category": "veh_parts",
"name": "medium hot air balloon envelope",
"description": "A folded up nylon envelope for use in a hot air balloon.",
"price": 800,
"weight": "113398 g",
"volume": "113398 ml",
"looks_like": "tarp",
"material": [ "nylon" ],
"symbol": "O",
"color": "blue"
},
{
"id": "large_hot_air_balloon",
"type": "GENERIC",
"category": "veh_parts",
"name": "large hot air balloon envelope",
"description": "A large folded up nylon envelope for use in a hot air balloon.",
"price": 1200,
"weight": "544310 g",
"volume": "544310 ml",
"looks_like": "tarp",
"material": [ "nylon" ],
"symbol": "O",
"color": "blue"
},
{
"id": "balloon_burner",
"type": "GENERIC",
"category": "veh_parts",
"name": "hot air balloon burner",
"description": "A hot air balloon burner, operating this outside of its intended use would be a bad idea.",
"weight": "12500 g",
"to_hit": -4,
"color": "red",
"symbol": ";",
"material": [ "steel" ],
"volume": "7500 ml",
"bashing": 5,
"price": 1200
}
]
56 changes: 56 additions & 0 deletions data/json/recipes/recipe_vehicle.json
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,26 @@
[ [ "plastic_chunk", 8 ] ]
]
},
{
"result": "balloon_burner",
"type": "recipe",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_PARTS",
"skill_used": "fabrication",
"skills_required": [ "mechanics", 3 ],
"difficulty": 3,
"time": "70 m",
"autolearn": true,
"using": [ [ "welding_standard", 5 ] ],
"reversible": true,
"qualities": [ { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 } ],
"components": [
[ [ "pilot_light", 1 ] ],
[ [ "steel_lump", 3 ], [ "steel_chunk", 12 ], [ "scrap", 36 ] ],
[ [ "metal_tank_little", 1 ] ],
[ [ "pipe", 3 ] ]
]
},
{
"result": "mountable_heater",
"type": "recipe",
Expand Down Expand Up @@ -414,6 +434,42 @@
"using": [ [ "sewing_standard", 100 ] ],
"components": [ [ [ "sheet", 2 ] ], [ [ "2x4", 4 ], [ "stick", 4 ] ], [ [ "nail", 20 ] ] ]
},
{
"type": "recipe",
"result": "small_hot_air_balloon",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_VEHICLE",
"skill_used": "tailor",
"difficulty": 6,
"time": "1440 m",
"autolearn": true,
"using": [ [ "sewing_standard", 1000 ] ],
"components": [ [ [ "scrap_nylon", 100 ] ], [ [ "cordage", 30, "LIST" ] ] ]
},
{
"type": "recipe",
"result": "medium_hot_air_balloon",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_VEHICLE",
"skill_used": "tailor",
"difficulty": 7,
"time": "2880 m",
"autolearn": true,
"using": [ [ "sewing_standard", 2000 ] ],
"components": [ [ [ "scrap_nylon", 200 ] ], [ [ "cordage", 60, "LIST" ] ] ]
},
{
"type": "recipe",
"result": "small_hot_air_balloon",
"category": "CC_OTHER",
"subcategory": "CSC_OTHER_VEHICLE",
"skill_used": "fabrication",
"difficulty": 6,
"time": "7000 m",
"autolearn": true,
"using": [ [ "sewing_standard", 3000 ] ],
"components": [ [ [ "scrap_nylon", 300 ] ], [ [ "cordage", 90, "LIST" ] ] ]
},
{
"type": "recipe",
"result": "hand_paddles",
Expand Down
72 changes: 72 additions & 0 deletions data/json/vehicleparts/balloons.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
[
{
"abstract": "hot_air_balloon",
"type": "vehicle_part",
"location": "on_roof",
"symbol": "O",
"color": "light_blue",
"broken_symbol": "s",
"broken_color": "light_gray",
"flags": [ "BALLOON" ],
"description": "A synthetic fabric balloon, designed to be filled with hot air, to make it rise, hopefully taking people with it."
},
{
"id": "small_hot_air_balloon",
"copy-from": "hot_air_balloon",
"type": "vehicle_part",
"name": "small hot air balloon",
"item": "small_hot_air_balloon",
"//": "balloon volume is in meters cubed",
"balloon_volume": 1000,
"difficulty": 4,
"durability": 30,
"description": "A small synthetic fabric balloon, designed to be filled with hot air, to make it rise, hopefully taking people with it.",
"damage_modifier": 50,
"breaks_into": [ { "item": "scrap_nylon", "count": [ 20, 80 ] } ]
},
{
"id": "medium_hot_air_balloon",
"copy-from": "hot_air_balloon",
"type": "vehicle_part",
"name": "medium hot air balloon",
"item": "medium_hot_air_balloon",
"//": "balloon volume is in meters cubed",
"balloon_volume": 2800,
"difficulty": 5,
"durability": 30,
"damage_modifier": 50,
"breaks_into": [ { "item": "scrap_nylon", "count": [ 60, 240 ] } ]
},
{
"id": "large_hot_air_balloon",
"copy-from": "hot_air_balloon",
"type": "vehicle_part",
"name": "large hot air balloon",
"item": "large_hot_air_balloon",
"//": "balloon volume is in meters cubed",
"description": "A large synthetic fabric balloon, designed to be filled with hot air, to make it rise, hopefully taking people with it.",
"balloon_volume": 12000,
"difficulty": 6,
"durability": 30,
"damage_modifier": 50,
"breaks_into": [ { "item": "scrap_nylon", "count": [ 240, 500 ] } ]
},
{
"id": "balloon_burner",
"type": "vehicle_part",
"name": "balloon burner",
"item": "balloon_burner",
"location": "center",
"symbol": "Y",
"broken_symbol": "y",
"color": "red",
"durability": 400,
"requirements": {
"install": { "skills": [ [ "mechanics", 1 ] ], "time": "2 m", "using": [ [ "vehicle_screw", 1 ] ] },
"removal": { "skills": [ [ "mechanics", 1 ] ], "time": "1 m", "using": [ [ "vehicle_screw", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 1 ] ], "time": "30 s", "using": [ [ "adhesive", 1 ] ] }
},
"breaks_into": [ { "item": "steel_lump" }, { "item": "steel_chunk", "count": [ 1, 3 ] }, { "item": "scrap", "count": [ 1, 3 ] } ],
"flags": [ "BURNER" ]
}
]
11 changes: 8 additions & 3 deletions src/handle_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,12 +468,17 @@ static void pldrive( int x, int y, int z = 0 )
return;
}
}
if( !remote && z != 0 && !u.has_trait( trait_PROF_HELI_PILOT ) ) {
if( !remote && z != 0 && ( veh->is_rotorcraft() && !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( z != 0 && !g->m.has_zlevels() ) {
u.add_msg_if_player( m_info, _( "This vehicle doesn't look very airworthy." ) );
if( z != 0 && ( !g->m.has_zlevels() || !veh->is_rotorcraft() ) ) {
if( veh->is_hot_air_balloon() ) {
u.add_msg_if_player( m_info,
_( "To fly in a hot air balloon, operate the burner from the controls." ) );
} else {
u.add_msg_if_player( m_info, _( "This vehicle doesn't look very airworthy." ) );
}
return;
}
if( z == -1 ) {
Expand Down
2 changes: 1 addition & 1 deletion src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1848,7 +1848,7 @@ void Item_factory::load( islot_comestible &slot, const JsonObject &jo, const std
assign( jo, "spoils_in", slot.spoils, strict, 1_hours );
assign( jo, "cooks_like", slot.cooks_like, strict );
assign( jo, "smoking_result", slot.smoking_result, strict );

for( const JsonObject &jsobj : jo.get_array( "contamination" ) ) {
slot.contamination.emplace( diseasetype_id( jsobj.get_string( "disease" ) ),
jsobj.get_int( "probability" ) );
Expand Down
9 changes: 4 additions & 5 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ bool map::vehproceed( VehicleList &vehicle_list )
// Then vertical-only movement
if( cur_veh == nullptr ) {
for( wrapped_vehicle &vehs_v : vehicle_list ) {
if( vehs_v.v->is_falling || ( vehs_v.v->is_rotorcraft() && vehs_v.v->get_z_change() != 0 ) ) {
if( vehs_v.v->is_falling || ( vehs_v.v->get_z_change() != 0 && vehs_v.v->is_airworthy() ) ) {
cur_veh = &vehs_v;
break;
}
Expand Down Expand Up @@ -483,7 +483,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &fac
// Split into vertical and horizontal movement
const int &coll_velocity = vertical ? veh.vertical_velocity : veh.velocity;
const int velocity_before = coll_velocity;
if( velocity_before == 0 && !veh.is_rotorcraft() && !veh.is_flying_in_air() ) {
if( velocity_before == 0 && !veh.is_flying_in_air() && !veh.is_airworthy() ) {
debugmsg( "%s tried to move %s with no velocity",
veh.name, vertical ? "vertically" : "horizontally" );
return &veh;
Expand Down Expand Up @@ -539,7 +539,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint &dp, const tileray &fac

const int velocity_after = coll_velocity;
bool can_move = velocity_after != 0 && sgn( velocity_after ) == sgn( velocity_before );
if( dp.z != 0 && veh.is_rotorcraft() ) {
if( dp.z != 0 && veh.is_airworthy() ) {
can_move = true;
}
int coll_turn = 0;
Expand Down Expand Up @@ -1030,7 +1030,6 @@ bool map::displace_vehicle( vehicle &veh, const tripoint &dp )
src.x, src.y, src.z, dst.x, dst.y, dst.z );
return false;
}

point src_offset;
point dst_offset;
submap *src_submap = get_submap_at( src, src_offset );
Expand Down Expand Up @@ -1072,7 +1071,7 @@ bool map::displace_vehicle( vehicle &veh, const tripoint &dp )
const bool remote = veh.remote_controlled( g->u );

// record every passenger and pet inside
std::vector<rider_data> riders = veh.get_riders();
std::vector<rider_data> riders = veh.get_riders( dp.z != 0 );

bool need_update = false;
int z_change = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/savegame_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2738,6 +2738,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( "desired_altitude", desired_altitude );
// Need to manually backfill the active item cache since the part loader can't call its vehicle.
for( const vpart_reference &vp : get_any_parts( VPFLAG_CARGO ) ) {
auto it = vp.part().items.begin();
Expand Down Expand Up @@ -2898,6 +2899,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( "desired_altitude", desired_altitude );
json.end_object();
}

Expand Down
11 changes: 8 additions & 3 deletions src/veh_interact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,10 @@ bool veh_interact::can_install_part()
}
}
}

bool already_balloon = false;
if( sel_vpart_info->has_flag( "BALLOON" ) && veh->has_part( "BALLOON" ) ) {
already_balloon = true;
}
int dif_steering = 0;
if( sel_vpart_info->has_flag( "STEERABLE" ) ) {
std::set<int> axles;
Expand All @@ -730,9 +733,11 @@ bool veh_interact::can_install_part()
std::string msg;
bool ok = format_reqs( msg, reqs, sel_vpart_info->install_skills,
sel_vpart_info->install_time( g->u ) );

msg += _( "<color_white>Additional requirements:</color>\n" );

if( already_balloon ) {
msg += _( "<color_red>Cannot install more than one balloon envelope." );
ok = false;
}
if( dif_eng > 0 ) {
if( g->u.get_skill_level( skill_mechanics ) < dif_eng ) {
ok = false;
Expand Down
19 changes: 19 additions & 0 deletions src/veh_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,17 @@ void vpart_info::load_rotor( cata::optional<vpslot_rotor> &roptr, const JsonObje
assert( roptr );
}

void vpart_info::load_balloon( cata::optional<vpslot_balloon> &balptr, const JsonObject &jo )
{
vpslot_balloon balloon_info{};
if( balptr ) {
balloon_info = *balptr;
}
assign( jo, "balloon_volume", balloon_info.balloon_volume );
balptr = balloon_info;
assert( balptr );
}

void vpart_info::load_wheel( cata::optional<vpslot_wheel> &whptr, const JsonObject &jo )
{
vpslot_wheel wh_info{};
Expand Down Expand Up @@ -425,6 +436,9 @@ void vpart_info::load( const JsonObject &jo, const std::string &src )
if( def.has_flag( "ROTOR" ) ) {
load_rotor( def.rotor_info, jo );
}
if( def.has_flag( "BALLOON" ) ) {
load_balloon( def.balloon_info, jo );
}

if( def.has_flag( "WORKBENCH" ) ) {
load_workbench( def.workbench_info, jo );
Expand Down Expand Up @@ -888,6 +902,11 @@ int vpart_info::rotor_diameter() const
return has_flag( VPFLAG_ROTOR ) ? rotor_info->rotor_diameter : 0;
}

int vpart_info::balloon_volume() const
{
return has_flag( "BALLOON" ) ? balloon_info->balloon_volume : 0;
}

const cata::optional<vpslot_workbench> &vpart_info::get_workbench_info() const
{
return workbench_info;
Expand Down
9 changes: 9 additions & 0 deletions src/veh_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ struct vpslot_rotor {
int rotor_diameter = 1;
};

struct vpslot_balloon {
int balloon_volume = 1;
};

struct vpslot_workbench {
// Base multiplier applied for crafting here
float multiplier = 1.0f;
Expand All @@ -147,6 +151,7 @@ class vpart_info
cata::optional<vpslot_engine> engine_info;
cata::optional<vpslot_wheel> wheel_info;
cata::optional<vpslot_rotor> rotor_info;
cata::optional<vpslot_balloon> balloon_info;
cata::optional<vpslot_workbench> workbench_info;

public:
Expand Down Expand Up @@ -314,6 +319,9 @@ class vpart_info
/** @name rotor specific functions
*/
int rotor_diameter() const;
/** @name balloon specific functions
*/
int balloon_volume() const;
/**
* Getter for optional workbench info
*/
Expand Down Expand Up @@ -355,6 +363,7 @@ class vpart_info
static void load_wheel( cata::optional<vpslot_wheel> &whptr, const JsonObject &jo );
static void load_workbench( cata::optional<vpslot_workbench> &wbptr, const JsonObject &jo );
static void load_rotor( cata::optional<vpslot_rotor> &whptr, const JsonObject &jo );
static void load_balloon( cata::optional<vpslot_balloon> &balptr, const JsonObject &jo );
static void load( const JsonObject &jo, const std::string &src );
static void finalize();
static void check();
Expand Down
Loading