Solved how to make a rebound ? (advenced math)

  • Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

  • LOOKING FOR A VERSION OF SKRIPT?

    You can always check out skUnity Downloads for downloads and any other information about Skript!

Status
Not open for further replies.

aeim

Member
Feb 21, 2017
38
5
8
27
Hi everyone (I'm FR, sorry for my english)! I have my own projectile trajectory system based on the reality.
This cool system allows me to predict the trajectory of my projectile even before firing (in 1 tick)!

How to calculate a projectile rebound against a block ?
(I'm talking about a projectile but it's an armorstand and not an arrow)

You can have your own technique for this problem.
Here is what I propose:

INFO:
With my current code the location of impact is ({_x}, {_y}, {_z});
The previous location is ({_x.old}, {_y.old}, {_z.old});
The location of the center of the block on which the projectile must bounce ({_bx}, {_by}, {_bz})

my idea :
1) We consider the block as a sphere and not a cube, we draw a vector between the point of impact and the current position.
2) A reflection effect of the previous location with respect to the vector is applied (vector which will be positioned from the point of impact)
Info: The old position, the point of impact and the vector are necessarily on the SAME plane which makes the operation possible.
3) A vector is drawn between the point of impact and the mirror point.
4) We recover the yaw and pitch of this vector with "vector yaw of %vector%"
5) It's over! The rest of my code takes care of considering the point of impact as if it is a new shot = D

This method is like folding a sheet of paper
ace876f92f.jpg


To help I have a lot of addon that can be used to solve this problem (Umbaska is removed voluntarily and I do not want to use it anymore).

1ef9791872.jpg


Help link :
https://skripthub.net/docs/?search=id:1345 (I need this but it seem to not result the correct location)
https://github.com/bi0qaw/Vectors-Skript (A secret addon ^^)

The part to modify is between the "================="
The rest of the code works very well

code_language.skript:
on script load:
  import "java.lang.System"
  import "java.lang.Math"

command /rr <number> <number>:             #this is just a test
    trigger:
        set {_x} to arg-1
        set {_z} to arg-2
        set {_pi} to {Math}.PI!
        set {_atan2} to {Math}.atan2({_x} and {_z})
        set {_yaw} to {_atan2}*180/{_pi}
        broadcast "%{_yaw}% %vector yaw of vector {_x}, 0, {_z}%"   #2 method to get yaw, first between [-180,180] , second between [0,360]
       
       
