Getting Race Course Positions

Discussion in 'Plugin Development' started by MoeMix, Apr 7, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    MoeMix

    Hi guys, I am working on a minigame and there is just one problem I can't seem to figure out! I am making sort of a mario kart simulation and I have already created the custom kart by nms and powerups.

    To get to the point. I don't know how I would be able to get the place the player is in. For example 1st, 2nd, 3rd, and so on... And no, the race course isn't going to be a straight course haha. I was thinking of using checkpoints but I'm lost in how to go about doing that and also feel as if there is another way. Any help on this topic would help me out a ton!

    I am not asking you guys to paste the code or a util on how to do it (just send me a link? :p). If you could just briefly show me a way of accomplishing this that would be great!

    Thanks again!
     
  2. Offline

    TeeePeee

    A checkpoint system would be a good bet.

    Have a block that you want to use for the checkpoint and give it different data values. The first checkpoint could have a data byte of 0, followed by 1, etc. etc. when you want to test to see who's winning, get the blocks around them, see if it's type is your checkpoint block and then check its durability. Compare who's is largest.

    For best results, have a lot of checkpoints.

    There might be a better way that I'm overlooking. Writing this comment hastily before dinner.
     
  3. Offline

    Europia79

    MoeMix
    TeeePeee idea sounds very good.

    Another idea would be to use a Mathematical Vector with an origin block. Vectors have magnitude and direction.

    So, let's think about some possible scenarios:

    1. I know you said the course isn't going to be straight... but let's consider ALL scenarios. For the straight-line course, you would put the origin block at the start of the course, OR the end of the course, then check the magnitude of the vector (which is distance) to determine each players place.

    2. Let's consider a circular course: Put the origin block in the middle of the circle. Define the course as circular. Stand at the starting location and run a command like "/race starting point here." Then, if you want to check what place a player is in, you would check the direction component of the vector.

    If two players have the same direction (say 45 degrees), then compare the magnitude (i would have to draw a picture to demonstrate this scenario better).

    Also, you would have to take into account if the course is going clockwise or counterclockwise. Degrees on a cartesian plane go counterclockwise:
    right is 0 degrees
    up to 90 degrees
    left is 180 degrees
    down is 270 degrees
    right is also 360 degrees

    That is what mathematicians use (so watch out if some math libraries use this notation and definitions) because the Minecraft world is like a map (if you've ever done land navigation)
    Minecraft and maps go clockwise:
    North is zero degrees
    East is 90 degrees
    South is 180 degrees
    West is 270 degrees
    North is also 360 degrees

    Just wanted to throw this idea out there as a possibility... I would have to ponder it a little more better choosing a particular implementation. For my /compass command, it's Essentials that has defined the clockwise orientation (like a map).

    (I wish the map makers and mathematicians would use the same system and notation).

    At any rate, if you're going to use a system like this, you'll at the very least, need a counter variable for each player to keep track of how many laps they've completed.

    Also, Java has a type of collection called Vector that is similar to an ArrayList.
    So try not to confuse the Java Collection Vector with the Mathematical Vector.
     
  4. Offline

    TeeePeee

    Europia79
    Yes, 3D vectors would be another solution, albeit very complicated to set up. Especially with large courses.

    The only other way I can think of simply is just to use recursion to find a path from the start to the end of the course. Something similar to an A* pathfinder to make its way along the course. This would be costly so you'd probably want to cache the results. Then, you can just get the location of a player and find its cost index from your A* path to see who is the furthest from the start of the course.

    And yes, you would have to track laps.
     
  5. Offline

    Europia79

    TeeePeee

    I edited my post.

    Like I said: just wanted to throw out that idea as a possibility.

    What do you think about using degrees and distance from an origin block ?

    It appears to work for both type of tracks: straight & circular.

    Where you check degrees first. And if necessary, check distance second.
     
  6. Offline

    MoeMix

    Thanks TeeePeee and Europia79!! I'd like to appreciate you guys for sharing your insight! But courses wouldn't be perfectly circular. That is why I was thinking of probably having multiple checkpoints at each turn. I could see that idea getting somewhere but what would I do from there?
     
  7. Offline

    Plo124

    MoeMix
    Checkpoints is a good idea.
    I would make a quick and simple thing which you can temporarily right click the ground in certain points to set them and then give you a list.
    In the code I would have a HashMap for each player (username not object to save ram) and their lap, and then check which checkpoint they are closest to and then if theres more than 1 to a checkpoint, check who is closer to the next checkpoint.


    A really simple way is to just measure how far they've travelled, but this is not the most accurate if you have corners or turns in your map since if they ride on the outside of the map they will have a bigger distance travelled, but get to the destination last.
     
  8. Offline

    Europia79

    MoeMix
    I have to go to work... But my option will work for course that aren't perfect circles.

    I'll draw you a picture so you can see what i'm talking about (when I get home).

    I'm a little bit familiar with Mario Kart tracks... So I know the odd shapes you'll have to deal with.

    The advantage to uses vectors is that it'll be easier on the end-user to setup each course:
    1. set the origin block.
    2. set the starting line.
    3. set clockwise=true|false

    Then you're good to go. Like I said, i'll draw a picture to elaborate in detail about scenarios that you're concerned with... So you can SEE that it will in fact work.

    And I'm not saying that you should use this option... I'm just saying that it's a possibility.
    You probably wanna evaluate all the options, and analyze the advantages and dis-advantages of each one.

    View attachment 19008

    MoeMix
    Here are some the extreme scenarios that you'll have to deal with: #1. (Red + Blue) When two players are neck & neck and about to cross the finish line... I think the best way to determine the winner would be with some kind of event: Whoever triggers the event 1st has crossed the finish line first. #2. (Yellow + Green) When two players have the exact same angle to the origin: compare the distance: The comparison depends on if the track is clockwise: true or clockwise: false. However, if we get the angle of all the players, and sort the list by angle, this approach fails because it would put Pink in the lead over purple. When, on a clockwise track, purple leads pink.

    Now, the important thing is the Event for the Finish Line: Whoever triggers the event 1st is first, whoever triggers the event 2nd is second place, 3rd is third, and so on. As far as the ranking during the race: I'm guessing you'll display this on the Scoreboard for the players ? (so they have some kind of idea what place they're in)... Well, you could potentially use this flawed approached that will work probably 90% to 99% of the time... and a small percentage of cases, the players will just have an incorrect DISPLAY... which will have *nothing* to do with determining the winner.

    I really believe that you could schedule a task to run every second or half second... that would calculate the ranks and display them for the players... using this method. Eventho, I've found some flaws, I think there's still a solution using this approach... I just can't think of it right now.

    If you're wondering what event to use for the finish line... maybe a pressure plate ? (don't know, first thing that came to mind). Maybe something else ?

    Anyways, this is a really interesting problem to solve. Lemme know what you decide. Hopefully, some other developers will come along with some bright ideas too. I'll let you know if i think of anything else.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
Thread Status:
Not open for further replies.

Share This Page