Skip to content

Commit

Permalink
Merge pull request CleverRaven#71961 from zack-shoylev/item-faults
Browse files Browse the repository at this point in the history
undefined
  • Loading branch information
Maleclypse authored Mar 6, 2024
2 parents 7072fe7 + 73bcb0a commit 58cef75
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 41 deletions.
71 changes: 71 additions & 0 deletions data/json/faults/faults_electronic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
[
{
"type": "fault",
"id": "fault_electronic_blown_fuse",
"fault_type": "shorted",
"name": { "str": "Blown fuse" },
"description": "Required for closing a protected electronic circuit.",
"item_prefix": "shorted",
"flags": [ "ITEM_BROKEN" ]
},
{
"type": "fault_fix",
"id": "mend_fault_electronic_blown_fuse",
"name": "Replace blown fuse",
"success_msg": "You replace the blown fuse of the %s.",
"time": "5 m",
"faults_removed": [ "fault_electronic_blown_fuse" ],
"skills": { "electronics": 3 },
"requirements": [ { "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ [ [ "e_scrap", 1 ], [ "copper_wire", 1 ] ] ] } ]
},
{
"type": "fault",
"id": "fault_electronic_blown_capacitor",
"fault_type": "shorted",
"name": { "str": "Blown capacitor" },
"description": "Required for storing charge in an electronic circuit.",
"item_prefix": "shorted",
"flags": [ "ITEM_BROKEN" ]
},
{
"type": "fault_fix",
"id": "mend_fault_electronic_blown_capacitor",
"name": "Replace blown fuse",
"success_msg": "You replace the blow capacitor of the %s.",
"time": "10 m",
"faults_removed": [ "fault_electronic_blown_capacitor" ],
"skills": { "electronics": 4 },
"requirements": [
{
"qualities": [ { "id": "SCREW", "level": 1 } ],
"tools": [ [ "soldering_iron" ], [ "soldering_iron_portable" ] ],
"components": [ [ [ "e_scrap", 1 ] ] ]
}
]
},
{
"type": "fault",
"id": "fault_electronic_shorted_circuit",
"fault_type": "shorted",
"name": { "str": "Shorted electronic circuit" },
"description": "An electronic circuit has been destroyed by overvoltage.",
"item_prefix": "shorted",
"flags": [ "ITEM_BROKEN" ]
},
{
"type": "fault_fix",
"id": "mend_fault_electronic_shorted_circuit",
"name": "Replace shorted circuit",
"success_msg": "You replace the shorted circuit of the %s.",
"time": "70 m",
"faults_removed": [ "fault_electronic_shorted_circuit" ],
"skills": { "electronics": 5 },
"requirements": [
{
"qualities": [ { "id": "SCREW", "level": 1 } ],
"tools": [ [ "soldering_iron" ], [ "soldering_iron_portable" ] ],
"components": [ [ [ "circuit", 1 ] ] ]
}
]
}
]
45 changes: 45 additions & 0 deletions data/json/faults/faults_water.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[
{
"id": "fault_wet",
"type": "fault",
"fault_type": "wet",
"name": { "str": "Wet" },
"description": "Item is too wet to use and has to be dried.",
"item_prefix": "waterlogged",
"flags": [ "ITEM_BROKEN" ]
},
{
"type": "fault_fix",
"id": "mend_fault_wet",
"name": "Passively dry",
"success_msg": "You dry the %s.",
"time": "120 m",
"faults_removed": [ "fault_wet" ],
"skills": { "fabrication": 2 },
"requirements": [
{
"qualities": [ { "id": "CONTAIN", "level": 1 } ],
"components": [ [ [ "flour", 10 ], [ "dry_rice", 10 ], [ "dry_beans", 10 ], [ "dry_lentils", 10 ] ] ]
}
]
},
{
"type": "fault_fix",
"id": "mend_fault_wet_oven",
"name": "Dry with hot air in an oven. Requires good temperature control.",
"success_msg": "You heat up and dry the %s.",
"time": "60 m",
"faults_removed": [ "fault_wet" ],
"skills": { "cooking": 4 },
"requirements": [ { "qualities": [ { "id": "OVEN", "level": 3 } ] } ]
},
{
"type": "fault_fix",
"id": "mend_fault_wet_hot_air",
"name": "Dry with hot air.",
"success_msg": "You dry the %s with hot air.",
"time": "10 m",
"faults_removed": [ "fault_wet" ],
"requirements": [ { "qualities": [ { "id": "BLOW_HOT_AIR", "level": 1 } ] } ]
}
]
7 changes: 6 additions & 1 deletion src/avatar_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "creature_tracker.h"
#include "debug.h"
#include "enums.h"
#include "fault.h"
#include "flag.h"
#include "game.h"
#include "game_constants.h"
Expand Down Expand Up @@ -1115,7 +1116,11 @@ void avatar_action::use_item( avatar &you, item_location &loc, std::string const
if( loc->wetness && loc->has_flag( flag_WATER_BREAK_ACTIVE ) ) {
if( query_yn( _( "This item is still wet and it will break if you turn it on. Proceed?" ) ) ) {
loc->deactivate();
loc->set_flag( flag_ITEM_BROKEN );
loc.get_item()->set_fault( random_entry( fault::get_by_type( std::string( "wet" ) ) ) );
// An electronic item in water is also shorted.
if( loc->has_flag( flag_ELECTRONIC ) ) {
loc.get_item()->set_fault( random_entry( fault::get_by_type( std::string( "shorted" ) ) ) );
}
} else {
return;
}
Expand Down
5 changes: 3 additions & 2 deletions src/explosion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "damage.h"
#include "debug.h"
#include "enums.h"
#include "fault.h"
#include "field_type.h"
#include "flag.h"
#include "game.h"
Expand Down Expand Up @@ -772,7 +773,7 @@ void emp_blast( const tripoint &p )
!player_character.has_flag( json_flag_EMP_IMMUNE ) ) {
add_msg( m_bad, _( "The EMP blast fries your %s!" ), it->tname() );
it->deactivate();
it->set_flag( flag_ITEM_BROKEN );
it->faults.insert( random_entry( fault::get_by_type( "shorted" ) ) );
}
}
}
Expand All @@ -785,7 +786,7 @@ void emp_blast( const tripoint &p )
add_msg( _( "The EMP blast fries the %s!" ), it.tname() );
}
it.deactivate();
it.set_flag( flag_ITEM_BROKEN );
it.set_fault( random_entry( fault::get_by_type( "shorted" ) ) );
}
}
// TODO: Drain NPC energy reserves
Expand Down
16 changes: 16 additions & 0 deletions src/fault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

