Blockodds strange behaviour
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:
- 1 - Block EVERYTHING, including during a combo (the entity receives the first hit and, even if their pain animation isn't over yet, it will automatically block the second hit, breaking from the pain animation)
- Any other value - didn't care to block at all
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.
- Windows
- Build 6330, 6315, 6392. But it was always like that if I remember well, so in version 4432 too.
I'll look into this. I think it's actually two separate issues.
- The formula for odds is set up wrong, that's probably a simple fix.
- No matter what odds are, the engine should not have the native ability to block if the entity is in any state other than idle. Most likely there's a missing flag check.
@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.
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.