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

Basic Appliance implementation #51286

Merged
merged 14 commits into from
Oct 25, 2021
11 changes: 11 additions & 0 deletions data/json/construction.json
Original file line number Diff line number Diff line change
Expand Up @@ -2808,6 +2808,17 @@
"pre_special": "check_empty",
"post_terrain": "f_barricade_road"
},
{
"type": "construction",
"id": "app_fridge",
"group": "place_fridge",
"category": "APPLIANCE",
"required_skills": [ [ "fabrication", 0 ] ],
"time": "5 m",
"components": [ [ [ "fridge", 1 ] ] ],
"pre_special": "check_empty",
"post_special": "done_appliance"
},
{
"type": "construction",
"id": "constr_pontoon_dp",
Expand Down
5 changes: 5 additions & 0 deletions data/json/construction_category.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
"id": "ALL",
"name": "All"
},
{
"type": "construction_category",
"id": "APPLIANCE",
"name": "Appliances"
},
{
"type": "construction_category",
"id": "CONSTRUCT",
Expand Down
5 changes: 5 additions & 0 deletions data/json/construction_group.json
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,11 @@
"id": "paint_wall_yellow",
"name": "Paint Wall Yellow"
},
{
"type": "construction_group",
"id": "place_fridge",
"name": "Place Fridge"
},
{
"type": "construction_group",
"id": "place_forge",
Expand Down
8 changes: 8 additions & 0 deletions data/json/flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,10 @@
"id": "ALWAYS_TWOHAND",
"type": "json_flag"
},
{
"id": "APPLIANCE",
"type": "json_flag"
},
{
"id": "BIPOD",
"type": "json_flag"
Expand Down Expand Up @@ -1354,6 +1358,10 @@
"id": "POWERED",
"type": "json_flag"
},
{
"id": "POWER_CORD",
"type": "json_flag"
},
{
"id": "PROCESSING",
"type": "json_flag"
Expand Down
44 changes: 44 additions & 0 deletions data/json/items/appliances.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[
{
"type": "GENERIC",
"id": "fridge",
"looks_like": "minifridge",
"symbol": "F",
"color": "light_blue",
"name": { "str": "fridge" },
"description": "A fridge for keeping food cool. Provides some insulation from outside weather.",
"longest_side": "1700 mm",
"insulation": 10,
"volume": "800 L",
"weight": "70 kg",
"pocket_data": [
{
"pocket_type": "CONTAINER",
"rigid": true,
"watertight": true,
"max_contains_volume": "700 L",
"max_contains_weight": "400 kg"
}
]
},
{
"type": "TOOL",
"id": "power_cord",
"name": { "str": "power cord" },
"description": "A power cord, like you've seen many times before: it's a short multi-stranded copper cord with power outlet at the end.",
"to_hit": 1,
"color": "dark_gray",
"symbol": "&",
"material": [ "steel", "plastic" ],
"volume": "500 ml",
"weight": "75 g",
"bashing": 2,
"category": "tools",
"price": 1,
"price_postapoc": 100,
"max_charges": 3,
"initial_charges": 3,
"use_action": [ "CABLE_ATTACH" ],
"flags": [ "CABLE_SPOOL", "POWER_CORD" ]
}
]
24 changes: 24 additions & 0 deletions data/json/recipes/recipe_vehicle.json
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,30 @@
[ [ "plastic_chunk", 8 ] ]
]
},
{
"result": "fridge",
"type": "recipe",
"activity_level": "MODERATE_EXERCISE",
"copy-from": "minifridge",
"skills_required": [ "fabrication", 4 ],
"proficiencies": [ { "proficiency": "prof_plasticworking", "required": false, "time_multiplier": 1.1, "learning_time_multiplier": 0.1 } ],
"qualities": [
{ "id": "HAMMER", "level": 2 },
{ "id": "SAW_M", "level": 1 },
{ "id": "DRILL", "level": 1 },
{ "id": "SCREW", "level": 1 },
{ "id": "WRENCH", "level": 1 }
],
"components": [
[ [ "sheet_metal", 20 ] ],
[ [ "condensor_coil", 1 ] ],
[ [ "evaporator_coil", 1 ] ],
[ [ "thermostat", 1 ] ],
[ [ "motor_small", 1 ] ],
[ [ "refrigerant_tank", 1 ] ],
[ [ "plastic_chunk", 16 ] ]
]
},
{
"result": "mountable_heater",
"type": "recipe",
Expand Down
52 changes: 52 additions & 0 deletions data/json/vehicleparts/appliances.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[
{
"type": "vehicle_part",
"id": "ap_fridge",
"name": { "str": "fridge" },
"symbol": "H",
"looks_like": "f_fridge",
"categories": [ "cargo" ],
"color": "light_blue",
"broken_symbol": "#",
"broken_color": "light_blue",
"damage_modifier": 80,
"durability": 100,
"description": "A fridge. When turned on, it will cool the food inside, extended the time until the food spoils.",
"//": "Use average consumption, not the max on the appliance rating plate. 30W ~ 260kWh per annum",
"epower": -30,
"size": 300,
"item": "fridge",
"location": "center",
"requirements": {
"install": { "skills": [ [ "mechanics", 3 ] ], "time": "60 m", "using": [ [ "vehicle_wrench_2", 1 ] ] },
"removal": { "skills": [ [ "mechanics", 2 ] ], "time": "30 m", "using": [ [ "vehicle_wrench_2", 1 ] ] },
"repair": { "skills": [ [ "mechanics", 4 ] ], "time": "60 m", "using": [ [ "welding_standard", 5 ] ] }
},
"flags": [ "CARGO", "OBSTACLE", "FRIDGE", "COVERED", "ENABLED_DRAINS_EPOWER", "APPLIANCE", "CTRL_ELECTRONIC" ],
"breaks_into": [
{ "item": "steel_lump", "count": [ 8, 13 ] },
{ "item": "steel_chunk", "count": [ 8, 13 ] },
{ "item": "scrap", "count": [ 8, 13 ] },
{ "item": "hose", "prob": 50 },
{ "item": "motor_tiny", "prob": 25 }
],
"damage_reduction": { "all": 32 }
},
{
"type": "vehicle_part",
"id": "power_cord",
"name": { "str": "power cord" },
"symbol": "{",
"categories": [ "other" ],
"color": "yellow",
"broken_symbol": "s",
"broken_color": "dark_gray",
"damage_modifier": 10,
"epower": 0,
"//": "Epower for POWER_TRANSFER stuff is how much percentage-wise loss there is in transmission",
"durability": 120,
"description": "A power cord sticking out of an appliance. You need to plug it in a powered grid for the appliance to work properly.",
"item": "power_cord",
"flags": [ "NOINSTALL", "NO_UNINSTALL", "UNMOUNT_ON_DAMAGE", "UNMOUNT_ON_MOVE", "POWER_TRANSFER" ]
}
]
4 changes: 4 additions & 0 deletions data/json/vehicleparts/vp_flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@
"id": "NOINSTALL",
"type": "json_flag"
},
{
"id": "NO_UNINSTALL",
"type": "json_flag"
},
{
"id": "OBSTACLE",
"type": "json_flag"
Expand Down
21 changes: 21 additions & 0 deletions src/construction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ static void done_nothing( const tripoint & ) {}
void done_trunk_plank( const tripoint & );
void done_grave( const tripoint & );
void done_vehicle( const tripoint & );
void done_appliance( const tripoint & );
void done_deconstruct( const tripoint & );
void done_digormine_stair( const tripoint &, bool );
void done_dig_stair( const tripoint & );
Expand Down Expand Up @@ -1309,6 +1310,25 @@ void construct::done_vehicle( const tripoint &p )
here.add_vehicle_to_cache( veh );
}

