Skip to content

Commit

Permalink
fix: Molotov Fix/Rework, make turn_per_charge less inconsistent. (#…
Browse files Browse the repository at this point in the history
…5480)

* Molotov Fix/Rework

Fixes molotovs burning out too quickly due to my changes to charge handling.

Makes it so that active items will now keep track of the turns they've been active if they use turns_per_charge.

Molotovs now consume their own charges and burn out if left alone too long, they are reloaded with rags, one charge of which lasts about 5 turns.

* Update item.cpp

* Update overwrite_scrap.json

* Lil fix

* Fix recipe

Setting it to use rags as ammo makes it not spawn with default charges.

* Update explosive.json

* Redoes the entire logic for molotov action.

Base molotov has no charges, instead, it transforms into a lit molotov that has charges, that over time depletes it's charges and turns back.

Disallow extinguishing it manually, as this produces molotovs with no max charge but a charge. They don't stack in the UI with other molotovs This issue will still occur if it gets extinguished by water.

* Update explosive.json

* Remove rag ammotype

* Update generic.json

---------

Co-authored-by: Chaosvolt <chaosvolt@users.noreply.github.com>
  • Loading branch information
KheirFerrum and chaosvolt authored Oct 2, 2024
1 parent c20793f commit 9081fe7
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 35 deletions.
2 changes: 1 addition & 1 deletion data/json/item_actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@
{
"type": "item_action",
"id": "MOLOTOV_LIT",
"name": { "str": "Light up" }
"name": { "str": "Detonate" }
},
{
"type": "item_action",
Expand Down
2 changes: 0 additions & 2 deletions data/json/items/generic/toys_and_sports.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"color": "pink",
"ammo": "battery",
"charges_per_use": 1,
"turns_per_charge": 20,
"use_action": "DOLLCHAT",
"magazines": [
[
Expand Down Expand Up @@ -47,7 +46,6 @@
"color": "pink",
"ammo": "battery",
"charges_per_use": 1,
"turns_per_charge": 20,
"use_action": "DOLLCHAT",
"magazines": [
[
Expand Down
8 changes: 4 additions & 4 deletions data/json/items/tool/explosives.json
Original file line number Diff line number Diff line change
Expand Up @@ -988,8 +988,6 @@
"material": [ "glass", "cotton" ],
"symbol": "*",
"color": "light_gray",
"initial_charges": 1,
"max_charges": 1,
"use_action": {
"target": "molotov_lit",
"msg": "You light the Molotov cocktail!",
Expand All @@ -1007,7 +1005,7 @@
"type": "TOOL",
"category": "weapons",
"name": { "str": "Molotov cocktail" },
"description": "A bottle of flammable liquid with a flaming rag stoppered in its neck. Throwing it will shatter the bottle on impact and ignite a fireball. Dropping it will set you on fire, so don't do that unless you want to burn to death.",
"description": "A bottle of flammable liquid with a flaming rag stoppered in its neck. Throwing it will shatter the bottle on impact and ignite a fireball. You can also activate it to smash it on yourself, but why would you want to do that?",
"weight": "742 g",
"volume": "750 ml",
"price": "0 cent",
Expand All @@ -1019,8 +1017,10 @@
"color": "light_gray",
"initial_charges": 1,
"max_charges": 1,
"turns_per_charge": 1,
"turns_per_charge": 5,
"use_action": "MOLOTOV_LIT",
"revert_to": "molotov",
"revert_msg": "Your lit molotov goes out.",
"flags": [ "LIGHT_20", "TRADER_AVOID", "NPC_THROW_NOW", "NO_REPAIR", "WATER_EXTINGUISH", "ACT_ON_RANGED_HIT" ]
},
{
Expand Down
40 changes: 24 additions & 16 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,9 @@ void item::deactivate()
}

active = false;
if( is_tool() ) {
type->tool->turns_active = 0;
}

// Is not placed in the world, so either a template of some kind or a temporary item.
if( !has_position() ) {
Expand Down Expand Up @@ -9906,32 +9909,37 @@ detached_ptr<item> item::process_tool( detached_ptr<item> &&self, player *carrie
int energy = 0;
const bool uses_UPS = self->has_flag( flag_USE_UPS );
bool revert_destroy = false;
if( self->type->tool->turns_per_charge > 0 &&
to_turn<int>( calendar::turn ) % self->type->tool->turns_per_charge == 0 ) {
energy = std::max( self->ammo_required(), 1 );

if( self->type->tool->turns_per_charge > 0 ) {
if( self->type->tool->turns_active >= self->type->tool->turns_per_charge ) {
energy = std::max( self->ammo_required(), 1 );
self->type->tool->turns_active = 0;
}
self->type->tool->turns_active += 1;
} else if( self->type->tool->power_draw > 0 ) {
// power_draw in mW / 1000000 to give kJ (battery unit) per second
energy = self->type->tool->power_draw / 1000000;
// energy_bat remainder results in chance at additional charge/discharge
energy += x_in_y( self->type->tool->power_draw % 1000000, 1000000 ) ? 1 : 0;
}

// If energy is 0 we just skip over this and go to tick processing.
if( energy ) {
energy -= self->ammo_consume( energy, pos );
// If ammo_required is 0 we just skip over this and go to tick processing.
if( energy || self->ammo_required() > 0 ) {
// No need to look for charges if energy is 0
if( energy ) {
energy -= self->ammo_consume( energy, pos );

// for power armor pieces, try to use power armor interface first.
if( carrier && self->is_power_armor() && character_funcs::can_interface_armor( *carrier ) ) {
if( carrier->use_charges_if_avail( itype_bio_armor, energy ) ) {
energy = 0;
// for power armor pieces, try to use power armor interface first.
if( carrier && self->is_power_armor() && character_funcs::can_interface_armor( *carrier ) ) {
if( carrier->use_charges_if_avail( itype_bio_armor, energy ) ) {
energy = 0;
}
}
}

// for items in player possession if insufficient charges within tool try UPS
if( carrier && uses_UPS ) {
if( carrier->use_charges_if_avail( itype_UPS, energy ) ) {
energy = 0;
// for items in player possession if insufficient charges within tool try UPS
if( carrier && uses_UPS ) {
if( carrier->use_charges_if_avail( itype_UPS, energy ) ) {
energy = 0;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ struct islot_tool {
int charge_factor = 1;
int charges_per_use = 0;
int turns_per_charge = 0;
int turns_active = 0;
int power_draw = 0;

std::vector<int> rand_charges;
Expand Down
23 changes: 11 additions & 12 deletions src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ static const itype_id itype_joint( "joint" );
static const itype_id itype_log( "log" );
static const itype_id itype_mask_h20survivor_on( "mask_h20survivor_on" );
static const itype_id itype_mininuke_act( "mininuke_act" );
static const itype_id itype_molotov( "molotov" );
static const itype_id itype_mobile_memory_card( "mobile_memory_card" );
static const itype_id itype_mobile_memory_card_used( "mobile_memory_card_used" );
static const itype_id itype_mp3( "mp3" );
Expand Down Expand Up @@ -3751,6 +3750,12 @@ int iuse::molotov_lit( player *p, item *it, bool t, const tripoint &pos )
if( pos.x == -999 || pos.y == -999 ) {
return 0;
} else if( !t ) {
if( p->has_item( *it ) ) {
if( !query_yn( "Really smash it on yourself?" ) ) {
p->add_msg_if_player( m_info, _( "You should probably throw it instead." ) );
return 0;
}
}
for( const tripoint &pt : g->m.points_in_radius( pos, 1, 0 ) ) {
const int intensity = 1 + one_in( 3 ) + one_in( 5 );
g->m.add_field( pt, fd_fire, intensity );
Expand All @@ -3760,18 +3765,12 @@ int iuse::molotov_lit( player *p, item *it, bool t, const tripoint &pos )
p->rem_morale( MORALE_PYROMANIA_NOFIRE );
p->add_msg_if_player( m_good, _( "Fire… Good…" ) );
}
// If you exploded it on yourself through activation.
if( it->has_position() ) {
it->detach();
}
return 1;
} else if( it->charges > 0 ) {
p->add_msg_if_player( m_info, _( "You've already lit the %s, try throwing it instead." ),
it->tname() );
return 0;
} else if( p->has_item( *it ) && it->charges == 0 ) {
it->charges += 1;
if( one_in( 5 ) ) {
p->add_msg_if_player( _( "Your lit Molotov goes out." ) );
it->convert( itype_molotov );
it->deactivate();
}
return 0;
}
return 0;
Expand Down Expand Up @@ -7737,7 +7736,7 @@ int iuse::foodperson( player *p, item *it, bool t, const tripoint &pos )
}

time_duration shift = time_duration::from_turns( it->magazine_current()->ammo_remaining() *
it->type->tool->turns_per_charge );
it->type->tool->turns_per_charge - it->type->tool->turns_active );

p->add_msg_if_player( m_info, _( "Your HUD lights-up: \"Your shift ends in %s\"." ),
to_string( shift ) );
Expand Down
8 changes: 8 additions & 0 deletions src/iuse_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,14 @@ void explosion_iuse::trigger_explosion( const tripoint &pos, Creature *source )
const int field_intensity = rng( fields_min_intensity, fields_max_intensity );
here.add_field( gas_source, fields_type, field_intensity, 1_turns );
}
if( source == &get_player_character() && source->has_trait( trait_PYROMANIA ) ) {
if( fields_type == fd_fire || fd_incendiary ) {
Character &p = get_player_character();
p.add_morale( MORALE_PYROMANIA_STARTFIRE, 15, 15, 8_hours, 6_hours );
p.rem_morale( MORALE_PYROMANIA_NOFIRE );
p.add_msg_if_player( m_good, _( "Fire… Good…" ) );
}
}
}
if( scrambler_blast_radius >= 0 ) {
for( const tripoint &dest : here.points_in_radius( pos, scrambler_blast_radius ) ) {
Expand Down
4 changes: 4 additions & 0 deletions src/savegame_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,9 @@ void item::io( Archive &archive )
archive.io( "invlet", invlet, '\0' );
archive.io( "damaged", damage_, 0 );
archive.io( "active", active, false );
if( is_tool() ) {
archive.io( "turns_active", type->tool->turns_active, 0 );
}
archive.io( "is_favorite", is_favorite, false );
archive.io( "item_counter", item_counter, static_cast<decltype( item_counter )>( 0 ) );
archive.io( "rot", rot, 0_turns );
Expand Down Expand Up @@ -2303,6 +2306,7 @@ void item::io( Archive &archive )
debugmsg( "Item %s was loaded with charges, but can not have any!", type->get_id() );
}
charges = 0;
curammo = nullptr;
}

// Relic check. Kinda late, but that's how relics have to be
Expand Down

0 comments on commit 9081fe7

Please sign in to comment.