function Shoot(shooter: player, type: string, force: number, predict: boolean):
    set {_pi} to {Math}.PI!
    set {_x0} to x-location of {_shooter}
    set {_y0} to y-location of {_shooter}
    set {_z0} to z-location of {_shooter}
    set {_pitch} to pitch of {_shooter}*-1  #The rotation of player
    set {_yaw} to yaw of {_shooter}*-1
    set {_v0} to 17.7*{_force}              #17.7 is my own chosen number randomly for the velocity
    set {_cosPitch} to cos ({_pitch}*3.14/180)
    set {_cosx} to (sin ({_yaw}*3.14/180) )* {_cosPitch}
    set {_cosz} to (cos ({_yaw}*3.14/180) )* {_cosPitch}
    set {_t} to 0
   
    set {_RotPitch} to {_pitch}             #The rotation of projectile
    set {_RotYaw} to {_yaw}
   
   
    if {_predict} is false:
        set {_ID} to "Shoot_%{_shooter}%_%{game.timer}%"
        run {_shooter} command "/summon ArmorStand %x-location of {_shooter}% %y-location of {_shooter}% %z-location of {_shooter}% {CustomName:""%{_ID}%"",Tags:[""Shoot"",""Shoot_%{_shooter}%""],NoGravity:1b,Small:1b,Marker:1b,Invisible:1,Invulnerable:0,DisabledSlots:2039583}" as op
        loop all armor stands:
            loop-entity's name is "%{_ID}%"
            set {_entity} to loop-entity    #not used for now
            execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /playsound minecraft:entity.irongolem.attack master @a %{_x0}% %{_y0}% %{_z0}% 1 1"
            if "%{player::*}%" contain "%{_shooter}%":
                execute console command "/mycmd add %{_shooter}% stats.use.%{_type}% 1"
            if "%{_type}%" is "fragmentation":
                set helmet of loop-entity to yellow dye
                set {_color} to "0 1 0"
            if "%{_type}%" is "retardement":
                set helmet of loop-entity to red dye
                set {_color} to "0 0 0"
            if "%{_type}%" is "chimique":
                set helmet of loop-entity to light green dye
                set {_color} to "0.27 0.77 0.18"
            if "%{_type}%" is "flame":
                set helmet of loop-entity to orange dye
                set {_color} to "1 0.5 0.1"
            if "%{_type}%" is "implosion":
                set helmet of loop-entity to light blue dye
                set {_color} to "0.1 0.9 1"
            if {_color} is not set:
                set {_color} to "1 1 1"
               
    loop 900 times:
        set {_xt} to {_v0}* {_cosx}         #I put this here cause of the speed {_v0} can be modified (exemple: in water)
        set {_zt} to {_v0}* {_cosz}
        set {_x} to {_x0}+{_xt}*{_t}
        set {_y} to (-12/2*{_t}^2) +{_v0}*{_t}*sin ({_Pitch}*3.14/180) +1.52 +{_y0}     #+1.52 is for eye's position
        set {_z} to {_z0}+{_zt}*{_t}
       
        set {_vectorx} to {_x} - {_x.old}           #I prefer use %vector% only if a complex math operation is more easy with an addon
        set {_vectory} to {_y} - {_y.old}
        set {_vectorz} to {_z} - {_z.old}
        set {_norme} to sqrt ( {_vectorx}^2 + {_vectory}^2 + {_vectorz}^2 )
        set {_vectordirx} to {_vectorx} / {_norme}
        set {_vectordiry} to {_vectory} / {_norme}
        set {_vectordirz} to {_vectorz} / {_norme}
       

        set {_RotPitch} to -57.2958* arc sin ({_vectordiry})
        set {_atan2} to {Math}.atan2({_vectordirx} and {_vectordirz})
        set {_RotYaw} to {_atan2}*180/{_pi}
        broadcast "<cyan>%vector pitch of vector {_vectorx}, {_vectory}, {_vectorz}% %vector yaw of vector {_vectorx}, {_vectory}, {_vectorz}%"
        broadcast "<gold>%{_RotPitch}% %{_RotYaw}%"
        #Same pitch and yaw : Yaw between [0,360] and [-180,180]
       
       
       
        set {_block} to block at location ({_x}, {_y}, {_z}) in world "%{map}%"
        if {_block} is air or water or any glass pane or carpet or pressure plate or window glass or painting or item frame or sign or button or flower pot or ladder or torch or redstone torch or wire:
            if {_block} is water:
                if {_predict} is false:
                    if block upward {_block} is air:
                        execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle splash %{_x}% %{_y}+1% %{_z}% 0.1 0 0.1 0 50 force"
                set {_v0} to {_v0}*0.98
                if {_v0} < 5:
                    set {_v0} to 5
            if {_block} is glass pane or window glass:
                if {_predict} is false:
                    set {_blockID} to id of block at location ({_x}, {_y}, {_z}) in world "%{map}%"
                    execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle blockcrack %x-location of {_block}% %y-location of {_block}% %z-location of {_block}% 0.1 0.1 0.1 1 10 force @a %{_blockID} + data of {_block}*4096%"
                    set block at location ({_x}, {_y}, {_z}) in world "%{map}%" to air
                set {_v0} to {_v0}*0.7
            if {_predict} is false:
                execute console command "/tp @e[type=ArmorStand,name=%{_ID}%] %{_x}% %{_y}-1% %{_z}% %{_RotYaw}% ~"
               # execute console command "/entitydata @e[type=ArmorStand,name=%{_ID}%] {Pose:{Head:[%({_RotPitch} -90)*-1%f,0f,0f]}}"
                execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle reddust %{_x}% %{_y}% %{_z}% %{_color}% 1 0 force"
                execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /playsound minecraft:entity.guardian.ambient master @a %{_x}% %{_y}% %{_z}% 0.1 2"
            add 0.01 to {_t}
           
        else:
            if {_v0} > 5:                                   #no bounce if velocity is under 5 cube/s
                set {_bx} to x-location of {_block}
                set {_by} to y-location of {_block}
                set {_bz} to z-location of {_block}
               
                #==============
                #CODE OF BOUNCE
                #NEED HELP HERE
                #==============

               
                #set {_pitch} to ???????                                 #NEED to know the new pitch
                #set {_yaw} to ???????                                   #NEED to know the new yaw
                #================
                #NEED HELP UPWARD
                #================
               
                #Code below = set the coord of the impact as a new shoot location reference with new pitch and yaw              
                set {_v0} to {_v0}*0.8
                set {_x0} to {_x}                                       #{_x}, {_y}, {_z} = Impact location
                set {_y0} to {_y}
                set {_z0} to {_z}
                set {_cosPitch} to cos ({_pitch}*3.14/180)              #Need to know the new {_pitch}
                set {_cosx} to (sin ({_yaw}*3.14/180) )* {_cosPitch}    #Need to know the new {_yaw}
                set {_cosz} to (cos ({_yaw}*3.14/180) )* {_cosPitch}
               
               
               
            else:
                exit loop
        set {_x.old} to {_x}
        set {_y.old} to {_y}
        set {_z.old} to {_z}
        if {_predict} is false:
            if {_t}*100 is divisible by 5:
                wait 1 tick
    if {_predict} is true:
        set block at location ({_x}, {_y}, {_z}) in world "%{map}%" to glowstone
    execute console command "/kill @e[type=ArmorStand,name=%{_ID}%]"

