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

feat(content,port): corpses decay into items, use existing harvest entries to actually implement feature, fix off-map decay behavior #4751

Merged
Show file tree
Hide file tree
Changes from 6 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
64 changes: 33 additions & 31 deletions data/json/harvest.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
"entries": [
{ "drop": "mutant_human_flesh", "type": "flesh", "mass_ratio": 0.34 },
{ "drop": "hstomach", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
{ "drop": "bone", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "raw_hfur", "type": "skin", "mass_ratio": 0.02 },
{ "drop": "mutant_human_fat", "type": "flesh", "mass_ratio": 0.07 }
Expand All @@ -175,7 +175,7 @@
{ "drop": "cyborg_harvest_uncommon", "type": "bionic_group", "faults": [ "fault_bionic_nonsterile" ] },
{ "drop": "mutant_human_flesh", "type": "flesh", "mass_ratio": 0.34 },
{ "drop": "hstomach", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
{ "drop": "bone", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "raw_hfur", "type": "skin", "mass_ratio": 0.02 },
{ "drop": "mutant_human_fat", "type": "flesh", "mass_ratio": 0.07 }
Expand All @@ -188,7 +188,7 @@
"entries": [
{ "drop": "mutant_human_flesh", "type": "flesh", "mass_ratio": 0.34 },
{ "drop": "hstomach_large", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
{ "drop": "bone", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "raw_hfur", "type": "skin", "mass_ratio": 0.02 },
{ "drop": "mutant_human_fat", "type": "flesh", "mass_ratio": 0.07 }
Expand All @@ -202,7 +202,7 @@
{ "drop": "cyborg_harvest_uncommon", "type": "bionic_group", "faults": [ "fault_bionic_nonsterile" ] },
{ "drop": "mutant_human_flesh", "type": "flesh", "mass_ratio": 0.34 },
{ "drop": "hstomach_large", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
{ "drop": "bone", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "raw_hfur", "type": "skin", "mass_ratio": 0.02 },
{ "drop": "mutant_human_fat", "type": "flesh", "mass_ratio": 0.07 }
Expand Down Expand Up @@ -539,6 +539,7 @@
"message": "<arachnid_harvest>",
"entries": [
{ "drop": "meat_tainted", "type": "flesh", "mass_ratio": 0.33 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.0035 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.015 },
{ "drop": "chitin_piece", "type": "skin", "mass_ratio": 0.15 }
Expand All @@ -550,21 +551,22 @@
"message": "<arachnid_flying_harvest>",
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.01 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.02 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.0035 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.015 },
{ "drop": "chitin_piece", "type": "skin", "mass_ratio": 0.015 }
{ "drop": "chitin_piece", "type": "skin", "mass_ratio": 0.15 }
]
},
{
"id": "acidant_queen",
"type": "harvest",
"message": "<acidant_harvest>",
"entries": [
{ "drop": "mutant_meat", "base_num": [ 40, 55 ], "scale_num": [ 0.5, 0.7 ], "max": 80, "type": "flesh" },
{ "drop": "acidchitin_piece", "base_num": [ 2, 6 ], "scale_num": [ 0.45, 0.9 ], "max": 15, "type": "skin" },
{ "drop": "mutant_fat", "base_num": [ 5, 8 ], "scale_num": [ 0.6, 0.8 ], "max": 18, "type": "flesh" }
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.33 },
{ "drop": "mutant_fat", "type": "flesh", "mass_ratio": 0.04 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "acidchitin_piece", "type": "skin", "mass_ratio": 0.15 }
]
},
{
Expand All @@ -574,7 +576,7 @@
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.33 },
{ "drop": "mutant_fat", "type": "flesh", "mass_ratio": 0.04 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.01 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.0035 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.015 },
{ "drop": "chitin_piece", "type": "skin", "mass_ratio": 0.15 }
Expand All @@ -587,7 +589,7 @@
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.33 },
{ "drop": "mutant_fat", "type": "flesh", "mass_ratio": 0.04 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.01 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "acidchitin_piece", "type": "skin", "mass_ratio": 0.15 }
]
},
Expand All @@ -597,8 +599,8 @@
"message": "What appeared to be insect hairs on the chitin of this creature look more like tiny feathers as you pare them back. Inside is a bundle of bubble-like tissue sacs that appear to be floating, which doesn't fit with what you know about real bees.",
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.23 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.01 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.02 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.0035 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.015 },
{ "drop": "bee_sting", "base_num": [ 0, 1 ], "type": "bone" },
Expand All @@ -611,8 +613,8 @@
"message": "<wasp_harvest>",
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.3 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.003 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.02 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.01 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.03 },
{ "drop": "wasp_sting", "base_num": [ 0, 1 ], "type": "bone" },
Expand All @@ -625,8 +627,8 @@
"message": "<wasp_queen_harvest>",
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.003 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.02 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.01 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.03 },
{ "drop": "wasp_sting", "base_num": [ 0, 1 ], "type": "bone" },
Expand All @@ -641,10 +643,11 @@
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.15 },
{ "drop": "mutant_fat", "type": "flesh", "mass_ratio": 0.04 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.005 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.02 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.0045 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.025 },
{ "drop": "chitin_piece", "type": "skin", "mass_ratio": 0.015 },
{ "drop": "chitin_piece", "type": "skin", "mass_ratio": 0.15 },
{ "drop": "egg_dragonfly", "type": "offal", "base_num": [ 5, 35 ], "scale_num": [ 0.3, 0.5 ] }
]
},
Expand All @@ -655,7 +658,7 @@
"//": "copied from arachnid_flying+egg",
"entries": [
{ "drop": "mutant_meat", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.01 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.00035 },
{ "drop": "mutant_bug_hydrogen_sacs", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "mutant_bug_lungs", "type": "flesh", "mass_ratio": 0.0035 },
{ "drop": "mutant_bug_organs", "type": "offal", "mass_ratio": 0.015 },
Expand Down Expand Up @@ -793,7 +796,7 @@
{ "drop": "human_flesh", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "hstomach", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
{ "drop": "human_fat", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.12 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.001 },
{ "drop": "raw_hleather", "type": "skin", "mass_ratio": 0.03 }
]
Expand All @@ -805,7 +808,7 @@
{ "drop": "mutant_human_flesh", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "hstomach", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
{ "drop": "mutant_human_fat", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.12 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.001 },
{ "drop": "raw_hleather", "type": "skin", "mass_ratio": 0.03 }
]
Expand All @@ -818,7 +821,7 @@
{ "drop": "meat", "type": "flesh", "mass_ratio": 0.4 },
{ "drop": "hstomach", "scale_num": [ 1, 1 ], "max": 1, "type": "offal" },
{ "drop": "human_fat", "type": "flesh", "mass_ratio": 0.1 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.12 },
{ "drop": "bone_human", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "sinew", "type": "bone", "mass_ratio": 0.001 },
{ "drop": "raw_leather", "type": "skin", "mass_ratio": 0.03 },
{ "drop": "raw_fur", "type": "skin", "mass_ratio": 0.001 }
Expand All @@ -838,10 +841,9 @@
"type": "harvest",
"message": "You laboriously hack and dig through the remains of the fungal mass.",
"entries": [
{ "drop": "veggy", "base_num": [ 6, 10 ], "scale_num": [ 0.6, 0.8 ], "max": 20, "type": "flesh" },
{ "drop": "veggy_tainted", "base_num": [ 16, 25 ], "scale_num": [ 0.6, 0.8 ], "max": 50, "type": "flesh" },
{ "drop": "plant_sac", "base_num": [ 3, 6 ], "scale_num": [ 0.7, 0.9 ], "max": 10, "type": "offal" },
{ "drop": "stick_fiber", "base_num": [ 4, 8 ], "scale_num": [ 0.5, 0.7 ], "max": 10, "type": "bone" }
{ "drop": "veggy_tainted", "type": "flesh", "mass_ratio": 0.5 },
{ "drop": "plant_sac", "type": "offal", "mass_ratio": 0.2 },
{ "drop": "stick_fiber", "type": "bone", "mass_ratio": 0.1 }
]
},
{
Expand Down Expand Up @@ -1072,7 +1074,7 @@
"id": "triffid_small",
"type": "harvest",
"entries": [
{ "drop": "stick_fiber", "type": "bone", "mass_ratio": 0.5 },
{ "drop": "stick_fiber", "type": "bone", "mass_ratio": 0.1 },
{ "drop": "veggy", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "veggy", "type": "offal", "mass_ratio": 0.05 }
]
Expand All @@ -1081,7 +1083,7 @@
"id": "triffid_large",
"type": "harvest",
"entries": [
{ "drop": "stick_fiber", "type": "bone", "mass_ratio": 0.4 },
{ "drop": "stick_fiber", "type": "bone", "mass_ratio": 0.1 },
{ "drop": "veggy", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "veggy", "type": "offal", "mass_ratio": 0.05 },
{ "drop": "stick", "type": "bone", "mass_ratio": 0.05 }
Expand All @@ -1092,7 +1094,7 @@
"type": "harvest",
"entries": [
{ "drop": "log", "type": "bone", "mass_ratio": 0.35 },
{ "drop": "stick_fiber", "type": "bone", "mass_ratio": 0.15 },
{ "drop": "stick_fiber", "type": "bone", "mass_ratio": 0.1 },
{ "drop": "veggy", "type": "flesh", "mass_ratio": 0.2 },
{ "drop": "veggy", "type": "offal", "mass_ratio": 0.05 }
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,14 @@ see ITEM_SPAWN.md. The default subtype is "distribution".
How the monster behaves on death. See JSON_FLAGS.md for a list of possible functions. One can add or
remove entries in mods via "add:death_function" and "remove:death_function".

## "harvest"

(string, optional)

If this monster's death function leaves a corpse behind, this defines what items will be produced
when butchering or dissecting its corpse. If none is specified, it will default to `human`. Harvest
entries, their yields, and mass ratios, are defined in harvest.json

## "emit_field"

(array of objects of emit_id and time_duration, optional) "emit_fields": [ { "emit_id":
Expand Down
8 changes: 8 additions & 0 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9911,6 +9911,9 @@ detached_ptr<item> item::process_internal( detached_ptr<item> &&self, player *ca
if( comestible && !self ) {
here.rotten_item_spawn( obj, pos );
}
if( obj.is_corpse() && !self && !obj.corpse->zombify_into ) {
here.handle_decayed_corpse( obj, pos );
}
}
return std::move( self );
}
Expand Down Expand Up @@ -10113,6 +10116,11 @@ std::string item::type_name( unsigned int quantity ) const
return ret_name;
}

const mtype *item::get_corpse_mon() const
{
return corpse;
}

std::string item::get_corpse_name()
{
if( corpse_name.empty() ) {
Expand Down
1 change: 1 addition & 0 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -2322,6 +2322,7 @@ class item : public location_visitable<item>, public game_object<item>
void add_component( detached_ptr<item> &&comp );
const location_vector<item> &get_components() const;
location_vector<item> &get_components();
const mtype *get_corpse_mon() const;
private:
location_vector<item> components;
const itype *curammo = nullptr;
Expand Down
44 changes: 44 additions & 0 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7273,6 +7273,50 @@ void map::remove_rotten_items( Container &items, const tripoint &pnt, temperatur
} );
}

void map::handle_decayed_corpse( const item &it, const tripoint &pnt )
{
if( !it.is_corpse() ) {
debugmsg( "Tried to decay a non-corpse item %s. Aborted", it.tname() );
return;
}
const mtype *dead_monster = it.get_corpse_mon();
if( !dead_monster ) {
debugmsg( "Corpse at tripoint %s has no associated monster?!", pnt.to_string() );
return;
}

int decayed_weight_grams = to_gram( dead_monster->weight ); // corpse might have stuff in it!
decayed_weight_grams *= rng_float( 0.5, 0.9 );

bool anything_left = false;
for( const harvest_entry &entry : dead_monster->harvest.obj() ) {
if( entry.type != "bionic" && entry.type != "bionic_group" ) {
detached_ptr<item> harvest = item::spawn( entry.drop, it.birthday() );
const float random_decay_modifier = rng_float( 0.0f, static_cast<float>( MAX_SKILL ) );
const float min_num = entry.scale_num.first * random_decay_modifier + entry.base_num.first;
const float max_num = entry.scale_num.second * random_decay_modifier + entry.base_num.second;
int roll = 0;
if( entry.mass_ratio != 0.00f ) {
roll = static_cast<int>( std::round( entry.mass_ratio * decayed_weight_grams ) );
roll = std::ceil( static_cast<double>( roll ) / to_gram( harvest->weight() ) );
} else {
roll = std::min<int>( entry.max, std::round( rng_float( min_num, max_num ) ) );
}
anything_left = roll > 0;
for( int i = 0; i < roll; i++ ) {
add_item_or_charges( pnt, item::spawn( *harvest ) );
}
}
}
if( g->u.sees( pnt ) ) {
if( anything_left ) {
add_msg( m_info, _( "The %1$s decays away, leaving something behind." ), it.tname() );
} else {
add_msg( m_info, _( "The %1$s decays away to nothing." ), it.tname() );
}
}
}

void map::rotten_item_spawn( const item &item, const tripoint &pnt )
{
if( g->critter_at( pnt ) != nullptr ) {
Expand Down
7 changes: 7 additions & 0 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,13 @@ class map
*/
void spawn_monsters( bool ignore_sight );

/**
* Checks to see if the corpse that is rotting away generates items when it does.
* @param it item that is spawning creatures
* @param pnt The point on this map where the item is and where bones/etc will be
*/
void handle_decayed_corpse( const item &it, const tripoint &pnt );

/**
* Checks to see if the item that is rotting away generates a creature when it does.
* @param item item that is spawning creatures
Expand Down
Loading