Skip to content

Commit

Permalink
Allow examining furniture to convert to appliances
Browse files Browse the repository at this point in the history
It's a little silly to deconstruct a piece of furniture, then put it
back up in the same place to turn it into an appliance - let's just
directly turn them into appliances with an examine.

Move some functions from construction.cpp to veh_appliance.cpp for reuse
in other things that place appliances (such as the examine action here).
  • Loading branch information
anothersimulacrum committed Apr 16, 2022
1 parent a50a766 commit 935e5c1
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 50 deletions.
6 changes: 5 additions & 1 deletion data/json/furniture_and_terrain/furniture-appliances.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@
"flags": [ "CONTAINER", "PLACE_ITEM", "BLOCKSDOOR", "MINEABLE", "NO_SELF_CONNECT", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "fridge", "count": 1 } ] },
"max_volume": "200 L",
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "fridge" },
"bash": {
"str_min": 18,
"str_max": 50,
Expand Down Expand Up @@ -259,6 +260,7 @@
"move_cost_mod": -1,
"coverage": 60,
"required_str": 10,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "freezer" },
"flags": [ "CONTAINER", "PLACE_ITEM", "BLOCKSDOOR", "MINEABLE", "NO_SELF_CONNECT", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "freezer", "count": 1 } ] },
"max_volume": "450 L",
Expand Down Expand Up @@ -363,9 +365,10 @@
"move_cost_mod": 2,
"coverage": 60,
"required_str": 10,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "oven" },
"//": "TODO: Replace FIRE_CONTAINER with some flag choking out small files",
"flags": [ "PLACE_ITEM", "TRANSPARENT", "EASY_DECONSTRUCT", "FIRE_CONTAINER", "CONTAINER", "BLOCKSDOOR", "MOUNTABLE" ],
"deconstruct": { "items": [ { "item": "oven", "count": 1 } ] },
"examine_action": "fireplace",
"max_volume": "120 L",
"bash": {
"str_min": 8,
Expand Down Expand Up @@ -586,6 +589,7 @@
"color": "yellow",
"move_cost_mod": 2,
"required_str": -1,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "solar_panel" },
"flags": [ "TRANSPARENT" ],
"deconstruct": { "items": [ { "item": "solar_panel", "count": 1 } ] },
"bash": {
Expand Down
1 change: 1 addition & 0 deletions data/json/furniture_and_terrain/furniture-decorative.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@
"color": "light_gray",
"move_cost_mod": 2,
"required_str": 1,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "standing_lamp" },
"flags": [ "TRANSPARENT", "BLOCKSDOOR", "PLACE_ITEM", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "standing_lamp", "count": 1 } ] },
"bash": {
Expand Down
1 change: 1 addition & 0 deletions data/json/furniture_and_terrain/furniture-recreation.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
"move_cost_mod": -1,
"coverage": 75,
"required_str": 12,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "arcade_machine" },
"flags": [ "BLOCKSDOOR", "TRANSPARENT" ],
"deconstruct": {
"items": [
Expand Down
7 changes: 7 additions & 0 deletions data/json/furniture_and_terrain/furniture-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@
"move_cost_mod": -1,
"coverage": 40,
"required_str": 10,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "drill_press" },
"flags": [ "BLOCKSDOOR", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "drill_press", "count": 1 } ] },
"bash": {
Expand Down Expand Up @@ -670,6 +671,7 @@
"move_cost_mod": 8,
"coverage": 40,
"required_str": 10,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "tablesaw" },
"flags": [ "BLOCKSDOOR", "TRANSPARENT", "MOUNTABLE", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "tablesaw", "count": 1 } ] },
"bash": {
Expand All @@ -696,6 +698,7 @@
"move_cost_mod": -1,
"coverage": 40,
"required_str": 10,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "mitresaw" },
"flags": [ "BLOCKSDOOR", "TRANSPARENT", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "mitresaw", "count": 1 } ] },
"bash": {
Expand All @@ -722,6 +725,7 @@
"move_cost_mod": -1,
"coverage": 40,
"required_str": 10,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "bandsaw" },
"flags": [ "BLOCKSDOOR", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "bandsaw", "count": 1 } ] },
"bash": {
Expand All @@ -748,6 +752,7 @@
"move_cost_mod": 8,
"coverage": 35,
"required_str": 14,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "router" },
"flags": [ "BLOCKSDOOR", "TRANSPARENT", "MOUNTABLE", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "router", "count": 1 } ] },
"bash": {
Expand All @@ -774,6 +779,7 @@
"move_cost_mod": -1,
"coverage": 40,
"required_str": 12,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "planer" },
"flags": [ "BLOCKSDOOR", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "planer", "count": 1 } ] },
"bash": {
Expand All @@ -800,6 +806,7 @@
"move_cost_mod": 8,
"coverage": 40,
"required_str": 14,
"examine_action": { "type": "appliance_convert", "furn_set": "f_null", "item": "jointer" },
"flags": [ "BLOCKSDOOR", "TRANSPARENT", "MOUNTABLE", "EASY_DECONSTRUCT" ],
"deconstruct": { "items": [ { "item": "jointer", "count": 1 } ] },
"bash": {
Expand Down
27 changes: 27 additions & 0 deletions doc/EXAMINE.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,33 @@ The examine actors are specified as JSON objects with a `type` corresponding to

## Examine Actors

### `appliance_convert`

#### `furn_set`
Optional, defaults to no change.
String.
Furniture id that this tile will be set to after placing the appliance.

#### `ter_set`
Optional, defaults to no change.
String.
Terrain id that this tile will be set to after placing the appliance.

#### `item`
Mandatory.
String.
Item id of the base item of this appliance.

#### Example
```json
{
"type": "appliance_convert",
"furn_set": "f_null",
"ter_set": "t_floor",
"item": "fridge"
}
```

### `cardreader`

#### `flags`
Expand Down
52 changes: 4 additions & 48 deletions src/construction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "ui_manager.h"
#include "uistate.h"
#include "units.h"
#include "veh_appliance.h"
#include "veh_type.h"
#include "vehicle.h"
#include "vpart_position.h"
Expand Down Expand Up @@ -94,7 +95,6 @@ static const trap_str_id tr_firewood_source( "tr_firewood_source" );
static const trap_str_id tr_practice_target( "tr_practice_target" );
static const trap_str_id tr_unfinished_construction( "tr_unfinished_construction" );

static const vpart_id vpart_ap_standing_lamp( "ap_standing_lamp" );
static const vpart_id vpart_frame_vertical_2( "frame_vertical_2" );

static const vproto_id vehicle_prototype_none( "none" );
Expand Down Expand Up @@ -1337,18 +1337,6 @@ static vpart_id vpart_from_item( const itype_id &item_id )
return vpart_frame_vertical_2;
}

static vpart_id vpart_appliance_from_item( const itype_id &item_id )
{
for( const std::pair<const vpart_id, vpart_info> &e : vpart_info::all() ) {
const vpart_info &vp = e.second;
if( vp.base_item == item_id && vp.has_flag( flag_APPLIANCE ) ) {
return vp.get_id();
}
}
debugmsg( "item %s used by construction is not base item of any appliance!", item_id.c_str() );
return vpart_ap_standing_lamp;
}

void construct::done_vehicle( const tripoint &p )
{
std::string name = string_input_popup()
Expand Down Expand Up @@ -1446,52 +1434,20 @@ void construct::done_wiring( const tripoint &p )
void construct::done_appliance( const tripoint &p )
{
map &here = get_map();
vehicle *veh = here.add_vehicle( vehicle_prototype_none, p, 0_degrees, 0, 0 );

if( !veh ) {
debugmsg( "error constructing vehicle" );
return;
}

const vpart_id &vpart = vpart_appliance_from_item( get_avatar().lastconsumed );
partial_con *pc = here.partial_con_at( p );
cata::optional<item> base = cata::nullopt;
const vpart_id &vpart = vpart_appliance_from_item( get_avatar().lastconsumed );
if( pc ) {
item base;
for( item &obj : pc->components ) {
if( obj.typeId() == vpart->base_item ) {
base = obj;
}
}
veh->install_part( point_zero, vpart, std::move( base ) );
} else {
debugmsg( "partial construction not found" );
veh->install_part( point_zero, vpart );
}
veh->name = vpart->name();

here.partial_con_remove( p );

veh->add_tag( flag_APPLIANCE );

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

// Connect to any neighbouring appliances or wires once
std::unordered_set<const vehicle *> connected_vehicles;
for( const tripoint &trip : here.points_in_radius( p, 1 ) ) {
const optional_vpart_position vp = here.veh_at( trip );
if( !vp ) {
continue;
}
const vehicle &veh_target = vp->vehicle();
if( veh_target.has_tag( flag_APPLIANCE ) || veh_target.has_tag( flag_WIRING ) ) {
if( connected_vehicles.find( &veh_target ) == connected_vehicles.end() ) {
veh->connect( p, trip );
connected_vehicles.insert( &veh_target );
}
}
}
place_appliance( p, vpart, base );
}

void construct::done_deconstruct( const tripoint &p )
Expand Down
47 changes: 47 additions & 0 deletions src/iexamine_actors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,57 @@
#include "messages.h"
#include "mtype.h"
#include "output.h"
#include "veh_appliance.h"

static const ter_str_id ter_t_door_metal_c( "t_door_metal_c" );
static const ter_str_id ter_t_door_metal_locked( "t_door_metal_locked" );

void appliance_convert_examine_actor::load( const JsonObject &jo )
{
optional( jo, false, "furn_set", furn_set );
optional( jo, false, "ter_set", ter_set );
mandatory( jo, false, "item", appliance_item );
}

void appliance_convert_examine_actor::call( Character &, const tripoint &examp ) const
{
if( !query_yn( _( "Connect %s to grid?" ), item::nname( appliance_item ) ) ) {
return;
}
map &here = get_map();
if( furn_set ) {
here.furn_set( examp, *furn_set );
}
if( ter_set ) {
here.ter_set( examp, *ter_set );
}

place_appliance( examp, vpart_appliance_from_item( appliance_item ) );
}

void appliance_convert_examine_actor::finalize() const
{
if( furn_set && !furn_set->is_valid() ) {
debugmsg( "Invalid furniture id %s in appliance_convert action", furn_set->str() );
}
if( ter_set && !ter_set->is_valid() ) {
debugmsg( "Invalid terrain id %s in appliance_convert action", ter_set->str() );
}

if( !appliance_item.is_valid() ) {
debugmsg( "Invalid appliance item %s in appliance_convert action", appliance_item.str() );
} else if( !vpart_appliance_from_item( appliance_item ).is_valid() ) {
// This will never actually trigger now, but is here if the semantics of vpart_appliance_from_item change
debugmsg( "In appliance_convert action, %s does not correspond to an appliance",
appliance_item.str() );
}
}

std::unique_ptr<iexamine_actor> appliance_convert_examine_actor::clone() const
{
return std::make_unique<appliance_convert_examine_actor>( *this );
}

void cardreader_examine_actor::consume_card( const std::vector<item_location> &cards ) const
{
if( !consume ) {
Expand Down
19 changes: 19 additions & 0 deletions src/iexamine_actors.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@
class Character;
class item_location;

class appliance_convert_examine_actor : public iexamine_actor
{
private:
cata::optional<furn_str_id> furn_set = cata::nullopt;
cata::optional<ter_str_id> ter_set = cata::nullopt;
itype_id appliance_item;

public:
explicit appliance_convert_examine_actor( const std::string &type = "appliance_convert" )
: iexamine_actor( type ) {}

void load( const JsonObject &jo ) override;
void call( Character &you, const tripoint &examp ) const override;
void finalize() const override;

std::unique_ptr<iexamine_actor> clone() const override;
};

class cardreader_examine_actor : public iexamine_actor
{
private:
Expand Down Expand Up @@ -63,4 +81,5 @@ class eoc_examine_actor : public iexamine_actor

std::unique_ptr<iexamine_actor> clone() const override;
};

#endif // CATA_SRC_IEXAMINE_ACTORS_H
1 change: 1 addition & 0 deletions src/mapdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,7 @@ static cata::clone_ptr<iexamine_actor> iexamine_actor_from_jsobj( const JsonObje

void init_mapdata()
{
add_actor( std::make_unique<appliance_convert_examine_actor>() );
add_actor( std::make_unique<cardreader_examine_actor>() );
add_actor( std::make_unique<eoc_examine_actor>() );
}
Expand Down
Loading

0 comments on commit 935e5c1

Please sign in to comment.