Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //funny thingy to find angles
- //aka what yaw/yaw/pitch do I need in order to throw a pearl
- //such that i get teleported into the dragon's body at such a precision to give me many velocity
- //in a direction that lets me shoot a mach 20 arrow into the dragon, killing it instantly
- //
- //This utilizes a sprint jump velocity desync between the server/client in order to fine-tune the exact pearl velocity
- //this lets us target extremely precise spots without adjusting our position at all
- //I think you can get within 0.001m pretty consistently. Which is pretty insane if you know how pearls work
- //
- //i also realize that this code is super inefficient
- //and can be vastly improved with a bit of trig
- //but I didn't pay attention in math class and turns out computers are REALLY good at math anyway
- //
- //you'll have to find your own dragon information to get it to run
- //but tbh if you can't obtain that you'll probably have a hard time anyway sorry
- //I also havent tested the initClientVel/initServerVel thingies because I didn't need them soo enter at your own risk
- //
- //in order to execute in-game you have to look in server yaw for one tick
- //then turn and sprint jump towards client yaw/pitch for one tick
- //and then throw a pearl
- class InstaKillinator {
- ///execute in minecraft:the_end run tp @s 44.10 91.00 -1.76 89.85 -22.41
- //starting pos
- static Vec3 initPos = new Vec3(46.11266719320051, 91.00, 5.495603971894525E-15);
- //server velocity right before throw tick(y has no effect because jump velocity).
- static Vec3 initServerVel = new Vec3(0.0,0,0.0);
- //client velocity during jump tick(y has no effect because you're assumed on the ground).
- static final Vec3 initClientVel = new Vec3(0,0,0.0);
- //random offset from pearl rng
- static final Vec3 pearlRNG = new Vec3(0,0,0);
- //dragon midpoint spot
- static Vec3 dBodyPos = new Vec3(44.18664241259023, 124.07306706667013, -13.115441869969073);
- //dragon neck hitbox
- static Vec3 dNeckNegPos = new Vec3(38.19537725378829, 123.95384732909187, -17.7381524500122);
- static Vec3 dNeckPosPos = new Vec3(41.19537725378829, 126.95384732909187, -17.7381524500122);
- //minimum velocity we want from this throw
- static final double minVel = 440.0;
- //increases the range of angles checked because i'm paranoid abt rounding
- //does this by increasing the size of the target area, while still not accepting speeds below the minVel
- static final double targetBuffer = 0.001;
- //how precise to iterate through our magic search area of angles
- //i wonder what it would look like to plot these on a 3d graph
- static final float serverYawStep = .1f;
- static final float clientYawStep = .1f;
- static final float clientPitchStep = .1f;
- public static void main(String[] args) {
- // our x,y plane will look like z,-x
- // (-Math.sin(f)), (Math.cos(f))
- double maxDistForVel = 8/minVel;
- double maxTargetDist = maxDistForVel + targetBuffer;
- initPos = initPos.add(initClientVel.x, 0, initClientVel.z); //incoming velocity essentially only offsets our base position
- initServerVel.add(pearlRNG); //pearl rng is just disguised server velocity
- double initDragonAngle = Math.atan2(-(dBodyPos.x - initPos.x), (dBodyPos.z - initPos.z)) / (Math.PI / 180); //angle towards dargon
- double initDragonDistance = Math.sqrt((dBodyPos.x - initPos.x) * (dBodyPos.x - initPos.x) + (dBodyPos.z - initPos.z) * (dBodyPos.z - initPos.z)); //dist to dragon
- //length of our server velocity vector in the direction of our dragon angle
- double serverVelDragonLength = Math.sqrt(initServerVel.x * initServerVel.x + initServerVel.z * initServerVel.z) * Math.cos(Math.atan2(-initServerVel.x, initServerVel.z) - initDragonAngle * (Math.PI / 180));
- //two positions we can jump to that change our angle to the dragon the most
- Vec3 posJumpBound = jumpOffset((float)(initDragonAngle + 90.0));
- Vec3 negJumpBound = jumpOffset((float)(initDragonAngle - 90.0));
- //and the angles they yield in relation to the most extreme section of the dragon tickle area
- //aka all possible pearl angles that could possibly hit the tickle area fall between these
- //it's a super large range but i don't know the math to make it smaller
- double minVelAngle = (Math.atan2(-(dBodyPos.x - (maxTargetDist * Math.sin(initDragonAngle - 90) * (Math.PI / 180)) - posJumpBound.x), (dBodyPos.z + (maxTargetDist * Math.cos(initDragonAngle - 90) * (Math.PI / 180)) - posJumpBound.z)) / (Math.PI / 180));
- double maxVelAngle = (Math.atan2(-(dBodyPos.x - (maxTargetDist * Math.sin(initDragonAngle + 90) * (Math.PI / 180)) - negJumpBound.x), (dBodyPos.z + (maxTargetDist * Math.cos(initDragonAngle + 90) * (Math.PI / 180)) - negJumpBound.z)) / (Math.PI / 180));
- //start searching angles....
- clientPitchLoop: for(float clientPitch = -90f; clientPitch <= 90f; clientPitch+= clientPitchStep){
- //approximate pearl upwards trajectory at this pitch in order to see if it can reach dragon
- //can't know exactly cuz sin/cos coarseness of x/z, but hopefully this is good enough
- double pearlPosY = initPos.y + 1.9399999901652336; //eye position + jump height but butchered by floats
- float pearlDirY = -BoyKisser.MCsin(clientPitch * BoyKisser.RAD());
- double pearlTestVelY = pearlDirY * 1.5f + 0.33319999363422365 + 0.0001; //+0.0001 so we don't miss anything from coarseness(i think that's big enough)
- double pearlTestPosY = pearlPosY;
- int trajectoryTickTime = 0;
- while(pearlTestVelY >= 0 && pearlTestPosY < dBodyPos.y - 0.3f){ //tick 1d pearl pog (no need for real collision cuz it's one infinite surface)
- pearlTestPosY+= pearlTestVelY;
- pearlTestVelY = (pearlTestVelY * .99f) - .03f; //air resistance/gravity
- trajectoryTickTime++;
- }
- if(pearlTestPosY < dBodyPos.y - 0.3f) break; //we fell too short, give up. Don't even try any more pitches since going lower isn't going to help.
- //we know we can reach the dragon height at this pitch, now screen for horizontal distance
- float pearlPitchFactor = BoyKisser.MCcos(clientPitch * BoyKisser.RAD());
- //find the furthest we can possibly throw the pearl at this pitch
- double pearlTestVelH = 1.5f * pearlPitchFactor + serverVelDragonLength + 0.18200001f;
- double pearlTestPosH = 0.3274000153899195;
- for(int ticks = 0; ticks < trajectoryTickTime; ticks++){ //tick 1d pearl pt.2 horizontal edition (until we hit dragon height)
- pearlTestPosH+= pearlTestVelH;
- pearlTestVelH*= .99f;
- }
- if(pearlTestPosH < initDragonDistance - maxTargetDist) continue; // pearl didn't go far enough even with perfect conditions. Try the next pitch
- //find the closest we can possibly throw the pearl at this pitch
- pearlTestVelH = 1.5f * pearlPitchFactor + serverVelDragonLength - 0.18200001f;
- pearlTestPosH = -0.3274000153899195;
- for(int ticks = 0; ticks < trajectoryTickTime; ticks++){ //tick 1d pearl pt.3 sucky horizontal edition(until we hit dragon height)
- pearlTestPosH+= pearlTestVelH;
- pearlTestVelH*= .99f;
- }
- if(pearlTestPosH > initDragonDistance + maxTargetDist) continue; // pearl went too far even with perfect conditions. Try the next pitch
- //at this point we have a reasonably vetted pitch that could potentially hit the dragon.
- //which means we can now start iterating over server yaws.
- //any angle here is fine since they're just acting as small offsets
- for(float serverYaw = 0; serverYaw <= 360f; serverYaw+= serverYawStep){
- //calculate server velocity from sprint jumping towards this direction(plus starting server vel)
- //and no need to deal with movement acceleration because server doesn't care and nobody asked
- Vec3 serverVel = jumpVelocity(serverYaw);
- serverVel.x+= initServerVel.x;
- serverVel.z+= initServerVel.z;
- //one tick of gravity/resistance because I'm too lazy to deal with lagged pearls in playback
- serverVel.x*= 0.91f;
- serverVel.y = (serverVel.y - 0.08) * 0.98f;
- serverVel.z*= 0.91f;
- //we can now use this vector as well as our min/maxVelAngles to construct a range of possible client yaws
- //that after being affected by the serverVel and position offsets have potential to hit the tickle area
- //there's a chance these min/maxs could be undefined when the horizontal velocity is less than server velocity
- //but it doesn't seem to break anything so idc
- float clientYawMin = (float)(startingAngleFromOffset(serverVel.x, serverVel.z, minVelAngle * (Math.PI / 180), 1.5f * pearlPitchFactor) / (Math.PI / 180));
- float clientYawMax = (float)(startingAngleFromOffset(serverVel.x, serverVel.z, maxVelAngle * (Math.PI / 180), 1.5f * pearlPitchFactor) / (Math.PI / 180));
- //now we can iterate through these yaws
- //and finally start bruteforcing pearls to see if we get any hits
- //everything up to here was just getting okayish bounds
- for(float clientYaw = clientYawMin; clientYaw < clientYawMax; clientYaw+= clientYawStep){
- //starting state:
- Vec3 pearlPos = jumpOffset(clientYaw); //pearl start pos
- pearlPos.y+= 1.5200000032782555; //eye height thingie
- Vec3 pearlVel = new Vec3(
- -BoyKisser.MCsin(clientYaw * BoyKisser.RAD()) * pearlPitchFactor,
- pearlDirY,
- BoyKisser.MCcos(clientYaw * BoyKisser.RAD()) * pearlPitchFactor
- ); //initial direction
- double l = (float)Math.sqrt((pearlVel.x * pearlVel.x + pearlVel.y * pearlVel.y + pearlVel.z * pearlVel.z));
- pearlVel.x = (pearlVel.x / l * (double)1.5f) + serverVel.x;
- pearlVel.y = (pearlVel.y / l * (double)1.5f) + serverVel.y;
- pearlVel.z = (pearlVel.z / l * (double)1.5f) + serverVel.z; //normalization cuz coarseness(?), speed adjustment, and server velocity factor
- int ticks = 0;
- while(true){
- ticks++;
- double pearlIntendedX = pearlPos.x + pearlVel.x;
- double pearlIntendedY = pearlPos.y + pearlVel.y;
- double pearlIntendedZ = pearlPos.z + pearlVel.z;
- if(pearlIntendedY >= dBodyPos.y - 0.3f) break; //we hit the dragon stop ticking
- if(pearlVel.y < 0) break clientPitchLoop; //turns out we couldn't hit the dragon, give up
- pearlPos.set(pearlIntendedX, pearlIntendedY, pearlIntendedZ); //update pos
- pearlVel.x*= .99f;
- pearlVel.y = pearlVel.y * .99f - .03f;
- pearlVel.z*= .99f; //air resistance/gravity
- }
- //pearlPos should now be the position the player will be teleported to(tick before it collides)
- //so we can just do some logic on it as if it was the player
- double playerDragonDistX = pearlPos.x - dBodyPos.x;
- double playerDragonDistZ = pearlPos.z - dBodyPos.z;
- double playerDragonDist = playerDragonDistX * playerDragonDistX + playerDragonDistZ * playerDragonDistZ;
- if(playerDragonDist > maxDistForVel * maxDistForVel) continue; //we missed the tickle area go next.
- //calculate exact velocity it gives us to see if it can hit a hitbox.
- double dragonVelBoostX = playerDragonDistX / playerDragonDist * 8.0;
- double dragonVelBoostZ = playerDragonDistZ / playerDragonDist * 8.0;
- dragonVelBoostZ*= .91f;
- dragonVelBoostX*= .91f;
- //collision time :heart_eyes:
- //only going to check x and z, y should be mostly guaranteed
- //and also only for the neck because that's all we can reach without like 100 y velocity which uhhhh yeah
- //also probably misses some things that could barely be hit with a little bit of aiming, but meh
- //you get enough results regardless
- CollisionTest:
- {
- if (dragonVelBoostX > 0) {
- double hitP = (dNeckNegPos.x - pearlPos.x) / dragonVelBoostX; //% along X axis where it would hit x- side
- double hitZ = pearlPos.z + hitP * dragonVelBoostZ; //coord where it'd hit on Z
- if (0.0 < hitP && hitP < 1.0 && dNeckNegPos.z - 1.0E-7 < hitZ && hitZ < dNeckPosPos.z + 1.0E-7) {
- break CollisionTest; //hit
- }
- }
- if (dragonVelBoostX < 0) {
- double hitP = (dNeckPosPos.x - pearlPos.x) / dragonVelBoostX; //% along X axis where it would x+ side
- double hitZ = pearlPos.z + hitP * dragonVelBoostZ; //coord where it'd hit on Z
- if (0.0 < hitP && hitP < 1.0 && dNeckNegPos.z - 1.0E-7 < hitZ && hitZ < dNeckPosPos.z + 1.0E-7) {
- break CollisionTest; //hit
- }
- }
- if (dragonVelBoostZ > 0) {
- double hitP = (dNeckNegPos.z - pearlPos.z) / dragonVelBoostZ; //% along Z axis where it would hit z- side
- double hitX = pearlPos.x + hitP * dragonVelBoostX; //coord where it'd hit on X
- if (0.0 < hitP && hitP < 1.0 && dNeckNegPos.x - 1.0E-7 < hitX && hitX < dNeckPosPos.x + 1.0E-7) {
- break CollisionTest; //hit
- }
- }
- if (dragonVelBoostZ < 0) {
- double hitP = (dNeckPosPos.z - pearlPos.z) / dragonVelBoostZ; //% along Z axis where it would z+ side
- double hitX = pearlPos.x + hitP * dragonVelBoostX; //coord where it'd hit on X
- if (0.0 < hitP && hitP < 1.0 && dNeckNegPos.x - 1.0E-7 < hitX && hitX < dNeckPosPos.x + 1.0E-7) {
- break CollisionTest; //hit
- }
- }
- continue;
- }
- double velAngle = Math.atan2(-dragonVelBoostX, dragonVelBoostZ) / BoyKisser.RAD();
- System.out.printf("hit in %d ticks at (%f,%f,%f) at dist %f with %f speed(%f, %f) at angle %f - serverYaw: %f, clientYaw: %f, clientPitch: %f%n", ticks, pearlPos.x, pearlPos.y, pearlPos.z, Math.sqrt(playerDragonDist), 8.0/Math.sqrt(playerDragonDist), dragonVelBoostX, dragonVelBoostZ, velAngle, serverYaw, clientYaw, clientPitch);
- }
- }
- }
- }
- //returns the starting position, offset by one tick's worth of movement
- //assuming starting on the ground with 0 momentum, and inputting forward, sprint, jump in whatever yaw
- //also assumes no collision and no hitbox. Just praying that hitbox float stuff doesn't become an issue
- static Vec3 jumpOffset(float yaw){
- //start with just jump velocity
- Vec3 offsetVel = jumpVelocity(yaw);
- //acceleration from holding forward
- offsetVel.x+= -((double)0.98f * (double)0.13000001f) * BoyKisser.MCsin(yaw * BoyKisser.RAD());
- offsetVel.z+= ((double)0.98f * (double)0.13000001f) * BoyKisser.MCcos(yaw * BoyKisser.RAD());
- //ez now just add to initial position and send her home
- return initPos.add(offsetVel);
- }
- //returns velocity from sprint jumping towards the specified yaw
- static Vec3 jumpVelocity(float yaw){
- return new Vec3(
- -BoyKisser.MCsin(yaw * BoyKisser.RAD()) * 0.2f,
- 0.42f,
- BoyKisser.MCcos(yaw * BoyKisser.RAD()) * 0.2f
- );
- }
- //i have no idea what to call this but it's a random function I pulled out my rear end no idea if it has a name/meaning
- //the idea is you can take an angle you want, desiredAngle
- //and solve for the angle B of a vector with length startLength
- //such that adding this vector to the offset vector provided yields our desiredAngle
- //it then just returns this angle B
- //also confines to minecraft coordinates X,Z- not necessarily x,y
- static double startingAngleFromOffset(double offsetX, double offsetZ, double desiredAngle, double startLength){
- //B = A - asin( (z*cos(A)-y*sin(A)) / n )
- return desiredAngle - Math.asin((-offsetZ * Math.sin(desiredAngle) - offsetX * Math.cos(desiredAngle)) / startLength);
- }
- }
- class BoyKisser { //silly math stuff to mimic how minecraft handles it
- //lookup table used by minecraft trigonometry functions
- private static final float[] MCsins = constructSines();
- //radian value thingy to make my life easier
- //or smthn ig idk what a math is
- private static final float RAD = ((float)Math.PI / 180);
- //builds the sin table from minecraft
- public static float[] constructSines(){
- float[] MCsins = new float[65536];
- for (int i = 0; i < 65536; ++i) {
- MCsins[i] = (float)Math.sin((double)i * Math.PI * 2.0 / 65536.0);
- }
- return MCsins;
- }
- //returns the sin value of a given radian
- //but using minecraft's quirky table
- public static float MCsin(float f) {
- return MCsins[(int)(f * 10430.378f) & 0xFFFF];
- }
- //returns the cos value of a given radian
- //but also using minecraft's quirky table
- public static float MCcos(float f) {
- return MCsins[(int)(f * 10430.378f + 16384.0f) & 0xFFFF];
- }
- //returns the funky radian value?
- public static float RAD(){
- return RAD;
- }
- }
- class Vec3{
- //:3
- public double x;
- public double y;
- public double z;
- public Vec3(){
- this.x = 0.0;
- this.y = 0.0;
- this.z = 0.0;
- }
- public Vec3(double x, double y, double z){
- this.x = x;
- this.y = y;
- this.z = z;
- }
- public String toString(){
- return String.format("(%.3f, %.3f, %.3f)", this.x, this.y, this.z);
- }
- public void set(double x, double y, double z){
- this.x = x;
- this.y = y;
- this.z = z;
- }
- public Vec3 add(Vec3 a){
- return new Vec3(this.x + a.x, this.y + a.y, this.z + a.z);
- }
- public Vec3 add(double x, double y, double z){
- return new Vec3(this.x + x, this.y + y, this.z + z);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment