Projectiles now respond correctly to floors #9
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This issue seemed simple going into it, but turned out to be challenging - I think I've got it working pretty well though. The problem was that any projectile that's meant to respond to floors would just slide against it instead. This can be seen by bringing Sylvanos, Kragg, Maypul, Ori, or others into the map and having them toss their projectile into the little pit right under where you spawn. This occurs because projectiles don't like non-rectangular floors.
To fix it, I was hoping I could just manually set the variable
free
to false when a projectile is just above a floor - however, it turns out that the processing order doesn't work out that way. Instead, I made it so that projectiles manually spawn a very small solid article named the Projectile Supporter. The Projectile Supporter is perfectly rectangular, so projectiles can bounce off of it or land on it without issue. It also deletes itself after one frame so that they don't accumulate. It's always placed exactly one pixel above the original floor, which does mean that if a projectile lands right where another object is already standing, that other object will be pushed upwards by a pixel for one frame and then drop back down. Unfortunately this was necessary, since if it's perfectly flush with the floor the projectile seems to be unable to "reach" it. I felt that this was an acceptable sacrifice to get this working though, since it doesn't seem to cause any issues. The Supporter despawns immediately, so you can't stack them to do anything weird. I also made sure that it used theHG_PROJECTILE_COLLISION_SPRITE
when available, so hopefully this should match the behaviour you'd get on normal stages pretty well.This fixes almost every projectile interaction I tested, including Workshop ones. The only projectile that still interacts weird with floors is Ranno's neutral special - it goes through not only floors but also walls. I'm pretty sure it's supposed to pop when it hits either. I don't know why it's weird like that but it probably isn't important, since they don't travel particularly far anyways, nor do they do anything interesting upon hitting a wall.
This fix also allows Kragg, Shovel Knight, Orcane, Elliana, and Sylvanos to plant their articles on the floor, which I find pretty exciting! Sylvanos required a bit of special treatment - his NSpecial and FTilt projectiles both have their
HG_PROJECTILE_GROUND_BEHAVIOR
configured to go through floors, for some reason? Projectiles that are configured to go through floors don't spawn Projectile Supporters. To fix this I made it so that on frame 3, when the stage puts players inPS_SPAWN
, it also checks if they're Sylvanos and changes those two moves if so. The change just sets the behaviour to stop at floors instead of going through them, which doesn't seem to cause any problems. Doing so allows them to spawn Supporters, which means Sylvanos can plant flowers :) He still doesn't get any grass though.This should hopefully have a pretty minimal performance impact, since it only runs any checks on projectiles that are moving downwards and are configured not to go through floors. Additionally, these projectiles usually just run a single collision check per frame, and only do more if they find that they're about to land.