Skip to content

Commit

Permalink
Merge pull request #24077 from Coolthulhu/fire-refuel
Browse files Browse the repository at this point in the history
[RDY]Automatic fire refuelling
  • Loading branch information
ZhilkinSerg authored Jul 8, 2018
2 parents f0b80c9 + 3bcce39 commit 47a80bc
Show file tree
Hide file tree
Showing 16 changed files with 238 additions and 58 deletions.
8 changes: 8 additions & 0 deletions data/json/construction.json
Original file line number Diff line number Diff line change
Expand Up @@ -2343,5 +2343,13 @@
],
"pre_terrain" : "t_reinforced_glass",
"post_terrain" : "t_reinforced_glass_shutter"
},{
"type" : "construction",
"description" : "Mark firewood source",
"category" : "OTHER",
"required_skills" : [],
"time" : 0,
"pre_special" : "check_no_trap",
"post_special" : "done_mark_firewood"
}
]
46 changes: 23 additions & 23 deletions data/json/materials.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"bash_dmg_verb": "cracked",
"cut_dmg_verb": "chipped",
"burn_data": [
{ "fuel": 0, "smoke": 1, "burn": 1, "chance": 5 },
{ "fuel": 0, "smoke": 1, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 1, "smoke": 3, "burn": 1 },
{ "fuel": 1, "smoke": 5, "burn": 5 }
]
Expand All @@ -74,7 +74,7 @@
"vitamins": [ [ "calcium", 2 ] ],
"burn_data": [
{ "fuel": 0, "smoke": 0, "burn": 0 },
{ "fuel": 0, "smoke": 1, "burn": 1, "chance": 1 },
{ "fuel": 0, "smoke": 1, "burn": 1, "volume_per_turn": "250_ml" },
{ "fuel": 1, "smoke": 1, "burn": 2 }
]
},
Expand Down Expand Up @@ -139,7 +139,7 @@
"bash_dmg_verb": "cracked",
"cut_dmg_verb": "chipped",
"burn_data": [
{ "fuel": 0, "smoke": 1, "burn": 1, "chance": 5 },
{ "fuel": 0, "smoke": 1, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 1, "smoke": 3, "burn": 1 },
{ "fuel": 1, "smoke": 5, "burn": 5 }
]
Expand Down Expand Up @@ -194,7 +194,7 @@
"bash_dmg_verb": "ripped",
"cut_dmg_verb": "cut",
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 1, "chance": 5 },
{ "fuel": 1, "smoke": 1, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 1, "smoke": 1, "burn": 1 },
{ "fuel": 1, "smoke": 1, "burn": 2 }
]
Expand Down Expand Up @@ -249,8 +249,8 @@
"cut_dmg_verb": "sliced",
"vitamins": [ [ "calcium", 0.1 ], [ "vitB", 1 ], [ "iron", 2 ] ],
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 1, "chance": 10 },
{ "fuel": 2, "smoke": 3, "burn": 2, "chance": 40 },
{ "fuel": 1, "smoke": 1, "burn": 1, "volume_per_turn": "2500_ml" },
{ "fuel": 2, "smoke": 3, "burn": 2, "volume_per_turn": "10000_ml" },
{ "fuel": 3, "smoke": 10, "burn": 3 }
]
},
Expand Down Expand Up @@ -286,7 +286,7 @@
"cut_dmg_verb": "cut",
"vitamins": [ [ "vitC", 2 ] ],
"burn_data": [
{ "fuel": 1, "smoke": 2, "burn": 1, "chance": 5 },
{ "fuel": 1, "smoke": 2, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 1, "smoke": 1, "burn": 2 },
{ "fuel": 1, "smoke": 1, "burn": 3 }
]
Expand All @@ -309,7 +309,7 @@
"bash_dmg_verb": "ripped",
"cut_dmg_verb": "sliced",
"burn_data": [
{ "fuel": 1, "smoke": 3, "burn": 1, "chance": 5 },
{ "fuel": 1, "smoke": 3, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 1, "smoke": 5, "burn": 2 },
{ "fuel": 1, "smoke": 10, "burn": 4 }
]
Expand All @@ -331,7 +331,7 @@
"burn_data": [
{ "fuel": 0, "smoke": 0, "burn": 0 },
{ "fuel": 0, "smoke": 0, "burn": 0 },
{ "fuel": 0, "smoke": 0, "burn": 1000, "chance": 20, "//": "More like shattering than melting" }
{ "fuel": 0, "smoke": 0, "burn": 1000, "volume_per_turn": "5000_ml", "//": "More like shattering than melting" }
]
},
{
Expand Down Expand Up @@ -385,8 +385,8 @@
"cut_dmg_verb": "sliced",
"vitamins": [ [ "calcium", 0.1 ], [ "vitB", 1 ], [ "iron", 2 ] ],
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 1, "chance": 10 },
{ "fuel": 2, "smoke": 3, "burn": 2, "chance": 40 },
{ "fuel": 1, "smoke": 1, "burn": 1, "volume_per_turn": "2500_ml" },
{ "fuel": 2, "smoke": 3, "burn": 2, "volume_per_turn": "10000_ml" },
{ "fuel": 3, "smoke": 10, "burn": 3 }
]
},
Expand Down Expand Up @@ -444,8 +444,8 @@
"cut_dmg_verb": "sliced",
"vitamins": [ [ "calcium", 1 ] ],
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 1, "chance": 10 },
{ "fuel": 2, "smoke": 3, "burn": 2, "chance": 40 },
{ "fuel": 1, "smoke": 1, "burn": 1, "volume_per_turn": "2500_ml" },
{ "fuel": 2, "smoke": 3, "burn": 2, "volume_per_turn": "10000_ml" },
{ "fuel": 3, "smoke": 10, "burn": 3 }
]
},
Expand Down Expand Up @@ -535,7 +535,7 @@
"cut_dmg_verb": "sliced",
"burn_data": [
{ "fuel": 0, "smoke": 0, "burn": 0 },
{ "fuel": 1, "smoke": 3, "burn": 2, "chance": 2 },
{ "fuel": 1, "smoke": 3, "burn": 2, "volume_per_turn": "500_ml" },
{ "fuel": 1, "smoke": 3, "burn": 2 }
]
},
Expand Down Expand Up @@ -579,7 +579,7 @@
"bash_dmg_verb": "ripped",
"cut_dmg_verb": "sliced",
"burn_data": [
{ "fuel": 1, "smoke": 3, "burn": 1, "chance": 10 },
{ "fuel": 1, "smoke": 3, "burn": 1, "volume_per_turn": "2500_ml" },
{ "fuel": 1, "smoke": 3, "burn": 2 },
{ "fuel": 1, "smoke": 3, "burn": 3 }
]
Expand Down Expand Up @@ -673,7 +673,7 @@
"bash_dmg_verb": "dented",
"cut_dmg_verb": "gouged",
"burn_data": [
{ "fuel": 1, "smoke": 2, "burn": 1, "chance": 3 },
{ "fuel": 1, "smoke": 2, "burn": 1, "volume_per_turn": "750_ml" },
{ "fuel": 1, "smoke": 3, "burn": 2 },
{ "fuel": 1, "smoke": 5, "burn": 5 }
]
Expand Down Expand Up @@ -794,8 +794,8 @@
"cut_dmg_verb": "cut",
"vitamins": [ [ "calcium", 0.1 ], [ "vitA", 1 ], [ "vitC", 0.5 ] ],
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 1, "chance": 5 },
{ "fuel": 2, "smoke": 1, "burn": 2, "chance": 10 },
{ "fuel": 1, "smoke": 1, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 2, "smoke": 1, "burn": 2, "volume_per_turn": "2500_ml" },
{ "fuel": 2, "smoke": 1, "burn": 3 }
]
},
Expand Down Expand Up @@ -854,8 +854,8 @@
"bash_dmg_verb": "splintered",
"cut_dmg_verb": "gouged",
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 0.02, "chance": 5 },
{ "fuel": 2, "smoke": 1, "burn": 0.04, "chance": 20 },
{ "fuel": 1, "smoke": 1, "burn": 0.02, "volume_per_turn": "1250_ml" },
{ "fuel": 2, "smoke": 1, "burn": 0.04, "volume_per_turn": "5000_ml" },
{ "fuel": 3, "smoke": 1, "burn": 0.06 }
],
"burn_products": [ [ "ash", 0.018 ] ]
Expand All @@ -878,7 +878,7 @@
"bash_dmg_verb": "torn",
"cut_dmg_verb": "cut",
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 1, "chance": 5 },
{ "fuel": 1, "smoke": 1, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 1, "smoke": 1, "burn": 2 },
{ "fuel": 1, "smoke": 1, "burn": 5 }
]
Expand All @@ -898,8 +898,8 @@
"bash_dmg_verb": "squished",
"cut_dmg_verb": "squished",
"burn_data": [
{ "fuel": 1, "smoke": 1, "burn": 1, "chance": 5 },
{ "fuel": 2, "smoke": 1, "burn": 2, "chance": 10 },
{ "fuel": 1, "smoke": 1, "burn": 1, "volume_per_turn": "1250_ml" },
{ "fuel": 2, "smoke": 1, "burn": 2, "volume_per_turn": "2500_ml" },
{ "fuel": 2, "smoke": 1, "burn": 3 }
]
}
Expand Down
15 changes: 10 additions & 5 deletions data/json/player_activities.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"type": "activity_type",
"stop_phrase": "Stop reading?",
"rooted": true,
"based_on": "speed"
"based_on": "speed",
"refuel_fires": true
},
{
"id": "ACT_GAME",
Expand All @@ -32,20 +33,23 @@
"id": "ACT_CRAFT",
"type": "activity_type",
"stop_phrase": "Stop crafting?",
"based_on": "neither"
"based_on": "neither",
"refuel_fires": true
},
{
"id": "ACT_LONGCRAFT",
"type": "activity_type",
"stop_phrase": "Stop crafting?",
"based_on": "neither"
"based_on": "neither",
"refuel_fires": true
},
{
"id": "ACT_DISASSEMBLE",
"type": "activity_type",
"stop_phrase": "Stop disassembly?",
"suspendable": false,
"based_on": "speed"
"based_on": "speed",
"refuel_fires": true
},
{
"id": "ACT_BUTCHER",
Expand All @@ -58,7 +62,8 @@
"type": "activity_type",
"stop_phrase": "Stop salvaging?",
"based_on": "speed",
"no_resume": true
"no_resume": true,
"refuel_fires": true
},
{
"id": "ACT_FORAGE",
Expand Down
12 changes: 12 additions & 0 deletions data/json/traps.json
Original file line number Diff line number Diff line change
Expand Up @@ -467,5 +467,17 @@
"drops" : ["metal_funnel"],
"benign" : true,
"funnel_radius": 400
},
{
"type" : "trap",
"id": "tr_firewood_source",
"name" : "firewood source",
"color" : "green",
"symbol" : "x",
"visibility" : -1,
"avoidance" : 0,
"difficulty" : 0,
"action" : "none",
"benign" : true
}
]
1 change: 1 addition & 0 deletions src/activity_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ void activity_on_turn_drop();
void activity_on_turn_move_items();
void activity_on_turn_pickup();
void activity_on_turn_stash();
void try_refuel_fire( player &p );