static std::map<fault_id, fault> faults_all;
static std::map<fault_fix_id, fault_fix> fault_fixes_all;
// Have a list of faults by type, the type right now is item prefix to avoid adding more JSON data
static std::map<std::string, std::list<fault_id>> faults_by_type;

/** @relates string_id */
template<>
Expand Down Expand Up @@ -70,6 +72,11 @@ std::string fault::item_prefix() const
return item_prefix_.translated();
}

std::string fault::type() const
{
return type_;
}

bool fault::has_flag( const std::string &flag ) const
{
return flags.count( flag );
Expand All @@ -88,11 +95,15 @@ void fault::load( const JsonObject &jo )
mandatory( jo, false, "name", f.name_ );
mandatory( jo, false, "description", f.description_ );
optional( jo, false, "item_prefix", f.item_prefix_ );
optional( jo, false, "fault_type", f.type_ );
optional( jo, false, "flags", f.flags );

if( !faults_all.emplace( f.id_, f ).second ) {
jo.throw_error_at( "id", "parsed fault overwrites existing definition" );
}
if( !f.type_.empty() ) {
faults_by_type[ std::string( f.type_ ) ].push_back( f.id() );
}
}

const std::map<fault_id, fault> &fault::all()
Expand Down Expand Up @@ -122,6 +133,11 @@ const std::map<fault_fix_id, fault_fix> &fault_fix::all()
return fault_fixes_all;
}

const std::list<fault_id> &fault::get_by_type( const std::string &type )
{
return faults_by_type.at( type );
}

