├── Approach.gml ├── DrawSpriteSkewExt.gml ├── Log.gml ├── Map.gml ├── Monokai.col.xml ├── README.md ├── TwoObjectView.gml ├── shaderOutline.gml └── simplex_noise.gml /Approach.gml: -------------------------------------------------------------------------------- 1 | /// Approach(start, end, shift); 2 | 3 | /**************************************** 4 | Increments a value by a given shift but 5 | never beyond the end value 6 | ****************************************/ 7 | 8 | if (argument0 < argument1) 9 | return min(argument0 + argument2, argument1); 10 | else 11 | return max(argument0 - argument2, argument1); 12 | -------------------------------------------------------------------------------- /DrawSpriteSkewExt.gml: -------------------------------------------------------------------------------- 1 | /// DrawSpriteSkewExt(sprite_index, image_index, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha, image_xskew, image_yskew); 2 | // Courtesy of https://zackbellgames.com/2014/11/11/sprite-skewing-for-procedural-animation/ 3 | var sprite = argument0; 4 | var index = argument1; 5 | var xx = argument2; 6 | var yy = argument3; 7 | var xscale = argument4; 8 | var yscale = argument5; 9 | var cosAngle = cos(degtorad(argument6)); 10 | var sinAngle = sin(degtorad(argument6)); 11 | var tint = argument7; 12 | var alpha = argument8; 13 | var hskew = argument9; 14 | var vskew = argument10; 15 | 16 | // Calculate common operations 17 | var sprTex = sprite_get_texture(sprite, index); 18 | var sprWidth = sprite_get_width(sprite); 19 | var sprHeight = sprite_get_height(sprite); 20 | var sprXOrig = sprite_get_xoffset(sprite); 21 | var sprYOrig = sprite_get_yoffset(sprite); 22 | 23 | var tempX, tempY, tempDir, tempDist; 24 | 25 | // Begin drawing primitive 26 | draw_primitive_begin_texture(pr_trianglestrip, sprTex); 27 | 28 | // Top-left corner 29 | tempX = (-sprXOrig + (sprYOrig / sprHeight) * hskew) * xscale; 30 | tempY = (-sprYOrig + (sprXOrig / sprWidth) * -vskew) * yscale; 31 | draw_vertex_texture_color(xx + tempX * cosAngle - tempY * sinAngle, yy + tempX * sinAngle + tempY * cosAngle, 0, 0, tint, alpha); 32 | 33 | // Top-right corner 34 | tempX = (sprWidth + (sprYOrig / sprHeight) * hskew - sprXOrig) * xscale; 35 | tempY = (-sprYOrig + (1 - sprXOrig / sprWidth) * vskew) * yscale; 36 | draw_vertex_texture_color(xx + tempX * cosAngle - tempY * sinAngle, yy + tempX * sinAngle + tempY * cosAngle, 1, 0, tint, alpha); 37 | 38 | // Bottom-left corner 39 | tempX = (-sprXOrig + (1 - sprYOrig / sprHeight) * -hskew) * xscale; 40 | tempY = (sprHeight - sprYOrig + (sprXOrig / sprWidth) * -vskew) * yscale; 41 | draw_vertex_texture_color(xx + tempX * cosAngle - tempY * sinAngle, yy + tempX * sinAngle + tempY * cosAngle, 0, 1, tint, alpha); 42 | 43 | // Bottom-right corner 44 | tempX = (sprWidth - sprXOrig + (1 - sprYOrig / sprHeight) * -hskew) * xscale; 45 | tempY = (sprHeight - sprYOrig + (1 - sprXOrig / sprWidth) * vskew) * yscale; 46 | draw_vertex_texture_color(xx + tempX * cosAngle - tempY * sinAngle, yy + tempX * sinAngle + tempY * cosAngle, 1, 1, tint, alpha); 47 | 48 | // Finish drawing primitive 49 | draw_primitive_end(); 50 | -------------------------------------------------------------------------------- /Log.gml: -------------------------------------------------------------------------------- 1 | /************************************************** 2 | * 3 | * Log(arg1, arg2, ...) 4 | * Stringify and log x number of arguments to the console 5 | * 6 | **************************************************/ 7 | 8 | var r = string(argument[0]), i; 9 | for (i = 1; i < argument_count; i++) { 10 | r += ", " + string(argument[i]) 11 | } 12 | show_debug_message(r) 13 | -------------------------------------------------------------------------------- /Map.gml: -------------------------------------------------------------------------------- 1 | ///Map(val, min1, max1, min2, max2) 2 | // taken from Processing's source 3 | 4 | return argument3 + (argument4 - argument3) * ((argument0 - argument1) / (argument2 - argument1)); 5 | -------------------------------------------------------------------------------- /Monokai.col.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16053492 4 | 5056494 5 | 7264994 6 | 6123892 7 | 2070011 8 | 2070011 9 | 15716693 10 | 3006629 11 | 3006629 12 | 2238503 13 | 3489854 14 | 6057322 15 | 8031626 16 | 4279113 17 | 3032732 18 | 5925223 19 | 7439489 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gamemaker-scripts 2 | collection of useful scripts 3 | -------------------------------------------------------------------------------- /TwoObjectView.gml: -------------------------------------------------------------------------------- 1 | ///TwoObjectView(object1, object2, view_index) 2 | /************************************************* 3 | * 4 | * Forces a view to follow a second object 5 | * 6 | * Source: http://gmc.yoyogames.com/index.php?showtopic=415796 7 | * 8 | * Example (from the first player object): 9 | * two_object_view(other_player, 0) 10 | * 11 | *************************************************/ 12 | 13 | minzoom=1 // sets the minimal zoom 14 | maxzoom=3 // sets the maximal zoom 15 | 16 | min_wview=room_width/maxzoom // sets the minimal width of the view 17 | min_hview=room_height/maxzoom // sets the minimal height of the view 18 | max_wview=room_width/minzoom // sets the maximal width of the view 19 | max_hview=room_height/minzoom // sets the maximal height of the view 20 | 21 | 22 | // calculates the size and position of the view 23 | xdistance=point_distance(argument0.x,0,argument1.x,0) 24 | ydistance=point_distance(0,argument0.y,0,argument1.y) 25 | 26 | if xdistance/room_width>ydistance/room_height { 27 | view_wview[argument2]=xdistance+room_width/4 28 | 29 | // Cap view width 30 | view_wview[argument2] = max(min_wview,view_wview[argument2]) 31 | view_wview[argument2] = min(max_wview,view_wview[argument2]) 32 | 33 | view_hview[argument2]=view_wview[argument2]/room_width*room_height 34 | } else { 35 | view_hview[argument2]=ydistance+room_height/4 36 | 37 | // Cap view height 38 | view_hview[argument2] = max(min_hview,view_hview[argument2]) 39 | view_hview[argument2] = min(max_hview,view_hview[argument2]) 40 | 41 | view_wview[argument2]=view_hview[argument2]/room_height*room_width 42 | } 43 | 44 | view_xview[argument2]=(argument0.x+argument1.x)/2-view_wview[argument2]/2 45 | view_yview[argument2]=(argument0.y+argument1.y)/2-view_hview[argument2]/2 46 | 47 | // keeps the view inside the room 48 | if(view_xview[argument2]+view_wview[argument2]>room_width) 49 | view_xview[argument2]=room_width-view_wview[argument2] 50 | 51 | if(view_yview[argument2]+view_hview[argument2]>room_height) 52 | view_yview[argument2]=room_height-view_hview[argument2] 53 | 54 | view_xview[argument2] = max(view_xview[argument2],0) 55 | view_yview[argument2] = max(view_yview[argument2],0) 56 | 57 | // Scale the view resolution based on the new size 58 | surface_resize(application_surface, view_wview[argument2], view_hview[argument2]) 59 | -------------------------------------------------------------------------------- /shaderOutline.gml: -------------------------------------------------------------------------------- 1 | // 2 | // FRAGMENT: Sprite outline shader 3 | // 4 | varying vec2 v_vTexcoord; 5 | varying vec4 v_vColour; 6 | uniform float outlineH; 7 | uniform float outlineW; 8 | uniform vec4 outlineColor; 9 | 10 | void main() 11 | { 12 | vec2 offsetx; 13 | offsetx.x = outlineW; 14 | vec2 offsety; 15 | offsety.y = outlineH; 16 | 17 | float alpha = texture2D( gm_BaseTexture, v_vTexcoord ).a; 18 | vec4 newColor = texture2D( gm_BaseTexture, v_vTexcoord ); 19 | 20 | if ( alpha < 1.0 ) { newColor = outlineColor; } 21 | 22 | alpha = max(alpha, texture2D( gm_BaseTexture, v_vTexcoord + offsetx).a); 23 | alpha = max(alpha, texture2D( gm_BaseTexture, v_vTexcoord - offsetx).a); 24 | alpha = max(alpha, texture2D( gm_BaseTexture, v_vTexcoord + offsety).a); 25 | alpha = max(alpha, texture2D( gm_BaseTexture, v_vTexcoord - offsety).a); 26 | 27 | 28 | gl_FragColor = newColor; 29 | gl_FragColor.a = alpha; 30 | } 31 | 32 | 33 | // USAGE: in the draw event 34 | shader_set(shaderOutline) 35 | 36 | var outlineColor = shader_get_uniform(shaderOutline,"outlineColor") 37 | shader_set_uniform_f(outlineColor, 0.2,0.2,0.2,0 ) 38 | 39 | 40 | var outlineW = shader_get_uniform(shaderOutline,"outlineW") 41 | shader_set_uniform_f(outlineW, 1/sprite_width) 42 | 43 | var outlineH = shader_get_uniform(shaderOutline,"outlineH") 44 | shader_set_uniform_f(outlineH, 1/sprite_height) 45 | 46 | draw_self() 47 | shader_reset() 48 | -------------------------------------------------------------------------------- /simplex_noise.gml: -------------------------------------------------------------------------------- 1 | 2 | /************************************************** 3 | * 4 | * Collection of simplex noise functions. 5 | * Source: http://gmc.yoyogames.com/index.php?showtopic=655137&p=4752468 6 | * Credit: Binsk 7 | * 8 | **************************************************/ 9 | #define simplex_raw2 10 | ///simplex_raw2(x, y, [ARRAY 1D:INT] hash, [ARRAY 1D:1D:INT] gradient, min, max) 11 | /* 12 | Calculates the simplex noise for a specified position. 13 | Assumes a size of 256! 14 | 15 | Argument0 - x position 16 | Argument1 - y position 17 | Argument2 - Array of hash values 18 | Argument3 - Corner gradients 19 | Argument4 - minimum range of final value 20 | Argument5 - maximum range of final value 21 | 22 | NOTE: https://code.google.com/p/battlestar-tux/source/browse/procedural/simplexnoise.cpp 23 | */ 24 | var result = 0, 25 | //Noise contributions from the three corners: 26 | n0, n1, n2, 27 | //Skew input space to determine current simplex cell 28 | f2 = 0.5 * (sqrt(3.0) - 1.0); 29 | //Hairy factor for 2D 30 | var s = (argument0 + argument1) * f2, 31 | i = floor(argument0 + s), // Treat as int 32 | j = floor(argument1 + s), // Treat as int 33 | g2 = (3.0 - sqrt(3.0)) / 6.0; 34 | 35 | var t = (i + j) * g2, 36 | //Unskew cell origin back to x / y 37 | X0 = i - t, 38 | Y0 = j - t; 39 | //x / y distances from the cell origin 40 | var x0 = argument0 - X0, 41 | y0 = argument1 - Y0; 42 | 43 | var i1, j1; 44 | if (x0 > y0) 45 | { 46 | i1 = 1; 47 | j1 = 0; 48 | } 49 | else 50 | { 51 | i1 = 0; 52 | j1 = 1; 53 | } 54 | 55 | var x1 = x0 - i1 + g2, 56 | y1 = y0 - j1 + g2, 57 | x2 = x0 - 1.0 + 2.0 * g2, 58 | y2 = y0 - 1.0 + 2.0 * g2; 59 | 60 | //Work out hashed gradient indices of the three simplex corners: 61 | var ii = i & 255, 62 | jj = j & 255; 63 | var gi0 = argument2[@ ii + argument2[@ jj]] % 12, 64 | gi1 = argument2[@ ii + i1 + argument2[@ jj + j1]] % 12, 65 | gi2 = argument2[@ ii + 1 + argument2[@ jj + 1]] % 12 66 | 67 | //Calculate contribution of ea. corner: 68 | var t0 = 0.5 - sqr(x0) - sqr(y0); 69 | 70 | if (t0 < 0) 71 | n0 = 0; 72 | else 73 | { 74 | t0 *= t0; 75 | n0 = sqr(t0) * simplex_dot2(argument3[@ gi0], x0, y0); 76 | } 77 | 78 | var t1 = 0.5 - sqr(x1) - sqr(y1); 79 | if (t1 < 0) 80 | n1 = 0; 81 | else 82 | { 83 | t1 *= t1; 84 | n1 = sqr(t1) * simplex_dot2(argument3[@ gi1], x1, y1); 85 | } 86 | 87 | var t2 = 0.5 - sqr(x2) - sqr(y2); 88 | if (t2 < 0) 89 | n2 = 0.0; 90 | else 91 | { 92 | t2 *= t2; 93 | n2 = sqr(t2) * simplex_dot2(argument3[@ gi2], x2, y2); 94 | } 95 | 96 | //Scale result between [-1..1] 97 | result = 70 * (n0 + n1 + n2); 98 | 99 | //Scale between whatever we like: 100 | return result * (argument5 - argument4) / 2 + (argument5 + argument4) / 2; 101 | 102 | #define simplex_octave2 103 | ///simplex_octave2(x, y, [ARRAY 1D:INT] hash, [ARRAY 1D:1D:INT] gradient, min, max, octaves, persistance, scale) 104 | /* 105 | Generates fractal simplex noise at the specified position. 106 | 107 | Argument0 - x position 108 | Argument1 - y position 109 | Argument2 - Array of hash values 110 | Argument3 - Corner gradients 111 | Argument4 - minimum range of final value 112 | Argument5 - maximum range of final value 113 | Argument6 - number of samples 114 | Argument7 - delta octave intensity [0..1] 115 | Argument8 - scale of deltas 116 | 117 | Returns - Calculated result 118 | 119 | NOTE: https://code.google.com/p/battlestar-tux/source/browse/procedural/simplexnoise.cpp 120 | https://code.google.com/p/battlestar-tux/source/browse/procedural/simplexnoise.h 121 | http://www.6by9.net/simplex-noise-for-c-and-python/ 122 | */ 123 | 124 | var total = 0, 125 | freq = argument8, 126 | amp = 1, 127 | maxAmp = 0; // Will keep things between [-1..1] 128 | 129 | for (var i = 0; i < argument6; ++i) 130 | { 131 | total += simplex_raw2(argument0 * freq, argument1 * freq, argument2, argument3, -1, 1) * amp; 132 | 133 | freq *= 2; 134 | maxAmp += amp; 135 | amp *= argument7; 136 | } 137 | 138 | return (total / maxAmp) * (argument5 - argument4) / 2 + (argument5 + argument4) / 2 ; 139 | 140 | #define simplex_raw3 141 | ///simplex_raw3(x, y, z, [ARRAY 1D:INT] hash, [ARRAY 1D:1D:INT] gradient, min, max) 142 | 143 | /* 144 | Calculates the simplex noise for a specified position. 145 | Assumes a size of 256! 146 | 147 | Argument0 - x position 148 | Argument1 - y position 149 | Argument2 - z position 150 | Argument3 - Array of hash values 151 | Argument4 - Corner gradients 152 | Argument5 - minimum range of final value 153 | Argument6 - maximum range of final value 154 | 155 | NOTE: https://code.google.com/p/battlestar-tux/source/browse/procedural/simplexnoise.cpp 156 | */ 157 | var __n0, __n1, __n2, __n3; // Noise of the four corners 158 | 159 | //Skew input space to determine which cell we are in: 160 | var __F3 = 1.0 / 3.0; 161 | var __s = (argument0 + argument1 + argument2) * __F3; 162 | var __i = floor(argument0 + __s), 163 | __j = floor(argument1 + __s), 164 | __k = floor(argument2 + __s); 165 | 166 | var __G3 = 1.0 / 6.0; // Unskew factor 167 | var __t = (__i + __j + __k) * __G3; 168 | var __X0 = __i - __t, //Unskey origin back to x, y, z 169 | __Y0 = __j - __t, 170 | __Z0 = __k - __t; 171 | var __x0 = argument0 - __X0, 172 | __y0 = argument1 - __Y0, 173 | __z0 = argument2 - __Z0; 174 | 175 | var __i1, __j1, __k1, 176 | __i2, __j2, __k2; 177 | 178 | if (__x0 >= __y0) 179 | { 180 | if (__y0 >= __z0) 181 | {__i1 = 1; __j1 = 0; __k1 = 0; __i2 = 1; __j2 = 1; __k2 = 0; } 182 | else if (__x0 >= __z0) 183 | {__i1 = 1; __j1 = 0; __k1 = 0; __i2 = 1; __j2 = 0; __k2 = 1; } 184 | else 185 | {__i1 = 0; __j1 = 0; __k1 = 1; __i2 = 1; __j2 = 0; __k2 = 1; } 186 | } 187 | else 188 | { 189 | if (__y0 < __z0) 190 | {__i1 = 0; __j1 = 0; __k1 = 1; __i2 = 0; __j2 = 1; __k2 = 1; } 191 | else if (__x0 < __z0) 192 | {__i1 = 0; __j1 = 1; __k1 = 0; __i2 = 0; __j2 = 1; __k2 = 1; } 193 | else 194 | {__i1 = 0; __j1 = 1; __k1 = 0; __i2 = 1; __j2 = 1; __k2 = 0; } 195 | } 196 | 197 | var __x1 = __x0 - __i1 + __G3, 198 | __y1 = __y0 - __j1 + __G3, 199 | __z1 = __z0 - __k1 + __G3, 200 | __x2 = __x0 - __i2 + 2.0 * __G3, 201 | __y2 = __y0 - __j2 + 2.0 * __G3, 202 | __z2 = __z0 - __k2 + 2.0 * __G3, 203 | __x3 = __x0 - 1.0 + 3.0 * __G3, 204 | __y3 = __y0 - 1.0 + 3.0 * __G3, 205 | __z3 = __z0 - 1.0 + 3.0 * __G3; 206 | 207 | var __ii = __i & 255, 208 | __jj = __j & 255, 209 | __kk = __k & 255; 210 | var __gi0 = argument3[@ __ii + argument3[@ __jj + argument3[@ __kk] ]] % 12, 211 | __gi1 = argument3[@ __ii + __i1 + argument3[@ __jj + __j1 + argument3[@ __kk + __k1] ]] % 12, 212 | __gi2 = argument3[@ __ii + __i2 + argument3[@ __jj + __j2 + argument3[@ __kk + __k2] ]] % 12, 213 | __gi3 = argument3[@ __ii + 1.0 + argument3[@ __jj + 1.0 + argument3[@ __kk + 1.0] ]] % 12; 214 | 215 | var __t0 = 0.6 - sqr(__x0) - sqr(__y0) - sqr(__z0); 216 | if (__t0 < 0) 217 | __n0= 0.0; 218 | else 219 | { 220 | __t0 *= __t0; 221 | __n0 = sqr(__t0) * simplex_dot3(argument4[__gi0], __x0, __y0, __z0); 222 | } 223 | 224 | var __t1 = 0.6 - sqr(__x1) - sqr(__y1) - sqr(__z1); 225 | if (__t1 < 1) 226 | __n1= 0.0; 227 | else 228 | { 229 | __t1 *= __t1; 230 | __n1 = sqr(__t1) * simplex_dot3(argument4[__gi1], __x1, __y1, __z1); 231 | } 232 | 233 | var __t2 = 0.6 - sqr(__x2) - sqr(__y2) - sqr(__z2); 234 | if (__t2 < 2) 235 | __n2= 0.0; 236 | else 237 | { 238 | __t2 *= __t2; 239 | __n2 = sqr(__t2) * simplex_dot3(argument4[__gi2], __x2, __y2, __z2); 240 | } 241 | 242 | var __t3 = 0.6 - sqr(__x3) - sqr(__y3) - sqr(__z3); 243 | if (__t3 < 3) 244 | __n3= 0.0; 245 | else 246 | { 247 | __t3 *= __t3; 248 | __n3 = sqr(__t3) * simplex_dot3(argument4[__gi3], __x3, __y3, __z3); 249 | } 250 | 251 | return (32.0 * (__n0 + __n1 + __n2 + __n3)) * (argument6 - argument5) / 2 + (argument6 + argument5) / 2; 252 | 253 | #define simplex_octave3 254 | ///simplex_octave3(x, y, z, [ARRAY 1D:INT] hash, [ARRAY 1D:1D:INT] gradient, min, max, octaves, persistance, scale) 255 | /* 256 | Generates fractal simplex noise at the specified position. 257 | 258 | Argument0 - x position 259 | Argument1 - y position 260 | Argument2 - z position 261 | Argument3 - Array of hash values 262 | Argument4 - Corner gradients 263 | Argument5 - minimum range of final value 264 | Argument6 - maximum range of final value 265 | Argument7 - number of samples 266 | Argument8 - delta octave intensity [0..1] 267 | Argument9 - scale of deltas 268 | 269 | Returns - Calculated result 270 | 271 | NOTE: https://code.google.com/p/battlestar-tux/source/browse/procedural/simplexnoise.cpp 272 | https://code.google.com/p/battlestar-tux/source/browse/procedural/simplexnoise.h 273 | http://www.6by9.net/simplex-noise-for-c-and-python/ 274 | */ 275 | 276 | var __total = 0, 277 | __freq = argument9, 278 | __amp = 1, 279 | __maxAmp = 0; // Will keep things between [-1..1] 280 | 281 | for (var i = 0; i < argument7; ++i) 282 | { 283 | __total += simplex_raw3(argument0 * __freq, argument1 * __freq, argument2 * __freq, argument3, argument4, -1, 1) * __amp; 284 | 285 | __freq *= 2; 286 | __maxAmp += __amp; 287 | __amp *= argument8; 288 | } 289 | 290 | return (__total / __maxAmp) * (argument6 - argument7) / 2 + (argument6 + argument7) / 2 ; 291 | 292 | #define simplex_dot2 293 | ///simplex_dot2([ARRAY 1D:INT] vec, x, y) 294 | /* 295 | 2D dot product. 296 | 297 | Argument0 - 1D array of 2 vector values 298 | Argument1 - x val 299 | Argument2 - y val 300 | 301 | Returns - Result 302 | */ 303 | 304 | return (argument0[@ 0] * argument1) + (argument0[@ 1] * argument2); 305 | 306 | #define simplex_dot3 307 | ///simplex_dot3([ARRAY 1D:INT] vec, x, y, z) 308 | /* 309 | 3D dot product. 310 | 311 | Argument0 - 1D array of 3 vector values 312 | Argument1 - x val 313 | Argument2 - y val 314 | Argument3 - z val 315 | 316 | Returns - Result 317 | */ 318 | 319 | return (argument0[@ 0] * argument1) + (argument0[@ 1] * argument2) + (argument0[@ 2] * argument3) 320 | 321 | #define simplex_generate_hash 322 | ///simplex_generate_hash() 323 | /* 324 | Generates a 512-size hash with 256 uniqe values, 325 | each repeated once (to avoid out-of-bounds. 326 | 327 | Returns - Array of hash values 328 | */ 329 | 330 | var __final; 331 | __final[512] = 0; 332 | 333 | for (var i = 0; i < 256; ++i) 334 | __final[i] = i; 335 | 336 | //Randomize hash by swapping: 337 | //Use different seeds for different simplex results: 338 | for (var i = 0; i < 256; ++i) 339 | { 340 | var __j = irandom(255), 341 | __s = __final[i]; 342 | __final[i] = __final[__j]; 343 | __final[__j] = __s; 344 | } 345 | 346 | for (var i = 0; i < 256; ++i) 347 | __final[255 + i] = __final[i]; 348 | 349 | return __final; 350 | 351 | #define simplex_generate_grad3 352 | ///simplex_generate_grad3() 353 | /* 354 | Generates the 3D gradients 355 | 356 | Returns - Array of arrays of points. 357 | */ 358 | var a0, a1, a2, a3, a4, a5, 359 | a6, a7, a8, a9, a10, a11; 360 | 361 | a0[0] = 1 a0[1] = 1 a0[2] = 0 362 | a1[0] = -1 a1[1] = 1 a1[2] = 0 363 | a2[0] = 1 a2[1] = -1 a2[2] = 0 364 | a3[0] = -1 a3[1] = -1 a3[2] = 0 365 | 366 | a4[0] = 1 a4[1] = 0 a4[2] = 1 367 | a5[0] = -1 a5[1] = 0 a5[2] = 1 368 | a6[0] = 1 a6[1] = 0 a6[2] = -1 369 | a7[0] = -1 a7[1] = 0 a7[2] = -1 370 | 371 | a8[0] = 0 a8[1] = 1 a8[2] = 0 372 | a9[0] = 0 a9[1] = -1 a9[2] = 0 373 | a10[0] = 0 a10[1] = 1 a10[2] = -1 374 | a11[0] = 0 a11[1] = -1 a11[2] = -1 375 | 376 | var result; 377 | 378 | result[11] = a11 379 | result[10] = a10 380 | result[9] = a9 381 | result[8] = a8 382 | result[7] = a7 383 | result[6] = a6 384 | result[5] = a5 385 | result[4] = a4 386 | result[3] = a3 387 | result[2] = a2 388 | result[1] = a1 389 | result[0] = a0 390 | 391 | return result 392 | --------------------------------------------------------------------------------