command /predict:                        #the command to do
    trigger:
        Shoot(player,"retardement", 1.4, false)     #set to "true" to predict the trajectory in a 1 tick
        set {map} to event-world                    #DEBUG : I use this on my server
        set {game.timer} to 0                       #DEBUG : I use this on my server

use command "/predict" to see what happen

Anybody who want help : I have made a test server.rar (28Mo) included all addons +the skript +Viaversion for 1.10.x to 1.11.2
The first shoot does not works but all other worked :emoji_wink:
https://drive.google.com/open?id=1AnvC_spWVg2d4TXAPU86cGD5PjsS_Sv-
Thank you very much for your help !!
 
Last edited:
So essentially you want to act as if it "bounced" from the center?
"bounced" from the impact location (in yellow on my picture)
The vector Center>>>Impact can be replace as an infinite line

you can Imagine a normal paper in 2D like in real life,
you draw 2 dot of fresh ink anywhere,
you draw a line in a random direction going through one of two points,
you fold the sheet following this line,
and a third dot appear (cause it's fresh ink) ... I need to know where is this dot in 3D space

I can do it if this code :
code_language.skript:
send "%location at (-1, 0, -1) mirrored at location at (0, 0, 0) in direction of vector 0, 0, -1%"
but this code result (0, 0, -1) ITS WRONG !! I need (1, 0, -1)

Anybody who want help : I have made a test server.rar (28Mo) included all addons +the skript +Viaversion for 1.10.x to 1.11.2
The first shoot does not works but all other worked :emoji_wink:
https://drive.google.com/open?id=1AnvC_spWVg2d4TXAPU86cGD5PjsS_Sv-

EDIT : IF it's possible to rebounce as it's a cube and not a sphere is awesome, but realy more difficult :/ (I guess ... no ?) Maybe by the same operation BUT the vector mirror is rouded to 90 degree
 
Last edited:
this work for upward and downward faces of a block, not horizontal faces :/
Well for horizontal faces wouldnt it be the same y but negative x and z? Assuming its possible to check which block face the arrow lands on
 
i have an other idea (i know how to code 50%)
1) Need to know the neerest round 90 degree of vector between the point of impact and the current position = know the one of all 6 Faces of the impact. # I don't know how to do it
2) Set a mirrored loc at future loc # I can do it
3) found lenght of h (see the picture below) # I don't know
4) set lenght of vector to 2*h # I can do it
5) put the vector to futur loc and apply a translation with vector # I can
6) Done, you get the Real mirrored dot location

