Started by
SkylieTuff
on
Topic category: Help with modding (Java Edition)
https://pastebin.com/ZP4H1xXr Code here as forum said it was to long.
Above is the code and on the x+1 and Z+1 sides it bounces the player accordingly. The other two sends the player up. And the top doesn't bounce you. Nor the bottom.
Any help be appreciated.
maybe it's something simple,
I don't know.
(code) 1.20.1 latest mcreator
Not sure if there's an easy way to do this, but I can think of some weird work arounds. I did something similar to this to make a block that launches entities away from it when triggered.
What if you make a procedure that first either checks if a n entity is colliding with your block, (you'd have to make the bounding box a pixel smaller on all sides so that this would work), or if there's a player in 1.05 meter cube around your block. (Using the 'if entity exists in square cube size...' function, or possible as an entity iterator to better handle multiple entities at once.
Just make sure the check is centered at the block's middle, not its corners- all the 'check in box' functions go from the middle instead of the bottom north-west corner, so you need to add + 0.5 meters to all coordinates involving them to center it properly. Also be careful using the 'nearest entity' function, as this will very easily crash the game if it for some reason doesn't return anything in its radius. An entity iterator is probably the better option.
You should just be able to reverse each of the target entity's velocity values in an 'attempt to override motion vector' function, multiplying the x y and z velocities by negative one. If you want to be more precise, you could use trig functions to get the exact vector, possibly also taking into account the direction the entity is moving relative to the face they collide with. (Otherwise, jumping downwards onto the block while moving forwards will bounce the entity backwards and upwards, instead of maintaining the forwards momentum), but this is substantially more complicated.
Tried all kinds of methods but had errors and errors even yours. I mean I got the collision one to work except for one problem. It didn't work with entites. Only the player. I tried raytracing and again only worked for players. I do see that their is something in the code for find path and attempt to move, maybe I need to use that for mobs and animals? I also had the problem of diagonal launching. And things kept getting more and more annoying. I'll come back to it because I want it. I want to make it work so it repels the entity on any side of the block and if block is pushed, it would repel the player from side of block they got hit. Kind of like a launcher like yours yes. But more versatile. I'll keep plugging at it. Thank you though. A lot of my issue is I don't know how to update my mcreator to use the proper newest forge with 1.20.1. And or understanding all the code.
Here's a basic example of how I achieved this effect, though keep in mind this is just for the X and Z axes- SY, (the amount of momentum to add in the Y axis), is set to a constant 0.3. This procedure is triggered by an invisible entity that launches everything in a 9 block radius backwards, meaning it runs every game tick, so your use case, (a single game tick), would need much higher values.
Entities in minecraft have X, Y, and Z momentum, that determine how much they move each tick, and in what direction. These are vectors- meaning if you're moving east you have positive x momentum, if you're moving west you have negative x momentum, falling means negative y momentum, jumping means positive... and so on and so forth. You don't want pathfinding, because pathfinding, (or just pressing keys to move your character), is just telling the game how much momentum you're trying to add. Walking adds momentum to the player, but it's influenced by surface friction, whether or not the player is swimming/on solid ground, etc. The 'Override Motion Vector' will instantly change the player's momentum to your desired values. (In this case, because it adds to the entity's existing momentum, it gradually overrides the player's existing momentum instead of all at once- if they're going really fast in one direction, it'll take a bit before the procedure fully zeroes out and then overrides their momentum.)
Your procedure may only work on players because your entity iterator is using 'event/target entity,' or has an unessasary check that's leaving out other entities. If you want it to only work on one type of entity, you could nest the stuff inside the entity iterator in a 'if entity is subtype of (whatever entity type you want),' which could be exclusively players, exclusively living entities, (not items or projectiles), etc. If you want it to work on everything, do not include such a check, and make sure all of the 'event/target entity' blocks are replaced with 'entity iterator,' (which is similar, but will trigger for all entities within the block's radius.) In this specific example, the 'event/target entity' refers to the entity doing the pushing, not the one being pushed.
The math here is kind of unpleasant, and I had to watch more Khan academy than I'm comfortably admitting to remember trig functions. The basic idea is that we don't know the exact distance the player is from the center of the outwards push, but we know the difference between the x position of the player, and the x position of the ce=nter; and the same for the z and y axes. So:
Sorry for the super exaustive explanation, but this took me embarassingly long to figure out, and I hope this helps. Best of luck!
Actually, your example might be way, way easier than that. You don't need something that pushes something outwards from a central point. You just need a block that bounces something based on the face that's hit. There's only six faces that can be hit, and the player must be moving in the correct direction on that face's axis to hit it.
You literally just need to do the collision box, like from before, but instead of calculating vectors or whatever, just determine which of the six faces the player is colliding with based on their position compared to the block's position; then reverse the correct motion vector by multiplying it by -1. (If they're colliding with the top or bottom, reverse their y velocity, if they're colliding with the east or west side, reverse x velocity, and for north or south, reverse the z velocity.)
...That should literally do it. It won't work for diagonals, but as long as the player collides head on with the hitbox, it'll bounce them in the correct direction, keeping other velocity, (such as forwards velocity when landing on the block from above), intact. Just make sure to check that the velocity in that direction is greater than 0, (or maybe that the absolute value is greater than 0.2 or something, so it doesn't continue endlessly), and probably multiply the reversed velocity by 0.6, 0.7, etc; depending on how bouncy you want it to be. (If you don't all momentum will be maintained, and the player will be able to bounce endlessly at the same height, if it's higher than 1 they'll gain more height each time they bounce.)
Don't have an example on hand, but that should be a substantially easier solution, the only tricky part is determining which side the player's hitting.
Very nice explanation Mindthemoods :)
@Mindthemooods: Thank you very much. I didn't think about entitiy/iterator vs eventtarget one. I'll try to set it up with block face direction. And let you know how it goes
Nice! You should probably be able to judge direction pretty well just with positions. (If subtracting the x and z positions of the entity from the x/z positions of the block's center gives less than half a meter for both, you can probably assume they're colliding with top or bottom depending on their y position... and so on.)
Happy to help!
@MindTheMoods If you don't mind or if you don't want to, could I get the first picture you sent to me via a file download as a saved import so it'd be easier for me to edit. And I'm a newb at math, I cheat with math using chatgpt, I know, a shame. So all the math stuff you used I really don't understand it. I just know it uses the vector and that is apparently what I need. And if you're willing to put in comments on each math and how it works, that would be helpful so I can learn.
Highly recommend checking out Khan Academy if you just need info on specific math stuff, like trig functions. For your situation though, you probably don't need much math. You just need to know what side the player is hitting, and with how much force.
For example: if the player's x and z positions are both within 0.5 of the block's center, (if subtracting the player's x position and the block center's position is less than 0.5 and greater than -0.5), that means the player must be colliding with the top or bottom of the block. (Because the player can't be closer than 0.5 meters to the center without being inside the block if they're horizontal to it). If either x or z was greater than 0.5, that would mean they weren't aligned with the block. The same thing should work for the horizontal axes, though since the player is two blocks tall, you'll need to also test for the top section of the player.
...And if you wanted a solution that's maybe even simpler, (but not as fancy, and probably a lot more resource intensive), then try this:
Figured out most of my problems except not being able to work with boats or minecarts. Works with all other entities though including armor stand.
just to show you what I did. I originally was adding to the velocity and that made it so it kept adding more and more velocity when more blocks were around. Lol.
Finally removed that and used entity iterator like you suggested and used velocity in the other spots so it would move freely instead of stopping. And it works.
Thank you @themindmoods and it works when you push the block with piston. Thing I can't get to work is with minecart, with minecart chest, boat, and boat chest oddly. But works with armor stands.