From 738641e6e74be1f96779352ae895383f454da608 Mon Sep 17 00:00:00 2001 From: Anton Burmistrov Date: Fri, 15 Nov 2024 14:56:55 +0400 Subject: [PATCH] No lit cigs in inventory anymore, only in hands or in mouth (#77834) * On smoking the cig, wear it (= put it in mouth) rather than put it into inventory * If we're taking cig off or unwielding it, extinguish it first Also changed displaying of interactions with cigs as `You take a puff of your cigarette.` rather than `You take a puff of your cigarette (lit) (active).` * Simplified "cig dies out" case by removing explicit item conversions depending on itype_id Instead, add `revert_to` field to cigar, cigarette, and joint. If "cig dies out" event happens, convert cig to its `revert_to`. If no `revert_to` is defined, check for `target` in `transform` use_action and convert to that `target`. This allows processing other cig items which may be added in the future to vanilla or mods. --- data/json/items/generic.json | 3 ++ src/item.cpp | 72 ++++++++++++++++++------------------ src/iuse.cpp | 2 +- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/data/json/items/generic.json b/data/json/items/generic.json index f97707cc3baa2..dd833b5e07fc8 100644 --- a/data/json/items/generic.json +++ b/data/json/items/generic.json @@ -3102,6 +3102,7 @@ "volume": "15 ml", "category": "drugs", "emits": [ "emit_tobacco_trail" ], + "revert_to": "cigar_butt", "use_action": [ { "type": "firestarter", "moves": 200, "moves_slow": 2000 }, { @@ -3149,6 +3150,7 @@ "volume": "4 ml", "category": "drugs", "emits": [ "emit_tobacco_trail" ], + "revert_to": "cig_butt", "use_action": [ { "type": "firestarter", "moves": 200, "moves_slow": 2000 }, { @@ -3196,6 +3198,7 @@ "volume": "4 ml", "category": "drugs", "emits": [ "emit_joint_trail" ], + "revert_to": "joint_roach", "use_action": [ { "type": "firestarter", "moves": 200, "moves_slow": 2000 }, { diff --git a/src/item.cpp b/src/item.cpp index 9b791a9a7e605..01a355da847ec 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -173,13 +173,9 @@ static const itype_id itype_blood( "blood" ); static const itype_id itype_brass_catcher( "brass_catcher" ); static const itype_id itype_bullet_crossbow( "bullet_crossbow" ); static const itype_id itype_cash_card( "cash_card" ); -static const itype_id itype_cig_butt( "cig_butt" ); -static const itype_id itype_cig_lit( "cig_lit" ); -static const itype_id itype_cigar_butt( "cigar_butt" ); -static const itype_id itype_cigar_lit( "cigar_lit" ); static const itype_id itype_disassembly( "disassembly" ); static const itype_id itype_hand_crossbow( "hand_crossbow" ); -static const itype_id itype_joint_roach( "joint_roach" ); +static const itype_id itype_joint_lit( "joint_lit" ); static const itype_id itype_null( "null" ); static const itype_id itype_power_cord( "power_cord" ); static const itype_id itype_rad_badge( "rad_badge" ); @@ -13436,24 +13432,38 @@ bool item::process_litcig( map &here, Character *carrier, const tripoint &pos ) // cig dies out if( item_counter == 0 ) { if( carrier != nullptr ) { - carrier->add_msg_if_player( m_neutral, _( "You finish your %s." ), tname() ); - } - if( typeId() == itype_cig_lit ) { - convert( itype_cig_butt, carrier ); - } else if( typeId() == itype_cigar_lit ) { - convert( itype_cigar_butt, carrier ); - } else { // joint - convert( itype_joint_roach, carrier ); - if( carrier != nullptr ) { - carrier->add_effect( effect_weed_high, 1_minutes ); // one last puff - here.add_field( pos + point( rng( -1, 1 ), rng( -1, 1 ) ), field_type_id( "fd_weedsmoke" ), 2 ); - weed_msg( *carrier ); - } + carrier->add_msg_if_player( m_neutral, _( "You finish your %s." ), type_name() ); + } + if( type->revert_to ) { + convert( *type->revert_to, carrier ); + } else { + type->invoke( carrier, *this, pos, "transform" ); + } + if( typeId() == itype_joint_lit && carrier != nullptr ) { + carrier->add_effect( effect_weed_high, 1_minutes ); // one last puff + here.add_field( pos + point( rng( -1, 1 ), rng( -1, 1 ) ), field_type_id( "fd_weedsmoke" ), 2 ); + weed_msg( *carrier ); } active = false; return false; } + if( carrier != nullptr ) { + // No lit cigs in inventory, only in hands or in mouth + // So if we're taking cig off or unwielding it, extinguish it first + if( !carrier->is_worn( *this ) && !carrier->is_wielding( *this ) ) { + if( type->revert_to ) { + carrier->add_msg_if_player( m_neutral, _( "You extinguish your %s and put it away." ), + type_name() ); + convert( *type->revert_to, carrier ); + } else { + type->invoke( carrier, *this, pos, "transform" ); + } + active = false; + return false; + } + } + if( !one_in( 10 ) ) { return false; } @@ -13470,7 +13480,7 @@ bool item::process_litcig( map &here, Character *carrier, const tripoint &pos ) } else if( carrier->has_trait( trait_LIGHTWEIGHT ) ) { duration = 30_seconds; } - carrier->add_msg_if_player( m_neutral, _( "You take a puff of your %s." ), tname() ); + carrier->add_msg_if_player( m_neutral, _( "You take a puff of your %s." ), type_name() ); if( has_flag( flag_TOBACCO ) ) { carrier->add_effect( effect_cig, duration ); } else { @@ -13481,14 +13491,14 @@ bool item::process_litcig( map &here, Character *carrier, const tripoint &pos ) if( ( carrier->has_effect( effect_shakes ) && one_in( 10 ) ) || ( carrier->has_trait( trait_JITTERY ) && one_in( 200 ) ) ) { carrier->add_msg_if_player( m_bad, _( "Your shaking hand causes you to drop your %s." ), - tname() ); + type_name() ); here.add_item_or_charges( pos + point( rng( -1, 1 ), rng( -1, 1 ) ), *this ); return true; // removes the item that has just been added to the map } if( carrier->has_effect( effect_sleep ) ) { carrier->add_msg_if_player( m_bad, _( "You fall asleep and drop your %s." ), - tname() ); + type_name() ); here.add_item_or_charges( pos + point( rng( -1, 1 ), rng( -1, 1 ) ), *this ); return true; // removes the item that has just been added to the map } @@ -13569,22 +13579,10 @@ bool item::process_extinguish( map &here, Character *carrier, const tripoint &po } } - // cig dies out - if( has_flag( flag_LITCIG ) ) { - if( typeId() == itype_cig_lit ) { - convert( itype_cig_butt, carrier ); - } else if( typeId() == itype_cigar_lit ) { - convert( itype_cigar_butt, carrier ); - } else { // joint - convert( itype_joint_roach, carrier ); - } - } else { // transform (lit) items - if( type->revert_to ) { - convert( *type->revert_to, carrier ); - } else { - type->invoke( carrier, *this, pos, "transform" ); - } - + if( type->revert_to ) { + convert( *type->revert_to, carrier ); + } else { + type->invoke( carrier, *this, pos, "transform" ); } active = false; // Item remains diff --git a/src/iuse.cpp b/src/iuse.cpp index ac5c057bcd26a..d466514d4179c 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -595,7 +595,7 @@ std::optional iuse::smoking( Character *p, item *it, const tripoint & ) // If we're here, we better have a cig to light. p->use_charges_if_avail( itype_fire, 1 ); cig.active = true; - p->inv->add_item( cig, false, true ); + p->wear_item( cig, false ); p->add_msg_if_player( m_neutral, _( "You light a %s." ), it->tname() ); // Parting messages