It's different from my original idea, same result. What is the most easy way? (idk)


5a44da2601.jpg



@Donut, yes it can work, but how to know the impact faces ?
 
The Block#getFace method gives you the face of the block relative to another. So you could get the block where the arrow is (im not sure if the arrow's location is considered in the block it hits or more where the tail is, if it is just subtract a little from its location) then compare it to the block it hits. Also I couldnt find a getFace expression in the skript docs so youll have to use skript-mirror but it looks like youre familar with it
 
The Block#getFace method gives you the face of the block relative to another. So you could get the block where the arrow is (im not sure if the arrow's location is considered in the block it hits or more where the tail is, if it is just subtract a little from its location) then compare it to the block it hits. Also I couldnt find a getFace expression in the skript docs so youll have to use skript-mirror but it looks like youre familar with it
Interesting,
Nowp, i'm not familar with it, I had download it today haha (and i don't know how to read java)

I have made this :

TO TEST :
code_language.skript:
on script load:
  import "java.lang.System"
  import "java.lang.Math"
  import "java.lang.Integer" #This exist ?

command /rr <integer=1> <integer=1>:
    trigger:
        set {_x} to arg-1
        set {_y} to 100
        set {_z} to arg-2
        set {_world} to player's world
        set {_Mirror.block} to {_world}.getBlockAt( {_x} and {_y} and {_z} )
        broadcast "%{_Mirror.block}%"
        add 1 to {_y}
        set {_Mirror.target} to world.getBlockAt( {_x} and {_y} and {_z} )
        send "%{_Mirror.block}.getFace({_Mirror.target})%"
Upward work 100% without any problem

code_language.skript:
                set {_bx} to x-location of {_block}
                set {_by} to y-location of {_block}
                set {_bz} to z-location of {_block}

                #==============
                #CODE OF BOUNCE
                #NEED HELP HERE
                #==============
                set {_world} to {_shooter}'s world
                set {_Mirror.block} to {_world}.getBlockAt( {_bx} and {_by} and {_bz} )
                broadcast "%{_Mirror.block}%"
                set {_Mirror.old} to {_world}.getBlockAt( {_x.old} and {_y.old} and {_z.old} )
                broadcast "%{_Mirror.old}%"
                set {_Mirror.face} to {_Mirror.block}.getFace({_Mirror.old})
                broadcast "%{_Mirror.face}%"           #YEAH I have NORTH :)
                exit loop
But in a function this work ... and 3 seconds after 1000 lines of [ERROR] appear on my console + the world "{_world}" is DELETED and recreate with a random seed. This appear every time with the function but not with the "/rr"
If i do :
!set {test} to player's world
!send "%{test}.getBlockAt( 0 and 0 and 0 )%"
This work fine, no crash ... so the Function is the problem ?
 
there's also this way to get a block face(in java)
Code:
targetLocation.getBlock().getFace(location.getBlock());

also from the looks of it, u should be able to get what you want using that mirror/reflect expression from biosphere2 @bio

code_language.skript:
%locations% (mirrored|reflected) at %location%[ (in|with) direction [of ]%-vector%]
you just have to calulate what the direction vector is that you want it mirrored at :emoji_wink:
 
Last edited:
Instead of calculating weird distances, you can use basic trigonometry. Calculate the angle between the vector rounded to the closest 90° and your input vector. Then you can get a length using "cos(angle) * 2*PreviousImpact". That'll give you 2h.
 
there's also this way to get a block face(in java)
Code:
targetLocation.getBlock().getFace(location.getBlock());

also from the looks of it, u should be able to get what you want using that mirror/reflect expression from biosphere2 @bio

code_language.skript:
%locations% (mirrored|reflected) at %location%[ (in|with) direction [of ]%-vector%]
you just have to calulate what the direction vector is that you want it mirrored at :emoji_wink:
Thx, this reflected expression is perfectly what I

need but the part "[ (in|with) direction [of ]%-vector%]" is broken, as i said upward in my second reply :

I can do it if this code :
  • send "%location at (-1, 0, -1) mirrored at location at (0, 0, 0) in direction of vector 0, 0, -1%"
