DCurrent / openbor

OpenBOR is the ultimate 2D side scrolling engine for beat em' ups, shooters, and more!
http://www.chronocrash.com
BSD 3-Clause "New" or "Revised" License
901 stars 121 forks source link

Blockodds strange behaviour #226

Closed dbaldan closed 7 months ago

dbaldan commented 3 years ago

Description

According to the manual, blockodds accepts different values, to be a ratio/chance of how an entity should block

blockodds {int}

{int} is a number from 1 to 2147483647. It determines how often an enemy will block an attack. 1 means they'll block almost all attacks. 2147483647 means they pretty much never, ever, ever block, ever.

// Run random chance against blockodds. If it
    // passes, AI will block.
    if ((rand32()&ent->modeldata.blockodds) == 1)
    {
        return 1;
    }

Debugging

But its not how it works. Because no matter what value I use, there is just two options:

Reproduce

Just set the blockoods 1 in the character header. If you set "blockoods" to any number that is not "1", the entity doesn't block at all. If you set "blockodds 1" and use "nopassiveblock 1", the engine doesn't block at all.

Expected behavior

The character must try to block in a percentage based on the value of blockodds. And if the first attack has already hit and the pain animation has not yet ended, it cannot block the next attacks.

Screenshots

Version

Please provide the SPECIFIC version the issue first appeared. This is very important, it is nearly impossible for us to pour through the entire code base to find singular issues without a starting point.

DCurrent commented 3 years ago

I'll look into this. I think it's actually two separate issues.

dbaldan commented 3 years ago

@DCurrent thanks. I remember some people reporting that some entities can block even if they are on the ground - right from the fall animation into the block, skipping the whole raise proccess.

fgames9000 commented 3 years ago

Hey guys! Thanks to your reports and comments I was able to find where the problem is. Here's the fixes:

Blockodds rate fix

    if ((rand32()&ent->modeldata.blockodds) == 0)
    {
        return 1;
    }

Block state fix, check if the "blocking instance" is gone or not before all other tasks

int check_blocking_eligible(entity *ent, entity *other, s_collision_attack *attack)
{
    if (!ent->blocking)
    {
        return 0;
    }

In the videos below you can see some tests:

Blockodds rate fix https://www.youtube.com/watch?v=6cgTytt4iOM

Block state fix https://www.youtube.com/watch?v=IHQbTMw3yRs

I'm doing more tests to see if everything is ok in a test build.