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

[RDY] Initial craft entity implementation #28937

Merged
merged 7 commits into from
Apr 9, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions data/json/item_actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1028,5 +1028,10 @@
"type": "item_action",
"id": "PANACEA",
"name": "Take"
},
{
"type": "item_action",
"id": "CRAFT",
"name": "Work on craft"
}
]
14 changes: 14 additions & 0 deletions data/json/items/generic.json
Original file line number Diff line number Diff line change
Expand Up @@ -3007,5 +3007,19 @@
"weight": 5,
"volume": 1,
"bashing": 1
},
{
"type": "GENERIC",
"id": "craft",
"symbol": "%",
"color": "white",
"name": "in progress craft",
"description": "This is an in progress craft.",
"price": 0,
"weight": 1,
"volume": 1,
"max_charges": 20,
"use_action": "CRAFT",
"flags": [ "NO_SALVAGE", "TRADER_AVOID" ]
}
]
7 changes: 0 additions & 7 deletions data/json/player_activities.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@
"based_on": "neither",
"refuel_fires": true
},
{
"id": "ACT_LONGCRAFT",
"type": "activity_type",
"stop_phrase": "Stop crafting?",
"based_on": "neither",
"refuel_fires": true
},
{
"id": "ACT_DISASSEMBLE",
"type": "activity_type",
Expand Down
55 changes: 35 additions & 20 deletions src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "mtype.h"
#include "output.h"
#include "player.h"
#include "recipe.h"
#include "requirements.h"
#include "rng.h"
#include "skill.h"
Expand Down Expand Up @@ -57,7 +58,6 @@ const std::map< activity_id, std::function<void( player_activity *, player * )>
activity_handlers::do_turn_functions = {
{ activity_id( "ACT_BURROW" ), burrow_do_turn },
{ activity_id( "ACT_CRAFT" ), craft_do_turn },
{ activity_id( "ACT_LONGCRAFT" ), craft_do_turn },
{ activity_id( "ACT_FILL_LIQUID" ), fill_liquid_do_turn },
{ activity_id( "ACT_PICKAXE" ), pickaxe_do_turn },
{ activity_id( "ACT_DROP" ), drop_do_turn },
Expand Down Expand Up @@ -136,8 +136,6 @@ activity_handlers::finish_functions = {
{ activity_id( "ACT_WAIT_NPC" ), wait_npc_finish },
{ activity_id( "ACT_SOCIALIZE" ), socialize_finish },
{ activity_id( "ACT_TRY_SLEEP" ), try_sleep_finish },
{ activity_id( "ACT_CRAFT" ), craft_finish },
{ activity_id( "ACT_LONGCRAFT" ), longcraft_finish },
{ activity_id( "ACT_DISASSEMBLE" ), disassemble_finish },
{ activity_id( "ACT_BUILD" ), build_finish },
{ activity_id( "ACT_VIBE" ), vibe_finish },
Expand Down Expand Up @@ -2632,8 +2630,30 @@ void activity_handlers::try_sleep_finish( player_activity *act, player *p )

void activity_handlers::craft_do_turn( player_activity *act, player *p )
{
const recipe &rec = recipe_id( act->name ).obj();
item *craft = act->targets.front().get_item();

if( !craft->is_craft() ) {
debugmsg( "ACT_CRAFT target '%s' is not a craft. Aborting ACT_CRAFT.", craft->tname() );
p->cancel_activity();
return;
}
if( !p->has_item( *craft ) ) {
p->add_msg_player_or_npc(
string_format(
_( "You no longer have the %1$s in your possession. You stop crafting. Reactivate the %1$s to continue crafting." ),
craft->tname() ),
string_format(
_( "<npcname> no longer has the %s in their possession. <npcname> stops crafting." ),
craft->tname() )
);
p->cancel_activity();
return;
}

const recipe &rec = craft->get_making();
const float crafting_speed = p->crafting_speed_multiplier( rec, true );
const bool is_long = act->values[0];

if( crafting_speed <= 0.0f ) {
if( p->lighting_craft_speed_multiplier( rec ) <= 0.0f ) {
p->add_msg_if_player( m_bad, _( "You can no longer see well enough to keep crafting." ) );
Expand All @@ -2643,28 +2663,23 @@ void activity_handlers::craft_do_turn( player_activity *act, player *p )
p->cancel_activity();
return;
}
act->moves_left -= crafting_speed * p->get_moves();
p->set_moves( 0 );
if( calendar::once_every( 1_hours ) && crafting_speed < 0.75f ) {
// TODO: Describe the causes of slowdown
p->add_msg_if_player( m_bad, _( "You can't focus and are working slowly." ) );
}
}

void activity_handlers::craft_finish( player_activity *act, player *p )
{
p->complete_craft();
act->set_to_null();
}
craft->item_counter += crafting_speed * p->get_moves();
p->set_moves( 0 );

void activity_handlers::longcraft_finish( player_activity *act, player *p )
{
const int batch_size = act->values.front();
p->complete_craft();
act->set_to_null();
// Workaround for a bug where longcraft can be unset in complete_craft().
if( p->making_would_work( p->lastrecipe, batch_size ) ) {
p->last_craft->execute();
if( craft->item_counter >= rec.time ) {
p->cancel_activity();
item craft_copy = p->i_rem( craft );
p->complete_craft( craft_copy );
if( is_long ) {
if( p->making_would_work( p->lastrecipe, craft_copy.charges ) ) {
p->last_craft->execute();
}
}
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/activity_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ void wait_weather_finish( player_activity *act, player *p );
void wait_npc_finish( player_activity *act, player *p );
void socialize_finish( player_activity *act, player *p );
void try_sleep_finish( player_activity *act, player *p );
void craft_finish( player_activity *act, player *p );
void longcraft_finish( player_activity *act, player *p );
void disassemble_finish( player_activity *act, player *p );
void build_finish( player_activity *act, player *p );
void vibe_finish( player_activity *act, player *p );
Expand Down
2 changes: 1 addition & 1 deletion src/clzones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ zone_type_id zone_manager::get_near_zone_type_for_item( const item &it,
const auto &it_food = it.is_food_container() ? it.contents.front() : it;

if( it_food.is_food() ) { // skip food without comestible, like MREs
if( it_food.type->comestible->comesttype == "DRINK" ) {
if( it_food.get_comestible()->comesttype == "DRINK" ) {
if( !preserves && it_food.goes_bad() && has_near( zone_type_id( "LOOT_PDRINK" ), where ) ) {
return zone_type_id( "LOOT_PDRINK" );
} else if( has_near( zone_type_id( "LOOT_DRINK" ), where ) ) {
Expand Down
38 changes: 21 additions & 17 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int player::kcal_for( const item &comest ) const
}
kcal /= comest.recipe_charges;
} else {
kcal = comest.type->comestible->get_calories();
kcal = comest.get_comestible()->get_calories();
}

if( has_trait( trait_GIZZARD ) ) {
Expand Down Expand Up @@ -165,7 +165,7 @@ std::pair<int, int> player::fun_for( const item &comest ) const
}

// As float to avoid rounding too many times
float fun = comest.type->comestible->fun;
float fun = comest.get_comestible()->fun;
if( comest.has_flag( flag_MUSHY ) && fun > -5.0f ) {
fun = -5.0f; // defrosted MUSHY food is practicaly tastless or tastes off
}
Expand Down Expand Up @@ -218,8 +218,8 @@ std::pair<int, int> player::fun_for( const item &comest ) const
}

if( has_active_bionic( bio_taste_blocker ) &&
power_level > abs( comest.type->comestible->fun ) &&
comest.type->comestible->fun < 0 ) {
power_level > abs( comest.get_comestible()->fun ) &&
comest.get_comestible()->fun < 0 ) {
fun = 0;
}

Expand Down Expand Up @@ -259,7 +259,7 @@ std::map<vitamin_id, int> player::vitamins_from( const item &it ) const
{
std::map<vitamin_id, int> res;

if( !it.type->comestible ) {
if( !it.get_comestible() ) {
return res;
}

Expand All @@ -277,7 +277,7 @@ std::map<vitamin_id, int> player::vitamins_from( const item &it ) const
}
} else {
// if we're here, whatever is returned is going to be based on the item's defined stats
res = it.type->comestible->vitamins;
res = it.get_comestible()->vitamins;
std::list<trait_id> traits = mut_vitamin_absorb_modify( *this );
// traits modify the absorption of vitamins here
if( !traits.empty() ) {
Expand Down Expand Up @@ -420,11 +420,15 @@ morale_type player::allergy_type( const item &food ) const
ret_val<edible_rating> player::can_eat( const item &food ) const
{

const auto &comest = food.type->comestible;
const auto &comest = food.get_comestible();
if( !comest ) {
return ret_val<edible_rating>::make_failure( _( "That doesn't look edible." ) );
}

if( food.is_craft() ) {
return ret_val<edible_rating>::make_failure( _( "That doesn't look edible in its current form." ) );
}

if( food.item_tags.count( "DIRTY" ) ) {
return ret_val<edible_rating>::make_failure(
_( "This is full of dirt after being on the ground." ) );
Expand Down Expand Up @@ -511,7 +515,7 @@ ret_val<edible_rating> player::will_eat( const item &food, bool interactive ) co
};

const bool saprophage = has_trait( trait_id( "SAPROPHAGE" ) );
const auto &comest = food.type->comestible;
const auto &comest = food.get_comestible();

if( food.rotten() ) {
const bool saprovore = has_trait( trait_id( "SAPROVORE" ) );
Expand Down Expand Up @@ -612,13 +616,13 @@ bool player::eat( item &food, bool force )

const bool hibernate = has_active_mutation( trait_id( "HIBERNATE" ) );
const int nutr = nutrition_for( food );
const int quench = food.type->comestible->quench;
const int quench = food.get_comestible()->quench;
const bool spoiled = food.rotten();

// The item is solid food
const bool chew = food.type->comestible->comesttype == "FOOD" || food.has_flag( "USE_EAT_VERB" );
const bool chew = food.get_comestible()->comesttype == "FOOD" || food.has_flag( "USE_EAT_VERB" );
// This item is a drink and not a solid food (and not a thick soup)
const bool drinkable = !chew && food.type->comestible->comesttype == "DRINK";
const bool drinkable = !chew && food.get_comestible()->comesttype == "DRINK";
// If neither of the above is true then it's a drug and shouldn't get mealtime penalty/bonus

if( hibernate &&
Expand Down Expand Up @@ -750,9 +754,9 @@ bool player::eat( item &food, bool force )
}
}

if( item::find_type( food.type->comestible->tool )->tool ) {
if( item::find_type( food.get_comestible()->tool )->tool ) {
// Tools like lighters get used
use_charges( food.type->comestible->tool, 1 );
use_charges( food.get_comestible()->tool, 1 );
}

if( has_bionic( bio_ethanol ) && food.type->can_use( "ALCOHOL" ) ) {
Expand All @@ -766,7 +770,7 @@ bool player::eat( item &food, bool force )
}

if( has_active_bionic( bio_taste_blocker ) ) {
charge_power( -abs( food.type->comestible->fun ) );
charge_power( -abs( food.get_comestible()->fun ) );
}

if( food.has_flag( "CANNIBALISM" ) ) {
Expand Down Expand Up @@ -874,8 +878,8 @@ bool player::eat( item &food, bool force )

// chance to become parasitised
if( !( has_bionic( bio_digestion ) || has_trait( trait_id( "PARAIMMUNE" ) ) ) ) {
if( food.type->comestible->parasites > 0 && !food.has_flag( "NO_PARASITES" ) &&
one_in( food.type->comestible->parasites ) ) {
if( food.get_comestible()->parasites > 0 && !food.has_flag( "NO_PARASITES" ) &&
one_in( food.get_comestible()->parasites ) ) {
switch( rng( 0, 3 ) ) {
case 0:
if( !has_trait( trait_id( "EATHEALTH" ) ) ) {
Expand Down Expand Up @@ -940,7 +944,7 @@ void player::consume_effects( const item &food )
debugmsg( "called player::consume_effects with non-comestible" );
return;
}
const auto &comest = *food.type->comestible;
const auto &comest = *food.get_comestible();

const int capacity = stomach_capacity();
if( has_trait( trait_id( "THRESH_PLANT" ) ) && food.type->can_use( "PLANTBLECH" ) ) {
Expand Down
10 changes: 1 addition & 9 deletions src/craft_command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,7 @@ void craft_command::execute()
}
}

auto type = activity_id( is_long ? "ACT_LONGCRAFT" : "ACT_CRAFT" );
auto activity = player_activity( type, crafter->base_time_to_craft( *rec, batch_size ), -1, INT_MIN,
rec->ident().str() );
activity.values.push_back( batch_size );
activity.values.push_back( calendar::turn );
activity.coords.push_back( crafter->pos() );

crafter->assign_activity( activity );

crafter->start_craft( *rec, batch_size, is_long );
crafter->last_batch = batch_size;
crafter->lastrecipe = rec->ident();

Expand Down
5 changes: 4 additions & 1 deletion src/craft_command.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ class craft_command
private:
const recipe *rec = nullptr;
int batch_size = 0;
/** Indicates the activity_type for this crafting job, Either ACT_CRAFT or ACT_LONGCRAFT. */
/**
* Indicates whether the player has initiated a one off craft or wishes to craft as
* long as possible.
*/
bool is_long = false;
// This is mainly here for maintainability reasons.
player *crafter;
Expand Down
Loading