Cataclysm-dda: Starting fire causes time to progress forever.

Created on 28 Mar 2020  路  3Comments  路  Source: CleverRaven/Cataclysm-DDA

Describe the bug

When starting a fire with a (worn?) pair of reading glasses, causes time to advance with no way to stop it, requiring an Alt+F4. This was done by lighting a log inside of a regular world gen stove, inside of a house, while standing in a door frame leading to the out-doors.

Steps To Reproduce

  • Have character with no way to start fire aside from reading glasses
  • Try to start fire by pressing "e" and selecting log inside stove
  • Game should start advancing time
  • Expected behavior


    Ideally I would like to be warned before starting a fire this way, as it is much more time consuming than just using a match.

    Screenshots

    Versions and configuration


    debug.log
    windows 7

    Additional context

    (S1 - Need confirmation) <Bug> Character / Player

    Most helpful comment

    This is being caused by a divide by 0 error in "iuse_actor.cpp", line 1439

    const int moves = std::max<int>( min_moves, moves_base * moves_modifier ) / light;
    

    Variable light is set by:

    tripoint pos = spos;
    float light = light_mod( pos );
    

    Replacing "light" in the first code snippet with "10.0f" or replacing the assignment in the second code snippet with "float light = light_mod( p.pos() )" solves the issue, whereas replacing "light" in the first code snippet with "0.0f" results in identical fault behaviour. Regardless i'm not exactly sure what I'm doing (though I believe "pos" refers to the position of the targeted fire container whereas "p.pos()" is the player position) so would rather not make a pull request to fix this issue myself.

    I believe the divide by zero error results from the code using the light level at the player's position to determine if he can attempt to light a fire, but the light level at the position of the fire to set the "light" variable. Doorways aren't covered by the TFLAG_INDOORS check in light_mod so are a valid position to light fires with a lens, as the position of the fire is indoors the TFLAG_INDOORS check causes the light_mod function to return "0.0f" resulting in a divide by 0 error.

    All 3 comments

    I haven't completely figured out what is causing this but it's related to the "need_sunlight" part of the "firestarter" use action. As removing it from the item solves the issue (this also occurs with bifocals and the magnifying glass). This bug only occurs if you attempt to light the fire by using (e)xamine to light a fire while standing in an external doorway, the fire container and item being burned don't matter. I suspect this might be an unaccounted for edge case somewhere in iuse_actor.cpp when checking that the player is in direct sunlight. The fire is lit but then the time taken to perform the action overflows:
    1585374228

    This is being caused by a divide by 0 error in "iuse_actor.cpp", line 1439

    const int moves = std::max<int>( min_moves, moves_base * moves_modifier ) / light;
    

    Variable light is set by:

    tripoint pos = spos;
    float light = light_mod( pos );
    

    Replacing "light" in the first code snippet with "10.0f" or replacing the assignment in the second code snippet with "float light = light_mod( p.pos() )" solves the issue, whereas replacing "light" in the first code snippet with "0.0f" results in identical fault behaviour. Regardless i'm not exactly sure what I'm doing (though I believe "pos" refers to the position of the targeted fire container whereas "p.pos()" is the player position) so would rather not make a pull request to fix this issue myself.

    I believe the divide by zero error results from the code using the light level at the player's position to determine if he can attempt to light a fire, but the light level at the position of the fire to set the "light" variable. Doorways aren't covered by the TFLAG_INDOORS check in light_mod so are a valid position to light fires with a lens, as the position of the fire is indoors the TFLAG_INDOORS check causes the light_mod function to return "0.0f" resulting in a divide by 0 error.

    Unfortunately I could not reproduce this bug. Every time I tried to start a fire as it should cause this error, it just started a fire.

    Could that work?

    p->mod_moves( -p->moves );
    const auto actor = dynamic_cast<const firestarter_actor *>( usef->get_actor_ptr() );
    const float light = actor->light_mod( p->pos() );
    act->moves_left -= light * 100;
    if( light < 0.1 ) {
        add_msg( m_bad, _( "There is not enough sunlight to start a fire now.  You stop trying." ) );
        p->cancel_activity();
    }
    const float actlight = actor->light_mod( act->placement );
    act->moves_left -= actlight * 100;
    if( actlight < 0.1 ) {
        add_msg( m_bad, _( "There is not enough sunlight to start at this position.  You stop trying." ) );
        p->cancel_activity();
    }
    
    Was this page helpful?
    0 / 5 - 0 ratings