void construct::done_appliance( const tripoint &p )
{
map &here = get_map();
vehicle *veh = here.add_vehicle( vproto_id( "none" ), p, 270_degrees, 0, 0 );

if( !veh ) {
debugmsg( "error constructing vehicle" );
return;
}
const vpart_id &vpart = vpart_from_item( get_avatar().lastconsumed );
veh->install_part( point_zero, vpart );
veh->add_tag( "APPLIANCE" );

veh->name = vpart->name();
// Update the vehicle cache immediately,
// or the appliance will be invisible for the first couple of turns.
here.add_vehicle_to_cache( veh );
}

void construct::done_deconstruct( const tripoint &p )
{
map &here = get_map();
Expand Down Expand Up @@ -1664,6 +1684,7 @@ void load_construction( const JsonObject &jo )
{ "done_trunk_plank", construct::done_trunk_plank },
{ "done_grave", construct::done_grave },
{ "done_vehicle", construct::done_vehicle },
{ "done_appliance", construct::done_appliance },
{ "done_deconstruct", construct::done_deconstruct },
{ "done_dig_stair", construct::done_dig_stair },
{ "done_mine_downstair", construct::done_mine_downstair },
Expand Down
7 changes: 5 additions & 2 deletions src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8704,13 +8704,16 @@ cata::optional<int> iuse::cable_attach( Character *p, item *it, bool, const trip
const bool solar_pack = initial_state == "solar_pack";
const bool UPS = initial_state == "UPS";
bool loose_ends = paying_out || cable_cbm || solar_pack || UPS;
bool is_power_cord = it->has_flag( flag_id( "POWER_CORD" ) );
uilist kmenu;
kmenu.text = _( "Using cable:" );
kmenu.addentry( 0, true, -1, _( "Detach and re-spool the cable" ) );
if( !is_power_cord ) {
kmenu.addentry( 0, true, -1, _( "Detach and re-spool the cable" ) );
}
kmenu.addentry( 1, ( paying_out || cable_cbm ) && !solar_pack &&
!UPS, -1, _( "Attach loose end to vehicle" ) );

if( has_bio_cable && loose_ends ) {
if( has_bio_cable && loose_ends && !is_power_cord ) {
kmenu.addentry( 2, !cable_cbm, -1, _( "Attach loose end to self" ) );
if( wearing_solar_pack ) {
kmenu.addentry( 3, !solar_pack && !paying_out && !UPS, -1, _( "Attach loose end to solar pack" ) );
Expand Down
6 changes: 5 additions & 1 deletion src/veh_interact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2255,7 +2255,7 @@ bool veh_interact::can_potentially_install( const vpart_info &vpart )
engine_reqs_met = engines < 2;
}

return hammerspace || ( can_make && engine_reqs_met );
return hammerspace || ( can_make && engine_reqs_met && !vpart.has_flag( VPFLAG_APPLIANCE ) );
}

/**
Expand Down Expand Up @@ -2844,6 +2844,10 @@ void veh_interact::display_list( size_t pos, const std::vector<const vpart_info
size_t page = pos / lines_per_page;
for( size_t i = page * lines_per_page; i < ( page + 1 ) * lines_per_page && i < list.size(); i++ ) {
const vpart_info &info = *list[i];
if( !info.has_flag( VPFLAG_APPLIANCE ) ) {
continue;
}

int y = i - page * lines_per_page + header;
mvwputch( w_list, point( 1, y ), info.color, special_symbol( info.sym ) );
nc_color col = can_potentially_install( info ) ? c_white : c_dark_gray;
Expand Down
1 change: 1 addition & 0 deletions src/veh_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ static std::unordered_map<vproto_id, vehicle_prototype> vtypes;

static const std::unordered_map<std::string, vpart_bitflags> vpart_bitflag_map = {
{ "ARMOR", VPFLAG_ARMOR },
{ "APPLIANCE", VPFLAG_APPLIANCE },
{ "EVENTURN", VPFLAG_EVENTURN },
{ "ODDTURN", VPFLAG_ODDTURN },
{ "CONE_LIGHT", VPFLAG_CONE_LIGHT },
Expand Down
1 change: 1 addition & 0 deletions src/veh_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class vehicle;
// won't be going away, are involved in core functionality, and are checked frequently
enum vpart_bitflags : int {
VPFLAG_ARMOR,
VPFLAG_APPLIANCE,
VPFLAG_EVENTURN,
VPFLAG_ODDTURN,
VPFLAG_CONE_LIGHT,
Expand Down
17 changes: 14 additions & 3 deletions src/vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1243,8 +1243,9 @@ bool vehicle::can_mount( const point &dp, const vpart_id &id ) const

const std::vector<int> parts_in_square = parts_at_relative( dp, false );

//First part in an empty square MUST be a structural part
if( parts_in_square.empty() && part.location != part_location_structure ) {
//First part in an empty square MUST be a structural part or be an appliance
if( parts_in_square.empty() && part.location != part_location_structure &&
!part.has_flag( "APPLIANCE" ) ) {
return false;
}
// If its a part that harnesses animals that don't allow placing on it.
Expand Down Expand Up @@ -6229,7 +6230,7 @@ void vehicle::shed_loose_parts()
tow_data.clear_towing();
}
const vehicle_part *part = &parts[elem];
if( !magic ) {
if( !magic && !part->properties_to_item().has_flag( flag_id( "POWER_CORD" ) ) ) {
item drop = part->properties_to_item();
here.add_item_or_charges( global_part_pos3( *part ), drop );
}
Expand Down Expand Up @@ -7272,6 +7273,16 @@ tripoint vehicle::exhaust_dest( int part ) const
return global_pos3() + tripoint( q, 0 );
}

void vehicle::add_tag( std::string tag )
{
tags.insert( tag );
}

bool vehicle::has_tag( std::string tag )
{
return tags.count( tag ) > 0;
}

template<>
bool vehicle_part_with_feature_range<std::string>::matches( const size_t part ) const
{
Expand Down
5 changes: 5 additions & 0 deletions src/vehicle.h
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,8 @@ class vehicle
*/
void use_controls( const tripoint &pos );

void plug_in( const tripoint &pos );

// Fold up the vehicle
bool fold_up();

Expand Down Expand Up @@ -1916,6 +1918,9 @@ class vehicle
cata::optional<smart_controller_config> smart_controller_cfg = cata::nullopt;
bool has_enabled_smart_controller = false; // NOLINT(cata-serialize)

void add_tag( std::string tag );
bool has_tag( std::string tag );

private:
mutable units::mass mass_cache; // NOLINT(cata-serialize)
// cached pivot point
Expand Down
Loading