// advanced_inv.cpp
void advanced_inv();
Expand Down
103 changes: 103 additions & 0 deletions src/activity_item_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@

#include "game.h"
#include "map.h"
#include "mapdata.h"
#include "item.h"
#include "player_activity.h"
#include "action.h"
#include "enums.h"
#include "field.h"
#include "fire.h"
#include "creature.h"
#include "pickup.h"
#include "translations.h"
#include "messages.h"
#include "monster.h"
#include "optional.h"
#include "output.h"
#include "trap.h"
#include "vehicle.h"
#include "vpart_position.h"
#include "vpart_reference.h"
Expand All @@ -26,12 +31,15 @@
#include <vector>
#include <cassert>
#include <algorithm>
#include <numeric>

void cancel_aim_processing();

const efftype_id effect_controlled( "controlled" );
const efftype_id effect_pet( "pet" );

const trap_str_id tr_firewood_source( "tr_firewood_source" );

/** Activity-associated item */
struct act_item {
const item *it; /// Pointer to the inventory item
Expand Down Expand Up @@ -640,3 +648,98 @@ void activity_on_turn_move_items()
}
}
}

cata::optional<tripoint> find_best_fire( const std::vector<tripoint> &from, const tripoint &center )
{
cata::optional<tripoint> best_fire;
time_duration best_fire_age = 1_days;
for( const tripoint &pt : from ) {
field_entry *fire = g->m.get_field( pt, fd_fire );
if( fire == nullptr || fire->getFieldDensity() > 1 ||
!g->m.clear_path( center, pt, PICKUP_RANGE, 1, 100 ) ) {
continue;
}
time_duration fire_age = fire->getFieldAge();
// Refuel only the best fueled fire (if it needs it)
if( fire_age < best_fire_age ) {
best_fire = pt;
best_fire_age = fire_age;
}
// If a contained fire exists, ignore any other fires
if( g->m.has_flag_furn( TFLAG_FIRE_CONTAINER, pt ) ) {
return pt;
}
}

return best_fire;
}