const requirement_data &fault_fix::get_requirements() const
{
return *requirements;
Expand Down
4 changes: 4 additions & 0 deletions src/fault.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define CATA_SRC_FAULT_H

#include <iosfwd>
#include <list>
#include <map>
#include <new>
#include <optional>
Expand Down Expand Up @@ -52,20 +53,23 @@ class fault
public:
const fault_id &id() const;
std::string name() const;
std::string type() const; // use a set of types?
std::string description() const;
std::string item_prefix() const;
bool has_flag( const std::string &flag ) const;

const std::set<fault_fix_id> &get_fixes() const;

static const std::map<fault_id, fault> &all();
static const std::list<fault_id> &get_by_type( const std::string &type );
static void load( const JsonObject &jo );
static void reset();
static void check_consistency();

private:
friend class fault_fix;
fault_id id_ = fault_id::NULL_ID();
std::string type_;
translation name_;
translation description_;
translation item_prefix_; // prefix added to affected item's name
Expand Down
48 changes: 18 additions & 30 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
#include "event.h"
#include "event_bus.h"
#include "faction.h"
#include "fault.h"
#include "field.h"
#include "field_type.h"
#include "filesystem.h"
Expand Down Expand Up @@ -11571,47 +11572,34 @@ void game::on_options_changed()

void game::water_affect_items( Character &ch ) const
{
std::vector<item_location> dissolved;
std::vector<item_location> destroyed;
std::vector<item_location> wet;

for( item_location &loc : ch.all_items_loc() ) {
// check flag first because its cheaper
if( loc->has_flag( flag_WATER_DISSOLVE ) && !loc.protected_from_liquids() ) {
dissolved.emplace_back( loc );
add_msg_if_player_sees( ch.pos(), m_bad, _( "%1$s %2$s dissolved in the water!" ),
ch.disp_name( true, true ), loc->display_name() );
loc.remove_item();
} else if( loc->has_flag( flag_WATER_BREAK ) && !loc->is_broken()
&& !loc.protected_from_liquids() ) {
destroyed.emplace_back( loc );

add_msg_if_player_sees( ch.pos(), m_bad, _( "The water destroyed %1$s %2$s!" ),
ch.disp_name( true ), loc->display_name() );
loc->deactivate();
// TODO: Maybe different types of wet faults? But I can't think of any.
// This just means it's still too wet to use.
loc->set_fault( random_entry( fault::get_by_type( std::string( "wet" ) ) ) );
// An electronic item in water is also shorted.
if( loc->has_flag( flag_ELECTRONIC ) ) {
loc->set_fault( random_entry( fault::get_by_type( std::string( "shorted" ) ) ) );
}
} else if( loc->has_flag( flag_WATER_BREAK_ACTIVE ) && !loc->is_broken()
&& !loc.protected_from_liquids() ) {
wet.emplace_back( loc );
const int wetness_add = 5100 * std::log10( units::to_milliliter( loc->volume() ) );
loc->wetness += wetness_add;
loc->wetness = std::min( loc->wetness, 5 * wetness_add );
} else if( loc->typeId() == itype_towel && !loc.protected_from_liquids() ) {
loc->convert( itype_towel_wet, &ch ).active = true;
}
}

if( dissolved.empty() && destroyed.empty() && wet.empty() ) {
return;
}

for( item_location &it : dissolved ) {
add_msg_if_player_sees( ch.pos(), m_bad, _( "%1$s %2$s dissolved in the water!" ),
ch.disp_name( true, true ), it->display_name() );
it.remove_item();
}

for( item_location &it : destroyed ) {
add_msg_if_player_sees( ch.pos(), m_bad, _( "The water destroyed %1$s %2$s!" ),
ch.disp_name( true ), it->display_name() );
it->deactivate();
it->set_flag( flag_ITEM_BROKEN );
}

for( item_location &it : wet ) {
const int wetness_add = 5100 * std::log10( units::to_milliliter( it->volume() ) );
it->wetness += wetness_add;
it->wetness = std::min( it->wetness, 5 * wetness_add );
}
}

bool game::fling_creature( Creature *c, const units::angle &dir, float flvel, bool controlled,
Expand Down
17 changes: 14 additions & 3 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7600,6 +7600,12 @@ item &item::set_flag( const flag_id &flag )
return *this;
}

item &item::set_fault( const fault_id &fault_id )
{
faults.insert( fault_id );
return *this;
}

item &item::unset_flag( const flag_id &flag )
{
item_tags.erase( flag );
Expand Down Expand Up @@ -9748,12 +9754,14 @@ bool item::is_irremovable() const

bool item::is_broken() const
{
return has_flag( flag_ITEM_BROKEN );
return has_flag( flag_ITEM_BROKEN ) || has_fault_flag( std::string( "ITEM_BROKEN" ) );
}

bool item::is_broken_on_active() const
{
return has_flag( flag_ITEM_BROKEN ) || ( wetness && has_flag( flag_WATER_BREAK_ACTIVE ) );
return has_flag( flag_ITEM_BROKEN ) ||
has_fault_flag( std::string( "ITEM_BROKEN" ) ) ||
( wetness && has_flag( flag_WATER_BREAK_ACTIVE ) );
}

int item::wind_resist() const
Expand Down Expand Up @@ -14020,7 +14028,10 @@ bool item::process_internal( map &here, Character *carrier, const tripoint &pos,

if( wetness && has_flag( flag_WATER_BREAK ) ) {
deactivate();
set_flag( flag_ITEM_BROKEN );
set_fault( random_entry( fault::get_by_type( std::string( "wet" ) ) ) );
if( has_flag( flag_ELECTRONIC ) ) {
set_fault( random_entry( fault::get_by_type( std::string( "shorted" ) ) ) );
}
}

if( !is_food() && item_counter > 0 ) {
Expand Down
3 changes: 3 additions & 0 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1970,6 +1970,9 @@ class item : public visitable
/** Idempotent filter setting an item specific flag. */
item &set_flag( const flag_id &flag );

/** Idempotent filter setting an item specific fault. */
item &set_fault( const fault_id &fault_id );

/** Idempotent filter removing an item specific flag */
item &unset_flag( const flag_id &flag );

Expand Down
Loading

0 comments on commit 58cef75

Please sign in to comment.