-
-
Notifications
You must be signed in to change notification settings - Fork 342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SteerVehicleEvent #2364
Add SteerVehicleEvent #2364
Conversation
src/main/java/org/spongepowered/api/event/entity/living/player/SteerVehicleEvent.java
Outdated
Show resolved
Hide resolved
/** | ||
* The possible scenarios of steering left or right. | ||
*/ | ||
enum Sway { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand it's effectively either left, right, or none, but I'm partial to still not having any enums here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d argue that using enums is the best solution here, since it’s more user friendly than the alternatives (I can think of). Additionally, they allow you to use switch statements, which is quite nice.
The alternatives that I can think of are
a) Just providing the float values straight from the packet
b) Having 4 distinct booleans (left, right, forwards, backwards)
The problem I have with alternative a is that it’s very easy to confuse the two directions. Does a positive number mean left or right?
Alternative b is also problematic in terms of clarity. Having distinct booleans for pressing left and right may give someone the impression that left and right may be true simultaneously, if both a and d are pressed.
Of course, both of these problems can be solved with good javadoc comments. However I personally still prefer enums, because I find them more user friendly and I like switch statements :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bigger problem I have here is that you're bleeding implementation details into the API.
Take this on its own, why is "RIGHT" or "LEFT" -1 and 1? Why does a plugin developer care? Quite simply, they don't and they shouldn't. If Mojang change the packet, we have to change the API in a breaking way. This is why we have our pseudo enums that hide as much implementation as possible.
If we are to have enums, they should go in the util
package and be named in a neutral way so they can be reused.
That said, thinking beyond this, it's quite clear that the packets can return sways and surges between -1 and 1, not just 1, 0 and -1 - is this information useful? For sway, is it simply an angular velocity (so, should we expose degrees per unit)? For surge, is it a linear velocity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have RideEntityEvent
. While this seems to be specific to Vehicle
s, should this event really be a sub-event of that?
Dismounting already has its own sub-event.
import org.spongepowered.api.util.annotation.eventgen.GenerateFactoryMethod; | ||
|
||
/** | ||
* Called each tick for any {@link ServerPlayer player} riding a vehicle. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this sensible? Having 50 players in boats riding about is going to get very spammy very quickly.
Why might you want to check this every tick? Would it be better to detect when the steering changes?
* | ||
* @return The player | ||
*/ | ||
ServerPlayer player(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is an event concerning a vehicle, then the Vehicle
should be exposed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is still a problem, what vehicle are we steering?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, more than likely, the steering is being caused by a player, which will likely be "required" as part of the Cause, but you've omitted the vehicle, my guess because it's accessible by the Player.vehicle() method?
* | ||
* @return Whether the player is attempting to dismount the entity. | ||
*/ | ||
boolean unmount(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dismounting should be a different event entirely to steering.
/** | ||
* The possible scenarios of steering left or right. | ||
*/ | ||
enum Sway { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bigger problem I have here is that you're bleeding implementation details into the API.
Take this on its own, why is "RIGHT" or "LEFT" -1 and 1? Why does a plugin developer care? Quite simply, they don't and they shouldn't. If Mojang change the packet, we have to change the API in a breaking way. This is why we have our pseudo enums that hide as much implementation as possible.
If we are to have enums, they should go in the util
package and be named in a neutral way so they can be reused.
That said, thinking beyond this, it's quite clear that the packets can return sways and surges between -1 and 1, not just 1, 0 and -1 - is this information useful? For sway, is it simply an angular velocity (so, should we expose degrees per unit)? For surge, is it a linear velocity?
Quoting the Javadoc, RideEntityEvent is "an event that involves an entity riding another." While this is fine for mount & dismount, only a player can steer a vehicle. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about the floats. I get why you did this, but it's not really what I meant.
This event is concerned with acceleration. When you steer a vehicle, you are accelerating (or decelerating) it in a given direction. My point was that you could work out the acceleration of the vehicle, However, that might be quite hard... maybe just a direction or some pseudo class as mentioned for "sway"?
I'm guessing the vehicle has a current velocity? If you stop steering it, it doesn't come to complete stop immediately. Thus, would it be useful to have the velocity, or at least the direction of travel in this event, so there is some easy way to get which direction "left" and "right" really are?
I still think this needs to be cancellable. We've already removed the unmounting part of it, so cancelling it should be trivial now, right?
* | ||
* @return The sway | ||
*/ | ||
float sway(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that you did this based on my comments, but it's not really what I meant. I talked about the acceleration in given directions.
Let's take this back a step for a moment. What information are we trying to convey to plugins - I'm probably better asking why is this is useful event? What does this do that the move event doesn't, for example? Why would preventing a steer be important?
Again, I know I talked about why we might not want this as an enum, but making this a float doesn't solve the problem itself. You're exposing numbers from the packet which means nothing. An enum was better than this... and I'm honestly thinking that we should just have a Steer
psuedo-enum that can take in a direction and return a rotated direction.
In fact, we could possibly use something like the Rotation
class here, you're either steering clockwise (to the right) or anti-clockwise (to the left), and we can include some useful functions on the class to aid with transformation of direction.
* | ||
* @return The surge | ||
*/ | ||
float surge(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of the same problem as "sway"
* | ||
* @return Whether the player is attempting to jump. | ||
*/ | ||
boolean jump(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should jump really be part of the steer event? I'd argue not - because it performs the same function as jumping out of a vehicle, this is covered by the move event.
Taking over this. Changed the API to be more friendly to consume. This is at least somewhat how I would imagine the values would be exposed. The input can be directly used to manipulate the entitys velocity. |
Also to add; This event is completly based on input. It does not take into account the current velocity, movement or direction. If the plugin developer wants to make the entity controllable by the rider, it should use the riders direction and then add velocity to the entity based on the input. |
I really don't know what I think about this - other than it's become a victim of ideas rather than solving a specific problem. What is the problem we want to solve? To be able to stop someone from steering clockwise/counter-clockwise? Or is there some more fine grained control we need? Once we know what we want to do, we can design the event around that. |
We are trying to solve how can we allow plugin to take control of how vehicle is being moved based on controls given by the player. To better visualize this, lets take a look at a real world example; Hypixel Turbo Kart Racers. The "vehicle" the player is inside is actually a armor stand with item on its head. The item has 3D model to make it look like you are sitting inside actual race car. To be able to "control" this vehicle, the client sends the steering packet, which normally would do nothing. In this case however, the vanilla action is overridden by a plugin to give the armor stand velocity based where the player would like to move (wasd). When the player tries to jump (pressed space), a honk is used instead and when the player tries to sneak (pressed shift), the car starts to drift. To make the visuals look more pleasing, it also moves the armor stands head around to allow the car to tilt a bit when making a turn. To solve that, we need a way for the plugin to interpret the steering packet and implement its own logic to override the vanilla behavior. |
To clear any confusion, an event should not be a façade for a packet itself, which is what this event tried to become. Instead, I see three significant events that should occur here:
In all cases you're riding an entity. Should we then be including this in
Does that cover what you're interested in doing? @gabizou @Zidane I suppose a good question here is if steer and jump should be sub-events or RideEntityEvent or not - any opinions? |
I did consider to implement them all as sub events (as I did for dismount) but then got a bit worried about whatever that would be too impactful for performance reasons. It looks way cleaner in my opinion and would 👍 for it. However, what data type should we use when exposing the steering direction? Booleans? New enum? Existing enum? Vector like I used? Also makes sense to move this all to RideEntityEvent, lets do that. |
I have no personal opinions here, sub events mean more to filter out. I don't know how spammy these events would be otherwise.
Correct me if I'm wrong, but there's 8 possible directions, (forward, back, left, right, forward left, forward right, back right, back left) at which point I personally believe we should just expose the Vector3d direction aligned by the entity currently riding (maybe even expose the Vector3d of the direction from the entity riding vs the direction aligned to the world's coordinates). |
Steering is clockwise or anti-clockwise - it's relative to the steering entity, not the world. Thus, that or left and right will suffice. |
Hey! You seem to be running an unsupported version (API 8) of SpongeAPI. Support for API 8 ended in October 2023. API-8 is now end-of-life. We will not be issuing any more API updates for version 8 of our API1 As part of our legacy cleanup we are closing issues relating to API8/1.16 If you wish to move this forward, please rebase this PR on the current branch and reopen it. Footnotes |
Sponge | SpongeAPI