void try_refuel_fire( player &p )
{
const tripoint pos = p.pos();
auto adjacent = closest_tripoints_first( PICKUP_RANGE, pos );
adjacent.erase( adjacent.begin() );
cata::optional<tripoint> best_fire = find_best_fire( adjacent, pos );

if( !best_fire || !g->m.accessible_items( *best_fire ) ) {
return;
}

const auto refuel_spot = std::find_if( adjacent.begin(), adjacent.end(),
[pos]( const tripoint & pt ) {
// Hacky - firewood spot is a trap and it's ID-checked
// @todo Something cleaner than ID-checking a trap
return g->m.tr_at( pt ).id == tr_firewood_source && g->m.has_items( pt ) &&
g->m.accessible_items( pt ) && g->m.clear_path( pos, pt, PICKUP_RANGE, 1, 100 );
} );
if( refuel_spot == adjacent.end() ) {
return;
}

// Special case: fire containers allow burning logs, so use them as fuel iif fire is contained
bool contained = g->m.has_flag_furn( TFLAG_FIRE_CONTAINER, *best_fire );
fire_data fd( 1, contained );
time_duration fire_age = g->m.get_field_age( *best_fire, fd_fire );

// Maybe @todo - refuelling in the rain could use more fuel
// First, simulate expected burn per turn, to see if we need more fuel
auto fuel_on_fire = g->m.i_at( *best_fire );
for( size_t i = 0; i < fuel_on_fire.size(); i++ ) {
fuel_on_fire[i].simulate_burn( fd );
// Uncontained fires grow below -50_minutes age
if( !contained && fire_age < -40_minutes && fd.fuel_produced > 1.0f &&
!fuel_on_fire[i].made_of( LIQUID ) ) {
// Too much - we don't want a firestorm!
// Put first item back to refuelling pile
std::list<int> indices_to_remove{ static_cast<int>( i ) };
std::list<int> quantities_to_remove{ 0 };
move_items( *best_fire - pos, false, *refuel_spot - pos, false, indices_to_remove,
quantities_to_remove );
return;
}
}

// Enough to sustain the fire
// @todo It's not enough in the rain
if( fd.fuel_produced >= 1.0f || fire_age < 10_minutes ) {
return;
}

// We need to move fuel from stash to fire
auto potential_fuel = g->m.i_at( *refuel_spot );
for( size_t i = 0; i < potential_fuel.size(); i++ ) {
if( potential_fuel[i].made_of( LIQUID ) ) {
continue;
}

float last_fuel = fd.fuel_produced;
potential_fuel[i].simulate_burn( fd );
if( fd.fuel_produced > last_fuel ) {
std::list<int> indices{ static_cast<int>( i ) };
std::list<int> quantities{ 0 };
// Note: move_items handles messages (they're the generic "you drop x")
move_items( *refuel_spot - p.pos(), false, *best_fire - p.pos(), false, indices, quantities );
return;
}
}
}
1 change: 1 addition & 0 deletions src/activity_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void activity_type::load( JsonObject &jo )
result.stop_phrase_ = _( jo.get_string( "stop_phrase" ).c_str() );
assign( jo, "suspendable", result.suspendable_, true );
assign( jo, "no_resume", result.no_resume_, true );
assign( jo, "refuel_fires", result.refuel_fires, false );

result.based_on_ = io::string_to_enum_look_up( based_on_type_values, jo.get_string( "based_on" ) );

Expand Down
Loading

0 comments on commit 47a80bc

Please sign in to comment.