├── contact.html ├── css └── style.css ├── img ├── 4thres.jpg ├── 4thres_letters.jpg ├── 4thres_letterslines.jpg ├── car.png ├── car_pin.png ├── car_pin_outline.png ├── car_pin_outline_blk.png ├── car_pin_outline_blue.png ├── car_pin_outline_org.png ├── car_small.png ├── circle.png ├── circle_active.png ├── circle_grey.png ├── favicon.png └── resetbtn.png ├── index.html ├── js ├── main.js └── math.js ├── license.md └── readme.md /contact.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | PUBG Plane Path 4 | 5 | 8 | 18 | 19 | 20 |
21 |
22 | Return to App

23 | Plane Path is still in beta, so please email or tweet me any bug reports or feedback.
24 | twitter: @stiknork
25 |
26 | 33 |
34 |
35 | 36 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | background-color: #333; 4 | } 5 | 6 | a 7 | { 8 | color: white; 9 | } 10 | 11 | #container 12 | { 13 | min-width: 1024px; 14 | width: 75%; 15 | margin-left: auto; 16 | margin-right: auto; 17 | height: 96%; 18 | } 19 | 20 | #sndcontainer 21 | { 22 | margin-left:auto; 23 | margin-right:auto; 24 | } 25 | 26 | #canvasContainer 27 | { 28 | position: relative; 29 | } 30 | 31 | #mainCanvas 32 | { 33 | position: absolute; 34 | top: 0px; 35 | left: 0px; 36 | } 37 | 38 | #bgCanvas 39 | { 40 | position: absolute; 41 | top: 0px; 42 | left: 0px; 43 | } 44 | 45 | #leftBar 46 | { 47 | position: relative; 48 | float: left; 49 | color: white; 50 | width: 20%; 51 | height: 100%; 52 | text-align: center; 53 | } 54 | 55 | #contact 56 | { 57 | color: white; 58 | width: 50%; 59 | margin-left: auto; 60 | margin-right: auto; 61 | font-size: 18px; 62 | text-align: center; 63 | margin-top: 25%; 64 | } 65 | 66 | #reset 67 | { 68 | margin-left: auto; 69 | margin-right: auto; 70 | width: 90%; 71 | height: 10.5%; 72 | cursor: pointer; 73 | margin-bottom: 10px; 74 | background-size: cover; 75 | background-image: url("../img/resetbtn.png"); 76 | border: 4px solid #000000; 77 | } 78 | 79 | #calculating 80 | { 81 | margin-top: 10px; 82 | /*display: none;*/ 83 | font-size: 20px; 84 | } 85 | 86 | #error 87 | { 88 | margin-top: 10px; 89 | color: red; 90 | font-size: 20px; 91 | } 92 | 93 | #legend 94 | { 95 | font-size: 1.8vh; 96 | display: none; 97 | text-align: left; 98 | width: 90%; 99 | height: 15%; 100 | } 101 | 102 | .legendline 103 | { 104 | margin-left: auto; 105 | margin-right: auto; 106 | margin-top: 8px; 107 | width: 92%; 108 | height: 22px; 109 | } 110 | 111 | #orangeblock 112 | { 113 | float: left; 114 | width: 22px; 115 | height: 22px; 116 | border: 2px solid #000000; 117 | background-color: rgba(255, 200, 0, 1.0); 118 | margin-right: 5px; 119 | } 120 | 121 | #blueblock 122 | { 123 | float: left; 124 | width: 22px; 125 | height: 22px; 126 | border: 2px solid #000000; 127 | background-color: rgba(60, 100, 200, 1.0); 128 | margin-right: 5px; 129 | } 130 | 131 | .legendtext 132 | { 133 | padding-top: 6px; 134 | height: 20px; 135 | } 136 | 137 | #gameclock 138 | { 139 | margin-top: 15%; 140 | font-size: 6.0vh; 141 | } 142 | 143 | #lowerclock 144 | { 145 | font-size: 1.2vh; 146 | } 147 | 148 | #car 149 | { 150 | float: left; 151 | margin-top: 5px; 152 | margin-right: 5px; 153 | } 154 | 155 | #healthbar 156 | { 157 | margin-top: 15%; 158 | width: 90%; 159 | height: 3.64%; 160 | } 161 | 162 | #healthtext 163 | { 164 | margin-top: 3%; 165 | margin-bottom: 10%; 166 | font-size: 1.2vh 167 | } 168 | 169 | progress[value] { 170 | /* Reset the default appearance */ 171 | -webkit-appearance: none; 172 | appearance: none; 173 | } 174 | 175 | progress[value]::-webkit-progress-bar { 176 | background-color: #000; 177 | border: 1px solid #eee; 178 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset; 179 | } 180 | 181 | /*progress[value]::-webkit-progress-value { 182 | background-color: #FFF; 183 | }*/ 184 | 185 | progress[value].lowhp::-webkit-progress-value { 186 | background-color: #FE0000; 187 | } 188 | 189 | progress[value].lowishhp::-webkit-progress-value { 190 | background-color: #d94545; 191 | } 192 | 193 | progress[value].medhp::-webkit-progress-value { 194 | background-color: #de756f; 195 | } 196 | 197 | progress[value].highhp::-webkit-progress-value { 198 | background-color: #e9a3a3; 199 | } 200 | 201 | progress[value].veryhighhp::-webkit-progress-value { 202 | background-color: #FFFFFF; 203 | } 204 | 205 | #circlecontainer 206 | { 207 | margin-top: 10%; 208 | } 209 | 210 | .activecircle 211 | { 212 | position: relative; 213 | margin-top: 10px; 214 | width: 90%; 215 | height: 8.5%; 216 | margin-left: auto; 217 | margin-right: auto; 218 | background-size: cover; 219 | background-image: url("../img/circle.png"); 220 | border: 2px solid rgba(255, 200, 0, 1.0); 221 | 222 | font-size: 3.3vh; 223 | font-weight: bold; 224 | } 225 | 226 | .circle 227 | { 228 | position: relative; 229 | margin-top: 10px; 230 | width: 90%; 231 | height: 8.5%; 232 | margin-left: auto; 233 | margin-right: auto; 234 | background-size: cover; 235 | background-image: url("../img/circle_grey.png"); 236 | font-size: 2.8vh; 237 | } 238 | 239 | .dps 240 | { 241 | position: absolute; 242 | top: 5%; 243 | left: 5%; 244 | font-size: 155%; 245 | font-weight: bold; 246 | text-align: center; 247 | width: 20%; 248 | } 249 | 250 | .circle .dps 251 | { 252 | color: #CCC; 253 | } 254 | 255 | .dpsfooter 256 | { 257 | position: absolute; 258 | top: 70%; 259 | left: 5%; 260 | font-size: 45%; 261 | width: 20%; 262 | text-align: center; 263 | } 264 | 265 | .closetime 266 | { 267 | position: absolute; 268 | top: 17%; 269 | right: 5%; 270 | font-size: 40%; 271 | text-align: right; 272 | width: 50%; 273 | } 274 | 275 | #footer 276 | { 277 | position: absolute; 278 | text-align: center; 279 | bottom: 0%; 280 | width: 100%; 281 | font-size: 1.5vh; 282 | } 283 | 284 | .danger 285 | { 286 | 287 | } 288 | 289 | .yield 290 | { 291 | 292 | } 293 | 294 | #reset:active 295 | { 296 | border: 4px solid #FFFFFF; 297 | } 298 | 299 | /* 300 | fuck 3 aligns 301 | #rightBar 302 | { 303 | height: 100%; 304 | background-color: black; 305 | } 306 | */ -------------------------------------------------------------------------------- /img/4thres.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/4thres.jpg -------------------------------------------------------------------------------- /img/4thres_letters.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/4thres_letters.jpg -------------------------------------------------------------------------------- /img/4thres_letterslines.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/4thres_letterslines.jpg -------------------------------------------------------------------------------- /img/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/car.png -------------------------------------------------------------------------------- /img/car_pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/car_pin.png -------------------------------------------------------------------------------- /img/car_pin_outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/car_pin_outline.png -------------------------------------------------------------------------------- /img/car_pin_outline_blk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/car_pin_outline_blk.png -------------------------------------------------------------------------------- /img/car_pin_outline_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/car_pin_outline_blue.png -------------------------------------------------------------------------------- /img/car_pin_outline_org.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/car_pin_outline_org.png -------------------------------------------------------------------------------- /img/car_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/car_small.png -------------------------------------------------------------------------------- /img/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/circle.png -------------------------------------------------------------------------------- /img/circle_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/circle_active.png -------------------------------------------------------------------------------- /img/circle_grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/circle_grey.png -------------------------------------------------------------------------------- /img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/favicon.png -------------------------------------------------------------------------------- /img/resetbtn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameslantz/planepath/88a29a93d9f329f65e8a2cb4e95f4fdcd94b0ec1/img/resetbtn.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | PUBG Plane Path 4 | 14 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 |
25 |
26 |
Click and drag to begin
27 |
28 |
29 |
30 |
31 |
= Likely chute path
32 |
33 |
34 |
35 |
= Potential chute path
36 |
37 |
38 |
39 |
= High % vehicle
40 |
41 |
42 |
43 |
44 |
45 |
46 | 51 |
52 | 53 |
54 | 55 |
56 | 57 | 58 |
59 |
60 |
61 | 62 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | //CONSTANTS 2 | var SECONDS = 1000; 3 | var STANDARD_SCALE = 600; //600px standard scale 4 | 5 | var CHUTE_DIST = [100, 165]; //early chute, late chute 6 | var CHUTE_1_COLOR = [255, 165, 0, 50]; 7 | var CHUTE_2_COLOR = [15, 15, 200, 50]; 8 | 9 | var FIRST_AID_TIME = 10.0; 10 | 11 | var CAR_POS = [[119, 234], [174, 190], [164, 168], [261 , 201], [296, 207], [323, 206], [334, 219], [463, 185], [386, 168], [426, 426], [443, 435], [445, 450], [517, 227], [439, 339], [257, 288]]; 12 | var CIRCLE_DEFS = [ 13 | //{idx: 0, downtime: 1, uptime: 1, dps: 5}, 14 | {idx: 1, downtime: 412, uptime: 300, dps: .5}, 15 | {idx: 2, downtime: 200, uptime: 149, dps: .75}, 16 | {idx: 3, downtime: 150, uptime: 90, dps: 1}, 17 | {idx: 4, downtime: 120, uptime: 52, dps: 1.5}, 18 | {idx: 5, downtime: 120, uptime: 42, dps: 3}, 19 | {idx: 6, downtime: 90, uptime: 30, dps: 5}, 20 | {idx: 7, downtime: 90, uptime: 26, dps: 7.5}, 21 | {idx: 8, downtime: 60, uptime: 15, dps: 11}, 22 | {idx: 9, downtime: 300, uptime: 15, dps: 11} 23 | ] 24 | 25 | //variables 26 | var lastDown = new Date().getTime(); 27 | var dragging = false; 28 | var downEvent = null; 29 | var moveEvent = null; 30 | var arrow = false; 31 | var pathDone = false; 32 | var postDone = false; 33 | var resizedDuringAnim = false; 34 | var lastResizeDraw = 0; 35 | 36 | var pathStart = [0, 0]; 37 | var pathEnd = [0, 0]; 38 | 39 | var lineDraw1 = [0, 0]; 40 | var lineDraw2 = [0, 0]; 41 | 42 | var linePts = []; 43 | var dists = []; 44 | var lineAngle = 0; 45 | 46 | var animStart = 0; 47 | var animFrames = 0; 48 | 49 | var pathCanvasHeight = 0; 50 | var pathCanvasWidth = 0; 51 | 52 | var pathSlope = 0; 53 | var pathB = 0; 54 | 55 | var clicked = false; 56 | var clickStart = [0, 0]; 57 | var clickEnd = [0, 0]; 58 | 59 | var lastScaled = null; 60 | 61 | var bg = new Image(); 62 | var bgLoaded = false; 63 | bg.src = "img/4thres.jpg"; 64 | 65 | var bgLines = new Image(); 66 | var bgLinesLoaded = false; 67 | bgLines.src = "img/4thres_letterslines.jpg"; 68 | 69 | var bgLetters = new Image(); 70 | var bgLettersLoaded = false; 71 | bgLetters.src = "img/4thres_letters.jpg"; 72 | 73 | var car = new Image(); 74 | var carLoaded = false; 75 | car.src = "img/car_pin.png"; 76 | 77 | var car_out = new Image(); 78 | var carOutLoaded = false; 79 | car_out.src = "img/car_pin_outline.png"; 80 | 81 | var car_out_blk = new Image(); 82 | var carOutBlkLoaded = false; 83 | car_out_blk.src = "img/car_pin_outline_blk.png"; 84 | 85 | var car_out_org = new Image(); 86 | var carOutOrgLoaded = false; 87 | car_out_org.src = "img/car_pin_outline_org.png"; 88 | 89 | var car_out_blue = new Image(); 90 | var carOutBlueLoaded = false; 91 | car_out_blue.src = "img/car_pin_outline_blue.png"; 92 | 93 | var dirty = true 94 | 95 | var heat = null; 96 | 97 | bg.onload = function() 98 | { 99 | bgLoaded = true; 100 | } 101 | 102 | bgLetters.onload = function() 103 | { 104 | bgLettersLoaded = true; 105 | } 106 | 107 | bgLines.onload = function() 108 | { 109 | bgLinesLoaded = true; 110 | } 111 | 112 | car.onload = function() 113 | { 114 | carLoaded = true; 115 | } 116 | 117 | car_out.onload = function() 118 | { 119 | carOutLoaded = true; 120 | } 121 | 122 | function DebugTime() 123 | { 124 | gameTime += 5 * SECONDS; 125 | } 126 | 127 | function Reset(error = false, errorMsg = "") 128 | { 129 | pathDone = false; 130 | postDone = false; 131 | clicked = false; 132 | 133 | var calculating = document.getElementById('calculating'); 134 | calculating.style.display = "inline"; 135 | 136 | if(error == true) 137 | { 138 | var error = document.getElementById('error'); 139 | error.innerHTML = errorMsg; 140 | } else 141 | { 142 | var error = document.getElementById('error'); 143 | error.innerHTML = ""; 144 | } 145 | 146 | var legend = document.getElementById('legend'); 147 | legend.style.display = "none"; 148 | 149 | var clock = document.getElementById('gameclock'); 150 | clock.innerHTML = ""; 151 | 152 | var clock2 = document.getElementById('lowerclock'); 153 | clock2.innerHTML = ""; 154 | 155 | var circlecont = document.getElementById('circlecontainer'); 156 | circlecont.innerHTML = ""; 157 | 158 | var healthbarcont = document.getElementById('healthbarcontainer'); 159 | healthbarcont.innerHTML = ""; 160 | 161 | var canvas = document.getElementById('mainCanvas'); 162 | var ctx = canvas.getContext("2d"); 163 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 164 | DrawBGCanvas(); 165 | } 166 | 167 | function DrawCars() 168 | { 169 | var canvas2 = document.getElementById('bgCanvas'); 170 | var ctx2 = canvas2.getContext('2d'); 171 | var scaleFactor = ctx2.canvas.height / STANDARD_SCALE; 172 | for(x=0;x= lastScaled + 400 && Date.now() >= lastResizeDraw + 400) 231 | { 232 | //Draw the path! 233 | DrawPath(true); 234 | } 235 | }, 500) 236 | } 237 | 238 | } 239 | 240 | 241 | var canvascont = document.getElementById('canvasContainer'); 242 | container.style.marginTop = (window.innerHeight - container.clientHeight) / 2; 243 | sndcontainer.style.width = (leftbar.clientWidth + ctx.canvas.width + 100); 244 | canvascont.style.width = ctx.canvas.width; 245 | canvascont.style.height = ctx.canvas.height; 246 | canvascont.style.left = leftbar.clientWidth; 247 | } 248 | 249 | function Scale() { 250 | var canvas = document.getElementById('mainCanvas'); 251 | var container = document.getElementById('container'); 252 | var leftbar = document.getElementById('leftBar'); 253 | var sndcontainer = document.getElementById('sndcontainer'); 254 | var ctx = canvas.getContext('2d'); 255 | var canvas2 = document.getElementById('bgCanvas'); 256 | var ctx2 = canvas2.getContext('2d'); 257 | //ctx.canvas.height = container.clientHeight; 258 | //ctx.canvas.width = ctx.canvas.height; 259 | //ctx2.canvas.height = container.clientHeight; 260 | //ctx2.canvas.width = ctx2.canvas.height; 261 | var canvascont = document.getElementById('canvasContainer'); 262 | container.style.marginTop = (window.innerHeight - container.clientHeight) / 2; 263 | sndcontainer.style.width = (leftbar.clientWidth + ctx.canvas.width + 100); 264 | canvascont.style.width = ctx.canvas.width; 265 | canvascont.style.height = ctx.canvas.height; 266 | canvascont.style.left = leftbar.clientWidth; 267 | } 268 | 269 | //lmao can you imagine being this much of a nerd that u know how this works 270 | function DrawArrow(fromx, fromy, tox, toy){ 271 | //variables to be used when creating the arrow 272 | var c = document.getElementById("mainCanvas"); 273 | var ctx = c.getContext("2d"); 274 | var headlen = 10; 275 | 276 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 277 | 278 | var angle = Math.atan2(toy-fromy,tox-fromx); 279 | 280 | //starting path of the arrow from the start square to the end square and drawing the stroke 281 | ctx.beginPath(); 282 | ctx.moveTo(fromx, fromy); 283 | ctx.lineTo(tox, toy); 284 | ctx.strokeStyle = "#FFFFFF"; 285 | ctx.lineWidth = 6; 286 | ctx.stroke(); 287 | 288 | //starting a new path from the head of the arrow to one of the sides of the point 289 | ctx.beginPath(); 290 | ctx.moveTo(tox, toy); 291 | ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7)); 292 | 293 | //path from the side point of the arrow, to the other side point 294 | ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7)); 295 | 296 | //path from the side point back to the tip of the arrow, and then again to the opposite side point 297 | ctx.lineTo(tox, toy); 298 | ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7)); 299 | 300 | //draws the paths created above 301 | ctx.strokeStyle = "#FFFFFF"; 302 | ctx.lineWidth = 6; 303 | ctx.stroke(); 304 | ctx.fillStyle = "#FFFFFF"; 305 | ctx.fill(); 306 | } 307 | 308 | function DrawClick(x, y) 309 | { 310 | var c = document.getElementById("mainCanvas"); 311 | var ctx = c.getContext("2d"); 312 | 313 | ctx.beginPath(); 314 | ctx.arc(x, y, 6, 0, 2 * Math.PI, false); 315 | ctx.fillStyle = '#FFFFFF'; 316 | ctx.strokeStyle = '#000000'; 317 | ctx.stroke(); 318 | ctx.fill(); 319 | } 320 | 321 | function getY(x, slope, b) 322 | { 323 | return (x * slope) + b; 324 | } 325 | 326 | function getX(y, slope, b) 327 | { 328 | return (y - b) / slope; 329 | } 330 | 331 | function DrawPath(resizeDraw = false){ 332 | 333 | var error = document.getElementById('error'); 334 | error.innerHTML = ""; 335 | 336 | DrawBGCanvas(); 337 | var c = document.getElementById("mainCanvas"); 338 | var ctx = c.getContext("2d"); 339 | 340 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 341 | 342 | var fromx = pathStart[0] * c.width / pathCanvasWidth; 343 | var fromy = pathStart[1] * c.height / pathCanvasHeight; 344 | var tox = pathEnd[0] * c.width / pathCanvasWidth; 345 | var toy = pathEnd[1] * c.height / pathCanvasHeight; 346 | 347 | var headlen = 10; 348 | 349 | var angle = Math.atan2(toy-fromy,tox-fromx); 350 | lineAngle = angle; 351 | 352 | var slopeNum = (toy - fromy); 353 | var slopeDenom = (tox - fromx); 354 | var slope = slopeNum/slopeDenom; 355 | 356 | //y = mx+b 357 | //y = slope(x) + b 358 | //fromy = slope(fromx) + b 359 | //b = fromy - slope(fromx) 360 | var b = fromy - (slope*fromx); 361 | 362 | var foundPos = false; 363 | var foundNeg = false; 364 | 365 | var posPos = [0, 0]; 366 | var negPos = [0, 0]; 367 | 368 | var x = fromx; 369 | var y = fromy; 370 | 371 | var idx = 0 372 | 373 | // //Add pts while we go! 374 | // linePts = []; 375 | 376 | // while(foundPos == false) 377 | // { 378 | // x = x * slopeDenom; 379 | // y = y * slopeNum; 380 | 381 | // if(x <= 0 || x >= c.width) 382 | // { 383 | // foundPos = true; 384 | // posPos[0] = x; 385 | // posPos[1] = getY(x, slope, b); 386 | // } 387 | // else if(y <= 0 || y >= c.height) 388 | // { 389 | // foundPos = true; 390 | // posPos[1] = y; 391 | // posPos[0] = getX(y, slope, b); 392 | // } 393 | 394 | // idx++; 395 | // if(idx >= 1000) 396 | // { 397 | // //bail out 398 | // foundPos = true; 399 | // posPos[0] = 1000; 400 | // posPos[1] = 1000; 401 | // } 402 | // } 403 | 404 | // var x = fromx; 405 | // var y = fromy; 406 | 407 | // idx = 0 408 | 409 | // while(foundNeg == false) 410 | // { 411 | // x = x * -1 * slopeDenom; 412 | // y = y * -1 * slopeNum; 413 | 414 | // if(x <= 0 || x >= c.width) 415 | // { 416 | // foundNeg = true; 417 | // negPos[0] = x; 418 | // negPos[1] = getY(x, slope, b); 419 | // } 420 | // else if(y <= 0 || y >= c.height) 421 | // { 422 | // foundNeg = true; 423 | // negPos[1] = y; 424 | // negPos[0] = getX(y, slope, b); 425 | // } 426 | 427 | // idx++; 428 | // if(idx >= 1000) 429 | // { 430 | // //bail out 431 | // foundNeg = true; 432 | // negPos[0] = -1000; 433 | // negPos[1] = -1000; 434 | // } 435 | // } 436 | 437 | // var iterX = fromx; 438 | // var iterY = fromy; 439 | 440 | // for(i=0; i<1000; i++) 441 | // { 442 | // if(slope > 1) 443 | // { 444 | // iterY = iterY + 1; 445 | // linePts.push([getX(iterY, slope, b), iterY]); 446 | // } 447 | // else 448 | // { 449 | // iterX = iterX + 1; 450 | // linePts.push([iterX, getY(iterX, slope, b)]); 451 | // } 452 | // } 453 | 454 | //console.log(angle); 455 | //console.log(angle*57.2); 456 | 457 | //test intersections 458 | 459 | var width = c.width; 460 | var height = c.height; 461 | 462 | var intersect1 = null; 463 | var intersect2 = null; 464 | var intersect3 = null; 465 | var intersect4 = null; 466 | 467 | var pt1 = [fromx, fromy]; 468 | var pt2 = [tox, toy]; 469 | 470 | if(slope < 0) 471 | { 472 | //top line 473 | intersect1 = math.intersect(pt1, pt2, [0, 0], [width, 0]); 474 | //left line 475 | intersect2 = math.intersect(pt1, pt2, [0, 0], [0, height]); 476 | // //right line 477 | intersect3 = math.intersect(pt1, pt2, [width, 0], [width, height]); 478 | // //bottom line 479 | intersect4 = math.intersect(pt1, pt2, [0, height], [width, height]); 480 | } else 481 | { 482 | //top line 483 | intersect1 = math.intersect(pt2, pt1, [0, 0], [width, 0]); 484 | //left line 485 | intersect2 = math.intersect(pt2, pt1, [0, 0], [0, height]); 486 | // //right line 487 | intersect3 = math.intersect(pt2, pt1, [width, 0], [width, height]); 488 | // //bottom line 489 | intersect4 = math.intersect(pt2, pt1, [0, height], [width, height]); 490 | } 491 | 492 | // console.log(intersect1); 493 | // console.log(intersect2); 494 | // console.log(intersect3); 495 | // console.log(intersect4); 496 | 497 | var solved = 0; 498 | 499 | if(intersect1 == null || intersect2 == null || intersect3 == null || intersect4 == null) 500 | { 501 | Reset(true, "Invalid Path!"); 502 | return; 503 | } 504 | 505 | if(intersect1[0] <= width + 1 && intersect1[0] >= -1) 506 | { 507 | if(solved == 0) 508 | { 509 | lineDraw1 = intersect1; 510 | solved++; 511 | } else { 512 | lineDraw2 = intersect1; 513 | } 514 | } 515 | 516 | if(intersect4[0] <= width + 1 && intersect4[0] >= -1) 517 | { 518 | if(solved == 0) 519 | { 520 | lineDraw1 = intersect4; 521 | solved++; 522 | } else { 523 | lineDraw2 = intersect4; 524 | } 525 | } 526 | 527 | if(intersect2[1] <= height + 1 && intersect2[1] >= -1) 528 | { 529 | if(solved == 0) 530 | { 531 | lineDraw1 = intersect2; 532 | solved++; 533 | } else { 534 | lineDraw2 = intersect2; 535 | } 536 | } 537 | 538 | if(intersect3[1] <= height + 1 && intersect3[1] >= -1) 539 | { 540 | if(solved == 0) 541 | { 542 | lineDraw1 = intersect3; 543 | solved++; 544 | } else { 545 | lineDraw2 = intersect3; 546 | } 547 | } 548 | 549 | // console.log(lineDraw1, lineDraw2); 550 | 551 | pathSlope = slope; 552 | pathB = b; 553 | 554 | UpdateLine(); 555 | 556 | animFrames = 0; 557 | animStart = Date.now(); 558 | currentIdx = 0; 559 | currentX = 0; 560 | currentY = 0; 561 | 562 | setTimeout(function(){CalcDists(resizeDraw)}, 1); 563 | } 564 | 565 | function UpdateLine() 566 | { 567 | var c = document.getElementById("mainCanvas"); 568 | var ctx = c.getContext("2d"); 569 | 570 | ctx.beginPath(); 571 | ctx.moveTo(lineDraw1[0], lineDraw1[1]); 572 | ctx.lineTo(lineDraw2[0], lineDraw2[1]); 573 | 574 | ctx.strokeStyle = '#000000'; 575 | ctx.lineWidth = 8; 576 | ctx.stroke(); 577 | ctx.strokeStyle = '#FFFFFF'; 578 | ctx.lineWidth = 6; 579 | ctx.stroke(); 580 | } 581 | 582 | function HandleDown(event) 583 | { 584 | //offsetx, offsety is what we want (ignores the screen) 585 | // console.log("!!! down") 586 | // console.log(event) 587 | 588 | if(arrow) 589 | { 590 | FinishPath(downEvent.offsetX, downEvent.offsetY, moveEvent.offsetX, moveEvent.offsetY) 591 | } 592 | else if(!pathDone){ 593 | lastDown = new Date().getTime(); 594 | dragging = true 595 | downEvent = event; 596 | } 597 | } 598 | 599 | function HandleMove(event) 600 | { 601 | //past X and without an up we're probably dragging 602 | if(new Date().getTime() - lastDown > 20 && dragging && pathDone == false && clicked == false) 603 | { 604 | arrow = true; 605 | document.body.style.cursor = "pointer"; 606 | moveEvent = event; 607 | //firefox hack 608 | offsetX = downEvent.offsetX; 609 | offsetY = downEvent.offsetY; 610 | if(downEvent.offsetX == 0 && downEvent.offsetY == 0) 611 | { 612 | offsetX = downEvent.layerX; 613 | offsetY = downEvent.layerY; 614 | } 615 | //end firefox hack 616 | DrawArrow(offsetX, offsetY, moveEvent.offsetX, moveEvent.offsetY); 617 | } 618 | } 619 | 620 | function HandleUp(event) 621 | { 622 | //If arrow, do X 623 | if(arrow) 624 | { 625 | //firefox hack 626 | offsetX = downEvent.offsetX; 627 | offsetY = downEvent.offsetY; 628 | if(downEvent.offsetX == 0 && downEvent.offsetY == 0) 629 | { 630 | offsetX = downEvent.layerX; 631 | offsetY = downEvent.layerY; 632 | } 633 | 634 | offsetX2 = moveEvent.offsetX; 635 | offsetY2 = moveEvent.offsetY; 636 | if(moveEvent.offsetX == 0 && moveEvent.offsetY == 0) 637 | { 638 | offsetX2 = moveEvent.layerX; 639 | offsetY2 = moveEvent.layerY; 640 | } 641 | //end firefox hack 642 | FinishPath(offsetX, offsetY, offsetX2, offsetY2); 643 | } 644 | else if(clicked == false && !pathDone) 645 | { 646 | clicked = true; 647 | clickStart[0] = event.offsetX; 648 | clickStart[1] = event.offsetY; 649 | DrawClick(clickStart[0], clickStart[1]); 650 | } 651 | else if(clicked == true && !pathDone) 652 | { 653 | clicked = false; 654 | FinishPath(clickStart[0], clickStart[1], event.offsetX, event.offsetY); 655 | } 656 | 657 | arrow = false 658 | dragging = false 659 | document.body.style.cursor = "default"; 660 | } 661 | 662 | function FinishPath(startx, starty, tox, toy) 663 | { 664 | var canvas = document.getElementById('mainCanvas'); 665 | var ctx = canvas.getContext('2d'); 666 | pathCanvasHeight = canvas.height; 667 | pathCanvasWidth = canvas.width; 668 | pathDone = true; 669 | pathStart[0] = startx; 670 | pathStart[1] = starty; 671 | pathEnd[0] = tox; 672 | pathEnd[1] = toy; 673 | 674 | DrawPath(); 675 | } 676 | 677 | //distance between two pts [x, y] 678 | function distsqd(pt1, pt2) 679 | { 680 | var a = pt1[0] - pt2[0]; 681 | var b = pt1[1] - pt2[1]; 682 | return Math.sqrt( a*a + b*b ); 683 | } 684 | 685 | function distfromline(pt) 686 | { 687 | var slope = 1 /pathSlope * -1; 688 | var pt1 = pt; 689 | var pt2 = [pt1[0] + 1, pt1[1] + slope]; 690 | 691 | var intersect = math.intersect(pt1, pt2, lineDraw1, lineDraw2); 692 | return distsqd(pt1, intersect); 693 | } 694 | 695 | //distance from closest point on a line using pythagorean theorem and congruency 696 | //this doesn't work! blurk 697 | // function distfromline(slope, lineb, pt, debug) 698 | // { 699 | // var x1 = pt[0]; 700 | // var y1 = pt[1]; 701 | // var x2 = getX(y1, slope, lineb); 702 | // var y2 = getY(x1, slope, lineb); 703 | 704 | // //make a right triangle 705 | // var a = Math.abs(x1 - x2); 706 | // var b = Math.abs(y1 - y2); 707 | 708 | // //find the hypoteneuse 709 | // var c = Math.sqrt(a*a + b*b); 710 | 711 | // //split in half 712 | // var d = c / 2; 713 | 714 | // if(debug) 715 | // { 716 | // console.log(x1, y1, x2, y2, a, b, c, d); 717 | // console.log("slope: " + slope); 718 | // console.log("lineb: " + lineb); 719 | // } 720 | 721 | // return d; 722 | // } 723 | 724 | var currentIdx = 0; 725 | var currentX = 0; 726 | var currentY = 0; 727 | var gameTime = 0; 728 | 729 | function RunGameTime() 730 | { 731 | if(pathDone) 732 | { 733 | var dt = Date.now() - lastUpdateTimer; 734 | lastUpdateTimer = Date.now() 735 | var clock = document.getElementById('gameclock'); 736 | var m = 0; 737 | var s = 0; 738 | gameTime += dt 739 | var displayTime = Math.floor(gameTime / SECONDS); 740 | //123 = 01:03 741 | s = displayTime % 60; 742 | m = (displayTime - s) / 60; 743 | var str = ""; 744 | if(m < 10) 745 | { 746 | str = str + "0"; 747 | } 748 | str = str + m.toString() + ":"; 749 | if(s < 10) 750 | { 751 | str = str + "0"; 752 | } 753 | str = str + s.toString(); 754 | 755 | clock.innerHTML = str; 756 | 757 | if(gameTime > 60 * SECONDS * 60) 758 | { 759 | Reset(); 760 | } 761 | 762 | setTimeout(function(){RunGameTime();},1000); 763 | } 764 | } 765 | 766 | var circles = []; 767 | 768 | function StartCircles() 769 | { 770 | circles = [] 771 | if(pathDone) 772 | { 773 | var circlecont = document.getElementById('circlecontainer'); 774 | var addTime = 0; 775 | 776 | //deep copy 777 | circles = JSON.parse(JSON.stringify(CIRCLE_DEFS)); 778 | 779 | for(n=0;n 0 ? "WAITING " : "CLOSING! "; 814 | var phrases = ["SAFE: ", "CLOSE: "]; 815 | // var timestr = ""; 816 | // var time = circles[i].downtime > 0 ? circles[i].downtime : circles[i].uptime; 817 | //var times = [circles[i].downtime, circles[i].uptime] 818 | var times = [circles[i].add_downtime - circles[i].downtime, circles[i].add_uptime]; 819 | var displayTimes = []; 820 | for(n=0;n
"+dps+"
DPS
"; 836 | str = str + "CIRCLE " + circles[i].idx + "
"; 837 | str = str + displayTimes[0] 838 | // for(n=0; n"; 844 | // } 845 | // } 846 | str = str +"
"; 847 | circlecont.innerHTML = circlecont.innerHTML + str; 848 | } 849 | 850 | UpdateHealth(); 851 | } 852 | 853 | function UpdateHealth() 854 | { 855 | if(circles.length > 0) 856 | { 857 | var healthbarcont = document.getElementById('healthbarcontainer'); 858 | var circle = circles[0]; 859 | var lowestHP = Math.ceil(circle.dps*FIRST_AID_TIME); 860 | var myclass = "veryhighhp" 861 | 862 | if(lowestHP <= 5) 863 | { 864 | myclass = "lowhp"; 865 | } 866 | else if(lowestHP <= 20) 867 | { 868 | myclass = "lowishhp"; 869 | } 870 | else if(lowestHP <= 50) 871 | { 872 | myclass = "medhp" 873 | } 874 | else if(lowestHP <= 75) 875 | { 876 | myclass="highhp"; 877 | } 878 | 879 | healthbarcont.innerHTML = "
LOWEST HEALTH TO USE FIRST AID
"; 880 | } 881 | } 882 | 883 | var lastUpdateCircles = 0; 884 | var lastUpdateTimer = 0; 885 | 886 | function RunCircles() 887 | { 888 | if(pathDone) 889 | { 890 | var circlecont = document.getElementById('circlecontainer'); 891 | 892 | var dt = Date.now() - lastUpdateCircles; 893 | lastUpdateCircles = Date.now(); 894 | 895 | if(circles.length > 0) 896 | { 897 | var i = 0; 898 | 899 | if(circles[i].downtime > 0) 900 | { 901 | circles[i].downtime -= dt; 902 | } else 903 | { 904 | circles[i].uptime -= dt; 905 | } 906 | 907 | // var time = circles[i].downtime > 0 ? circles[i].downtime : circles[i].uptime; 908 | // var displayTime = Math.floor(time / SECONDS) 909 | // var closing = circles[i].downtime > 0 ? "WAIT " : "CLOSE "; 910 | // var timestr = ""; 911 | // var s = displayTime % 60; 912 | // var m = (displayTime - s) / 60; 913 | // if(m < 10) 914 | // { 915 | // timestr = timestr + "0"; 916 | // } 917 | // timestr = timestr + m.toString() + ":"; 918 | // if(s < 10) 919 | // { 920 | // timestr = timestr + "0"; 921 | // } 922 | // timestr = timestr + s.toString(); 923 | 924 | // var el = circlecont.firstChild; 925 | // var close = el.getElementsByClassName('closetime')[0]; 926 | // close.innerHTML = closing + timestr; 927 | 928 | if(circles[i].uptime <= 0) 929 | { 930 | var a_time = 800; 931 | circles.splice(0, 1); 932 | var els = circlecont.getElementsByClassName('circle'); 933 | var animDate = Date.now(); 934 | 935 | var canvas = document.getElementById('mainCanvas'); 936 | var ctx = canvas.getContext('2d'); 937 | 938 | var height = ctx.canvas.height; 939 | 940 | //ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 941 | 942 | var scaleFactor = height / STANDARD_SCALE; 943 | 944 | setTimeout(function(){CircleAnim(els, a_time, animDate, 0, scaleFactor)}, 5); 945 | setTimeout(function(){DisplayCircles();},a_time); 946 | } 947 | } 948 | 949 | setTimeout(function(){RunCircles();},1000); 950 | } 951 | } 952 | 953 | function CircleAnim(els, a_time, animDate, pos, scaleFactor) 954 | { 955 | var step = a_time / 5; 956 | var distance = 70 * scaleFactor; 957 | var delta = distance/step; 958 | 959 | var active_el = document.getElementsByClassName('activecircle')[0]; 960 | 961 | if(pos==0) 962 | { 963 | active_el.style.opacity = 1.0; 964 | } 965 | 966 | if(Date.now() - animDate > a_time) 967 | { 968 | return 969 | } 970 | 971 | pos = pos - delta; 972 | var displaypos = pos; 973 | 974 | for(idx=0;idx lastDistLimit) 1100 | // { 1101 | // if(dist <= CHUTE_DIST[0] * scaleFactor) 1102 | // { 1103 | // DrawPixel(ctx, x, y, c1[0], c1[1], c1[2], c1[3]); 1104 | // } 1105 | // else if(dist <= CHUTE_DIST[1] * scaleFactor) 1106 | // { 1107 | // DrawPixel(ctx, x, y, c2[0], c2[1], c2[2], c2[3]); 1108 | // } 1109 | // } 1110 | // } 1111 | // } 1112 | 1113 | var newEnd1 = new Array(lineDraw1[0], lineDraw1[1]); 1114 | var newEnd2 = new Array(lineDraw2[0], lineDraw2[1]); 1115 | 1116 | if(newEnd1[0] > -.1 && newEnd1[0] < .1) 1117 | { 1118 | newEnd1 = math.intersect(newEnd1, newEnd2, [-200, 0], [-200, height + 200]); 1119 | } 1120 | if(newEnd1[0] > width - 1 && newEnd1[0] < width + 1) 1121 | { 1122 | newEnd1 = math.intersect(newEnd1, newEnd2, [width + 200, 0], [width + 200, height + 200]); 1123 | } 1124 | if(newEnd1[1] > -.1 && newEnd1[1] < .1) 1125 | { 1126 | newEnd1 = math.intersect(newEnd1, newEnd2, [0, -200], [width + 200, -200]); 1127 | } 1128 | if(newEnd1[1] > height - 1 && newEnd1[1] < height + 1) 1129 | { 1130 | newEnd1 = math.intersect(newEnd1, newEnd2, [0, height + 200], [width + 200, height + 200]); 1131 | } 1132 | 1133 | if(newEnd2[0] > -.1 && newEnd2[0] < .1) 1134 | { 1135 | newEnd2 = math.intersect(newEnd1, newEnd2, [-200, 0], [-200, height + 200]); 1136 | } 1137 | if(newEnd2[0] > width - 1 && newEnd2[0] < width + 1) 1138 | { 1139 | newEnd2 = math.intersect(newEnd1, newEnd2, [width + 200, 0], [width + 200, height + 200]); 1140 | } 1141 | if(newEnd2[1] > -.1 && newEnd2[1] < .1) 1142 | { 1143 | newEnd2 = math.intersect(newEnd1, newEnd2, [0, -200], [width + 200, -200]); 1144 | } 1145 | if(newEnd2[1] > height - 1 && newEnd2[1] < height + 1) 1146 | { 1147 | newEnd2 = math.intersect(newEnd1, newEnd2, [0, height + 200], [width + 200, height + 200]); 1148 | } 1149 | 1150 | var lw_og = Math.floor(t/10) * scaleFactor * 2; 1151 | var lw1 = lw_og; 1152 | var lw2 = lw_og 1153 | 1154 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 1155 | 1156 | ctx.beginPath(); 1157 | ctx.moveTo(newEnd1[0], newEnd1[1]); 1158 | ctx.lineTo(newEnd2[0], newEnd2[1]); 1159 | 1160 | ctx.strokeStyle = 'rgba(0, 0, 100, 0.17)'; 1161 | if(lw1 > CHUTE_DIST[1] * scaleFactor * 2) 1162 | { 1163 | lw1 = CHUTE_DIST[1] * scaleFactor * 2 1164 | } 1165 | ctx.lineWidth = lw1; 1166 | ctx.stroke(); 1167 | 1168 | ctx.beginPath(); 1169 | ctx.moveTo(newEnd1[0], newEnd1[1]); 1170 | ctx.lineTo(newEnd2[0], newEnd2[1]); 1171 | 1172 | ctx.strokeStyle = 'rgba(255, 200, 0, 0.2)'; 1173 | lw = lw_og; 1174 | if(lw2 > CHUTE_DIST[0] * scaleFactor * 2) 1175 | { 1176 | lw2 = CHUTE_DIST[0] * scaleFactor * 2; 1177 | } 1178 | ctx.lineWidth = lw2; 1179 | ctx.stroke(); 1180 | 1181 | UpdateLine() 1182 | 1183 | for(x=0;x lastDistLimit) 1190 | { 1191 | var canvas2 = document.getElementById('bgCanvas'); 1192 | var ctx2 = canvas2.getContext('2d'); 1193 | 1194 | if(dist <= CHUTE_DIST[0] * scaleFactor + 5) 1195 | { 1196 | ctx2.drawImage(car_out_org, Math.floor((CAR_POS[x][0] - 1) * scaleFactor), Math.floor((CAR_POS[x][1] - 1) * scaleFactor), Math.floor(18 * scaleFactor), Math.floor(18 * scaleFactor)); 1197 | ctx2.drawImage(car, Math.floor(CAR_POS[x][0] * scaleFactor), Math.floor(CAR_POS[x][1] * scaleFactor), Math.floor(16 * scaleFactor), Math.floor(16 * scaleFactor)); 1198 | } 1199 | else if(dist <= CHUTE_DIST[1] * scaleFactor + 5) 1200 | { 1201 | ctx2.drawImage(car_out_blue, Math.floor((CAR_POS[x][0] - 1) * scaleFactor), Math.floor((CAR_POS[x][1] - 1) * scaleFactor), Math.floor(18 * scaleFactor), Math.floor(18 * scaleFactor)); 1202 | ctx2.drawImage(car, Math.floor(CAR_POS[x][0] * scaleFactor), Math.floor(CAR_POS[x][1] * scaleFactor), Math.floor(16 * scaleFactor), Math.floor(16 * scaleFactor)); 1203 | } 1204 | } 1205 | } 1206 | 1207 | lastDistLimit = distLimit; 1208 | 1209 | //1.5 seconds of animation = entire screen accounted for (unecessarily) 1210 | if(t >= 3000) 1211 | { 1212 | postDone = true; 1213 | } 1214 | 1215 | // if(lastDistLimit <= 10) 1216 | // { 1217 | // UpdateLine(); 1218 | // } 1219 | 1220 | animFrames++; 1221 | 1222 | if(!postDone && pathDone) 1223 | { 1224 | requestAnimationFrame(PostPathUpdate); 1225 | } 1226 | } 1227 | 1228 | // function Update() 1229 | // { 1230 | // var canvas = document.getElementById('mainCanvas'); 1231 | // var ctx = canvas.getContext('2d'); 1232 | 1233 | // if(bgLoaded) 1234 | // { 1235 | // ctx.drawImage(bg, 0, 0, canvas.width, canvas.height); 1236 | // DrawHeatAtPoint(ctx, 50, 50, 50) 1237 | // } 1238 | 1239 | // if(arrow) 1240 | // { 1241 | // DrawArrow(downEvent.offsetX, downEvent.offsetY, moveEvent.offsetX, moveEvent.offsetY); 1242 | // } 1243 | 1244 | // if(clicked) 1245 | // { 1246 | // DrawClick(clickStart[0], clickStart[1]); 1247 | // } 1248 | 1249 | // if(pathDone) 1250 | // { 1251 | // DrawPath(); 1252 | // } 1253 | 1254 | // requestAnimationFrame(Update); 1255 | // } 1256 | 1257 | function DrawPixel(ctx, x, y, r, g, b, a) 1258 | { 1259 | ctx.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")"; 1260 | ctx.fillRect( x, y, 1, 1 ); 1261 | } 1262 | 1263 | window.mobilecheck = function() { 1264 | var check = false; 1265 | (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); 1266 | return check; 1267 | }; 1268 | 1269 | window.onload = function() 1270 | { 1271 | Resize(false); 1272 | var canvas = document.getElementById('mainCanvas'); 1273 | window.addEventListener('resize', function(){Resize(true)}, false); 1274 | canvas.addEventListener('mousedown', HandleDown, false); 1275 | canvas.addEventListener('mousemove', HandleMove, false); 1276 | canvas.addEventListener('mouseup', HandleUp, false); 1277 | 1278 | var canvas2 = document.getElementById('bgCanvas'); 1279 | var ctx = canvas2.getContext('2d'); 1280 | 1281 | if(bgLinesLoaded && carLoaded) 1282 | { 1283 | DrawBGCanvas() 1284 | } 1285 | 1286 | document.getElementById("reset").addEventListener('mouseup', Reset, false); 1287 | 1288 | var is_mobile = window.mobilecheck(); 1289 | 1290 | if(is_mobile) 1291 | { 1292 | var calculating = document.getElementById('calculating'); 1293 | calculating.innerHTML = "Touch two points to begin" 1294 | } 1295 | 1296 | // Update(); 1297 | } -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Plane Path 2 | ============== 3 | 4 | Client side drawing of Plane Path for PUBG (and some other stuff) 5 | 6 | Next additions: 7 | 8 | Squadsync 9 | 10 | New map 11 | 12 | Extra information --------------------------------------------------------------------------------