Closed Psojed closed 3 years ago
I suspected as much just by watching the video, but I also confirmed this through testing. Looks like this is happening because the blocking logic causes the missile to glance off the player's shield/staff, allowing the missile to continue moving after the colliding with the player. Blood Star doesn't move fast enough to vacate the player's space in the next frame after the first collision frame so it ends up colliding with the player a second time.
Also, the save file reproduces another issue you can see in the snow_witch_blocking.mp4
video. The Blood Star projectile frequently disappears for several frames after the missile is blocked. When this happens, I get a bunch of these messages in the debug output.
INFO: Draw Missile 2 type 24: NULL Cel Buffer
This seems to suggest there's some missing animation data for the Blood Star projectile.
Should we mark missiles as "already hit player X" or something like that? The missile would need to keep track of this for all players I guess, and then check if it has already hit the player on the hit check and skip if so.
I couldn't think of a way to fix this that wouldn't involve expanding the missile struct or using the _miVarX
variables. Your solution seems viable to me if we're willing to make use of _miVar3
.
Actually, there is a couple things I forgot to mention.
woudn't just marking it for deletion or setting range to 0 work?
woudn't just marking it for deletion or setting range to 0 work?
Shouldn't it still atempt to hit other players for example?
What would be the most intuitive approach to me would be for the game to have 2 missile types: single-hit, and multi-hit.
For single-hit missiles, the missile should keep track of all entitities it has already made a hit check against, and avoid doing the checks against entities it has already done so before.
I have no idea how missiles work today so disregard if this makes no sense.
As @julealgon suggested, if there was another player standing behind the blocking player, they could potentially still be hit by the missile. The game does delete the missile if the player is hit. Marking the missile for deletion would make it behave more like the spell had hit the player. That might be fine for Blood Star, but I wouldn't recommend doing that for all projectiles. For example, I believe arrows fly crooked when blocked, which is a nice touch.
Actually, I'm pretty sure that's the cause of the disappearing Blood Star. Whenever the following random number returned 1, the projectile would disappear for a few frames. If it returned 0 (resulting in -1), there was no issue. If you follow the method calls, it's basically looking for an adjacent animation in the mAnimData
array for that missile, but Blood Star only has animation data at index 0.
https://github.com/diasurgical/devilutionX/blob/2969b80163c4bbd5dbb624fdef28e8a7e017450c/Source/missiles.cpp#L1089
I played around with editing projectile velocities, and this issue still occurs at arrow speeds. To be sure, I went ahead and tested arrows as well, and I can also confirm that this issue is not isolated to Blood Star. It's just that Blood Star is one of the slowest projectiles that the player has to deal with so it happens a lot more often.
woudn't just marking it for deletion or setting range to 0 work?
It probably would but why get rid of such a cool mechanic? Deflecting missiles and seeing them fly away is AWESOME
True to my usual process, I decided to compile a list of missiles that would potentially be affected by this bug as well as those which should not be affected by this bug.
Affected
MI_LArrow()
MI_Arrow()
MI_Firebolt()
MIS_FIREBOLT
MIS_MAGMABALL
MIS_FLARE
MIS_ACID
MIS_LICH
MIS_PSYCHORB
MIS_NECROMORB
MIS_ARCHLICH
MIS_BONEDEMON
MI_Lightball()
MI_Krull()
~MI_Fireball()
MI_HorkSpawn()
~
MI_Immolation()
MI_Firemove()
MI_Weapexp()
MI_Cbolt()
~
MI_Element()
MI_Bonespirit()
Should not be affected
AddRuneExplosion()
(nodel)MI_LArrow()
(nodel)MI_Acidpud()
(unblockable)MI_Firewall()
(unblockable, nodel)MI_Fireball()
(nodel)MI_LightningWall()
(unblockable)MI_Immolation()
(nodel)MI_Lightning()
(unblockable)MI_Flash()
/MI_Flash2()
(unblockable, nodel)MI_Boom()
(nodel)MI_Flame()
(unblockable)MI_Hbolt()
(can't hit players)MI_Element()
(unblockable, nodel)Additional notes
nodel
means the missile isn't deleted on impact
false
for nodel
, but they immediately update their _mirange
values after checking the collision logic, effectively making them similar to nodel
missiles. That means some of the missiles in the affected list should definitely be looked at more closely. These include MI_Lightball()
, MI_Firemove()
, MI_Cbolt()
, MI_Element()
, and MI_Bonespirit()
.MIS_LICH
, MIS_PSYCHORB
, MIS_NECROMORB
, MIS_ARCHLICH
, and MIS_BONEDEMON
are all processed exactly the same way as Blood Star (using AddFlare()
and MI_Firebolt()
); they just have different animations??? MIS_LICH https://diablo2.diablowiki.net/Lich ??? MIS_PSYCHORB https://diablo2.diablowiki.net/Psychorb ??? MIS_NECROMORB https://diablo2.diablowiki.net/Psychorb ??? MIS_ARCHLICH https://diablo2.diablowiki.net/Lich ??? MIS_BONEDEMON https://diablo2.diablowiki.net/Skullwing ??? MI_Lightball() Individual Nova lighnings ??? MI_Krull() For an unused monster ??? MI_HorkSpawn() https://diablo2.diablowiki.net/Hork_Spawn ??? MI_Weapexp() weapons with fire/lightning damage
??? MI_Flame() (unblockable)
Inferno?
single_0.zip
We tested using a single succubus enemy type shooting their Blood Stars. Sometimes the spell is blocked completely, but sometimes the spell gets blocked but still deals damage. The same issue is present in vanilla Hellfire.
Hellfire 1.0.1: https://www.youtube.com/watch?v=8l9SDX6BPjQ (thx Maxpire) devilutionX 1.2.1 Hellfire: https://cdn.discordapp.com/attachments/764970679564501052/831966291337543680/snow_witch_blocking.mp4
In the second video you can see instances of "damage taken" sound triggering, but me not taking damage, that is most likely because I'm wearing 64% magic resistance and items with -5 damage taken.
The expected behaviour is that every blocked Blood Star should be fully blocked and deal no damage, regardless of damage reductions.
PS: Attached is my save from devilutionX 1.2.1 Hellfire in a position ready to test.