but this code result (0, 0, -1) ITS WRONG !! I need (1, 0, -1)

Or maybe i don't kow how to us this part :/ (If i know how to use it, all of my problem can be solved :emoji_astonished:)


Instead of calculating weird distances, you can use basic trigonometry. Calculate the angle between the vector rounded to the closest 90° and your input vector. Then you can get a length using "cos(angle) * 2*PreviousImpact". That'll give you 2h.

Ok now i have debug my world reset (the problem was just a # blabla # blabla)
and i can get the Face of the impact = i can get the vector 90°

code_language.skript:
                set {_bx} to x-location of {_block}
                set {_by} to y-location of {_block}
                set {_bz} to z-location of {_block}

                #==============
                #CODE OF BOUNCE
                #NEED HELP HERE
                #==============
                set {_face} to Face({_world}, {_bx}, {_by}, {_bz}, {_x.old}, {_y.old}, {_z.old})
                broadcast "%{_face}%"
                if "%{_face}%" is "UP":
                    set {_vector90} to vector 0, 1, 0
                if "%{_face}%" is "DOWN":
                    set {_vector90} to vector 0, -1, 0
                if "%{_face}%" is "EAST":
                    set {_vector90} to vector 1, 0, 0
                if "%{_face}%" is "WEST":
                    set {_vector90} to vector -1, 0, 0
                if "%{_face}%" is "SOUTH":
                    set {_vector90} to vector 0, 0, 1
                if "%{_face}%" is "NORTH":
                    set {_vector90} to vector 0, 0, -1

(Yeah this is a progress ^^ ... I hope my {_vector90} are in right direction)

i would like to know the angle between {_vector90} and input vector with basic trigonometry but it's 3D and not 2D and i'm not an expert with that :'(
(cause of the input vector have a yaw and pitch )

the code "angle between %vector% and %vector%" does not work and return "can't understand this expression"
 
If nothing works, you can use skript-mirror and use the following expression to get the angle :
code_language.skript:
{_inputVector}.angle({_vector90})
The thing is, this result is in radians, so the forementioned method would not work. To convert from radians to degrees, use :
code_language.skript:
(180 * {_radians}) / acos(-1)
Note : acos(-1) = π
 
Guys ... it ... IT'S WORKING =D !!

thx everyone !

code_language.skript:
on script load:
  import "java.lang.System"
  import "java.lang.Math"
  import "java.lang.Integer"

 
function Face(world: world, x1: number, y1: number, z1: number, x2: number, y2: number, z2: number) :: string:
    set {_Mirror.block1} to {_world}.getBlockAt( {_x1} and {_y1} and {_z1} )
    set {_Mirror.block2} to {_world}.getBlockAt( {_x2} and {_y2} and {_z2} )
    set {_mirror.face} to {_Mirror.block1}.getFace({_Mirror.block2})
    return "%{_mirror.face}%"

function Shoot(shooter: player, type: string, force: number, predict: boolean):
    set {_world} to {_shooter}'s world
    set {_pi} to {Math}.PI!
    set {_x0} to x-location of {_shooter}
    set {_y0} to y-location of {_shooter}
    set {_z0} to z-location of {_shooter}
    set {_v0} to 17.7*{_force}              #17.7 is my own chosen number randomly for the velocity
    set {_pitch} to pitch of {_shooter}*-1  #The rotation of player
    set {_yaw} to yaw of {_shooter}*-1
    set {_cosPitch} to cos ({_pitch}*3.14/180)
    set {_cosx} to (sin ({_yaw}*3.14/180) )* {_cosPitch}
    set {_cosz} to (cos ({_yaw}*3.14/180) )* {_cosPitch}
    set {_t} to 0
    set {_colorRandom} to "1 0 0"
    set {_RotPitch} to {_pitch}             #The initial rotation of projectile
    set {_RotYaw} to {_yaw}

    if {_predict} is false:
        set {_ID} to "Shoot_%{_shooter}%_%{game.timer}%"
        run {_shooter} command "/summon ArmorStand %x-location of {_shooter}% %y-location of {_shooter}% %z-location of {_shooter}% {CustomName:""%{_ID}%"",Tags:[""Shoot"",""Shoot_%{_shooter}%""],NoGravity:1b,Small:1b,Marker:1b,Invisible:1,Invulnerable:0,DisabledSlots:2039583}" as op
        loop all armor stands:
            loop-entity's name is "%{_ID}%"
            set {_entity} to loop-entity    #not used for now
            execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /playsound minecraft:entity.irongolem.attack master @a %{_x0}% %{_y0}% %{_z0}% 1 1"
            if "%{player::*}%" contain "%{_shooter}%":
                execute console command "/mycmd add %{_shooter}% stats.use.%{_type}% 1"
            if "%{_type}%" is "fragmentation":
                set helmet of loop-entity to yellow dye
                set {_color} to "0 1 0"
            if "%{_type}%" is "retardement":
                set helmet of loop-entity to red dye
                set {_color} to "0 0 0"
            if "%{_type}%" is "chimique":
                set helmet of loop-entity to light green dye
                set {_color} to "0.27 0.77 0.18"
            if "%{_type}%" is "flame":
                set helmet of loop-entity to orange dye
                set {_color} to "1 0.5 0.1"
            if "%{_type}%" is "implosion":
                set helmet of loop-entity to light blue dye
                set {_color} to "0.1 0.9 1"
            if {_color} is not set:
                set {_color} to "1 1 1"
                
    loop 900 times:
        set {_xt} to {_v0}* {_cosx}         #I put this here cause of the speed {_v0} can be modified (exemple: in water)
        set {_zt} to {_v0}* {_cosz}
        set {_x} to {_x0}+{_xt}*{_t}
        set {_y} to (-12/2*{_t}^2) +{_v0}*{_t}*sin ({_Pitch}*3.14/180) +1.52 +{_y0}     #+1.52 is for eye's position
        set {_z} to {_z0}+{_zt}*{_t}
        
        set {_vectorx} to {_x} - {_x.old}           #I prefer use %vector% only if a complex math operation is more easy with an addon
        set {_vectory} to {_y} - {_y.old}
        set {_vectorz} to {_z} - {_z.old}
        set {_norme} to sqrt ( {_vectorx}^2 + {_vectory}^2 + {_vectorz}^2 )
        set {_vectordirx} to {_vectorx} / {_norme}
        set {_vectordiry} to {_vectory} / {_norme}
        set {_vectordirz} to {_vectorz} / {_norme}
        

        set {_RotPitch} to -57.2958* arc sin ({_vectordiry})
        set {_atan2} to {Math}.atan2({_vectordirx} and {_vectordirz})
        set {_RotYaw} to {_atan2}*180/{_pi}
        #broadcast "<cyan>%vector pitch of vector {_vectorx}, {_vectory}, {_vectorz}% %vector yaw of vector {_vectorx}, {_vectory}, {_vectorz}%"
        #broadcast "<gold>%{_RotPitch}% %{_RotYaw}%"
        #Same pitch and yaw : Yaw between [0,360] and [-180,180]
        
        
        set {_block} to block at location ({_x}, {_y}, {_z}) in world "%{map}%"
        if {_block} is air or water or any glass pane or carpet or pressure plate or window glass or painting or item frame or sign or button or flower pot or ladder or torch or redstone torch or wire:
            if {_block} is water:
                if {_predict} is false:
                    if block upward {_block} is air:
                        execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle splash %{_x}% %{_y}+1% %{_z}% 0.1 0 0.1 0 50 force"
                set {_v0} to {_v0}*0.98
                if {_v0} < 5:
                    set {_v0} to 5
            if {_block} is glass pane or window glass:
                if {_predict} is false:
                    set {_blockID} to id of block at location ({_x}, {_y}, {_z}) in world "%{map}%"
                    execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle blockcrack %x-location of {_block}% %y-location of {_block}% %z-location of {_block}% 0.1 0.1 0.1 1 10 force @a %{_blockID} + data of {_block}*4096%"
                    set block at location ({_x}, {_y}, {_z}) in world "%{map}%" to air
                set {_v0} to {_v0}*0.7
            if {_predict} is false:
                execute console command "/tp @e[type=ArmorStand,name=%{_ID}%] %{_x}% %{_y}-1% %{_z}% %{_RotYaw}% ~"
               # execute console command "/entitydata @e[type=ArmorStand,name=%{_ID}%] {Pose:{Head:[%({_RotPitch} -90)*-1%f,0f,0f]}}"
                execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle reddust %{_x}% %{_y}% %{_z}% %{_color}% 1 0 force"
                execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /playsound minecraft:entity.guardian.ambient master @a %{_x}% %{_y}% %{_z}% 0.1 2"
            add 0.01 to {_t} 
        else:
            if {_v0} > 5:                                   #no bounce if velocity is under 5 cube/s
                #broadcast "impact: %{_x}% %{_y}% %{_z}%"
                #broadcast "velocity: %{_v0}% angle: %{_pitch}% %{_yaw}%"
                set {_bx} to x-location of {_block}
                set {_by} to y-location of {_block}
                set {_bz} to z-location of {_block}
                set {_inputVector} to vector {_x.old}-{_x}, {_y.old}-{_y}, {_z.old}-{_z}
                #==============
                #CODE OF BOUNCE
                #NEED HELP HERE
                #==============
                set {_face} to Face({_world}, {_bx}, {_by}, {_bz}, {_x.old}, {_y.old}, {_z.old})
                if "%{_face}%" is "<none>":
                    if {_RotPitch} > 0:
                        set {_face} to "UP"
                    else:
                        set {_face} to "DOWN"
                if "%{_face}%" is "UP":
                    set {_vector90} to vector 0, 1, 0
                if "%{_face}%" is "DOWN":
                    set {_vector90} to vector 0, -1, 0
                if "%{_face}%" is "EAST":
                    set {_vector90} to vector 1, 0, 0
                if "%{_face}%" is "WEST":
                    set {_vector90} to vector -1, 0, 0
                if "%{_face}%" is "SOUTH":
                    set {_vector90} to vector 0, 0, 1
                if "%{_face}%" is "NORTH":
                    set {_vector90} to vector 0, 0, -1
                if "%{_face}%" is "SOUTH_WEST":
                    set {_vector90} to vector -1, 0, 1
                if "%{_face}%" is "SOUTH_EAST":
                    set {_vector90} to vector 1, 0, 1
                if "%{_face}%" is "NORTH_WEST":
                    set {_vector90} to vector -1, 0, -1
                if "%{_face}%" is "NORTH_EAST":
                    set {_vector90} to vector 1, 0, -1
                set {_angle} to {_inputVector}.angle({_vector90}) *180/{_pi}
                set {_length} to 2* vector length of {_inputVector}
                set {_length} to {_length} * cos({_angle})
                set {_vector90} to {_vector90} normalized ** {_length}
                set {_mirror1} to location ({_x.old}, {_y.old}, {_z.old}) in world "%{_world}%" mirrored at location ({_x}, {_y}, {_z}) in world "%{_world}%"
                set {_mirror2} to {_mirror1} ~ {_vector90}      #Offset a location by a vector : %location% ~ %vector%
                set {_VectorRebound} to vector x-location of {_mirror2} - {_x}, y-location of {_mirror2} - {_y}, z-location of {_mirror2} - {_z}
                
                #loop 90 times:
                #    execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle reddust %{_x}% %{_y}% %{_z}% 1 0 0 1 0 force"
                #    execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle reddust %{_x.old}% %{_y.old}% %{_z.old}% 0 1 0 1 0 force"
                #    execute console command "/execute @e[type=ArmorStand,name=%{_ID}%] ~ ~ ~ /particle reddust %x-location of {_mirror2}% %y-location of {_mirror2}% %z-location of {_mirror2}% 0 0 1 1 0 force"
                #    wait a tick
                    
                set {_pitch} to vector pitch of {_VectorRebound}
                set {_yaw} to vector yaw of {_VectorRebound}
                set {_pitch} to {_pitch} *-1
                set {_yaw} to {_yaw} *-1
                #broadcast "<cyan>%{_pitch}% %{_yaw}%"
                #================
                #NEED HELP UPWARD
                #================
                
                #Code below = set the coord of the impact as a new shoot location reference with new pitch and yaw               
                set {_v0} to {_v0}*0.8                               #change to 0.2 for normal rebound
                set {_x0} to {_x}                                       #{_x}, {_y}, {_z} = Impact location
                set {_y0} to {_y} -1.52
                set {_z0} to {_z}
                set {_cosPitch} to cos ({_pitch}*3.14/180)
                set {_cosx} to (sin ({_yaw}*3.14/180) )* {_cosPitch}
                set {_cosz} to (cos ({_yaw}*3.14/180) )* {_cosPitch}
                set {_t} to 0.05
                set {_RotPitch} to {_pitch}
                set {_RotYaw} to {_yaw}
                set {_colorRandom} to a random element out of "1 1 1", "0 1 0" and "0 0 1"
            else:
                exit loop
        execute console command "/execute @r ~ ~ ~ /particle reddust %{_x}% %{_y}% %{_z}% %{_colorRandom}% 1 0 force"
        set {_x.old} to {_x}
        set {_y.old} to {_y}
        set {_z.old} to {_z}
        if {_predict} is false:
            if {_t}*100 is divisible by 5:
                wait 1 tick
    if {_predict} is true:
        set block at location ({_x}, {_y}, {_z}) in world "%{map}%" to glowstone
    execute console command "/kill @e[type=ArmorStand,name=%{_ID}%]"

command /predict:
    trigger:
        loop 10 times:
            Shoot(player,"retardement", 1.4, true)      #set to "true" to predict the trajectory in a 1 tick
            wait a second
        #set {map} to event-world                    #DEBUG : I use this on my server
        #set {game.timer} to 0                       #DEBUG : I use this on my server

You can try this code, (parameter for a lot of rebounce with a lot of color ^^), if you don't have all plugins use this pack:
Anybody who want help : I have made a test server.rar (28Mo) included all addons +the skript +Viaversion for 1.10.x to 1.11.2
The first shoot does not works but all other worked :emoji_wink:
https://drive.google.com/open?id=1AnvC_spWVg2d4TXAPU86cGD5PjsS_Sv-

and a little bonus bonus, the code for correct mirroring "location at (-1, 0, -1) mirrored at location at (0, 0, 0) in direction of vector 0, 0, -1" of @bi0
code_language.skript:
on script load:
  import "java.lang.System"
  import "java.lang.Math"
  import "java.lang.Integer"


command /mirror <integer= 1> <integer= 0> <integer= 0>:
    trigger:
        set {_pi} to {Math}.PI!
        set {_vector90} to vector arg-1, arg-2, arg-3
        set {_inputVector} to vector -1, 0, -1              #=direction of the bullet inverted
        set {_angle} to {_inputVector}.angle({_vector90}) *180/{_pi}
        set {_length} to 2* vector length of {_inputVector}
        set {_length} to {_length} * cos({_angle})

        set {_vector90} to {_vector90} normalized ** {_length}
        set {_mirror1} to location (-1, 0, -1) in world "%event-world%" mirrored at location (0, 0, 0) in world "%event-world%"
        set {_vectorMirror1} to vector x-location of {_mirror1}, y-location of {_mirror1}, z-location of {_mirror1}
        set {_mirror2} to {_vectorMirror1} ++ {_vector90}
        broadcast "angle: %{_angle}% cos: %cos({_angle})% length of InputVector: %vector length of {_inputVector}% length: %{_length}%"
        broadcast "<cyan>mirror : %{_mirror2}%"

I have against some problem with my trajectory but i have learn a lot of thing. I will try to solve them alone.
 

Attachments

  • ballistic.sk
    12.2 KB · Views: 323
  • Like
Reactions: Sashie
Instead of using 3.14 as an approximate for pi, you can make an option like this
code_language.skript:
options:
    pi : acos(-1)
 
Instead of using 3.14 as an approximate for pi, you can make an option like this
code_language.skript:
options:
    pi : acos(-1)
ok

code_language.skript:
set {_pi} to {Math}.PI!
Does not return a good Pi ?
 
Status
Not open for further replies.