├── .gitignore ├── bow.blend ├── sight.blend ├── WackClubSans-Regular.ttf ├── blender_log_mesh_data.py ├── .gitmodules ├── README.md ├── shaders.glsl ├── bake.sh ├── gen_bow.py ├── json2flat.py ├── main.c └── map.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.blend1 3 | build 4 | -------------------------------------------------------------------------------- /bow.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedric-h/rpgc/HEAD/bow.blend -------------------------------------------------------------------------------- /sight.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedric-h/rpgc/HEAD/sight.blend -------------------------------------------------------------------------------- /WackClubSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedric-h/rpgc/HEAD/WackClubSans-Regular.ttf -------------------------------------------------------------------------------- /blender_log_mesh_data.py: -------------------------------------------------------------------------------- 1 | import bpy 2 | import bmesh 3 | 4 | print([[int(x) for x in p.vertices] for p in bpy.context.active_object.data.polygons]) 5 | print('\n'.join([str(x.co) for x in bpy.context.active_object.data.vertices])) 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sokol"] 2 | path = sokol 3 | url = git@github.com:floooh/sokol.git 4 | [submodule "sokol-tools-bin"] 5 | path = sokol-tools-bin 6 | url = git@github.com:floooh/sokol-tools-bin.git 7 | [submodule "stb"] 8 | path = stb 9 | url = git@github.com:nothings/stb.git 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://github.com/cedric-h/rpgc/assets/25539554/7e685f20-5c93-47f5-92b3-46aae3ef0824) 2 | ![image](https://github.com/cedric-h/rpgc/assets/25539554/c35e5f1b-2596-4293-b766-954d7185e785) 3 | 4 | 5 | # goal 6 | sup nerds. this is a rewrite in C of [a game i wrote in rust a while ago](https://github.com/cedric-h/rpg). 7 | 8 | ## deps 9 | `sudo apt-get install libgl-dev libx11-dev libxi-dev libxcursor-dev` 10 | 11 | `git submodule update --init --depth=1` 12 | 13 | `python3 json2flat.py` 14 | 15 | ## run 16 | `./bake.sh && ./build/a.out` 17 | 18 | ## watch 19 | `ls *.c | entr -s 'echo && ./bake.sh && ./build/a.out'` 20 | -------------------------------------------------------------------------------- /shaders.glsl: -------------------------------------------------------------------------------- 1 | #pragma sokol @ctype mat4 Mat4 2 | 3 | #pragma sokol @vs vs 4 | uniform vs_params { 5 | mat4 mvp; 6 | }; 7 | 8 | in vec4 position; 9 | in float palette_index0; 10 | in vec2 uv0; 11 | 12 | out float palette_index; 13 | out vec2 uv; 14 | 15 | void main() { 16 | gl_Position = mvp * position; 17 | palette_index = palette_index0; 18 | uv = uv0; 19 | } 20 | #pragma sokol @end 21 | 22 | #pragma sokol @fs fs 23 | uniform sampler2D palette; 24 | uniform sampler2D tex; 25 | in float palette_index; 26 | in vec2 uv; 27 | out vec4 frag_color; 28 | 29 | void main() { 30 | frag_color = vec4(texture(tex, uv).r) * texture( 31 | palette, 32 | vec2( 33 | (0.5 + int(palette_index) % 8) / 8, 34 | (0.5 + int(palette_index / 8)) / 8 35 | ) 36 | ); 37 | } 38 | #pragma sokol @end 39 | 40 | #pragma sokol @program triangle vs fs 41 | -------------------------------------------------------------------------------- /bake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -d "build" ]; then 4 | mkdir build 5 | fi 6 | 7 | cd build 8 | 9 | # print a horizontal line of dashes; helps separate the output if run serially 10 | printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - | lolcat 11 | 12 | if [[ $OSTYPE == 'darwin'* ]]; then 13 | if [[ $(../sokol-tools-bin/bin/osx/sokol-shdc --input ../shaders.glsl --output shaders.glsl.h --slang metal_macos | tee /dev/tty) ]]; then 14 | exit 1 15 | fi 16 | 17 | gcc -g -O0 -ObjC ../main.c -Wall -Werror -framework QuartzCore -framework Cocoa -framework MetalKit -framework Metal -framework OpenGL -framework AudioToolbox 18 | else 19 | if [[ $(../sokol-tools-bin/bin/linux/sokol-shdc --input ../shaders.glsl --output shaders.glsl.h --slang glsl330 | tee /dev/tty) ]]; then 20 | exit 1 21 | fi 22 | 23 | clang -fsanitize=undefined -g -O0 -L/usr/lib -lX11 -lXi -lXcursor -lGL -ldl -lm -lpthread ../main.c 24 | # gcc -g -O0 ../main.c -Wall -Werror -lX11 -lXi -lXcursor -lGL -ldl -lm -lpthread 25 | fi 26 | -------------------------------------------------------------------------------- /gen_bow.py: -------------------------------------------------------------------------------- 1 | from math import sqrt 2 | import bpy 3 | 4 | coords = [] 5 | faces = [] 6 | idx = 0 7 | 8 | def draw_line(x0, y0, x1, y1, thickness): 9 | global idx 10 | dx = x0 - x1 11 | dy = y0 - y1 12 | 13 | nx = -dy 14 | ny = dx 15 | 16 | tmag = sqrt(nx*nx + ny*ny) 17 | tx = nx / tmag * (thickness * 0.5) 18 | ty = ny / tmag * (thickness * 0.5) 19 | 20 | coords.append((x0 + tx, y0 + ty, 0.0)) 21 | coords.append((x0 - tx, y0 - ty, 0.0)) 22 | coords.append((x1 + tx, y1 + ty, 0.0)) 23 | coords.append((x1 - tx, y1 - ty, 0.0)) 24 | faces.append((idx+0, idx+1, idx+2)) 25 | faces.append((idx+2, idx+1, idx+3)) 26 | idx += 4 27 | 28 | draw_line(-0.10, -1.0, 0.03, -1.1, 0.045) 29 | draw_line(-0.10, -1.0, 0.20, -0.4, 0.105) 30 | draw_line( 0.25, -0.1, 0.20, -0.4, 0.095) 31 | draw_line( 0.25, -0.1, 0.10, 0.0, 0.075) 32 | draw_line( 0.25, 0.1, 0.10, 0.0, 0.075) 33 | draw_line( 0.25, 0.1, 0.20, 0.4, 0.095) 34 | draw_line(-0.10, 1.0, 0.20, 0.4, 0.105) 35 | draw_line(-0.10, 1.0, 0.03, 1.1, 0.045) 36 | 37 | mesh = bpy.data.meshes.new(name="MyMesh") 38 | 39 | object = bpy.data.objects.new('MESH', mesh) 40 | bpy.context.collection.objects.link(object) 41 | 42 | mesh.from_pydata(coords, [], faces) 43 | mesh.update(calc_edges=True) 44 | -------------------------------------------------------------------------------- /json2flat.py: -------------------------------------------------------------------------------- 1 | import json 2 | import struct 3 | 4 | out = bytearray() 5 | 6 | kinds = [ 7 | { "inJson": "trees", "name": "tree", "floats": 2, "fields": ['x', 'y'] }, 8 | { "inJson": "circles", "name": "circle", "floats": 3, "fields": ['x', 'y', 'radius' ] }, 9 | ] 10 | 11 | with open('build/map.h', 'w') as f: 12 | f.write("#include \n\n"); 13 | 14 | for kd in kinds: 15 | f.write(f"typedef struct {{" + '\n') 16 | for field in kd['fields']: 17 | f.write(f" float {field};" + '\n') 18 | f.write(f"}} MapData_{kd['name'].capitalize()};" + '\n') 19 | 20 | f.write('typedef struct {\n') 21 | for kd in kinds: 22 | f.write(f" MapData_{kd['name'].capitalize()} *{kd['inJson']};" + '\n'); 23 | f.write(f" uint32_t n{kd['inJson']};" + '\n'); 24 | f.write('} MapData;\n\n') 25 | 26 | f.write('static MapData parse_map_data(FILE *f) {\n'); 27 | f.write(' MapData md = {0};\n'); 28 | f.write(' uint32_t sec_len = 0;\n'); 29 | for kd in kinds: 30 | data_type = 'MapData_' + kd['name'].capitalize() 31 | f.write(f" if (fread(&sec_len, sizeof(uint32_t), 1, f) < 1)\n") 32 | f.write(f' perror("couldn\'t get map data section length"), exit(1);\n') 33 | f.write(f" sec_len = md.n{kd['inJson']} = ntohl(sec_len);\n") 34 | f.write(f" if (fread(\n") 35 | f.write(f" md.{kd['inJson']} = calloc(sizeof({data_type}), sec_len),\n") 36 | f.write(f" sizeof({data_type}),\n"), 37 | f.write(f" sec_len,\n") 38 | f.write(f" f\n") 39 | f.write(f' ) < sec_len) perror("less map data than section length"), exit(1);\n') 40 | f.write(' return md;\n'); 41 | f.write('}'); 42 | 43 | 44 | with open("map.json", "r") as f: 45 | data = json.loads(f.read()) 46 | for kd in kinds: 47 | inJson = data[kd['inJson']] 48 | out += struct.pack('!L', len(inJson)) 49 | for pl in inJson: 50 | if type(pl) is dict and pl['pos']: 51 | en = pl['pos'] + [pl['radius']] 52 | else: 53 | en = pl 54 | out += struct.pack('f'*kd['floats'], *en) 55 | 56 | with open('build/map.bytes', 'wb') as f: 57 | f.write(out) 58 | 59 | print("done!") 60 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SOKOL_IMPL 4 | #if defined(_MSC_VER) 5 | #define SOKOL_D3D11 6 | #define SOKOL_LOG(str) OutputDebugStringA(str) 7 | #elif defined(__EMSCRIPTEN__) 8 | #define SOKOL_GLES2 9 | #elif defined(__APPLE__) 10 | // NOTE: on macOS, sokol.c is compiled explicitly as ObjC 11 | #define SOKOL_METAL 12 | #else 13 | #define SOKOL_GLCORE33 14 | #endif 15 | 16 | #include "sokol/sokol_time.h" 17 | #include "sokol/sokol_app.h" 18 | #include "sokol/sokol_gfx.h" 19 | #include "sokol/sokol_glue.h" 20 | 21 | static float signum(float f) { return (f > 0) - (f < 0); } 22 | static float lerp_rads(float a, float b, float t) { 23 | float difference = fmodf(b - a, M_PI*2.0f), 24 | distance = fmodf(2.0f * difference, M_PI*2.0f) - difference; 25 | return a + distance * t; 26 | } 27 | 28 | #define vec2(_x, _y) ((Vec2) { .x = (_x), .y = (_y) }) 29 | typedef union { struct { float x, y; }; float arr[2]; } Vec2; 30 | static float vec2_rads(Vec2 a) { return atan2f(a.y, a.x); } 31 | static Vec2 rads2(float r) { return vec2(cosf(r), sinf(r)); } 32 | static Vec2 sub2(Vec2 a, Vec2 b) { return vec2(a.x-b.x, a.y-b.y); } 33 | static Vec2 add2(Vec2 a, Vec2 b) { return vec2(a.x+b.x, a.y+b.y); } 34 | static Vec2 mul2(Vec2 a, Vec2 b) { return vec2(a.x*b.x, a.y*b.y); } 35 | // static Vec2 sub2f(Vec2 a, float f) { return vec2(a.x-f, a.y-f); } 36 | static Vec2 div2f(Vec2 a, float f) { return vec2(a.x/f, a.y/f); } 37 | static Vec2 mul2f(Vec2 a, float f) { return vec2(a.x*f, a.y*f); } 38 | static float dot2(Vec2 a, Vec2 b) { return a.x*b.x + a.y*b.y; } 39 | static float mag2(Vec2 a) { return sqrtf(dot2(a, a)); } 40 | static Vec2 perp2(Vec2 v) { return vec2(-v.y, v.x); } 41 | static Vec2 lerp2(Vec2 a, Vec2 b, float t) { return add2(mul2f(a, 1.0f - t), mul2f(b, t)); } 42 | static float dist2(Vec2 a, Vec2 b) { return mag2(sub2(a, b)); } 43 | static Vec2 norm2(Vec2 a) { return div2f(a, mag2(a) ?: 1.0f); } 44 | static Vec2 refl2(Vec2 d, Vec2 norm) { return sub2(d, mul2f(norm, 2.0f*dot2(d, norm))); } 45 | 46 | typedef struct { float arr[2][2]; } Mat2; 47 | static Mat2 z_rot2x2(float rads) { 48 | float sin = sinf(rads), cos = cosf(rads); 49 | return (Mat2) { 50 | .arr = { 51 | { cos, sin }, 52 | { -sin, cos }, 53 | } 54 | }; 55 | } 56 | static Vec2 mul2x22(Mat2 m, Vec2 v) { 57 | return vec2( 58 | m.arr[0][0] * v.arr[0] + m.arr[1][0] * v.arr[1], 59 | m.arr[0][1] * v.arr[0] + m.arr[1][1] * v.arr[1] 60 | ); 61 | } 62 | 63 | typedef struct { float arr[4][4]; } Mat4; 64 | static Mat4 ortho4x4(float left, float right, float bottom, float top, float near, float far) { 65 | Mat4 res = {0}; 66 | 67 | res.arr[0][0] = 2.0f / (right - left); 68 | res.arr[1][1] = 2.0f / (top - bottom); 69 | res.arr[2][2] = 2.0f / (near - far); 70 | res.arr[3][3] = 1.0f; 71 | 72 | res.arr[3][0] = (left + right) / (left - right); 73 | res.arr[3][1] = (bottom + top) / (bottom - top); 74 | res.arr[3][2] = (far + near) / (near - far); 75 | 76 | return res; 77 | } 78 | 79 | typedef struct { float arr[4]; } Vec4; 80 | static Vec4 mul4x44(Mat4 m, Vec4 v) { 81 | Vec4 res; 82 | for(int x = 0; x < 4; ++x) { 83 | float sum = 0; 84 | for(int y = 0; y < 4; ++y) 85 | sum += m.arr[y][x] * v.arr[y]; 86 | 87 | res.arr[x] = sum; 88 | } 89 | return res; 90 | } 91 | 92 | 93 | #include "build/shaders.glsl.h" 94 | 95 | #include "build/map.h" 96 | 97 | // #define STB_RECT_PACK_IMPLEMENTATION 98 | // #include "stb/stb_rect_pack.h" 99 | 100 | #define STB_TRUETYPE_IMPLEMENTATION 101 | #include "stb/stb_truetype.h" 102 | 103 | typedef uint64_t Tick; 104 | 105 | typedef struct { float x, y, z, color, u, v; } Vert; 106 | typedef struct { 107 | Vert *verts; 108 | uint16_t *idxs; 109 | int nvert, nidx; 110 | float min_z, max_z; 111 | sg_bindings bind; 112 | } Geo; 113 | static Geo geo_alloc(int nvert, int nidx) { 114 | return (Geo) { 115 | .nvert = nvert, 116 | .nidx = nidx, 117 | .verts = calloc(sizeof(Vert), nvert), 118 | .idxs = calloc(sizeof(uint16_t), nidx), 119 | }; 120 | } 121 | static void geo_bind_init(Geo *geo, const char *lvert, const char *lidx, sg_usage usg) { 122 | geo->bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc) { 123 | .size = sizeof(Vert) * geo->nvert, 124 | .data = (usg == SG_USAGE_IMMUTABLE) 125 | ? (sg_range) { .ptr = geo->verts, .size = geo->nvert * sizeof(Vert) } 126 | : (sg_range) { 0 }, 127 | .usage = usg, 128 | .label = lvert 129 | }); 130 | geo->bind.index_buffer = sg_make_buffer(&(sg_buffer_desc) { 131 | .size = sizeof(uint16_t) * geo->nidx, 132 | .type = SG_BUFFERTYPE_INDEXBUFFER, 133 | .data = (usg == SG_USAGE_IMMUTABLE) 134 | ? (sg_range) { .ptr = geo->idxs, .size = geo->nidx * sizeof(uint16_t) } 135 | : (sg_range) { 0 }, 136 | .usage = usg, 137 | .label = lidx 138 | }); 139 | } 140 | float geo_min_z = -1.0f, geo_max_z = 1.0f; 141 | static void geo_find_z_range(Vert *beg, Vert *end) { 142 | for (Vert *i = beg; i != end; i++) 143 | geo_min_z = (i->z < geo_min_z) ? i->z : geo_min_z, 144 | geo_max_z = (i->z > geo_max_z) ? i->z : geo_max_z; 145 | } 146 | 147 | /* Entity Index - generationally indexed entity pointer */ 148 | typedef struct { uint32_t idx, gen; } Edx; 149 | 150 | #define WAFFLE_NSLOT (8) 151 | #define WAFFLE_SLOT_OCCUPANCY_DIST (0.5f) 152 | typedef struct { 153 | Edx slots[WAFFLE_NSLOT]; 154 | Edx attacker; 155 | } Waffle; 156 | 157 | 158 | typedef enum { 159 | EntMask_Player = (1 << 0), 160 | EntMask_Terrain = (1 << 1), 161 | EntMask_Enemy = (1 << 2), 162 | } EntMask; 163 | 164 | typedef enum { 165 | EntLooks_None, 166 | EntLooks_Player, 167 | EntLooks_Pot, 168 | EntLooks_Arrow, 169 | } EntLooks; 170 | 171 | typedef enum { 172 | EntItem_None, 173 | EntItem_Sword, 174 | EntItem_Bow, 175 | EntItem_COUNT, 176 | } EntItem; 177 | uint8_t item_shoots[EntItem_COUNT] = { 178 | [EntItem_Bow] = 1, 179 | }; 180 | uint8_t item_hits[EntItem_COUNT] = { 181 | [EntItem_Sword] = 1, 182 | }; 183 | float item_x_offset[EntItem_COUNT] = { 184 | [EntItem_Bow] = -0.75f, 185 | }; 186 | float item_rot_offset[EntItem_COUNT] = { 187 | [EntItem_Sword] = -M_PI_2, 188 | }; 189 | uint8_t item_always_point_down[EntItem_COUNT] = { 190 | [EntItem_Bow] = 1, 191 | }; 192 | Tick item_attack_duration[EntItem_COUNT] = { 193 | [EntItem_Sword] = 50, 194 | [EntItem_Bow] = 85, 195 | }; 196 | 197 | typedef struct Ent Ent; 198 | struct Ent { 199 | /* bookkeeping */ 200 | uint8_t active; 201 | uint32_t gen; 202 | 203 | /* appearance */ 204 | EntLooks looks; 205 | 206 | /* combat */ 207 | Tick last_damaged; 208 | uint8_t hp, hostile, aggroed, pointy; 209 | 210 | /* physics */ 211 | float radius, friction; 212 | EntMask has_mask, hit_mask, item_hit_mask; 213 | Vec2 pos, vel; 214 | 215 | /* held item */ 216 | EntItem item; 217 | struct { Tick end; Vec2 toward; uint8_t shot; } swing; 218 | }; 219 | 220 | typedef struct { 221 | Vec2 pos; 222 | uint8_t hp; 223 | Tick tick; 224 | Ent *ent; 225 | } DmgLbl; 226 | 227 | typedef enum { 228 | UiBoxLooks_NONE, /* UiBoxes with this Look will be skipped */ 229 | UiBoxLooks_Frame, 230 | UiBoxLooks_Slot, 231 | UiBoxLooks_Item, 232 | } UiBoxLooks; 233 | 234 | typedef enum { 235 | UiBoxProp_CanDrag = (1 << 1), 236 | UiBoxProp_DragZone = (1 << 2), /* track when something lifted off of you */ 237 | UiBoxProp_DropZone = (1 << 3), /* track when something dropped onto you */ 238 | UiBoxProp_LockDrop = (1 << 4), /* lock your movement to relevant zones */ 239 | } UiBoxProp; 240 | 241 | typedef struct UiBox UiBox; 242 | struct UiBox { 243 | UiBoxProp props; 244 | UiBoxLooks looks; 245 | 246 | UiBox *parent; /* only "position me relative to this" */ 247 | Vec2 pos, size; /* pos = top left */ 248 | 249 | EntItem item; /* hmm */ 250 | }; 251 | #define UI_BOX_COUNT (1 << 5) 252 | typedef struct { 253 | UiBox boxes[UI_BOX_COUNT]; 254 | UiBox *grabbed, *root, *drag_start_box, *player_weapon_slot; 255 | Vec2 last_mouse; 256 | } UiState; 257 | 258 | /* application state */ 259 | static struct { 260 | MapData map; 261 | 262 | uint8_t keys[SAPP_MAX_KEYCODES]; 263 | struct { uint8_t active; Vec2 pos; } aimer; 264 | 265 | Ent ents[1 << 10]; 266 | DmgLbl dmg_lbls[1 << 7]; 267 | 268 | UiState ui; 269 | 270 | uint64_t frame; /* a sokol_time tick, not one of our game ticks */ 271 | Tick tick; 272 | double fixed_tick_accumulator; 273 | 274 | Ent *player; 275 | Waffle waffle; 276 | Vec2 cam; 277 | 278 | Geo static_geo, dyn_geo; 279 | size_t static_geo_n_idx; 280 | 281 | sg_pipeline pip; 282 | sg_pass_action pass_action; 283 | } state; 284 | #define ENT_MAX (sizeof(state.ents) / sizeof(state.ents[0])) 285 | 286 | /* appropriating ECS terminology here. 287 | * a SYSTEM is just something that iterates over all entities. */ 288 | #define SYSTEM(e) for (Ent *e = state.ents; (e - state.ents) < ENT_MAX; e++) if (e->active) 289 | #define UI_SYSTEM(b) for (UiBox *b = state.ui.boxes; (b - state.ui.boxes) < UI_BOX_COUNT; b++) if (b->looks) 290 | static Ent *ent_alloc(void) { 291 | for (int i = 0; i < ENT_MAX; i++) 292 | if (!state.ents[i].active) { 293 | state.ents[i] = (Ent) { 294 | .active = 1, 295 | .gen = state.ents[i].gen, 296 | .swing.toward.x = 1.0f 297 | }; 298 | return state.ents + i; 299 | } 300 | puts("entity pool exhausted"), exit(1); 301 | } 302 | static void ent_free(Ent *ent) { 303 | ent->gen++; 304 | ent->active = 0; 305 | } 306 | static void dmg_lbl_push(uint8_t hp, Vec2 pos, Ent *ent); 307 | static int ent_damage(Ent *hit, Ent *hitter) { 308 | uint8_t dmg = 1; // hitter->item == EntItem_Sword; 309 | 310 | int can_damage = state.tick - hit->last_damaged > 5; 311 | if (can_damage) { 312 | dmg_lbl_push(dmg, add2(hit->pos, vec2(0.0f, 1.0f)), hit); 313 | hit->last_damaged = state.tick; 314 | if (hit->hp < dmg) 315 | ent_free(hit); 316 | else 317 | hit->hp -= dmg; 318 | } 319 | return can_damage; 320 | } 321 | 322 | static float ent_speed(Ent *e) { 323 | return (e->vel.x == 0.0f || signum(e->vel.x) == signum(e->swing.toward.x)) 324 | ? 0.0075f 325 | : 0.0045f; 326 | } 327 | 328 | static Edx edx_from(Ent *ent) { 329 | return (Edx) { .idx = (ent - state.ents) + 1, .gen = ent->gen }; 330 | } 331 | static Ent *edx_deref(Edx edx) { 332 | return (edx.idx > 0 && edx.gen == state.ents[edx.idx-1].gen) 333 | ? (state.ents + edx.idx - 1) 334 | : NULL; 335 | } 336 | 337 | static Vec2 waffle_slot_pos(int slot_i) { 338 | float angle = ((float)slot_i / (float)WAFFLE_NSLOT) * M_PI * 2.0f; 339 | return add2(state.player->pos, mul2f(rads2(angle), 2.0f)); 340 | } 341 | 342 | static void waffle_update(Waffle *waffle) { 343 | Ent *attacker = edx_deref(waffle->attacker); 344 | 345 | if (state.player->gen > 0) return; 346 | 347 | SYSTEM(e) { 348 | if (!e->hostile || e == attacker) continue; 349 | 350 | if (dist2(e->pos, state.player->pos) < 5.0f) 351 | e->aggroed = 1; 352 | 353 | if (!e->aggroed) continue; 354 | 355 | /* find the closest slot */ 356 | Vec2 close_slot; 357 | int close_slot_i; 358 | float slot_dist = 20.0f; 359 | for (int i = 0; i < WAFFLE_NSLOT; i++) { 360 | Ent *slot_e = edx_deref(waffle->slots[i]); 361 | if (slot_e && slot_e != e) continue; 362 | 363 | Vec2 slot_pos = waffle_slot_pos(i); 364 | float to_slot = dist2(slot_pos, e->pos); 365 | if (to_slot < slot_dist) 366 | slot_dist = to_slot, 367 | close_slot = slot_pos, 368 | close_slot_i = i; 369 | } 370 | 371 | /* be propelled toward it */ 372 | if (slot_dist > 0.1f && slot_dist < 20.0f) { 373 | Vec2 delta = sub2(close_slot, e->pos); 374 | float del_mag = mag2(delta); 375 | float speed = fminf(del_mag, ent_speed(e) * 0.9f); 376 | delta = div2f(delta, del_mag); 377 | e->vel = add2(e->vel, mul2f(delta, speed)); 378 | e->swing.toward = delta; 379 | } 380 | 381 | /* claim it if you're close enough */ 382 | if (slot_dist < WAFFLE_SLOT_OCCUPANCY_DIST) { 383 | waffle->slots[close_slot_i] = edx_from(e); 384 | e->swing.toward = norm2(sub2(state.player->pos, e->pos)); 385 | } 386 | } 387 | 388 | int attacker_slot_i = 0; 389 | for (int i = 0; i < WAFFLE_NSLOT; i++) { 390 | Ent *slot_e = edx_deref(waffle->slots[i]); 391 | if (!slot_e) continue; 392 | if (slot_e == attacker) { attacker_slot_i = i; continue; } 393 | 394 | /* unclaim slots with distant owners */ 395 | if (dist2(slot_e->pos, waffle_slot_pos(i)) > WAFFLE_SLOT_OCCUPANCY_DIST) { 396 | waffle->slots[i] = (Edx) {0}; 397 | continue; 398 | } 399 | 400 | /* if nobody is attacking yet, well shucks, guess I oughta! */ 401 | if (!attacker) { 402 | waffle->attacker = edx_from(slot_e); 403 | attacker = slot_e; 404 | slot_e->swing.end = state.tick + item_attack_duration[slot_e->item]; 405 | } 406 | } 407 | 408 | if (attacker) { 409 | if (state.tick > attacker->swing.end) 410 | waffle->attacker = (Edx) {0}; 411 | else { 412 | Vec2 slot_pos = waffle_slot_pos(attacker_slot_i); 413 | Vec2 goal = lerp2(state.player->pos, slot_pos, 0.6f); 414 | 415 | Vec2 delta = sub2(goal, attacker->pos); 416 | float delta_mag = mag2(delta); 417 | delta = div2f(delta, delta_mag); 418 | 419 | float speed = 0.005f * fminf(delta_mag, 1.00f); 420 | attacker->vel = add2(attacker->vel, mul2f(delta, speed)); 421 | } 422 | } 423 | } 424 | 425 | 426 | stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs 427 | 428 | #define PALETTE \ 429 | X(Color_White, 1.00f, 1.00f, 1.00f, 1.00f) \ 430 | X(Color_Beige, 0.72f, 0.64f, 0.53f, 1.00f) \ 431 | X(Color_Brown, 0.50f, 0.42f, 0.31f, 1.00f) \ 432 | X(Color_DarkBrown, 0.30f, 0.25f, 0.18f, 1.00f) \ 433 | X(Color_DarkerBrown, 0.25f, 0.20f, 0.13f, 1.00f) \ 434 | X(Color_Blue, 0.00f, 0.47f, 0.95f, 1.00f) \ 435 | X(Color_Red, 0.90f, 0.16f, 0.22f, 1.00f) \ 436 | X(Color_Maroon, 0.75f, 0.13f, 0.22f, 1.00f) \ 437 | X(Color_DarkMaroon, 0.55f, 0.03f, 0.12f, 1.00f) \ 438 | X(Color_Green, 0.00f, 0.89f, 0.19f, 1.00f) \ 439 | X(Color_LightGrey, 0.78f, 0.78f, 0.78f, 1.00f) \ 440 | X(Color_LightishGrey, 0.68f, 0.68f, 0.68f, 1.00f) \ 441 | X(Color_Grey, 0.51f, 0.51f, 0.51f, 1.00f) \ 442 | X(Color_DarkGrey, 0.31f, 0.31f, 0.31f, 1.00f) \ 443 | X(Color_Yellow, 0.99f, 0.98f, 0.00f, 1.00f) \ 444 | X(Color_SlotColor, 0.42f, 0.40f, 0.39f, 1.00f) \ 445 | X(Color_DarkSlotColor, 0.32f, 0.30f, 0.29f, 1.00f) \ 446 | X(Color_ForestShadow, 0.18f, 0.43f, 0.36f, 1.00f) \ 447 | X(Color_TreeBorder, 0.00f, 0.42f, 0.13f, 1.00f) \ 448 | X(Color_TreeGreen, 0.00f, 0.46f, 0.17f, 1.00f) \ 449 | X(Color_TreeGreen1, 0.04f, 0.50f, 0.21f, 1.00f) \ 450 | X(Color_TreeGreen2, 0.08f, 0.54f, 0.25f, 1.00f) \ 451 | X(Color_TreeGreen3, 0.12f, 0.58f, 0.29f, 1.00f) \ 452 | 453 | #define X(name, r, g, b, a) name, 454 | typedef enum { PALETTE } Color; 455 | #undef X 456 | 457 | #define GAME_SCALE (11.8f) 458 | static Mat4 mvp4x4(void) { 459 | float f_range = 1.0f / (geo_max_z - geo_min_z); 460 | 461 | float xx = 1.0f / GAME_SCALE; 462 | float yy = sapp_widthf() / sapp_heightf() / GAME_SCALE; 463 | float zz = f_range; 464 | float zw = -f_range * geo_min_z; 465 | Mat4 res = { 466 | .arr = { 467 | { xx, 0.0f, 0.0f, 0.0f }, 468 | { 0.0f, yy, 0.0f, 0.0f }, 469 | { 0.0f, 0.0f, zz, 0.0f }, 470 | { 0.0f, 0.0f, zw, 1.0f }, 471 | } 472 | }; 473 | 474 | Vec4 trans_cam = mul4x44(res, (Vec4) {{ 475 | -state.cam.x, -state.cam.y, 0.0f, 1.0f 476 | }}); 477 | 478 | res.arr[3][0] = trans_cam.arr[0]; 479 | res.arr[3][1] = trans_cam.arr[1]; 480 | return res; 481 | } 482 | 483 | static int dmg_lbl_alive(DmgLbl *dl) { 484 | return dl->tick && (state.tick - dl->tick) < 20; 485 | } 486 | 487 | static void dmg_lbl_push(uint8_t hp, Vec2 world_pos, Ent *ent) { 488 | Vec4 lbl_pos4 = mul4x44(mvp4x4(), (Vec4) {{ world_pos.x, world_pos.y, 0.0f, 1.0f }}); 489 | Vec2 pos = vec2((lbl_pos4.arr[0] + 1.0f) / 2.0f, (lbl_pos4.arr[1] + 1.0f) / 2.0f); 490 | pos = mul2(pos, vec2(sapp_widthf(), sapp_heightf())); 491 | 492 | int oldest_i = -1; 493 | Tick oldest_i_tick = state.tick; 494 | for (int i = 0; i < sizeof(state.dmg_lbls) / sizeof(state.dmg_lbls[0]); i++) { 495 | DmgLbl *dl = state.dmg_lbls + i; 496 | if (dmg_lbl_alive(dl) && dl->ent == ent && dist2(dl->pos, pos) < 60.0f) { 497 | dl->hp += hp; 498 | dl->tick = state.tick; 499 | return; 500 | } 501 | 502 | if (dl->tick < oldest_i_tick) 503 | oldest_i_tick = dl->tick, 504 | oldest_i = i; 505 | } 506 | 507 | if (oldest_i > -1) 508 | state.dmg_lbls[oldest_i] = (DmgLbl) { 509 | .pos = pos, 510 | .hp = hp, 511 | .tick = state.tick, 512 | }; 513 | } 514 | 515 | typedef struct { 516 | Geo *geo; 517 | uint16_t *idx; 518 | Vert *vert; 519 | } GeoWtr; 520 | static GeoWtr geo_wtr(Geo *geo) { 521 | return (GeoWtr) { .geo = geo, .vert = geo->verts, .idx = geo->idxs }; 522 | } 523 | 524 | static void geo_wtr_flush(GeoWtr *wtr) { 525 | size_t v_used = wtr->vert - wtr->geo->verts; 526 | uint32_t max_v = wtr->geo->nvert; 527 | if (v_used > max_v) printf("%ld/%u verts used!\n", v_used, max_v), exit(1); 528 | 529 | size_t i_used = wtr->idx - wtr->geo->idxs; 530 | uint32_t max_i = wtr->geo->nidx; 531 | if (i_used > max_i) printf("%ld/%u idxs used!\n", i_used, max_i), exit(1); 532 | 533 | 534 | sg_update_buffer(wtr->geo->bind.vertex_buffers[0], &(sg_range) { 535 | .ptr = wtr->geo->verts, 536 | .size = (wtr->vert - wtr->geo->verts) * sizeof(Vert), 537 | }); 538 | 539 | sg_update_buffer(wtr->geo->bind.index_buffer, &(sg_range) { 540 | .ptr = wtr->geo->idxs, 541 | .size = (wtr->idx - wtr->geo->idxs) * sizeof(uint16_t), 542 | }); 543 | } 544 | 545 | static void write_circ(GeoWtr *wtr, float x, float y, float r, Color clr, float z) { 546 | size_t start = wtr->vert - wtr->geo->verts; 547 | uint16_t circ_indices[] = { 548 | 2 + start, 6 + start, 8 + start, 549 | 0 + start, 1 + start, 8 + start, 550 | 1 + start, 2 + start, 8 + start, 551 | 2 + start, 3 + start, 4 + start, 552 | 4 + start, 5 + start, 2 + start, 553 | 5 + start, 6 + start, 2 + start, 554 | 6 + start, 7 + start, 8 + start 555 | }; 556 | memcpy(wtr->idx, circ_indices, sizeof(circ_indices)); 557 | wtr->idx += sizeof(circ_indices) / sizeof(uint16_t); 558 | 559 | *(wtr->vert)++ = (Vert) { x + r * 0.0000f, y + r * 1.0000f, z, clr }; 560 | *(wtr->vert)++ = (Vert) { x + r * -0.6428f, y + r * 0.7660f, z, clr }; 561 | *(wtr->vert)++ = (Vert) { x + r * -0.9848f, y + r * 0.1736f, z, clr }; 562 | *(wtr->vert)++ = (Vert) { x + r * -0.8660f, y + r * -0.5000f, z, clr }; 563 | *(wtr->vert)++ = (Vert) { x + r * -0.3420f, y + r * -0.9397f, z, clr }; 564 | *(wtr->vert)++ = (Vert) { x + r * 0.3420f, y + r * -0.9397f, z, clr }; 565 | *(wtr->vert)++ = (Vert) { x + r * 0.8660f, y + r * -0.5000f, z, clr }; 566 | *(wtr->vert)++ = (Vert) { x + r * 0.9848f, y + r * 0.1736f, z, clr }; 567 | *(wtr->vert)++ = (Vert) { x + r * 0.6428f, y + r * 0.7660f, z, clr }; 568 | } 569 | 570 | static void write_tri(GeoWtr *wtr, Vert v0, Vert v1, Vert v2) { 571 | size_t start = wtr->vert - wtr->geo->verts; 572 | *(wtr->vert)++ = v0; 573 | *(wtr->vert)++ = v1; 574 | *(wtr->vert)++ = v2; 575 | 576 | *(wtr->idx)++ = start + 0; 577 | *(wtr->idx)++ = start + 1; 578 | *(wtr->idx)++ = start + 2; 579 | } 580 | 581 | static void write_quad(GeoWtr *wtr, Vert v0, Vert v1, Vert v2, Vert v3) { 582 | size_t start = wtr->vert - wtr->geo->verts; 583 | *(wtr->vert)++ = v0; 584 | *(wtr->vert)++ = v1; 585 | *(wtr->vert)++ = v2; 586 | *(wtr->vert)++ = v3; 587 | 588 | *(wtr->idx)++ = start + 0; 589 | *(wtr->idx)++ = start + 1; 590 | *(wtr->idx)++ = start + 2; 591 | *(wtr->idx)++ = start + 0; 592 | *(wtr->idx)++ = start + 2; 593 | *(wtr->idx)++ = start + 3; 594 | } 595 | 596 | static void write_rect(GeoWtr *wtr, float x, float y, float w, float h, Color clr, float z) { 597 | write_quad(wtr, 598 | (Vert) { x - w/2.0f, y , z, clr }, 599 | (Vert) { x + w/2.0f, y , z, clr }, 600 | (Vert) { x + w/2.0f, y + h, z, clr }, 601 | (Vert) { x - w/2.0f, y + h, z, clr } 602 | ); 603 | } 604 | 605 | static void write_line( 606 | GeoWtr *wtr, 607 | float x0, float y0, 608 | float x1, float y1, 609 | float thickness, 610 | Color clr, float z 611 | ) { 612 | Vec2 n = perp2(sub2(vec2(x0, y0), vec2(x1, y1))); 613 | Vec2 t = mul2f(norm2(n), thickness * 0.5f); 614 | 615 | size_t vert0 = wtr->vert - wtr->geo->verts; 616 | *(wtr->vert)++ = (Vert) { x0 + t.x, y0 + t.y, z, clr }; 617 | *(wtr->vert)++ = (Vert) { x0 - t.x, y0 - t.y, z, clr }; 618 | *(wtr->vert)++ = (Vert) { x1 + t.x, y1 + t.y, z, clr }; 619 | *(wtr->vert)++ = (Vert) { x1 - t.x, y1 - t.y, z, clr }; 620 | 621 | *(wtr->idx)++ = vert0 + 0; 622 | *(wtr->idx)++ = vert0 + 1; 623 | *(wtr->idx)++ = vert0 + 2; 624 | *(wtr->idx)++ = vert0 + 2; 625 | *(wtr->idx)++ = vert0 + 1; 626 | *(wtr->idx)++ = vert0 + 3; 627 | } 628 | 629 | static void write_sight(GeoWtr *wtr, float x, float y, float r, Color clr, float z) { 630 | size_t start = wtr->vert - wtr->geo->verts; 631 | uint16_t circ_indices[] = { 632 | 5 + start, 13 + start, 6 + start, 633 | 3 + start, 11 + start, 4 + start, 634 | 1 + start, 9 + start, 2 + start, 635 | 6 + start, 7 + start, 0 + start, 636 | 4 + start, 12 + start, 5 + start, 637 | 3 + start, 9 + start, 10 + start, 638 | 0 + start, 8 + start, 1 + start, 639 | 5 + start, 12 + start, 13 + start, 640 | 3 + start, 10 + start, 11 + start, 641 | 1 + start, 8 + start, 9 + start, 642 | 6 + start, 13 + start, 7 + start, 643 | 4 + start, 11 + start, 12 + start, 644 | 3 + start, 2 + start, 9 + start, 645 | 0 + start, 7 + start, 8 + start 646 | }; 647 | memcpy(wtr->idx, circ_indices, sizeof(circ_indices)); 648 | wtr->idx += sizeof(circ_indices) / sizeof(uint16_t); 649 | 650 | *(wtr->vert)++ = (Vert) { x + r * 0.3405f, y + r * 0.9402f, z, clr }; 651 | *(wtr->vert)++ = (Vert) { x + r * -0.5228f, y + r * 0.8524f, z, clr }; 652 | *(wtr->vert)++ = (Vert) { x + r * -0.9924f, y + r * 0.1227f, z, clr }; 653 | *(wtr->vert)++ = (Vert) { x + r * -0.7147f, y + r * -0.6994f, z, clr }; 654 | *(wtr->vert)++ = (Vert) { x + r * 0.1012f, y + r * -0.9949f, z, clr }; 655 | *(wtr->vert)++ = (Vert) { x + r * 0.8409f, y + r * -0.5412f, z, clr }; 656 | *(wtr->vert)++ = (Vert) { x + r * 0.9474f, y + r * 0.3200f, z, clr }; 657 | *(wtr->vert)++ = (Vert) { x + r * 0.2554f, y + r * 0.7053f, z, clr }; 658 | *(wtr->vert)++ = (Vert) { x + r * -0.3922f, y + r * 0.6395f, z, clr }; 659 | *(wtr->vert)++ = (Vert) { x + r * -0.7445f, y + r * 0.0921f, z, clr }; 660 | *(wtr->vert)++ = (Vert) { x + r * -0.5362f, y + r * -0.5246f, z, clr }; 661 | *(wtr->vert)++ = (Vert) { x + r * 0.0759f, y + r * -0.7463f, z, clr }; 662 | *(wtr->vert)++ = (Vert) { x + r * 0.6308f, y + r * -0.4060f, z, clr }; 663 | *(wtr->vert)++ = (Vert) { x + r * 0.7107f, y + r * 0.2401f, z, clr }; 664 | 665 | write_rect(wtr, x + r - 0.2f*r, y - 0.125f*r, 1.0f*r, 0.25f*r, clr, z); 666 | write_rect(wtr, x - r + 0.2f*r, y - 0.125f*r, 1.0f*r, 0.25f*r, clr, z); 667 | write_rect(wtr, x, y + r - 0.7f*r, 0.25f*r, 1.0f*r, clr, z); 668 | write_rect(wtr, x, y - r - 0.3f*r, 0.25f*r, 1.0f*r, clr, z); 669 | } 670 | 671 | static void _write_pot_inr(GeoWtr *wtr, float x, float y, float size, float scale, Color clr, float z) { 672 | #define POT_RATIO (0.7f) 673 | write_circ(wtr, x, y, scale/2.0f, clr, z); 674 | write_rect(wtr, x, y, scale, size * POT_RATIO, clr, z); 675 | write_circ(wtr, x, y + size * POT_RATIO, scale/2.0f, clr, z); 676 | write_rect(wtr, x, y + size * 0.9f, scale - 0.24f, scale * 0.5f, clr, z); 677 | #undef POT_RATIO 678 | } 679 | 680 | static void write_pot(GeoWtr *wtr, float x, float y, float size) { 681 | _write_pot_inr(wtr, x, y, size, size, Color_DarkBrown, y); 682 | _write_pot_inr(wtr, x, y, size, size - 0.15f, Color_Brown, y - 0.01f); 683 | } 684 | 685 | #define GOLDEN_RATIO (1.618034f) 686 | static void write_sword(GeoWtr *wtr, float rads, float x, float y, float z) { 687 | Vert *vert0 = wtr->vert; 688 | write_tri(wtr, 689 | (Vert) { 0.075f, 0.0f, z, Color_DarkBrown }, 690 | (Vert) { -0.075f, 0.0f, z, Color_DarkBrown }, 691 | (Vert) { 0.000f, GOLDEN_RATIO, z, Color_DarkBrown } 692 | ); 693 | write_tri(wtr, 694 | (Vert) { 0.0f, GOLDEN_RATIO, z, Color_Grey }, 695 | (Vert) { 0.1f, 0.35f, z, Color_Grey }, 696 | (Vert) { 0.2f, 1.35f, z, Color_Grey } 697 | ); 698 | write_tri(wtr, 699 | (Vert) { 0.0f, GOLDEN_RATIO, z, Color_Grey }, 700 | (Vert) { -0.1f, 0.35f, z, Color_Grey }, 701 | (Vert) { -0.2f, 1.35f, z, Color_Grey } 702 | ); 703 | write_tri(wtr, 704 | (Vert) { -0.1f, 0.35f, z, Color_Grey }, 705 | (Vert) { 0.1f, 0.35f, z, Color_Grey }, 706 | (Vert) { 0.0f, GOLDEN_RATIO, z, Color_Grey } 707 | ); 708 | float t = 0.135f, w = 0.225f; 709 | write_rect(wtr, 0.0f, 0.4f - t, 2.0f * w, t, Color_DarkGrey, z); 710 | 711 | Mat2 m = z_rot2x2(rads); 712 | for (Vert *i = vert0; i < wtr->vert; i++) { 713 | Vec2 p = mul2x22(m, vec2(i->x, i->y)); 714 | i->x = x + p.x; 715 | i->y = y + p.y; 716 | } 717 | } 718 | 719 | static void _write_arrow_inr(GeoWtr *wtr, float x, float z) { 720 | for (float f = 1.0f; f >= -1.0f; f -= 2.0f) { 721 | write_tri(wtr, 722 | (Vert) { 0.35f + x, 0.01f * f, z, Color_Red }, 723 | (Vert) { 0.20f + x, 0.12f * f, z, Color_Red }, 724 | (Vert) { 0.00f + x, 0.12f * f, z, Color_Red } 725 | ); 726 | write_tri(wtr, 727 | (Vert) { 0.35f + x, 0.01f * f, z, Color_Red }, 728 | (Vert) { 0.05f + x, 0.01f * f, z, Color_Red }, 729 | (Vert) { 0.00f + x, 0.12f * f, z, Color_Red } 730 | ); 731 | } 732 | 733 | write_line(wtr, 1.05f + x, 0.0f, 0.05f + x, 0.0f, 0.08f, Color_DarkBrown, z); 734 | write_tri(wtr, 735 | (Vert) { 1.34f + x, 0.000f, z, Color_Grey }, 736 | (Vert) { 1.10f + x, -0.105f, z, Color_Grey }, 737 | (Vert) { 1.10f + x, 0.105f, z, Color_Grey } 738 | ); 739 | write_tri(wtr, 740 | (Vert) { 0.975f + x, 0.000f, z, Color_Grey }, 741 | (Vert) { 1.100f + x, -0.105f, z, Color_Grey }, 742 | (Vert) { 1.100f + x, 0.105f, z, Color_Grey } 743 | ); 744 | } 745 | 746 | static void write_arrow(GeoWtr *wtr, float rads, float x, float y, float z) { 747 | Vert *vert0 = wtr->vert; 748 | _write_arrow_inr(wtr, 0.0f, z); 749 | 750 | Mat2 m = z_rot2x2(rads); 751 | for (Vert *i = vert0; i < wtr->vert; i++) { 752 | Vec2 p = mul2x22(m, vec2(i->x, i->y)); 753 | i->x = x + p.x; 754 | i->y = y + p.y; 755 | } 756 | } 757 | 758 | static void write_bow(GeoWtr *wtr, float rads, float x, float y, float z, Ent *e) { 759 | Vert *vert0 = wtr->vert; 760 | 761 | float r = 1.0f - (e->swing.end - state.tick) / ((float) item_attack_duration[e->item]); 762 | if (r < 0.0f || r > 1.0f || e->swing.shot) r = 0.0f; 763 | write_line(wtr, -0.1f, -1.0f, -0.1f - r * 0.6f, 0.0f, 0.035f, Color_LightGrey, z); 764 | write_line(wtr, -0.1f, 1.0f, -0.1f - r * 0.6f, 0.0f, 0.035f, Color_LightGrey, z); 765 | 766 | if (r > 0.0f) _write_arrow_inr(wtr, -r, z); 767 | 768 | /* generated by running gen_bow.py in Blender, 769 | * then doing touchups manually to get bow.blend, 770 | * then blender_log_mesh_data.py and formatting like so: */ 771 | size_t idx0 = wtr->vert - wtr->geo->verts; 772 | uint16_t bow_indices[] = { 773 | 0 + idx0, 1 + idx0, 2 + idx0, 774 | 2 + idx0, 1 + idx0, 3 + idx0, 775 | 4 + idx0, 5 + idx0, 6 + idx0, 776 | 6 + idx0, 5 + idx0, 7 + idx0, 777 | 8 + idx0, 9 + idx0, 7 + idx0, 778 | 7 + idx0, 9 + idx0, 10 + idx0, 779 | 15 + idx0, 16 + idx0, 13 + idx0, 780 | 14 + idx0, 29 + idx0, 13 + idx0, 781 | 18 + idx0, 19 + idx0, 20 + idx0, 782 | 20 + idx0, 19 + idx0, 21 + idx0, 783 | 22 + idx0, 23 + idx0, 21 + idx0, 784 | 21 + idx0, 23 + idx0, 24 + idx0, 785 | 25 + idx0, 26 + idx0, 27 + idx0, 786 | 27 + idx0, 26 + idx0, 28 + idx0, 787 | 5 + idx0, 1 + idx0, 0 + idx0, 788 | 7 + idx0, 10 + idx0, 6 + idx0, 789 | 21 + idx0, 24 + idx0, 20 + idx0, 790 | 25 + idx0, 22 + idx0, 26 + idx0, 791 | 12 + idx0, 11 + idx0, 9 + idx0, 792 | 16 + idx0, 19 + idx0, 18 + idx0, 793 | 29 + idx0, 17 + idx0, 13 + idx0, 794 | 17 + idx0, 15 + idx0, 13 + idx0, 795 | 11 + idx0, 12 + idx0, 13 + idx0, 796 | 12 + idx0, 14 + idx0, 13 + idx0 797 | }; 798 | memcpy(wtr->idx, bow_indices, sizeof(bow_indices)); 799 | wtr->idx += sizeof(bow_indices) / sizeof(uint16_t); 800 | 801 | *(wtr->vert)++ = (Vert) {-0.1137f, -1.0178f, z, Color_Brown }; 802 | *(wtr->vert)++ = (Vert) {-0.0863f, -0.9822f, z, Color_Brown }; 803 | *(wtr->vert)++ = (Vert) { 0.0163f, -1.1178f, z, Color_Brown }; 804 | *(wtr->vert)++ = (Vert) { 0.0437f, -1.0822f, z, Color_Brown }; 805 | *(wtr->vert)++ = (Vert) {-0.0530f, -1.0235f, z, Color_Brown }; 806 | *(wtr->vert)++ = (Vert) {-0.1065f, -0.9765f, z, Color_Brown }; 807 | *(wtr->vert)++ = (Vert) { 0.2470f, -0.4235f, z, Color_Brown }; 808 | *(wtr->vert)++ = (Vert) { 0.1531f, -0.3844f, z, Color_Brown }; 809 | *(wtr->vert)++ = (Vert) { 0.2031f, -0.0922f, z, Color_Brown }; 810 | *(wtr->vert)++ = (Vert) { 0.2969f, -0.1078f, z, Color_Brown }; 811 | *(wtr->vert)++ = (Vert) { 0.2469f, -0.4078f, z, Color_Brown }; 812 | *(wtr->vert)++ = (Vert) { 0.2708f, -0.0688f, z, Color_Brown }; 813 | *(wtr->vert)++ = (Vert) { 0.2292f, -0.1312f, z, Color_Brown }; 814 | *(wtr->vert)++ = (Vert) { 0.1673f, -0.0000f, z, Color_Brown }; 815 | *(wtr->vert)++ = (Vert) { 0.0792f, -0.0312f, z, Color_Brown }; 816 | *(wtr->vert)++ = (Vert) { 0.2292f, 0.1312f, z, Color_Brown }; 817 | *(wtr->vert)++ = (Vert) { 0.2708f, 0.0688f, z, Color_Brown }; 818 | *(wtr->vert)++ = (Vert) { 0.0792f, 0.0312f, z, Color_Brown }; 819 | *(wtr->vert)++ = (Vert) { 0.2969f, 0.1078f, z, Color_Brown }; 820 | *(wtr->vert)++ = (Vert) { 0.2031f, 0.0922f, z, Color_Brown }; 821 | *(wtr->vert)++ = (Vert) { 0.2469f, 0.4078f, z, Color_Brown }; 822 | *(wtr->vert)++ = (Vert) { 0.1531f, 0.3844f, z, Color_Brown }; 823 | *(wtr->vert)++ = (Vert) {-0.1065f, 0.9765f, z, Color_Brown }; 824 | *(wtr->vert)++ = (Vert) {-0.0530f, 1.0235f, z, Color_Brown }; 825 | *(wtr->vert)++ = (Vert) { 0.2470f, 0.4235f, z, Color_Brown }; 826 | *(wtr->vert)++ = (Vert) {-0.0863f, 0.9822f, z, Color_Brown }; 827 | *(wtr->vert)++ = (Vert) {-0.1137f, 1.0178f, z, Color_Brown }; 828 | *(wtr->vert)++ = (Vert) { 0.0437f, 1.0822f, z, Color_Brown }; 829 | *(wtr->vert)++ = (Vert) { 0.0163f, 1.1178f, z, Color_Brown }; 830 | *(wtr->vert)++ = (Vert) { 0.1000f, 0.0000f, z, Color_Brown }; 831 | 832 | Mat2 m = z_rot2x2(rads); 833 | for (Vert *i = vert0; i < wtr->vert; i++) { 834 | Vec2 p = mul2x22(m, vec2(i->x, i->y)); 835 | i->x = x + p.x; 836 | i->y = y + p.y; 837 | } 838 | } 839 | 840 | static void write_text(GeoWtr *wtr, float x, float y, char *buf, Color clr) { 841 | for (char *text = buf; *text; text++) { 842 | stbtt_aligned_quad q; 843 | stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 844 | write_quad( 845 | wtr, 846 | (Vert) { q.x0, q.y0, 0.0f, clr, q.s0, q.t1 }, 847 | (Vert) { q.x1, q.y0, 0.0f, clr, q.s1, q.t1 }, 848 | (Vert) { q.x1, q.y1, 0.0f, clr, q.s1, q.t0 }, 849 | (Vert) { q.x0, q.y1, 0.0f, clr, q.s0, q.t0 } 850 | ); 851 | } 852 | } 853 | 854 | static void write_corner(GeoWtr *wtr, float x, float y, float mx, float my, Color clr, float z) { 855 | write_line(wtr, x-16.0f*mx, y-48.0f*my, x-16.0f*mx, y-11.2f*my, 16.0f, clr, z); 856 | write_line(wtr, x-16.0f*mx, y-16.0f*my, x+16.0f*mx, y+16.0f*my, 16.0f, clr, z); 857 | write_line(wtr, x+11.2f*mx, y+16.0f*my, x+52.0f*mx, y+16.0f*my, 16.0f, clr, z); 858 | } 859 | 860 | static void write_item(GeoWtr *wtr, float rot, Vec2 pos, Ent *ent, float z) { 861 | switch (ent->item) { 862 | case EntItem_Sword: write_sword(wtr, rot, pos.x, pos.y, z); break; 863 | case EntItem_Bow: write_bow (wtr, rot, pos.x, pos.y, z, ent); break; 864 | case EntItem_None: 865 | case EntItem_COUNT: 866 | break; 867 | } 868 | } 869 | 870 | static void write_frame(GeoWtr *wtr, float x, float y, float w, float h) { 871 | #define GAP (3.36f) 872 | #define PULL (-1.00f) 873 | x += 32.0f; 874 | y += 32.0f; 875 | w -= 64.0f; 876 | h -= 64.0f; 877 | 878 | float z = 0.0f; 879 | float w2 = w / 2.0f; 880 | float h2 = h / 2.0f; 881 | x += w2, y += h2; 882 | 883 | write_rect(wtr, x, y - 8.0f - h2, w + 16.0f, h + 16.0f, Color_DarkBrown, z); 884 | 885 | for (float u = 1.0f; u >= -1.0f; u -= 2.0f) { 886 | for (float v = 1.0f; v >= -1.0f; v -= 2.0f) { 887 | write_corner(wtr, u*(-w2+PULL+GAP)+x, v*(h2-PULL-GAP)+y, u, v, Color_DarkGrey, z); 888 | } 889 | } 890 | 891 | // for not jank ui: s/- 4.0f/+10.4/g 892 | // don't forget the /g, that's how we got the jank in the first place 893 | write_line(wtr, -w2+x, h2+y, w2+x, 16.0f+h2+y, 16.0f, Color_Brown, z); 894 | write_line(wtr, -w2+x, -h2+y, w2+x, -16.0f-h2+y, 16.0f, Color_Brown, z); 895 | write_line(wtr, -w2+x, h2+y, -16.0f-w2+x, -h2+y, 16.0f, Color_Brown, z); 896 | write_line(wtr, w2+x, h2+y, 16.0f+w2+x, -h2+y, 16.0f, Color_Brown, z); 897 | 898 | for (float u = 1.0f; u >= -1.0f; u -= 2.0f) { 899 | for (float v = 1.0f; v >= -1.0f; v -= 2.0f) { 900 | write_corner(wtr, u*(-w2+PULL-GAP)+x, v*(h2-PULL+GAP)+y, u, v, Color_LightishGrey, z); 901 | write_corner(wtr, u*(-w2+PULL )+x, v*(h2-PULL )+y, u, v, Color_Grey, z); 902 | } 903 | } 904 | #undef GAP 905 | #undef PULL 906 | } 907 | 908 | #define map (state.map) 909 | static size_t write_map(Geo *geo) { 910 | GeoWtr wtr = geo_wtr(geo); 911 | 912 | for (MapData_Tree *t = map.trees; (t - map.trees) < map.ntrees; t++) { 913 | float w = 0.8f, h = GOLDEN_RATIO, r = 0.4f; 914 | write_circ(&wtr, t->x, t->y + r, r, Color_Brown, t->y); 915 | write_rect(&wtr, t->x, t->y + r, w, h, Color_Brown, t->y); 916 | 917 | write_circ(&wtr, t->x + 0.80f, t->y + 2.2f, 0.8f, Color_TreeGreen, t->y - 1.1f); 918 | write_circ(&wtr, t->x + 0.16f, t->y + 3.0f, 1.0f, Color_TreeGreen1, t->y - 1.1f); 919 | write_circ(&wtr, t->x - 0.80f, t->y + 2.5f, 0.9f, Color_TreeGreen2, t->y - 1.1f); 920 | write_circ(&wtr, t->x - 0.16f, t->y + 2.0f, 0.8f, Color_TreeGreen3, t->y - 1.1f); 921 | 922 | write_circ(&wtr, t->x + 0.80f, t->y + 2.2f, 0.8f+0.1f, Color_TreeBorder, t->y); 923 | write_circ(&wtr, t->x + 0.16f, t->y + 3.0f, 1.0f+0.1f, Color_TreeBorder, t->y); 924 | write_circ(&wtr, t->x - 0.80f, t->y + 2.5f, 0.9f+0.1f, Color_TreeBorder, t->y); 925 | write_circ(&wtr, t->x - 0.16f, t->y + 2.0f, 0.8f+0.1f, Color_TreeBorder, t->y); 926 | 927 | float sr = 0.92f; 928 | write_circ(&wtr, t->x, t->y + r, sr, Color_ForestShadow, t->y + sr); 929 | } 930 | 931 | geo_find_z_range(geo->verts, wtr.vert); 932 | return wtr.idx - geo->idxs; 933 | } 934 | #undef map 935 | 936 | static void ui_init(void) { 937 | UiBox *inventory, *wtr = state.ui.boxes; 938 | *(inventory = wtr++) = (UiBox) { 939 | .looks = UiBoxLooks_Frame, 940 | .props = UiBoxProp_CanDrag, 941 | .pos = vec2(sapp_widthf()/2.0f - 128.0f, sapp_heightf()/2.0f - 128.0f), 942 | .size = vec2(504.0f, 320.0f), 943 | }; 944 | 945 | typedef struct { Vec2 pos, size; } UiBoxGrid; 946 | UiBoxGrid grid = { 947 | .pos = mul2(inventory->size, vec2(0.5f, 0.45f)), 948 | .size = vec2(inventory->size.x / 2.0f, inventory->size.y), 949 | }; 950 | 951 | Vec2 slot_poses[7] = {0}; 952 | Vec2 *slot_pos_wtr = slot_poses; 953 | for (int i = 0; i < 6; i++) { 954 | int w = (int)floorf(grid.size.x / 70.0f); 955 | *slot_pos_wtr++ = vec2( 956 | grid.pos.x + i % w * 70.0f, 957 | grid.pos.y - i / w * 70.0f 958 | ); 959 | } 960 | 961 | *slot_pos_wtr++ = vec2(100.0f, 55.0f); 962 | state.ui.player_weapon_slot = wtr + 6; 963 | 964 | for (Vec2 *p = slot_poses; p != slot_pos_wtr; p++) { 965 | UiBox *slot = wtr++; 966 | slot->pos = *p; 967 | slot->size = vec2(60.0f, 60.0f); 968 | slot->props = UiBoxProp_DropZone | UiBoxProp_DragZone; 969 | slot->looks = UiBoxLooks_Slot; 970 | slot->parent = inventory; 971 | } 972 | 973 | UiBox *item_holder = wtr++; 974 | *item_holder = (UiBox) { 975 | .size = inventory->size, 976 | .parent = inventory, 977 | }; 978 | for (Vec2 *p = slot_poses; p != slot_pos_wtr; p++) { 979 | UiBox *item = wtr++; 980 | item->pos = *p; 981 | item->size = vec2(60.0f, 60.0f); 982 | item->props = UiBoxProp_CanDrag | UiBoxProp_LockDrop; 983 | item->parent = item_holder; 984 | item->looks = UiBoxLooks_Item; 985 | item->item = ((p - slot_poses) % 2) ? EntItem_Sword : EntItem_Bow; 986 | } 987 | 988 | state.ui.root = state.ui.boxes; 989 | } 990 | 991 | static void init(void) { 992 | state.player = ent_alloc(); 993 | state.player->has_mask = EntMask_Player; 994 | state.player->hit_mask = ~EntMask_Player; 995 | state.player->item_hit_mask = EntMask_Enemy; 996 | state.player->looks = EntLooks_Player; 997 | state.player->item = EntItem_Bow; 998 | state.player->hp = 15; 999 | state.player->radius = 0.2f; 1000 | 1001 | ui_init(); 1002 | 1003 | struct { float x, y, radius; } pots[] = { 1004 | { 5.0f + 3.0f, 3.0f, 0.6f }, 1005 | { 5.0f + 5.0f, 2.0f, 0.7f }, 1006 | { 5.0f + 4.0f, 5.0f, 0.5f }, 1007 | }; 1008 | for (int i = 0; i < sizeof(pots) / sizeof(pots[0]); i++) { 1009 | Ent *pot = ent_alloc(); 1010 | pot->pos = vec2(pots[i].x, pots[i].y); 1011 | pot->radius = pots[i].radius; 1012 | pot->looks = EntLooks_Pot; 1013 | pot->item = EntItem_Sword; 1014 | pot->has_mask = EntMask_Enemy; 1015 | pot->hit_mask = ~0; 1016 | pot->item_hit_mask = EntMask_Player; 1017 | pot->hostile = 1; 1018 | pot->hp = 3; 1019 | } 1020 | 1021 | stm_setup(); 1022 | sg_setup(&(sg_desc){ .context = sapp_sgcontext() }); 1023 | 1024 | state.map = parse_map_data(fopen("build/map.bytes", "rb")); 1025 | state.static_geo = geo_alloc(1 << 16, 1 << 18); 1026 | state.static_geo_n_idx = write_map(&state.static_geo); 1027 | geo_bind_init(&state.static_geo, "static_vert", "static_idx", SG_USAGE_IMMUTABLE); 1028 | free(state.static_geo.verts); 1029 | free(state.static_geo.idxs); 1030 | 1031 | #define map (state.map) 1032 | for (MapData_Circle *t = map.circles; (t - map.circles) < map.ncircles; t++) { 1033 | Ent *circ = ent_alloc(); 1034 | circ->has_mask = EntMask_Terrain; 1035 | circ->hit_mask = 0; 1036 | circ->radius = t->radius; 1037 | circ->pos = vec2(t->x, t->y); 1038 | } 1039 | #undef map 1040 | 1041 | state.dyn_geo = geo_alloc(1 << 15, 1 << 17); 1042 | geo_bind_init(&state.dyn_geo, "dyn_vert", "dyn_idx", SG_USAGE_STREAM); 1043 | 1044 | uint8_t palette[8*8*4] = {0}, *plt_wtr = palette; 1045 | 1046 | #define X(name, r, g, b, a) \ 1047 | *plt_wtr++ = (uint8_t)(r * 255.0); \ 1048 | *plt_wtr++ = (uint8_t)(g * 255.0); \ 1049 | *plt_wtr++ = (uint8_t)(b * 255.0); \ 1050 | *plt_wtr++ = (uint8_t)(a * 255.0); 1051 | PALETTE 1052 | #undef X 1053 | 1054 | /* NOTE: tex_slot is provided by shader code generation */ 1055 | state.static_geo.bind.fs_images[SLOT_palette] = 1056 | state.dyn_geo.bind.fs_images[SLOT_palette] = sg_make_image(&(sg_image_desc){ 1057 | .width = 8, 1058 | .height = 8, 1059 | .data.subimage[0][0] = SG_RANGE(palette), 1060 | .label = "palette-texture" 1061 | }); 1062 | 1063 | /* -- font tex init -- */ 1064 | unsigned char ttf_buffer[1<<20]; 1065 | unsigned char temp_bitmap[512*512]; 1066 | if (!fread(ttf_buffer, 1, 1<<20, fopen("./WackClubSans-Regular.ttf", "rb"))) 1067 | perror("couldn't get font"); 1068 | // no guarantee this fits! 1069 | stbtt_BakeFontBitmap(ttf_buffer,0, 24.0, temp_bitmap,512,512, 32,96, cdata); 1070 | temp_bitmap[0] = 255; 1071 | state.dyn_geo.bind.fs_images[SLOT_tex] = 1072 | state.static_geo.bind.fs_images[SLOT_tex] = sg_make_image(&(sg_image_desc){ 1073 | .width = 512, 1074 | .height = 512, 1075 | .pixel_format = SG_PIXELFORMAT_R8, 1076 | .data.subimage[0][0] = SG_RANGE(temp_bitmap), 1077 | .label = "font-texture" 1078 | }); 1079 | 1080 | /* create shader from code-generated sg_shader_desc */ 1081 | sg_shader shd = sg_make_shader(triangle_shader_desc(sg_query_backend())); 1082 | 1083 | /* create a pipeline object (default render states are fine for triangle) */ 1084 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 1085 | .shader = shd, 1086 | .index_type = SG_INDEXTYPE_UINT16, 1087 | .layout = { 1088 | .attrs = { 1089 | [ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3, 1090 | [ATTR_vs_palette_index0].format = SG_VERTEXFORMAT_FLOAT, 1091 | [ATTR_vs_uv0].format = SG_VERTEXFORMAT_FLOAT2, 1092 | } 1093 | }, 1094 | .colors[0].blend = (sg_blend_state) { 1095 | .enabled = true, 1096 | .src_factor_rgb = SG_BLENDFACTOR_ONE, 1097 | .dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 1098 | .src_factor_alpha = SG_BLENDFACTOR_ONE, 1099 | .dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 1100 | }, 1101 | .depth = { 1102 | .compare = SG_COMPAREFUNC_LESS_EQUAL, 1103 | .write_enabled = true 1104 | }, 1105 | .label = "default-pipeline" 1106 | }); 1107 | 1108 | /* a pass action to framebuffer to black */ 1109 | state.pass_action = (sg_pass_action) { 1110 | .colors[0] = { .action=SG_ACTION_CLEAR, .value={ 0.255f, 0.51f, 0.439f, 1.0f } } 1111 | }; 1112 | } 1113 | 1114 | static int ent_swing(Ent *e, Vec2 toward) { 1115 | int can_swing = state.tick > e->swing.end; 1116 | if (can_swing) 1117 | e->swing.shot = 0, 1118 | e->swing.end = state.tick + item_attack_duration[e->item], 1119 | e->swing.toward = norm2(toward); 1120 | return can_swing; 1121 | } 1122 | 1123 | static void ent_item_transform(Ent *e, float *out_rot, Vec2 *out_pos, uint8_t *out_dmg) { 1124 | Vec2 toward = e->swing.toward; 1125 | Vec2 center = vec2(0.0f, 0.5f); 1126 | Vec2 hand_pos = add2(center, mul2f(toward, 0.5f)); 1127 | 1128 | float rot = vec2_rads(e->swing.toward) + item_rot_offset[e->item]; 1129 | float dir = signum(e->swing.toward.x) ?: 1.0f; 1130 | 1131 | float rest_rot; 1132 | Vec2 rest_pos; 1133 | { 1134 | float vl = mag2(e->vel); 1135 | float tickf = state.tick; 1136 | float drag = fminf(vl, 0.07f); 1137 | float breathe = sinf(tickf / 35.0f) / 30.0f; 1138 | float jog = sinf(tickf / 6.85f) * fminf(vl, 0.175f); 1139 | float x_offset = item_x_offset[e->item]; 1140 | rest_rot = -(M_PI_2 + breathe + jog); 1141 | if (!item_always_point_down[e->item]) rest_rot *= dir; 1142 | rest_pos.x = (0.55 + breathe / 3.2 + jog * 1.5 + drag + x_offset) * -dir; 1143 | rest_pos.y = 0.35 + (breathe + jog) / 2.8 + drag * 0.5; 1144 | } 1145 | 1146 | *out_rot = rest_rot; 1147 | *out_pos = rest_pos; 1148 | if (out_dmg) *out_dmg = 0; 1149 | 1150 | float time = (e->swing.end - state.tick) / ((float) item_attack_duration[e->item]); 1151 | if (time > 0.0f) { 1152 | typedef enum { 1153 | KF_Rotates = (1 << 1), 1154 | KF_Moves = (1 << 2), 1155 | KF_Damages = (1 << 3), 1156 | } KF_Flag; 1157 | typedef struct { float duration; KF_Flag flags; float rot; Vec2 pos; } KF; 1158 | 1159 | float swing = 0.5f * dir; 1160 | #define FRAME_COUNT (5) 1161 | KF frames[FRAME_COUNT] = {0}; 1162 | KF *f = frames; 1163 | 1164 | if (e->item == EntItem_Sword) { 1165 | *f++=(KF){0.2174f, KF_Rotates | KF_Moves, rot-swing * 1.f, hand_pos}; 1166 | *f++=(KF){0.2304f, KF_Rotates , rot-swing * 2.f, }; 1167 | *f++=(KF){0.0870f, KF_Damages | KF_Rotates , rot+swing * 2.f, }; 1168 | *f++=(KF){0.2478f, KF_Rotates , rot+swing * 3.f, }; 1169 | *f++=(KF){0.2174f, KF_Rotates | KF_Moves, rest_rot, rest_pos}; 1170 | } 1171 | if (e->item == EntItem_Bow) { 1172 | /* ready, backup, FIRE, recover, return */ 1173 | *f++=(KF){0.2703f, KF_Moves | KF_Rotates, rot, hand_pos}; 1174 | *f++=(KF){0.2703f, KF_Moves , 0.0f, hand_pos}; 1175 | *f++=(KF){0.0541f, KF_Damages | KF_Moves , 0.0f, hand_pos}; 1176 | *f++=(KF){0.1351f, KF_Moves , 0.0f, hand_pos}; 1177 | *f++=(KF){0.2703f, KF_Moves | KF_Rotates, rest_rot, rest_pos}; 1178 | frames[1].pos = sub2(hand_pos, mul2f(toward, 0.2f)); 1179 | frames[2].pos = sub2(hand_pos, mul2f(toward, 0.6f)); 1180 | }; 1181 | 1182 | for (KF *f = frames; (f - frames) < FRAME_COUNT; f++) { 1183 | if (time > f->duration) { 1184 | time -= f->duration; 1185 | if (f->flags & KF_Rotates) *out_rot = f->rot; 1186 | if (f->flags & KF_Moves) *out_pos = f->pos; 1187 | continue; 1188 | }; 1189 | 1190 | float t = time / f->duration; 1191 | if (f->flags & KF_Rotates) *out_rot = lerp_rads(*out_rot, f->rot, t); 1192 | if (f->flags & KF_Moves) *out_pos = lerp2(*out_pos, f->pos, t); 1193 | if (f->flags & KF_Damages && out_dmg) *out_dmg = 1; 1194 | break; 1195 | } 1196 | } 1197 | #undef FRAME_COUNT 1198 | 1199 | out_pos->x += e->pos.x; 1200 | out_pos->y += e->pos.y; 1201 | } 1202 | 1203 | static Vec2 ui_box_pos(UiBox *box) { 1204 | Vec2 ret = box->pos; 1205 | if (box->parent) ret = add2(ret, ui_box_pos(box->parent)); 1206 | return ret; 1207 | } 1208 | 1209 | static bool ui_box_contains_pos(UiBox *box, Vec2 pos) { 1210 | Vec2 boxpos = ui_box_pos(box); 1211 | float max_x = boxpos.x + box->size.x, 1212 | min_x = boxpos.x, 1213 | max_y = boxpos.y + box->size.y, 1214 | min_y = boxpos.y; 1215 | return (pos.x > min_x && pos.x < max_x && 1216 | pos.y > min_y && pos.y < max_y); 1217 | } 1218 | 1219 | static UiBox *ui_box_at_pos(Vec2 pos, UiBoxProp mask) { 1220 | UiBox *ret = NULL; 1221 | UI_SYSTEM(box) { 1222 | if (box->props & mask && ui_box_contains_pos(box, pos)) { 1223 | /* we just uh prioritize boxes with parents because ... meh */ 1224 | if (!ret || box->parent) 1225 | ret = box; 1226 | } 1227 | } 1228 | return ret; 1229 | } 1230 | 1231 | static void write_ent(GeoWtr *wtr, Ent *e) { 1232 | switch (e->looks) { 1233 | case EntLooks_None: break; 1234 | case EntLooks_Player: { 1235 | write_rect(wtr, e->pos.x, e->pos.y, 1.0f, 1.0f, Color_Blue, e->pos.y); 1236 | } break; 1237 | case EntLooks_Pot: { 1238 | write_pot(wtr, e->pos.x, e->pos.y, e->radius); 1239 | } break; 1240 | case EntLooks_Arrow: { 1241 | write_arrow(wtr, vec2_rads(e->vel), e->pos.x, e->pos.y, e->pos.y); 1242 | } break; 1243 | } 1244 | 1245 | if (e->item) { 1246 | float im_rot; 1247 | Vec2 im_pos; 1248 | ent_item_transform(e, &im_rot, &im_pos, NULL); 1249 | write_item(wtr, im_rot, im_pos, e, im_pos.y - 1.0f); 1250 | } 1251 | } 1252 | 1253 | static void write_ui(GeoWtr *wtr) { 1254 | UI_SYSTEM(box) { 1255 | Vec2 pos = ui_box_pos(box); 1256 | float size = (box->size.x + box->size.y) / 2.0f; 1257 | float hsize = size / 2.0f; 1258 | 1259 | switch (box->looks) { 1260 | case UiBoxLooks_NONE: { } break; 1261 | case UiBoxLooks_Frame: { 1262 | float w = box->size.x; 1263 | float h = box->size.y; 1264 | write_frame(wtr, pos.x, pos.y, w, h); 1265 | 1266 | char *msg = "sup nerds"; 1267 | float x = pos.x + w / 2.0f, 1268 | y = pos.y + h / 2.0f; 1269 | write_text(wtr, x - 70.0f, y + 100.0f, msg, Color_White); 1270 | 1271 | 1272 | Ent player = *state.player; 1273 | player.pos = (Vec2){0}; 1274 | 1275 | float scale = 40.0f; 1276 | Vec2 offset = {{ -75.0f, -66.0f }}; 1277 | 1278 | Vert *vert0 = wtr->vert; 1279 | write_ent(wtr, &player); 1280 | for (Vert *i = vert0; i < wtr->vert; i++) 1281 | i->x = i->x * scale + pos.x + offset.x + hsize, 1282 | i->y = i->y * scale + pos.y + offset.y + hsize, 1283 | i->z = 0.0f; 1284 | 1285 | } break; 1286 | case UiBoxLooks_Slot: { 1287 | Vec2 bg = add2(pos, vec2(2.0f, -5.0f)); 1288 | write_circ(wtr, bg.x + hsize, bg.y + hsize, hsize, Color_DarkerBrown, 0.0f); 1289 | write_circ(wtr, pos.x + hsize, pos.y + hsize, hsize, Color_SlotColor, 0.0f); 1290 | } break; 1291 | case UiBoxLooks_Item: { 1292 | float scale = 30.0f; 1293 | Vec2 offset = {{ 16.0f, 16.0f }}; 1294 | if (box->item == EntItem_Sword) 1295 | offset = mul2(offset, vec2(-0.9f, -1.2f)); 1296 | if (box->item == EntItem_Bow) 1297 | scale = 25.0f, 1298 | offset = mul2f(offset, 0.02f); 1299 | 1300 | Ent ent = { .item = box->item }; 1301 | 1302 | Vert *vert0 = wtr->vert; 1303 | write_item(wtr, -M_2_PI, (Vec2){0}, &ent, 0.0f); 1304 | for (Vert *i = vert0; i < wtr->vert; i++) 1305 | i->x = i->x * scale + pos.x + offset.x + hsize + 2, 1306 | i->y = i->y * scale + pos.y + offset.y + hsize - 2, 1307 | i->color = Color_DarkSlotColor; 1308 | 1309 | vert0 = wtr->vert; 1310 | write_item(wtr, -M_2_PI, (Vec2){0}, &ent, 0.0f); 1311 | for (Vert *i = vert0; i < wtr->vert; i++) 1312 | i->x = i->x * scale + pos.x + offset.x + hsize, 1313 | i->y = i->y * scale + pos.y + offset.y + hsize; 1314 | } break; 1315 | } 1316 | } 1317 | } 1318 | 1319 | static void game_event(const sapp_event *ev) { 1320 | switch (ev->type) { 1321 | case SAPP_EVENTTYPE_KEY_UP: 1322 | case SAPP_EVENTTYPE_KEY_DOWN: { 1323 | state.keys[ev->key_code] = ev->type == SAPP_EVENTTYPE_KEY_DOWN; 1324 | if (ev->key_code == SAPP_KEYCODE_ESCAPE) 1325 | sapp_request_quit(); 1326 | else if (ev->key_code == SAPP_KEYCODE_SPACE) { 1327 | if (ev->type == SAPP_EVENTTYPE_KEY_UP && state.aimer.active) { 1328 | if (ent_swing(state.player, norm2(state.aimer.pos))) 1329 | state.aimer.active = 0; 1330 | } else if (!state.aimer.active && state.tick > state.player->swing.end) { 1331 | state.aimer.active = 1, 1332 | state.aimer.pos = vec2(0.0f, 0.0f); 1333 | } 1334 | } 1335 | } break; 1336 | case SAPP_EVENTTYPE_MOUSE_DOWN: { 1337 | Vec2 cam = state.cam; 1338 | float ar = sapp_widthf() / sapp_heightf(); /* aspect ratio */ 1339 | float x = -(1.0f - ev->mouse_x / sapp_widthf() * 2.0f) * GAME_SCALE + cam.x; 1340 | float y = (1.0f - ev->mouse_y / sapp_heightf() * 2.0f) * (GAME_SCALE / ar) + cam.y; 1341 | if (state.tick > state.player->swing.end) 1342 | ent_swing(state.player, norm2(sub2(vec2(x, y), state.player->pos))); 1343 | } break; 1344 | default: {} 1345 | } 1346 | } 1347 | 1348 | /* ui gatekeeps events from the game */ 1349 | static void event(const sapp_event *ev) { 1350 | Vec2 mouse_pos = vec2(ev->mouse_x, sapp_heightf() - ev->mouse_y); 1351 | 1352 | switch (ev->type) { 1353 | case SAPP_EVENTTYPE_MOUSE_DOWN: { 1354 | UiBox *hovered = ui_box_at_pos(mouse_pos, UiBoxProp_CanDrag); 1355 | UiBox *drag_start = ui_box_at_pos(mouse_pos, UiBoxProp_DragZone); 1356 | 1357 | if (hovered) { 1358 | if (drag_start) state.ui.drag_start_box = drag_start; 1359 | state.ui.grabbed = hovered; 1360 | goto CAPTURE; 1361 | } 1362 | } break; 1363 | case SAPP_EVENTTYPE_MOUSE_MOVE: { 1364 | if (state.ui.grabbed) { 1365 | state.ui.grabbed->pos.x += mouse_pos.x - state.ui.last_mouse.x; 1366 | state.ui.grabbed->pos.y += mouse_pos.y - state.ui.last_mouse.y; 1367 | // state.ui.grabbed->pos = mouse_pos; 1368 | goto CAPTURE; 1369 | } 1370 | } break; 1371 | case SAPP_EVENTTYPE_MOUSE_UP: { 1372 | if (state.ui.grabbed) { 1373 | if (state.ui.grabbed->props & UiBoxProp_LockDrop) { 1374 | UiBox *drop_zone = ui_box_at_pos(mouse_pos, UiBoxProp_DropZone); 1375 | 1376 | if (drop_zone) { 1377 | /* see if there's another LockDrop at this pos that != us */ 1378 | state.ui.grabbed->props &= ~UiBoxProp_LockDrop; 1379 | UiBox *other = ui_box_at_pos(mouse_pos, UiBoxProp_LockDrop); 1380 | state.ui.grabbed->props |= UiBoxProp_LockDrop; 1381 | 1382 | if (other) other->pos = state.ui.drag_start_box->pos; 1383 | 1384 | state.ui.grabbed->pos = drop_zone->pos; 1385 | 1386 | if (state.ui.player_weapon_slot == drop_zone) 1387 | state.player->item = state.ui.grabbed->item; 1388 | else if (state.ui.player_weapon_slot == state.ui.drag_start_box) 1389 | state.player->item = other->item; 1390 | } else if (state.ui.drag_start_box) { 1391 | state.ui.grabbed->pos = state.ui.drag_start_box->pos; 1392 | } 1393 | } 1394 | 1395 | state.ui.grabbed = NULL; 1396 | goto CAPTURE; 1397 | } 1398 | } break; 1399 | default: {} 1400 | } 1401 | 1402 | game_event(ev); 1403 | 1404 | CAPTURE: 1405 | /* note: this runs every frame whether UI captures or not */ 1406 | switch (ev->type) { 1407 | case SAPP_EVENTTYPE_MOUSE_DOWN: 1408 | case SAPP_EVENTTYPE_MOUSE_MOVE: 1409 | case SAPP_EVENTTYPE_MOUSE_UP: 1410 | state.ui.last_mouse = mouse_pos; 1411 | default: {} 1412 | } 1413 | } 1414 | 1415 | unsigned int positive_inf = 0x7F800000; // 0xFF << 23 1416 | #define POS_INF_F (*(float *)&positive_inf) 1417 | static float scene_distance(Vec2 p, Ent *exclude, EntMask hit_mask, Ent **ent) { 1418 | float dist = POS_INF_F; 1419 | 1420 | SYSTEM(e) { 1421 | if (!(e->has_mask & hit_mask)) continue; 1422 | if (e == exclude) continue; 1423 | 1424 | float this_dist = dist2(p, e->pos) - e->radius; 1425 | if (this_dist < dist) { 1426 | dist = this_dist; 1427 | if (ent) *ent = e; 1428 | } 1429 | } 1430 | return dist; 1431 | } 1432 | 1433 | static float raymarch(Vec2 origin, Vec2 dir, Ent *exclude, EntMask hit_mask, Ent **hit) { 1434 | float t = 0.0f; 1435 | for (int iter = 0; iter < 5; iter++) { 1436 | float d = scene_distance(add2(origin, mul2f(dir, t)), exclude, hit_mask, hit); 1437 | if (d == POS_INF_F) return d; 1438 | if (d < 0.01f) return t; 1439 | t += d; 1440 | } 1441 | return t; 1442 | } 1443 | 1444 | static float raymarch_ent(Ent *ent, Ent **hit) { 1445 | return raymarch(ent->pos, ent->vel, ent, ent->hit_mask, hit); 1446 | } 1447 | 1448 | 1449 | #define TICK_MS (1000.0f / 60.0f) 1450 | static void tick(void) { 1451 | state.tick++; 1452 | 1453 | state.cam = lerp2(state.cam, add2(state.player->pos, vec2(0.0f, 0.5f)), 0.05f); 1454 | 1455 | Vec2 move = {0}; 1456 | if (state.keys[SAPP_KEYCODE_W]) move.y += 1.0; 1457 | if (state.keys[SAPP_KEYCODE_S]) move.y -= 1.0; 1458 | if (state.keys[SAPP_KEYCODE_A]) move.x -= 1.0; 1459 | if (state.keys[SAPP_KEYCODE_D]) move.x += 1.0; 1460 | move = norm2(move); 1461 | float speed = ent_speed(state.player); 1462 | if (!state.keys[SAPP_KEYCODE_LEFT_SHIFT]) 1463 | state.player->vel = add2(state.player->vel, mul2f(move, speed)); 1464 | if (state.aimer.active) { 1465 | float aimer_speed = 0.08f * (1.0f + state.keys[SAPP_KEYCODE_LEFT_SHIFT]); 1466 | state.aimer.pos = add2(state.aimer.pos, mul2f(move, aimer_speed)); 1467 | } 1468 | 1469 | waffle_update(&state.waffle); 1470 | 1471 | SYSTEM(e) { 1472 | if (e->item) { 1473 | float item_rot; 1474 | Vec2 item_pos; 1475 | uint8_t item_dmg; 1476 | ent_item_transform(e, &item_rot, &item_pos, &item_dmg); 1477 | if (item_shoots[e->item] && item_dmg && !e->swing.shot) { 1478 | e->swing.shot = 1; 1479 | e->vel = sub2(e->vel, mul2f(e->swing.toward, 0.145f)); 1480 | 1481 | Ent *blt = ent_alloc(); 1482 | blt->pos = item_pos; 1483 | blt->looks = EntLooks_Arrow; 1484 | blt->vel = mul2f(e->swing.toward, 0.13f); 1485 | blt->hit_mask = e->item_hit_mask; 1486 | blt->friction = 1.0f; 1487 | blt->pointy = true; 1488 | } 1489 | if (item_hits [e->item] && item_dmg) { 1490 | Vec2 dir = rads2(item_rot + M_PI_2); 1491 | Ent *hit; 1492 | if (raymarch(item_pos, dir, NULL, e->item_hit_mask, &hit) < 1.5f) { 1493 | if (ent_damage(hit, e)) { 1494 | Vec2 normal = norm2(sub2(e->pos, hit->pos)); 1495 | e->vel = add2(e->vel, mul2f(normal, 0.07f)); 1496 | hit->vel = add2(hit->vel, mul2f(normal, -0.2f)); 1497 | } 1498 | } 1499 | } 1500 | } 1501 | 1502 | float vel_mag = mag2(e->vel); 1503 | if (vel_mag <= 0.0f) continue; 1504 | 1505 | float d; 1506 | Ent *closest_ent; 1507 | float closest_dist = raymarch_ent(e, &closest_ent) - e->radius; 1508 | if (closest_dist <= 0.0f) { 1509 | /* by moving forward we'd hit a thing, if we're an arrow that means damage */ 1510 | if (e->pointy && closest_ent) { 1511 | if (ent_damage(closest_ent, e)) 1512 | closest_ent->vel = add2(closest_ent->vel, mul2f(e->vel, 0.4f)); 1513 | ent_free(e); 1514 | return; 1515 | } 1516 | 1517 | /* otherwise let's just bounce off of that thing */ 1518 | e->vel = mul2f(refl2(norm2(e->vel), norm2(sub2(e->pos, closest_ent->pos))), vel_mag); 1519 | d = vel_mag; 1520 | 1521 | } else { 1522 | d = fminf(vel_mag, closest_dist); 1523 | } 1524 | 1525 | // e->pos = add2(e->pos, mul2f(e->vel, d / vel_mag)); 1526 | e->pos = add2(e->pos, mul2f(norm2(e->vel), d)); 1527 | e->vel = mul2f(e->vel, e->friction ?: 0.93f); 1528 | } 1529 | } 1530 | 1531 | static void frame(void) { 1532 | double elapsed = stm_ms(stm_laptime(&state.frame)); 1533 | state.fixed_tick_accumulator += elapsed; 1534 | while (state.fixed_tick_accumulator > TICK_MS) { 1535 | state.fixed_tick_accumulator -= TICK_MS; 1536 | tick(); 1537 | } 1538 | 1539 | GeoWtr wtr = geo_wtr(&state.dyn_geo); 1540 | 1541 | /* push game ents */ 1542 | if (state.aimer.active) { 1543 | Vec2 p = add2(state.player->pos, state.aimer.pos); 1544 | write_sight(&wtr, p.x + 0.045f, p.y - 0.045f, 0.3f, Color_DarkMaroon, p.y - 1.0f); 1545 | write_sight(&wtr, p.x + 0.000f, p.y - 0.000f, 0.3f, Color_Maroon, p.y - 1.0f); 1546 | } 1547 | SYSTEM(e) { 1548 | if (!e->looks) continue; 1549 | write_ent(&wtr, e); 1550 | } 1551 | 1552 | uint16_t *text_start = wtr.idx; 1553 | { /* push text */ 1554 | char buf[1 << 6]; 1555 | sprintf(buf, "%d FPS", (int)roundf(1.0f / sapp_frame_duration())); 1556 | write_text(&wtr, sapp_widthf() - 90.0f, sapp_heightf(), buf, Color_White); 1557 | 1558 | write_ui(&wtr); 1559 | 1560 | for (int i = 0; i < sizeof(state.dmg_lbls) / sizeof(state.dmg_lbls[0]); i++) { 1561 | DmgLbl *dl = state.dmg_lbls + i; 1562 | float t = state.tick - dl->tick; 1563 | if (dmg_lbl_alive(dl)) { 1564 | sprintf(buf, "%dhp", dl->hp); 1565 | write_text(&wtr, dl->pos.x, dl->pos.y + t, buf, Color_Red); 1566 | } 1567 | } 1568 | } 1569 | 1570 | geo_wtr_flush(&wtr); 1571 | 1572 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 1573 | sg_apply_pipeline(state.pip); 1574 | 1575 | geo_find_z_range(state.dyn_geo.verts, wtr.vert); 1576 | vs_params_t vs_params = { .mvp = mvp4x4() }; 1577 | sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, &SG_RANGE(vs_params)); 1578 | 1579 | sg_apply_bindings(&state.static_geo.bind); 1580 | sg_draw(0, state.static_geo_n_idx, 1); 1581 | 1582 | sg_apply_bindings(&state.dyn_geo.bind); 1583 | sg_draw(0, text_start - state.dyn_geo.idxs, 1); 1584 | 1585 | sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, &SG_RANGE(((vs_params_t) { 1586 | .mvp = ortho4x4(0.0f, sapp_widthf(), 0.0f, sapp_heightf(), -1.0f, 1.0f), 1587 | }))); 1588 | sg_draw(text_start - state.dyn_geo.idxs, wtr.idx - text_start, 1); 1589 | 1590 | sg_end_pass(); 1591 | sg_commit(); 1592 | } 1593 | 1594 | static void cleanup(void) { 1595 | sg_shutdown(); 1596 | } 1597 | 1598 | sapp_desc sokol_main(int argc, char* argv[]) { 1599 | (void)argc; (void)argv; 1600 | return (sapp_desc){ 1601 | .init_cb = init, 1602 | .frame_cb = frame, 1603 | .cleanup_cb = cleanup, 1604 | .event_cb = event, 1605 | .width = 1280, 1606 | .height = 720, 1607 | .gl_force_gles2 = true, 1608 | .window_title = "rpgc", 1609 | .icon.sokol_default = true, 1610 | .sample_count = 8, 1611 | }; 1612 | } 1613 | -------------------------------------------------------------------------------- /map.json: -------------------------------------------------------------------------------- 1 | { 2 | "trees": [ 3 | [ 4 | -7.391028881072998, 5 | 26.940689086914062 6 | ], 7 | [ 8 | -6.357036113739014, 9 | 26.849788665771484 10 | ], 11 | [ 12 | -5.3167948722839355, 13 | 26.928775787353516 14 | ], 15 | [ 16 | -4.277228832244873, 17 | 26.859363555908203 18 | ], 19 | [ 20 | -3.216662645339966, 21 | 26.897254943847656 22 | ], 23 | [ 24 | -2.168349504470825, 25 | 26.94976043701172 26 | ], 27 | [ 28 | -1.1580232381820679, 29 | 26.82351303100586 30 | ], 31 | [ 32 | -0.10421499609947205, 33 | 26.85668182373047 34 | ], 35 | [ 36 | 0.9330240488052368, 37 | 26.860023498535156 38 | ], 39 | [ 40 | 1.9651647806167603, 41 | -6.168181419372559 42 | ], 43 | [ 44 | 0.9282346963882446, 45 | -6.454672813415527 46 | ], 47 | [ 48 | -0.08824095129966736, 49 | -6.263028144836426 50 | ], 51 | [ 52 | -1.1619218587875366, 53 | -6.250588417053223 54 | ], 55 | [ 56 | -2.177039384841919, 57 | -6.456387519836426 58 | ], 59 | [ 60 | 0.9535719156265259, 61 | -5.328883171081543 62 | ], 63 | [ 64 | -0.10023435950279236, 65 | -5.1025896072387695 66 | ], 67 | [ 68 | -7.382331371307373, 69 | 25.82840919494629 70 | ], 71 | [ 72 | -6.343898296356201, 73 | 25.83770179748535 74 | ], 75 | [ 76 | -5.305915355682373, 77 | 25.676355361938477 78 | ], 79 | [ 80 | -4.244735240936279, 81 | 25.79109001159668 82 | ], 83 | [ 84 | -3.2261078357696533, 85 | 25.516258239746094 86 | ], 87 | [ 88 | -2.168105363845825, 89 | 25.84162139892578 90 | ], 91 | [ 92 | -1.1295427083969116, 93 | 25.59747314453125 94 | ], 95 | [ 96 | -0.09505400061607361, 97 | 25.57638168334961 98 | ], 99 | [ 100 | 0.9254728555679321, 101 | 25.742435455322266 102 | ], 103 | [ 104 | 3.0189454555511475, 105 | 25.705142974853516 106 | ], 107 | [ 108 | 4.077459812164307, 109 | 25.62393569946289 110 | ], 111 | [ 112 | 5.094445705413818, 113 | 25.72765350341797 114 | ], 115 | [ 116 | 6.133793354034424, 117 | 25.59033203125 118 | ], 119 | [ 120 | -8.402581214904785, 121 | 24.597883224487305 122 | ], 123 | [ 124 | -7.380492687225342, 125 | 24.675081253051758 126 | ], 127 | [ 128 | -6.324050426483154, 129 | 24.58774757385254 130 | ], 131 | [ 132 | -5.31361722946167, 133 | 24.368104934692383 134 | ], 135 | [ 136 | -4.274867534637451, 137 | 24.40217399597168 138 | ], 139 | [ 140 | -3.226741075515747, 141 | 24.548667907714844 142 | ], 143 | [ 144 | -2.1982452869415283, 145 | 24.696887969970703 146 | ], 147 | [ 148 | -1.1356080770492554, 149 | 24.59020233154297 150 | ], 151 | [ 152 | -0.09424147009849548, 153 | 24.617488861083984 154 | ], 155 | [ 156 | 0.9401670694351196, 157 | 24.469459533691406 158 | ], 159 | [ 160 | 1.995313286781311, 161 | 24.511703491210938 162 | ], 163 | [ 164 | 3.0272138118743896, 165 | 24.515819549560547 166 | ], 167 | [ 168 | 4.075900554656982, 169 | 24.390209197998047 170 | ], 171 | [ 172 | 5.092116832733154, 173 | 24.570960998535156 174 | ], 175 | [ 176 | 6.124745845794678, 177 | 24.389522552490234 178 | ], 179 | [ 180 | 7.1613688468933105, 181 | 24.381946563720703 182 | ], 183 | [ 184 | 8.23335075378418, 185 | 24.7095947265625 186 | ], 187 | [ 188 | 9.252485275268555, 189 | 24.540931701660156 190 | ], 191 | [ 192 | 10.313355445861816, 193 | 24.379634857177734 194 | ], 195 | [ 196 | 12.364527702331543, 197 | 24.396759033203125 198 | ], 199 | [ 200 | 13.413041114807129, 201 | 24.419109344482422 202 | ], 203 | [ 204 | 10.315384864807129, 205 | -2.874802350997925 206 | ], 207 | [ 208 | 14.439663887023926, 209 | 24.63119125366211 210 | ], 211 | [ 212 | 15.503743171691895, 213 | 24.64275360107422 214 | ], 215 | [ 216 | 23.803974151611328, 217 | -2.708094358444214 218 | ], 219 | [ 220 | 24.85065460205078, 221 | -2.8298327922821045 222 | ], 223 | [ 224 | 25.902610778808594, 225 | -2.8255984783172607 226 | ], 227 | [ 228 | 26.93360137939453, 229 | -2.6384150981903076 230 | ], 231 | [ 232 | -10.48686695098877, 233 | -4.057674407958984 234 | ], 235 | [ 236 | -9.442793846130371, 237 | -3.946641683578491 238 | ], 239 | [ 240 | -8.426976203918457, 241 | -4.064794540405273 242 | ], 243 | [ 244 | -7.38228178024292, 245 | -3.966520071029663 246 | ], 247 | [ 248 | -6.343539714813232, 249 | -3.817859411239624 250 | ], 251 | [ 252 | -5.2921061515808105, 253 | -4.123071670532227 254 | ], 255 | [ 256 | -4.245822429656982, 257 | -3.9526784420013428 258 | ], 259 | [ 260 | -3.2328598499298096, 261 | -3.9736945629119873 262 | ], 263 | [ 264 | -2.169348955154419, 265 | -4.122990608215332 266 | ], 267 | [ 268 | 6.141785144805908, 269 | -4.1217451095581055 270 | ], 271 | [ 272 | 7.19260835647583, 273 | -4.014704704284668 274 | ], 275 | [ 276 | 10.292120933532715, 277 | -4.117642402648926 278 | ], 279 | [ 280 | 21.753135681152344, 281 | -4.103812217712402 282 | ], 283 | [ 284 | 22.777549743652344, 285 | -3.797011137008667 286 | ], 287 | [ 288 | 23.80011749267578, 289 | -3.9428317546844482 290 | ], 291 | [ 292 | 24.866104125976562, 293 | -3.8352763652801514 294 | ], 295 | [ 296 | 25.896930694580078, 297 | -3.8314692974090576 298 | ], 299 | [ 300 | 26.932823181152344, 301 | -3.969820737838745 302 | ], 303 | [ 304 | 27.98153305053711, 305 | -4.115435600280762 306 | ], 307 | [ 308 | -10.489720344543457, 309 | -5.014102935791016 310 | ], 311 | [ 312 | -9.460566520690918, 313 | -5.076089859008789 314 | ], 315 | [ 316 | -8.436324119567871, 317 | -5.110567092895508 318 | ], 319 | [ 320 | -7.373950481414795, 321 | -5.068840026855469 322 | ], 323 | [ 324 | -6.333995342254639, 325 | -5.016460418701172 326 | ], 327 | [ 328 | -5.296420574188232, 329 | -4.942766189575195 330 | ], 331 | [ 332 | -4.252528667449951, 333 | -5.131217956542969 334 | ], 335 | [ 336 | -3.2022812366485596, 337 | -5.160269737243652 338 | ], 339 | [ 340 | -2.1775848865509033, 341 | -5.173876762390137 342 | ], 343 | [ 344 | -1.1432489156723022, 345 | -5.217520713806152 346 | ], 347 | [ 348 | 1.986570954322815, 349 | -5.063370704650879 350 | ], 351 | [ 352 | 3.0267341136932373, 353 | -5.183527946472168 354 | ], 355 | [ 356 | 4.067022800445557, 357 | -5.091790199279785 358 | ], 359 | [ 360 | 5.096022129058838, 361 | -5.02241325378418 362 | ], 363 | [ 364 | 6.153286457061768, 365 | -5.09260368347168 366 | ], 367 | [ 368 | 7.161579608917236, 369 | -5.205262184143066 370 | ], 371 | [ 372 | 8.215882301330566, 373 | -5.123154640197754 374 | ], 375 | [ 376 | 9.248194694519043, 377 | -5.151153564453125 378 | ], 379 | [ 380 | 10.316435813903809, 381 | -4.959439277648926 382 | ], 383 | [ 384 | 11.357922554016113, 385 | -5.0652875900268555 386 | ], 387 | [ 388 | 12.368346214294434, 389 | -5.218578338623047 390 | ], 391 | [ 392 | 13.40701961517334, 393 | -5.232579231262207 394 | ], 395 | [ 396 | 15.496878623962402, 397 | -5.129790306091309 398 | ], 399 | [ 400 | 16.523574829101562, 401 | -5.018956184387207 402 | ], 403 | [ 404 | 17.58731460571289, 405 | -5.050427436828613 406 | ], 407 | [ 408 | 18.622756958007812, 409 | -5.019278526306152 410 | ], 411 | [ 412 | 19.66565704345703, 413 | -5.153481483459473 414 | ], 415 | [ 416 | 20.696815490722656, 417 | -5.018467903137207 418 | ], 419 | [ 420 | 21.726768493652344, 421 | -5.049874305725098 422 | ], 423 | [ 424 | 22.79912567138672, 425 | -5.190743446350098 426 | ], 427 | [ 428 | 23.811180114746094, 429 | -5.216368675231934 430 | ], 431 | [ 432 | 24.84337043762207, 433 | -5.007328987121582 434 | ], 435 | [ 436 | 25.910049438476562, 437 | -5.073565483093262 438 | ], 439 | [ 440 | 26.939895629882812, 441 | -5.206118583679199 442 | ], 443 | [ 444 | -9.453770637512207, 445 | -6.115883827209473 446 | ], 447 | [ 448 | 3.0166518688201904, 449 | -6.401995658874512 450 | ], 451 | [ 452 | 4.051788806915283, 453 | -6.119446754455566 454 | ], 455 | [ 456 | 5.105478763580322, 457 | -6.247435569763184 458 | ], 459 | [ 460 | 6.1488938331604, 461 | -6.391026496887207 462 | ], 463 | [ 464 | 7.191559314727783, 465 | -6.111870765686035 466 | ], 467 | [ 468 | 8.204346656799316, 469 | -6.279688835144043 470 | ], 471 | [ 472 | 9.242526054382324, 473 | -6.130253791809082 474 | ], 475 | [ 476 | 10.305399894714355, 477 | -6.081393241882324 478 | ], 479 | [ 480 | 11.338997840881348, 481 | -6.143793106079102 482 | ], 483 | [ 484 | 12.383620262145996, 485 | -6.103856086730957 486 | ], 487 | [ 488 | 13.400490760803223, 489 | -6.160196304321289 490 | ], 491 | [ 492 | 14.47077465057373, 493 | -6.374889373779297 494 | ], 495 | [ 496 | 15.492718696594238, 497 | -6.319214820861816 498 | ], 499 | [ 500 | 16.53897476196289, 501 | -6.39315128326416 502 | ], 503 | [ 504 | 17.583850860595703, 505 | -6.098574638366699 506 | ], 507 | [ 508 | 18.63467788696289, 509 | -6.357743263244629 510 | ], 511 | [ 512 | 19.64798355102539, 513 | -6.174965858459473 514 | ], 515 | [ 516 | 20.683155059814453, 517 | -6.090052604675293 518 | ], 519 | [ 520 | 21.75238800048828, 521 | -6.297385215759277 522 | ], 523 | [ 524 | 22.774898529052734, 525 | -6.056353569030762 526 | ], 527 | [ 528 | 15.50478744506836, 529 | -7.471123695373535 530 | ], 531 | [ 532 | 16.556427001953125, 533 | -7.199959754943848 534 | ], 535 | [ 536 | -8.403334617614746, 537 | 23.316225051879883 538 | ], 539 | [ 540 | -7.372191905975342, 541 | 23.27195167541504 542 | ], 543 | [ 544 | -6.326766490936279, 545 | 23.4621639251709 546 | ], 547 | [ 548 | -5.305404186248779, 549 | 23.238920211791992 550 | ], 551 | [ 552 | -4.265113353729248, 553 | 23.534502029418945 554 | ], 555 | [ 556 | -3.2371819019317627, 557 | 23.271873474121094 558 | ], 559 | [ 560 | -2.191992998123169, 561 | 23.293472290039062 562 | ], 563 | [ 564 | -1.1567529439926147, 565 | 23.39691162109375 566 | ], 567 | [ 568 | -0.10865148901939392, 569 | 23.4990234375 570 | ], 571 | [ 572 | 0.9553209543228149, 573 | 23.372352600097656 574 | ], 575 | [ 576 | 1.9703880548477173, 577 | 23.562694549560547 578 | ], 579 | [ 580 | 3.0364692211151123, 581 | 23.5128173828125 582 | ], 583 | [ 584 | 4.078301906585693, 585 | 23.356155395507812 586 | ], 587 | [ 588 | 5.104798793792725, 589 | 23.564186096191406 590 | ], 591 | [ 592 | 6.1360554695129395, 593 | 23.26333236694336 594 | ], 595 | [ 596 | 7.182495594024658, 597 | 23.328968048095703 598 | ], 599 | [ 600 | 8.233595848083496, 601 | 23.485610961914062 602 | ], 603 | [ 604 | 9.262598991394043, 605 | 23.36990737915039 606 | ], 607 | [ 608 | 10.29695987701416, 609 | 23.32406234741211 610 | ], 611 | [ 612 | 11.321799278259277, 613 | 23.385517120361328 614 | ], 615 | [ 616 | 12.398972511291504, 617 | 23.443077087402344 618 | ], 619 | [ 620 | 13.408881187438965, 621 | 23.463775634765625 622 | ], 623 | [ 624 | 14.45824146270752, 625 | 23.316959381103516 626 | ], 627 | [ 628 | 15.517868995666504, 629 | 23.434951782226562 630 | ], 631 | [ 632 | 16.54769515991211, 633 | 23.3720703125 634 | ], 635 | [ 636 | 17.567752838134766, 637 | 23.498729705810547 638 | ], 639 | [ 640 | 18.612552642822266, 641 | 23.276201248168945 642 | ], 643 | [ 644 | -9.452719688415527, 645 | 22.108911514282227 646 | ], 647 | [ 648 | -8.403368949890137, 649 | 22.271398544311523 650 | ], 651 | [ 652 | -7.395633220672607, 653 | 22.436063766479492 654 | ], 655 | [ 656 | -6.327441692352295, 657 | 22.202924728393555 658 | ], 659 | [ 660 | -5.298472881317139, 661 | 22.404970169067383 662 | ], 663 | [ 664 | -4.242702007293701, 665 | 22.29218864440918 666 | ], 667 | [ 668 | -3.225207567214966, 669 | 22.30063247680664 670 | ], 671 | [ 672 | -2.1989662647247314, 673 | 22.267669677734375 674 | ], 675 | [ 676 | -1.1224626302719116, 677 | 22.180526733398438 678 | ], 679 | [ 680 | -0.11756643652915955, 681 | 22.226016998291016 682 | ], 683 | [ 684 | 0.9581362009048462, 685 | 22.20116424560547 686 | ], 687 | [ 688 | 1.9868007898330688, 689 | 22.344100952148438 690 | ], 691 | [ 692 | 3.010305166244507, 693 | 22.248451232910156 694 | ], 695 | [ 696 | 4.062727451324463, 697 | 22.3544921875 698 | ], 699 | [ 700 | 5.0996880531311035, 701 | 22.1507568359375 702 | ], 703 | [ 704 | 6.151241779327393, 705 | 22.27635955810547 706 | ], 707 | [ 708 | 7.19533109664917, 709 | 22.36077880859375 710 | ], 711 | [ 712 | 8.234415054321289, 713 | 22.387104034423828 714 | ], 715 | [ 716 | 9.246014595031738, 717 | 22.16509246826172 718 | ], 719 | [ 720 | 10.297163963317871, 721 | 22.369922637939453 722 | ], 723 | [ 724 | 11.328680992126465, 725 | 22.11456298828125 726 | ], 727 | [ 728 | 12.385146141052246, 729 | 22.352584838867188 730 | ], 731 | [ 732 | 13.4387788772583, 733 | 22.246593475341797 734 | ], 735 | [ 736 | 14.468920707702637, 737 | 22.383163452148438 738 | ], 739 | [ 740 | 15.480818748474121, 741 | 22.34091567993164 742 | ], 743 | [ 744 | 16.537700653076172, 745 | 22.2120361328125 746 | ], 747 | [ 748 | 17.59661865234375, 749 | 22.31563949584961 750 | ], 751 | [ 752 | 18.626129150390625, 753 | 22.149553298950195 754 | ], 755 | [ 756 | 19.660770416259766, 757 | 22.327051162719727 758 | ], 759 | [ 760 | -9.470011711120605, 761 | 21.127233505249023 762 | ], 763 | [ 764 | -8.432219505310059, 765 | 21.007062911987305 766 | ], 767 | [ 768 | -7.3847880363464355, 769 | 21.000524520874023 770 | ], 771 | [ 772 | -6.3267436027526855, 773 | 21.050207138061523 774 | ], 775 | [ 776 | -5.316731929779053, 777 | 21.056482315063477 778 | ], 779 | [ 780 | -4.256862163543701, 781 | 21.19947624206543 782 | ], 783 | [ 784 | -3.228154420852661, 785 | 21.049171447753906 786 | ], 787 | [ 788 | -2.199450731277466, 789 | 21.06298828125 790 | ], 791 | [ 792 | -1.15060555934906, 793 | 21.06340789794922 794 | ], 795 | [ 796 | -0.10473951697349548, 797 | 21.220855712890625 798 | ], 799 | [ 800 | 0.9214216470718384, 801 | 21.115558624267578 802 | ], 803 | [ 804 | 1.9924951791763306, 805 | 21.00879669189453 806 | ], 807 | [ 808 | 3.027890920639038, 809 | 21.040809631347656 810 | ], 811 | [ 812 | 4.047983646392822, 813 | 21.014423370361328 814 | ], 815 | [ 816 | 5.081307888031006, 817 | 21.073955535888672 818 | ], 819 | [ 820 | 6.132078647613525, 821 | 21.276073455810547 822 | ], 823 | [ 824 | 7.16222620010376, 825 | 21.277324676513672 826 | ], 827 | [ 828 | 8.232707023620605, 829 | 21.281871795654297 830 | ], 831 | [ 832 | 9.275662422180176, 833 | 21.160579681396484 834 | ], 835 | [ 836 | 10.28408145904541, 837 | 21.083816528320312 838 | ], 839 | [ 840 | 11.33841609954834, 841 | 21.113231658935547 842 | ], 843 | [ 844 | 12.36215877532959, 845 | 20.963279724121094 846 | ], 847 | [ 848 | 13.415457725524902, 849 | 21.181888580322266 850 | ], 851 | [ 852 | 14.477417945861816, 853 | 21.214336395263672 854 | ], 855 | [ 856 | 15.515974998474121, 857 | 21.152286529541016 858 | ], 859 | [ 860 | 16.51934051513672, 861 | 21.27404022216797 862 | ], 863 | [ 864 | 17.56656837463379, 865 | 21.212116241455078 866 | ], 867 | [ 868 | 18.620220184326172, 869 | 21.176427841186523 870 | ], 871 | [ 872 | 19.661212921142578, 873 | 21.070951461791992 874 | ], 875 | [ 876 | 20.718509674072266, 877 | 21.203779220581055 878 | ], 879 | [ 880 | -10.50916576385498, 881 | 20.075876235961914 882 | ], 883 | [ 884 | -9.463221549987793, 885 | 20.042715072631836 886 | ], 887 | [ 888 | -8.414742469787598, 889 | 19.85154914855957 890 | ], 891 | [ 892 | -7.363927364349365, 893 | 19.981325149536133 894 | ], 895 | [ 896 | -6.334056377410889, 897 | 20.0964298248291 898 | ], 899 | [ 900 | -5.286984920501709, 901 | 19.93976402282715 902 | ], 903 | [ 904 | -4.27853536605835, 905 | 20.02613639831543 906 | ], 907 | [ 908 | -3.209752321243286, 909 | 19.89153289794922 910 | ], 911 | [ 912 | -2.176305055618286, 913 | 19.810550689697266 914 | ], 915 | [ 916 | -1.1451696157455444, 917 | 19.847557067871094 918 | ], 919 | [ 920 | -0.08622488379478455, 921 | 19.894935607910156 922 | ], 923 | [ 924 | 0.9404436349868774, 925 | 19.960430145263672 926 | ], 927 | [ 928 | 1.9844175577163696, 929 | 20.116790771484375 930 | ], 931 | [ 932 | 3.0350234508514404, 933 | 20.144329071044922 934 | ], 935 | [ 936 | 4.050759792327881, 937 | 20.13055419921875 938 | ], 939 | [ 940 | 5.081950664520264, 941 | 19.98394775390625 942 | ], 943 | [ 944 | 6.135941982269287, 945 | 19.870193481445312 946 | ], 947 | [ 948 | 7.193999767303467, 949 | 19.929386138916016 950 | ], 951 | [ 952 | 8.217489242553711, 953 | 20.079444885253906 954 | ], 955 | [ 956 | 9.249852180480957, 957 | 20.11568832397461 958 | ], 959 | [ 960 | 10.305588722229004, 961 | 20.121726989746094 962 | ], 963 | [ 964 | 11.319579124450684, 965 | 20.11520767211914 966 | ], 967 | [ 968 | 12.399086952209473, 969 | 19.862224578857422 970 | ], 971 | [ 972 | 13.400015830993652, 973 | 20.032955169677734 974 | ], 975 | [ 976 | 14.460057258605957, 977 | 20.093223571777344 978 | ], 979 | [ 980 | 15.486197471618652, 981 | 20.004173278808594 982 | ], 983 | [ 984 | 16.534950256347656, 985 | 19.98867416381836 986 | ], 987 | [ 988 | 17.56262969970703, 989 | 20.005321502685547 990 | ], 991 | [ 992 | 18.605953216552734, 993 | 19.844038009643555 994 | ], 995 | [ 996 | 19.67353057861328, 997 | 20.098180770874023 998 | ], 999 | [ 1000 | 20.71363639831543, 1001 | 19.847196578979492 1002 | ], 1003 | [ 1004 | 21.73694610595703, 1005 | 20.10877799987793 1006 | ], 1007 | [ 1008 | 22.799072265625, 1009 | 19.84255027770996 1010 | ], 1011 | [ 1012 | 23.836179733276367, 1013 | 19.927289962768555 1014 | ], 1015 | [ 1016 | -10.499957084655762, 1017 | 18.92744255065918 1018 | ], 1019 | [ 1020 | -9.466959953308105, 1021 | 18.83292579650879 1022 | ], 1023 | [ 1024 | -8.419899940490723, 1025 | 18.970666885375977 1026 | ], 1027 | [ 1028 | -7.376065731048584, 1029 | 18.70721435546875 1030 | ], 1031 | [ 1032 | -6.340178966522217, 1033 | 18.843809127807617 1034 | ], 1035 | [ 1036 | -5.303725719451904, 1037 | 19.011640548706055 1038 | ], 1039 | [ 1040 | -4.242459774017334, 1041 | 18.750314712524414 1042 | ], 1043 | [ 1044 | -3.200770616531372, 1045 | 18.73776626586914 1046 | ], 1047 | [ 1048 | -2.1781418323516846, 1049 | 18.9500732421875 1050 | ], 1051 | [ 1052 | -1.1463407278060913, 1053 | 18.90473175048828 1054 | ], 1055 | [ 1056 | -0.09586843848228455, 1057 | 18.89834976196289 1058 | ], 1059 | [ 1060 | 9.243556022644043, 1061 | 18.71228790283203 1062 | ], 1063 | [ 1064 | 10.309945106506348, 1065 | 18.955158233642578 1066 | ], 1067 | [ 1068 | 11.341439247131348, 1069 | 18.935039520263672 1070 | ], 1071 | [ 1072 | 12.360529899597168, 1073 | 18.99261474609375 1074 | ], 1075 | [ 1076 | 13.4044828414917, 1077 | 18.681690216064453 1078 | ], 1079 | [ 1080 | 14.447211265563965, 1081 | 18.9429931640625 1082 | ], 1083 | [ 1084 | 15.49550724029541, 1085 | 18.91706085205078 1086 | ], 1087 | [ 1088 | 16.523082733154297, 1089 | 18.753524780273438 1090 | ], 1091 | [ 1092 | 17.5718994140625, 1093 | 18.74692153930664 1094 | ], 1095 | [ 1096 | 18.63275146484375, 1097 | 18.907609939575195 1098 | ], 1099 | [ 1100 | 19.64910888671875, 1101 | 18.71996307373047 1102 | ], 1103 | [ 1104 | 20.710987091064453, 1105 | 18.676326751708984 1106 | ], 1107 | [ 1108 | 21.733558654785156, 1109 | 18.716407775878906 1110 | ], 1111 | [ 1112 | 22.76898956298828, 1113 | 18.814943313598633 1114 | ], 1115 | [ 1116 | 23.833145141601562, 1117 | 18.847436904907227 1118 | ], 1119 | [ 1120 | 24.846311569213867, 1121 | 18.7872371673584 1122 | ], 1123 | [ 1124 | 25.9064998626709, 1125 | 18.83587074279785 1126 | ], 1127 | [ 1128 | -10.49790096282959, 1129 | 17.57065200805664 1130 | ], 1131 | [ 1132 | -9.462389945983887, 1133 | 17.816360473632812 1134 | ], 1135 | [ 1136 | -8.440516471862793, 1137 | 17.649051666259766 1138 | ], 1139 | [ 1140 | -7.380120754241943, 1141 | 17.733375549316406 1142 | ], 1143 | [ 1144 | -6.336673259735107, 1145 | 17.864200592041016 1146 | ], 1147 | [ 1148 | -5.289353847503662, 1149 | 17.826030731201172 1150 | ], 1151 | [ 1152 | -4.268966197967529, 1153 | 17.63662338256836 1154 | ], 1155 | [ 1156 | -3.214564561843872, 1157 | 17.707786560058594 1158 | ], 1159 | [ 1160 | -2.1703503131866455, 1161 | 17.589881896972656 1162 | ], 1163 | [ 1164 | 12.38660717010498, 1165 | 17.759498596191406 1166 | ], 1167 | [ 1168 | 13.40784740447998, 1169 | 17.73719024658203 1170 | ], 1171 | [ 1172 | 14.464306831359863, 1173 | 17.572036743164062 1174 | ], 1175 | [ 1176 | 19.640865325927734, 1177 | 17.844097137451172 1178 | ], 1179 | [ 1180 | 20.681808471679688, 1181 | 17.693164825439453 1182 | ], 1183 | [ 1184 | 21.737211227416992, 1185 | 17.57984161376953 1186 | ], 1187 | [ 1188 | 22.776880264282227, 1189 | 17.61398696899414 1190 | ], 1191 | [ 1192 | 23.809600830078125, 1193 | 17.80609130859375 1194 | ], 1195 | [ 1196 | 24.85955047607422, 1197 | 17.714927673339844 1198 | ], 1199 | [ 1200 | 25.901262283325195, 1201 | 17.788921356201172 1202 | ], 1203 | [ 1204 | 26.950878143310547, 1205 | 17.613750457763672 1206 | ], 1207 | [ 1208 | 27.993892669677734, 1209 | 17.794387817382812 1210 | ], 1211 | [ 1212 | -8.428242683410645, 1213 | 16.56429672241211 1214 | ], 1215 | [ 1216 | -7.379727840423584, 1217 | 16.542922973632812 1218 | ], 1219 | [ 1220 | -6.3407721519470215, 1221 | 16.631778717041016 1222 | ], 1223 | [ 1224 | -5.301406383514404, 1225 | 16.670848846435547 1226 | ], 1227 | [ 1228 | 20.693256378173828, 1229 | 16.548439025878906 1230 | ], 1231 | [ 1232 | 21.727521896362305, 1233 | 16.478839874267578 1234 | ], 1235 | [ 1236 | 22.798917770385742, 1237 | 16.672260284423828 1238 | ], 1239 | [ 1240 | 23.819286346435547, 1241 | 16.526443481445312 1242 | ], 1243 | [ 1244 | 24.86516571044922, 1245 | 16.574722290039062 1246 | ], 1247 | [ 1248 | 25.89580535888672, 1249 | 16.565650939941406 1250 | ], 1251 | [ 1252 | 26.939176559448242, 1253 | 16.71371841430664 1254 | ], 1255 | [ 1256 | 27.960111618041992, 1257 | 16.437686920166016 1258 | ], 1259 | [ 1260 | -6.327094554901123, 1261 | 15.52993106842041 1262 | ], 1263 | [ 1264 | 3.0118377208709717, 1265 | 15.516743659973145 1266 | ], 1267 | [ 1268 | 4.075287342071533, 1269 | 15.48894214630127 1270 | ], 1271 | [ 1272 | 5.1186957359313965, 1273 | 15.264138221740723 1274 | ], 1275 | [ 1276 | 6.155886173248291, 1277 | 15.535378456115723 1278 | ], 1279 | [ 1280 | 7.1833109855651855, 1281 | 15.45851993560791 1282 | ], 1283 | [ 1284 | 8.204151153564453, 1285 | 15.54131031036377 1286 | ], 1287 | [ 1288 | 22.789169311523438, 1289 | 15.35012149810791 1290 | ], 1291 | [ 1292 | 23.808372497558594, 1293 | 15.34902286529541 1294 | ], 1295 | [ 1296 | 24.856142044067383, 1297 | 15.300515174865723 1298 | ], 1299 | [ 1300 | 25.9039306640625, 1301 | 15.359776496887207 1302 | ], 1303 | [ 1304 | 26.953346252441406, 1305 | 15.427998542785645 1306 | ], 1307 | [ 1308 | 27.97264862060547, 1309 | 15.37255573272705 1310 | ], 1311 | [ 1312 | -2.1622135639190674, 1313 | 14.380873680114746 1314 | ], 1315 | [ 1316 | -1.1454709768295288, 1317 | 14.261778831481934 1318 | ], 1319 | [ 1320 | -0.10003599524497986, 1321 | 14.20398998260498 1322 | ], 1323 | [ 1324 | 0.9319521188735962, 1325 | 14.419156074523926 1326 | ], 1327 | [ 1328 | 1.9838777780532837, 1329 | 14.167645454406738 1330 | ], 1331 | [ 1332 | 3.032353162765503, 1333 | 14.450156211853027 1334 | ], 1335 | [ 1336 | 4.064542293548584, 1337 | 14.246537208557129 1338 | ], 1339 | [ 1340 | 5.10577917098999, 1341 | 14.193163871765137 1342 | ], 1343 | [ 1344 | 6.122413158416748, 1345 | 14.150181770324707 1346 | ], 1347 | [ 1348 | 7.183699131011963, 1349 | 14.183455467224121 1350 | ], 1351 | [ 1352 | 8.216997146606445, 1353 | 14.167180061340332 1354 | ], 1355 | [ 1356 | 9.263872146606445, 1357 | 14.414454460144043 1358 | ], 1359 | [ 1360 | 10.283324241638184, 1361 | 14.217787742614746 1362 | ], 1363 | [ 1364 | 23.7996826171875, 1365 | 14.141999244689941 1366 | ], 1367 | [ 1368 | 24.847728729248047, 1369 | 14.11725902557373 1370 | ], 1371 | [ 1372 | 25.88238525390625, 1373 | 14.438363075256348 1374 | ], 1375 | [ 1376 | 26.95014190673828, 1377 | 14.15552806854248 1378 | ], 1379 | [ 1380 | 27.991992950439453, 1381 | 14.44942569732666 1382 | ], 1383 | [ 1384 | -3.228686571121216, 1385 | 13.283415794372559 1386 | ], 1387 | [ 1388 | -2.160844087600708, 1389 | 13.171650886535645 1390 | ], 1391 | [ 1392 | -1.1299680471420288, 1393 | 13.277422904968262 1394 | ], 1395 | [ 1396 | -0.08942541480064392, 1397 | 13.308001518249512 1398 | ], 1399 | [ 1400 | 0.9225736856460571, 1401 | 13.219786643981934 1402 | ], 1403 | [ 1404 | 1.9862066507339478, 1405 | 13.123948097229004 1406 | ], 1407 | [ 1408 | 3.0332114696502686, 1409 | 13.158976554870605 1410 | ], 1411 | [ 1412 | 4.057875156402588, 1413 | 13.00110149383545 1414 | ], 1415 | [ 1416 | 5.083786487579346, 1417 | 13.112105369567871 1418 | ], 1419 | [ 1420 | 6.136216640472412, 1421 | 13.038565635681152 1422 | ], 1423 | [ 1424 | 7.198131084442139, 1425 | 13.180489540100098 1426 | ], 1427 | [ 1428 | 8.239005088806152, 1429 | 13.044390678405762 1430 | ], 1431 | [ 1432 | 9.250706672668457, 1433 | 13.201878547668457 1434 | ], 1435 | [ 1436 | 10.282429695129395, 1437 | 13.017945289611816 1438 | ], 1439 | [ 1440 | 11.346474647521973, 1441 | 13.147412300109863 1442 | ], 1443 | [ 1444 | 23.824125289916992, 1445 | 13.223250389099121 1446 | ], 1447 | [ 1448 | 24.873332977294922, 1449 | 13.024649620056152 1450 | ], 1451 | [ 1452 | 25.88571548461914, 1453 | 13.296814918518066 1454 | ], 1455 | [ 1456 | 26.924842834472656, 1457 | 12.985428810119629 1458 | ], 1459 | [ 1460 | 27.974258422851562, 1461 | 13.027131080627441 1462 | ], 1463 | [ 1464 | -6.326453685760498, 1465 | 11.835463523864746 1466 | ], 1467 | [ 1468 | -5.283425807952881, 1469 | 12.04699993133545 1470 | ], 1471 | [ 1472 | -4.279876232147217, 1473 | 11.880105018615723 1474 | ], 1475 | [ 1476 | -3.224412202835083, 1477 | 12.101161003112793 1478 | ], 1479 | [ 1480 | -2.199876070022583, 1481 | 12.01170825958252 1482 | ], 1483 | [ 1484 | -1.1301854848861694, 1485 | 12.052247047424316 1486 | ], 1487 | [ 1488 | -0.11178144812583923, 1489 | 11.848977088928223 1490 | ], 1491 | [ 1492 | 0.9550100564956665, 1493 | 11.83349895477295 1494 | ], 1495 | [ 1496 | 1.992409348487854, 1497 | 12.161870002746582 1498 | ], 1499 | [ 1500 | 3.0024726390838623, 1501 | 12.047492027282715 1502 | ], 1503 | [ 1504 | 4.051798343658447, 1505 | 11.984591484069824 1506 | ], 1507 | [ 1508 | 5.081303119659424, 1509 | 11.864331245422363 1510 | ], 1511 | [ 1512 | 6.135258197784424, 1513 | 12.123713493347168 1514 | ], 1515 | [ 1516 | 7.181192874908447, 1517 | 12.09312915802002 1518 | ], 1519 | [ 1520 | 8.235000610351562, 1521 | 11.866835594177246 1522 | ], 1523 | [ 1524 | 9.269454002380371, 1525 | 12.08874225616455 1526 | ], 1527 | [ 1528 | 10.2964506149292, 1529 | 12.07625675201416 1530 | ], 1531 | [ 1532 | 11.340758323669434, 1533 | 11.964545249938965 1534 | ], 1535 | [ 1536 | 12.387951850891113, 1537 | 12.040680885314941 1538 | ], 1539 | [ 1540 | 23.832727432250977, 1541 | 11.925883293151855 1542 | ], 1543 | [ 1544 | 24.878437042236328, 1545 | 12.066145896911621 1546 | ], 1547 | [ 1548 | 25.91796112060547, 1549 | 12.023003578186035 1550 | ], 1551 | [ 1552 | 26.93288803100586, 1553 | 12.176331520080566 1554 | ], 1555 | [ 1556 | 27.969524383544922, 1557 | 11.997048377990723 1558 | ], 1559 | [ 1560 | -7.388770580291748, 1561 | 10.936348915100098 1562 | ], 1563 | [ 1564 | -6.332038402557373, 1565 | 10.959826469421387 1566 | ], 1567 | [ 1568 | -5.319457530975342, 1569 | 10.841483116149902 1570 | ], 1571 | [ 1572 | -4.257461071014404, 1573 | 10.819941520690918 1574 | ], 1575 | [ 1576 | -3.213965654373169, 1577 | 10.770171165466309 1578 | ], 1579 | [ 1580 | -2.1619884967803955, 1581 | 11.01965045928955 1582 | ], 1583 | [ 1584 | -1.1383260488510132, 1585 | 10.791998863220215 1586 | ], 1587 | [ 1588 | -0.11262831091880798, 1589 | 10.789694786071777 1590 | ], 1591 | [ 1592 | 0.9504991769790649, 1593 | 10.979874610900879 1594 | ], 1595 | [ 1596 | 1.984535813331604, 1597 | 11.013592720031738 1598 | ], 1599 | [ 1600 | 3.0337188243865967, 1601 | 10.719498634338379 1602 | ], 1603 | [ 1604 | 4.0419087409973145, 1605 | 10.977002143859863 1606 | ], 1607 | [ 1608 | 5.1043877601623535, 1609 | 10.739331245422363 1610 | ], 1611 | [ 1612 | 6.119503498077393, 1613 | 10.945130348205566 1614 | ], 1615 | [ 1616 | 7.193187236785889, 1617 | 10.932690620422363 1618 | ], 1619 | [ 1620 | 8.209663391113281, 1621 | 10.741045951843262 1622 | ], 1623 | [ 1624 | 9.24659252166748, 1625 | 11.02753734588623 1626 | ], 1627 | [ 1628 | 10.31350326538086, 1629 | 10.967434883117676 1630 | ], 1631 | [ 1632 | 11.328295707702637, 1633 | 11.024611473083496 1634 | ], 1635 | [ 1636 | 12.367293357849121, 1637 | 10.78528881072998 1638 | ], 1639 | [ 1640 | 13.430215835571289, 1641 | 10.927420616149902 1642 | ], 1643 | [ 1644 | 14.472447395324707, 1645 | 10.911961555480957 1646 | ], 1647 | [ 1648 | 22.775007247924805, 1649 | 10.701668739318848 1650 | ], 1651 | [ 1652 | 23.803646087646484, 1653 | 10.95345401763916 1654 | ], 1655 | [ 1656 | 24.87860870361328, 1657 | 10.959824562072754 1658 | ], 1659 | [ 1660 | 25.894020080566406, 1661 | 10.943646430969238 1662 | ], 1663 | [ 1664 | 26.953121185302734, 1665 | 10.8278169631958 1666 | ], 1667 | [ 1668 | 27.962928771972656, 1669 | 11.016011238098145 1670 | ], 1671 | [ 1672 | -9.457560539245605, 1673 | 9.865925788879395 1674 | ], 1675 | [ 1676 | -8.401642799377441, 1677 | 9.763232231140137 1678 | ], 1679 | [ 1680 | -7.37729024887085, 1681 | 9.887716293334961 1682 | ], 1683 | [ 1684 | -6.3395819664001465, 1685 | 9.673303604125977 1686 | ], 1687 | [ 1688 | -5.293025493621826, 1689 | 9.6754150390625 1690 | ], 1691 | [ 1692 | -4.268504619598389, 1693 | 9.704833984375 1694 | ], 1695 | [ 1696 | -3.2151405811309814, 1697 | 9.821500778198242 1698 | ], 1699 | [ 1700 | -2.198064088821411, 1701 | 9.602165222167969 1702 | ], 1703 | [ 1704 | -1.1239484548568726, 1705 | 9.747640609741211 1706 | ], 1707 | [ 1708 | -0.10700544714927673, 1709 | 9.58985710144043 1710 | ], 1711 | [ 1712 | 0.948616623878479, 1713 | 9.69701099395752 1714 | ], 1715 | [ 1716 | 1.9964205026626587, 1717 | 9.61841869354248 1718 | ], 1719 | [ 1720 | 3.00715708732605, 1721 | 9.79699993133545 1722 | ], 1723 | [ 1724 | 4.065037250518799, 1725 | 9.64635944366455 1726 | ], 1727 | [ 1728 | 5.09330415725708, 1729 | 9.617424964904785 1730 | ], 1731 | [ 1732 | 6.15505838394165, 1733 | 9.863717079162598 1734 | ], 1735 | [ 1736 | 7.165889263153076, 1737 | 9.771672248840332 1738 | ], 1739 | [ 1740 | 8.203202247619629, 1741 | 9.839152336120605 1742 | ], 1743 | [ 1744 | 9.272812843322754, 1745 | 9.613240242004395 1746 | ], 1747 | [ 1748 | 10.315655708312988, 1749 | 9.780896186828613 1750 | ], 1751 | [ 1752 | 11.356675148010254, 1753 | 9.8751802444458 1754 | ], 1755 | [ 1756 | 12.372871398925781, 1757 | 9.742098808288574 1758 | ], 1759 | [ 1760 | 13.414365768432617, 1761 | 9.654606819152832 1762 | ], 1763 | [ 1764 | 14.45807933807373, 1765 | 9.568438529968262 1766 | ], 1767 | [ 1768 | 15.506051063537598, 1769 | 9.63049030303955 1770 | ], 1771 | [ 1772 | 16.55853271484375, 1773 | 9.747235298156738 1774 | ], 1775 | [ 1776 | 20.690000534057617, 1777 | 9.815625190734863 1778 | ], 1779 | [ 1780 | 21.74359130859375, 1781 | 9.697346687316895 1782 | ], 1783 | [ 1784 | 22.773834228515625, 1785 | 9.573613166809082 1786 | ], 1787 | [ 1788 | 23.826091766357422, 1789 | 9.695473670959473 1790 | ], 1791 | [ 1792 | 24.868064880371094, 1793 | 9.863160133361816 1794 | ], 1795 | [ 1796 | 25.88677406311035, 1797 | 9.849761009216309 1798 | ], 1799 | [ 1800 | 26.948448181152344, 1801 | 9.854283332824707 1802 | ], 1803 | [ 1804 | -10.503230094909668, 1805 | 8.459689140319824 1806 | ], 1807 | [ 1808 | -9.464598655700684, 1809 | 8.489790916442871 1810 | ], 1811 | [ 1812 | -8.437697410583496, 1813 | 8.457221031188965 1814 | ], 1815 | [ 1816 | -7.3632025718688965, 1817 | 8.549870491027832 1818 | ], 1819 | [ 1820 | -6.330512523651123, 1821 | 8.58360767364502 1822 | ], 1823 | [ 1824 | -5.30573034286499, 1825 | 8.694504737854004 1826 | ], 1827 | [ 1828 | -4.273477077484131, 1829 | 8.687409400939941 1830 | ], 1831 | [ 1832 | -3.213893175125122, 1833 | 8.696930885314941 1834 | ], 1835 | [ 1836 | -2.1987850666046143, 1837 | 8.708342552185059 1838 | ], 1839 | [ 1840 | -1.1262563467025757, 1841 | 8.635294914245605 1842 | ], 1843 | [ 1844 | -0.08520635962486267, 1845 | 8.444220542907715 1846 | ], 1847 | [ 1848 | 0.9356924295425415, 1849 | 8.503905296325684 1850 | ], 1851 | [ 1852 | 1.9698148965835571, 1853 | 8.71694278717041 1854 | ], 1855 | [ 1856 | 3.016779661178589, 1857 | 8.744254112243652 1858 | ], 1859 | [ 1860 | 4.067215442657471, 1861 | 8.543488502502441 1862 | ], 1863 | [ 1864 | 5.082224369049072, 1865 | 8.698553085327148 1866 | ], 1867 | [ 1868 | 6.127522945404053, 1869 | 8.66129207611084 1870 | ], 1871 | [ 1872 | 7.177821636199951, 1873 | 8.502463340759277 1874 | ], 1875 | [ 1876 | 8.199605941772461, 1877 | 8.612056732177734 1878 | ], 1879 | [ 1880 | 9.247607231140137, 1881 | 8.723306655883789 1882 | ], 1883 | [ 1884 | 10.296724319458008, 1885 | 8.446842193603516 1886 | ], 1887 | [ 1888 | 11.340682029724121, 1889 | 8.561829566955566 1890 | ], 1891 | [ 1892 | 12.38354778289795, 1893 | 8.443514823913574 1894 | ], 1895 | [ 1896 | 13.424073219299316, 1897 | 8.471465110778809 1898 | ], 1899 | [ 1900 | 14.458769798278809, 1901 | 8.556448936462402 1902 | ], 1903 | [ 1904 | 15.488991737365723, 1905 | 8.45336627960205 1906 | ], 1907 | [ 1908 | 16.529010772705078, 1909 | 8.693099021911621 1910 | ], 1911 | [ 1912 | 17.58157730102539, 1913 | 8.606905937194824 1914 | ], 1915 | [ 1916 | 20.69012451171875, 1917 | 8.48995304107666 1918 | ], 1919 | [ 1920 | 21.727699279785156, 1921 | 8.59582233428955 1922 | ], 1923 | [ 1924 | 22.768098831176758, 1925 | 8.62536907196045 1926 | ], 1927 | [ 1928 | 23.82443618774414, 1929 | 8.505221366882324 1930 | ], 1931 | [ 1932 | 24.871755599975586, 1933 | 8.701167106628418 1934 | ], 1935 | [ 1936 | 25.91752815246582, 1937 | 8.597672462463379 1938 | ], 1939 | [ 1940 | 26.942386627197266, 1941 | 8.586020469665527 1942 | ], 1943 | [ 1944 | -10.493819236755371, 1945 | 7.3657121658325195 1946 | ], 1947 | [ 1948 | -9.456755638122559, 1949 | 7.538843154907227 1950 | ], 1951 | [ 1952 | -8.403435707092285, 1953 | 7.478846549987793 1954 | ], 1955 | [ 1956 | -7.397090435028076, 1957 | 7.613604545593262 1958 | ], 1959 | [ 1960 | -6.358701229095459, 1961 | 7.499163627624512 1962 | ], 1963 | [ 1964 | -5.319577693939209, 1965 | 7.578639030456543 1966 | ], 1967 | [ 1968 | -4.276393413543701, 1969 | 7.528044700622559 1970 | ], 1971 | [ 1972 | -3.204333543777466, 1973 | 7.5790910720825195 1974 | ], 1975 | [ 1976 | -2.1905014514923096, 1977 | 7.523961067199707 1978 | ], 1979 | [ 1980 | -1.1341012716293335, 1981 | 7.616311073303223 1982 | ], 1983 | [ 1984 | -0.09571966528892517, 1985 | 7.602285385131836 1986 | ], 1987 | [ 1988 | 3.0383212566375732, 1989 | 7.313565254211426 1990 | ], 1991 | [ 1992 | 4.056677341461182, 1993 | 7.3566083908081055 1994 | ], 1995 | [ 1996 | 5.104024410247803, 1997 | 7.492525100708008 1998 | ], 1999 | [ 2000 | 6.12858247756958, 2001 | 7.304166793823242 2002 | ], 2003 | [ 2004 | 7.168507099151611, 2005 | 7.615339279174805 2006 | ], 2007 | [ 2008 | 8.233668327331543, 2009 | 7.3530168533325195 2010 | ], 2011 | [ 2012 | 9.254631042480469, 2013 | 7.27708625793457 2014 | ], 2015 | [ 2016 | 10.29549503326416, 2017 | 7.506482124328613 2018 | ], 2019 | [ 2020 | 11.336350440979004, 2021 | 7.558147430419922 2022 | ], 2023 | [ 2024 | 12.370635032653809, 2025 | 7.511772155761719 2026 | ], 2027 | [ 2028 | 13.416449546813965, 2029 | 7.466236114501953 2030 | ], 2031 | [ 2032 | 14.46982479095459, 2033 | 7.44618034362793 2034 | ], 2035 | [ 2036 | 15.506047248840332, 2037 | 7.438211441040039 2038 | ], 2039 | [ 2040 | 16.548789978027344, 2041 | 7.406256675720215 2042 | ], 2043 | [ 2044 | 17.580249786376953, 2045 | 7.434629440307617 2046 | ], 2047 | [ 2048 | 22.7724666595459, 2049 | 7.292044639587402 2050 | ], 2051 | [ 2052 | 23.836275100708008, 2053 | 7.490462303161621 2054 | ], 2055 | [ 2056 | 24.87920379638672, 2057 | 7.364270210266113 2058 | ], 2059 | [ 2060 | 25.885860443115234, 2061 | 7.5733232498168945 2062 | ], 2063 | [ 2064 | 26.936796188354492, 2065 | 7.529166221618652 2066 | ], 2067 | [ 2068 | -10.482417106628418, 2069 | 6.265753746032715 2070 | ], 2071 | [ 2072 | -9.469325065612793, 2073 | 6.1846418380737305 2074 | ], 2075 | [ 2076 | -8.430155754089355, 2077 | 6.428196907043457 2078 | ], 2079 | [ 2080 | -7.3739142417907715, 2081 | 6.471667289733887 2082 | ], 2083 | [ 2084 | -6.337008953094482, 2085 | 6.323260307312012 2086 | ], 2087 | [ 2088 | -5.29440450668335, 2089 | 6.400521278381348 2090 | ], 2091 | [ 2092 | -4.249223232269287, 2093 | 6.411035537719727 2094 | ], 2095 | [ 2096 | -3.2045528888702393, 2097 | 6.350255966186523 2098 | ], 2099 | [ 2100 | -2.167882204055786, 2101 | 6.430477142333984 2102 | ], 2103 | [ 2104 | 6.1205315589904785, 2105 | 6.286114692687988 2106 | ], 2107 | [ 2108 | 7.174753665924072, 2109 | 6.435826301574707 2110 | ], 2111 | [ 2112 | 8.232592582702637, 2113 | 6.240455627441406 2114 | ], 2115 | [ 2116 | 9.243098258972168, 2117 | 6.138704299926758 2118 | ], 2119 | [ 2120 | 10.308438301086426, 2121 | 6.374777793884277 2122 | ], 2123 | [ 2124 | 11.353960037231445, 2125 | 6.344629287719727 2126 | ], 2127 | [ 2128 | 12.364520072937012, 2129 | 6.419631004333496 2130 | ], 2131 | [ 2132 | 13.423436164855957, 2133 | 6.3917646408081055 2134 | ], 2135 | [ 2136 | 14.44560432434082, 2137 | 6.216473579406738 2138 | ], 2139 | [ 2140 | 15.511187553405762, 2141 | 6.390920639038086 2142 | ], 2143 | [ 2144 | 16.524356842041016, 2145 | 6.253385543823242 2146 | ], 2147 | [ 2148 | 17.56149673461914, 2149 | 6.229679107666016 2150 | ], 2151 | [ 2152 | 18.616985321044922, 2153 | 6.325680732727051 2154 | ], 2155 | [ 2156 | 22.78240394592285, 2157 | 6.174063682556152 2158 | ], 2159 | [ 2160 | 23.838909149169922, 2161 | 6.18483829498291 2162 | ], 2163 | [ 2164 | 24.86331558227539, 2165 | 6.413825035095215 2166 | ], 2167 | [ 2168 | 25.883296966552734, 2169 | 6.1468000411987305 2170 | ], 2171 | [ 2172 | 26.921913146972656, 2173 | 6.164034843444824 2174 | ], 2175 | [ 2176 | -9.475974082946777, 2177 | 5.119235038757324 2178 | ], 2179 | [ 2180 | -8.417998313903809, 2181 | 5.030512809753418 2182 | ], 2183 | [ 2184 | -7.392266750335693, 2185 | 5.267207145690918 2186 | ], 2187 | [ 2188 | -6.339776515960693, 2189 | 5.011710166931152 2190 | ], 2191 | [ 2192 | -5.288785457611084, 2193 | 5.149259567260742 2194 | ], 2195 | [ 2196 | -4.257911205291748, 2197 | 5.133522033691406 2198 | ], 2199 | [ 2200 | -3.2117702960968018, 2201 | 5.292070388793945 2202 | ], 2203 | [ 2204 | 13.427016258239746, 2205 | 5.009634017944336 2206 | ], 2207 | [ 2208 | 14.467330932617188, 2209 | 5.286190032958984 2210 | ], 2211 | [ 2212 | 15.504061698913574, 2213 | 5.094522476196289 2214 | ], 2215 | [ 2216 | 16.55272674560547, 2217 | 5.321178436279297 2218 | ], 2219 | [ 2220 | 17.58022117614746, 2221 | 5.196657180786133 2222 | ], 2223 | [ 2224 | 21.735122680664062, 2225 | 5.06209659576416 2226 | ], 2227 | [ 2228 | 22.776376724243164, 2229 | 5.223088264465332 2230 | ], 2231 | [ 2232 | 23.833690643310547, 2233 | 5.108521461486816 2234 | ], 2235 | [ 2236 | 24.85059356689453, 2237 | 4.997450828552246 2238 | ], 2239 | [ 2240 | 25.893123626708984, 2241 | 5.006237983703613 2242 | ], 2243 | [ 2244 | 26.948917388916016, 2245 | 5.170134544372559 2246 | ], 2247 | [ 2248 | -9.478999137878418, 2249 | 3.8738415241241455 2250 | ], 2251 | [ 2252 | -8.401625633239746, 2253 | 4.013014793395996 2254 | ], 2255 | [ 2256 | -7.397719860076904, 2257 | 4.170064926147461 2258 | ], 2259 | [ 2260 | -6.35090970993042, 2261 | 4.152243614196777 2262 | ], 2263 | [ 2264 | -5.306437969207764, 2265 | 3.8986876010894775 2266 | ], 2267 | [ 2268 | -4.254868984222412, 2269 | 3.975755453109741 2270 | ], 2271 | [ 2272 | 16.536571502685547, 2273 | 4.050959587097168 2274 | ], 2275 | [ 2276 | 17.583385467529297, 2277 | 3.9338581562042236 2278 | ], 2279 | [ 2280 | 21.743988037109375, 2281 | 3.9569599628448486 2282 | ], 2283 | [ 2284 | 22.77292251586914, 2285 | 3.888381242752075 2286 | ], 2287 | [ 2288 | 23.831104278564453, 2289 | 3.9230282306671143 2290 | ], 2291 | [ 2292 | 24.862764358520508, 2293 | 3.878920793533325 2294 | ], 2295 | [ 2296 | 25.899707794189453, 2297 | 3.92033314704895 2298 | ], 2299 | [ 2300 | 26.93303108215332, 2301 | 4.0586442947387695 2302 | ], 2303 | [ 2304 | -9.449080467224121, 2305 | 2.9390804767608643 2306 | ], 2307 | [ 2308 | -8.42834758758545, 2309 | 2.9807088375091553 2310 | ], 2311 | [ 2312 | -7.3781962394714355, 2313 | 2.8360583782196045 2314 | ], 2315 | [ 2316 | -6.325393199920654, 2317 | 2.9213669300079346 2318 | ], 2319 | [ 2320 | -5.316386699676514, 2321 | 3.054572820663452 2322 | ], 2323 | [ 2324 | -4.243180751800537, 2325 | 2.9384496212005615 2326 | ], 2327 | [ 2328 | 21.727312088012695, 2329 | 3.041430711746216 2330 | ], 2331 | [ 2332 | 22.792240142822266, 2333 | 2.7389004230499268 2334 | ], 2335 | [ 2336 | 23.820804595947266, 2337 | 2.837918519973755 2338 | ], 2339 | [ 2340 | 24.86675262451172, 2341 | 3.015673875808716 2342 | ], 2343 | [ 2344 | 25.89011001586914, 2345 | 3.0219757556915283 2346 | ], 2347 | [ 2348 | 26.947988510131836, 2349 | 2.9082672595977783 2350 | ], 2351 | [ 2352 | -8.41732120513916, 2353 | 1.6983740329742432 2354 | ], 2355 | [ 2356 | -7.377078533172607, 2357 | 1.7353918552398682 2358 | ], 2359 | [ 2360 | -6.349206447601318, 2361 | 1.644684076309204 2362 | ], 2363 | [ 2364 | -5.29890775680542, 2365 | 1.6540796756744385 2366 | ], 2367 | [ 2368 | -4.268502712249756, 2369 | 1.5763685703277588 2370 | ], 2371 | [ 2372 | 22.781801223754883, 2373 | 1.817897081375122 2374 | ], 2375 | [ 2376 | 23.808387756347656, 2377 | 1.7119724750518799 2378 | ], 2379 | [ 2380 | 24.845577239990234, 2381 | 1.7016422748565674 2382 | ], 2383 | [ 2384 | 25.91876983642578, 2385 | 1.6060230731964111 2386 | ], 2387 | [ 2388 | 26.942501068115234, 2389 | 1.797868013381958 2390 | ], 2391 | [ 2392 | -9.465567588806152, 2393 | 0.60335373878479 2394 | ], 2395 | [ 2396 | -8.440302848815918, 2397 | 0.7252562046051025 2398 | ], 2399 | [ 2400 | -7.378865718841553, 2401 | 0.495952844619751 2402 | ], 2403 | [ 2404 | -6.322669506072998, 2405 | 0.5535871982574463 2406 | ], 2407 | [ 2408 | -5.292535305023193, 2409 | 0.6603710651397705 2410 | ], 2411 | [ 2412 | 23.806867599487305, 2413 | 0.6715118885040283 2414 | ], 2415 | [ 2416 | 24.86533546447754, 2417 | 0.5698349475860596 2418 | ], 2419 | [ 2420 | 25.902851104736328, 2421 | 0.6232540607452393 2422 | ], 2423 | [ 2424 | -9.473776817321777, 2425 | -0.6425235271453857 2426 | ], 2427 | [ 2428 | -8.407177925109863, 2429 | -0.46659350395202637 2430 | ], 2431 | [ 2432 | -7.380130290985107, 2433 | -0.4301164150238037 2434 | ], 2435 | [ 2436 | -6.342250347137451, 2437 | -0.6949784755706787 2438 | ], 2439 | [ 2440 | -5.282374858856201, 2441 | -0.43076014518737793 2442 | ], 2443 | [ 2444 | 24.866641998291016, 2445 | -0.3613460063934326 2446 | ], 2447 | [ 2448 | 25.88711929321289, 2449 | -0.48679614067077637 2450 | ], 2451 | [ 2452 | 26.925926208496094, 2453 | -0.4245288372039795 2454 | ], 2455 | [ 2456 | -10.5089750289917, 2457 | -1.5598199367523193 2458 | ], 2459 | [ 2460 | -9.460536003112793, 2461 | -1.5577638149261475 2462 | ], 2463 | [ 2464 | -8.428576469421387, 2465 | -1.5982091426849365 2466 | ], 2467 | [ 2468 | -7.386256694793701, 2469 | -1.6711957454681396 2470 | ], 2471 | [ 2472 | -6.333720684051514, 2473 | -1.788384199142456 2474 | ], 2475 | [ 2476 | -5.313552379608154, 2477 | -1.70505690574646 2478 | ], 2479 | [ 2480 | -4.252326488494873, 2481 | -1.7391126155853271 2482 | ], 2483 | [ 2484 | 23.829662322998047, 2485 | -1.6886775493621826 2486 | ], 2487 | [ 2488 | 24.860998153686523, 2489 | -1.6392180919647217 2490 | ], 2491 | [ 2492 | 25.914081573486328, 2493 | -1.7548282146453857 2494 | ], 2495 | [ 2496 | 26.946435928344727, 2497 | -1.6755931377410889 2498 | ], 2499 | [ 2500 | -10.517882347106934, 2501 | -2.9647977352142334 2502 | ], 2503 | [ 2504 | -9.47757625579834, 2505 | -2.657386541366577 2506 | ], 2507 | [ 2508 | -8.427855491638184, 2509 | -2.678992986679077 2510 | ], 2511 | [ 2512 | -7.372512340545654, 2513 | -2.8782899379730225 2514 | ], 2515 | [ 2516 | -6.334640026092529, 2517 | -2.639655828475952 2518 | ], 2519 | [ 2520 | -5.30159330368042, 2521 | -2.8958871364593506 2522 | ], 2523 | [ 2524 | -4.247748851776123, 2525 | -2.8971078395843506 2526 | ] 2527 | ], 2528 | "brambles": [ 2529 | [ 2530 | 8.475709915161133, 2531 | 5.032989501953125 2532 | ], 2533 | [ 2534 | 9.059589385986328, 2535 | 3.9586496353149414 2536 | ], 2537 | [ 2538 | 9.526694297790527, 2539 | 2.767533302307129 2540 | ], 2541 | [ 2542 | 9.760247230529785, 2543 | 1.4362859725952148 2544 | ], 2545 | [ 2546 | 9.643470764160156, 2547 | 0.10503844916820526 2548 | ], 2549 | [ 2550 | 9.223076820373535, 2551 | -1.2495641708374023 2552 | ], 2553 | [ 2554 | 8.382288932800293, 2555 | -2.253838539123535 2556 | ], 2557 | [ 2558 | 7.307949066162109, 2559 | -2.837719202041626 2560 | ] 2561 | ], 2562 | "circles": [ 2563 | { 2564 | "pos": [ 2565 | 8.083909034729004, 2566 | 10.464831352233887 2567 | ], 2568 | "radius": 4.485800743103027 2569 | }, 2570 | { 2571 | "pos": [ 2572 | 15.143128395080566, 2573 | 7.770716667175293 2574 | ], 2575 | "radius": 2.8945505619049072 2576 | }, 2577 | { 2578 | "pos": [ 2579 | 17.09389877319336, 2580 | 4.666121482849121 2581 | ], 2582 | "radius": 1.1874386072158813 2583 | }, 2584 | { 2585 | "pos": [ 2586 | 18.530635833740234, 2587 | 6.333296775817871 2588 | ], 2589 | "radius": 0.6128610372543335 2590 | }, 2591 | { 2592 | "pos": [ 2593 | 1.5417371988296509, 2594 | 11.757006645202637 2595 | ], 2596 | "radius": 3.6751203536987305 2597 | }, 2598 | { 2599 | "pos": [ 2600 | 3.5301291942596436, 2601 | 7.955470085144043 2602 | ], 2603 | "radius": 1.1238754987716675 2604 | }, 2605 | { 2606 | "pos": [ 2607 | -1.5712751150131226, 2608 | 11.041369438171387 2609 | ], 2610 | "radius": 3.6751203536987305 2611 | }, 2612 | { 2613 | "pos": [ 2614 | -5.478579998016357, 2615 | 7.922513008117676 2616 | ], 2617 | "radius": 3.978299856185913 2618 | }, 2619 | { 2620 | "pos": [ 2621 | -8.262972831726074, 2622 | 7.630969047546387 2623 | ], 2624 | "radius": 3.138763427734375 2625 | }, 2626 | { 2627 | "pos": [ 2628 | -6.872853755950928, 2629 | 3.0702264308929443 2630 | ], 2631 | "radius": 3.138763427734375 2632 | }, 2633 | { 2634 | "pos": [ 2635 | -7.836711406707764, 2636 | -2.7564094066619873 2637 | ], 2638 | "radius": 3.790437698364258 2639 | }, 2640 | { 2641 | "pos": [ 2642 | -3.2807114124298096, 2643 | -4.69584846496582 2644 | ], 2645 | "radius": 1.5589972734451294 2646 | }, 2647 | { 2648 | "pos": [ 2649 | -1.4687665700912476, 2650 | -5.884018898010254 2651 | ], 2652 | "radius": 1.5589972734451294 2653 | }, 2654 | { 2655 | "pos": [ 2656 | 1.4188963174819946, 2657 | -5.765101432800293 2658 | ], 2659 | "radius": 1.5589972734451294 2660 | }, 2661 | { 2662 | "pos": [ 2663 | 3.611159086227417, 2664 | -5.770585060119629 2665 | ], 2666 | "radius": 1.5589972734451294 2667 | }, 2668 | { 2669 | "pos": [ 2670 | 6.56803560256958, 2671 | -5.348418235778809 2672 | ], 2673 | "radius": 1.5589972734451294 2674 | }, 2675 | { 2676 | "pos": [ 2677 | 9.424619674682617, 2678 | -5.6157941818237305 2679 | ], 2680 | "radius": 1.5589972734451294 2681 | }, 2682 | { 2683 | "pos": [ 2684 | 12.439099311828613, 2685 | -5.617505073547363 2686 | ], 2687 | "radius": 1.5589972734451294 2688 | }, 2689 | { 2690 | "pos": [ 2691 | 10.203185081481934, 2692 | -3.440845251083374 2693 | ], 2694 | "radius": 1.0932811498641968 2695 | }, 2696 | { 2697 | "pos": [ 2698 | 15.373773574829102, 2699 | -6.302666664123535 2700 | ], 2701 | "radius": 1.5589972734451294 2702 | }, 2703 | { 2704 | "pos": [ 2705 | 17.58938980102539, 2706 | -6.178488731384277 2707 | ], 2708 | "radius": 1.5589972734451294 2709 | }, 2710 | { 2711 | "pos": [ 2712 | 20.195556640625, 2713 | -5.693284034729004 2714 | ], 2715 | "radius": 1.5589972734451294 2716 | }, 2717 | { 2718 | "pos": [ 2719 | 22.677318572998047, 2720 | -5.1717424392700195 2721 | ], 2722 | "radius": 1.5589972734451294 2723 | }, 2724 | { 2725 | "pos": [ 2726 | 26.109516143798828, 2727 | -3.224013090133667 2728 | ], 2729 | "radius": 2.862858295440674 2730 | }, 2731 | { 2732 | "pos": [ 2733 | 24.517444610595703, 2734 | 4.075201988220215 2735 | ], 2736 | "radius": 3.598024845123291 2737 | }, 2738 | { 2739 | "pos": [ 2740 | -3.137782335281372, 2741 | 22.369211196899414 2742 | ], 2743 | "radius": 4.421356678009033 2744 | }, 2745 | { 2746 | "pos": [ 2747 | -6.935237407684326, 2748 | 19.21177864074707 2749 | ], 2750 | "radius": 3.4766101837158203 2751 | }, 2752 | { 2753 | "pos": [ 2754 | -9.495320320129395, 2755 | 18.87043571472168 2756 | ], 2757 | "radius": 1.9951282739639282 2758 | }, 2759 | { 2760 | "pos": [ 2761 | -6.331338405609131, 2762 | 15.509661674499512 2763 | ], 2764 | "radius": 0.48089367151260376 2765 | }, 2766 | { 2767 | "pos": [ 2768 | 3.091749906539917, 2769 | 23.350507736206055 2770 | ], 2771 | "radius": 3.652811050415039 2772 | }, 2773 | { 2774 | "pos": [ 2775 | 25.950969696044922, 2776 | -0.08372378349304199 2777 | ], 2778 | "radius": 1.5589972734451294 2779 | }, 2780 | { 2781 | "pos": [ 2782 | 21.43246841430664, 2783 | 9.141222953796387 2784 | ], 2785 | "radius": 1.3851391077041626 2786 | }, 2787 | { 2788 | "pos": [ 2789 | 24.369308471679688, 2790 | 7.971959114074707 2791 | ], 2792 | "radius": 2.765479803085327 2793 | }, 2794 | { 2795 | "pos": [ 2796 | 25.997879028320312, 2797 | 12.532910346984863 2798 | ], 2799 | "radius": 2.765479803085327 2800 | }, 2801 | { 2802 | "pos": [ 2803 | 6.16384744644165, 2804 | 23.0452823638916 2805 | ], 2806 | "radius": 3.652811050415039 2807 | }, 2808 | { 2809 | "pos": [ 2810 | 13.561821937561035, 2811 | 20.27509880065918 2812 | ], 2813 | "radius": 2.3099071979522705 2814 | }, 2815 | { 2816 | "pos": [ 2817 | 10.965476036071777, 2818 | 21.115434646606445 2819 | ], 2820 | "radius": 2.6530370712280273 2821 | }, 2822 | { 2823 | "pos": [ 2824 | 17.47087287902832, 2825 | 21.131839752197266 2826 | ], 2827 | "radius": 2.8727240562438965 2828 | }, 2829 | { 2830 | "pos": [ 2831 | 21.652339935302734, 2832 | 18.358417510986328 2833 | ], 2834 | "radius": 2.2578039169311523 2835 | }, 2836 | { 2837 | "pos": [ 2838 | 24.468429565429688, 2839 | 16.609027862548828 2840 | ], 2841 | "radius": 2.2588839530944824 2842 | }, 2843 | { 2844 | "pos": [ 2845 | 22.761709213256836, 2846 | 9.867478370666504 2847 | ], 2848 | "radius": 1.5935596227645874 2849 | }, 2850 | { 2851 | "pos": [ 2852 | 13.443284034729004, 2853 | 4.997420310974121 2854 | ], 2855 | "radius": 0.5583524703979492 2856 | }, 2857 | { 2858 | "pos": [ 2859 | 12.143528938293457, 2860 | 6.937196731567383 2861 | ], 2862 | "radius": 0.9621806144714355 2863 | }, 2864 | { 2865 | "pos": [ 2866 | 10.650147438049316, 2867 | 6.851861000061035 2868 | ], 2869 | "radius": 0.9621806144714355 2870 | }, 2871 | { 2872 | "pos": [ 2873 | 6.137192249298096, 2874 | 6.3234405517578125 2875 | ], 2876 | "radius": 0.6128610372543335 2877 | }, 2878 | { 2879 | "pos": [ 2880 | 9.248650550842285, 2881 | 6.192126274108887 2882 | ], 2883 | "radius": 0.6128610372543335 2884 | }, 2885 | { 2886 | "pos": [ 2887 | -0.14486631751060486, 2888 | 7.662554740905762 2889 | ], 2890 | "radius": 0.4847904443740845 2891 | }, 2892 | { 2893 | "pos": [ 2894 | 2.8418967723846436, 2895 | 6.8091936111450195 2896 | ], 2897 | "radius": 0.6128610372543335 2898 | }, 2899 | { 2900 | "pos": [ 2901 | 11.366376876831055, 2902 | 6.370542526245117 2903 | ], 2904 | "radius": 0.5583524703979492 2905 | }, 2906 | { 2907 | "pos": [ 2908 | 17.562725067138672, 2909 | 6.267675399780273 2910 | ], 2911 | "radius": 0.8942558765411377 2912 | }, 2913 | { 2914 | "pos": [ 2915 | 15.495661735534668, 2916 | 19.014570236206055 2917 | ], 2918 | "radius": 0.6128610372543335 2919 | }, 2920 | { 2921 | "pos": [ 2922 | 14.36369800567627, 2923 | 17.7021484375 2924 | ], 2925 | "radius": 0.6128610372543335 2926 | }, 2927 | { 2928 | "pos": [ 2929 | 13.412192344665527, 2930 | 17.816986083984375 2931 | ], 2932 | "radius": 0.6128610372543335 2933 | }, 2934 | { 2935 | "pos": [ 2936 | 12.460686683654785, 2937 | 17.849796295166016 2938 | ], 2939 | "radius": 0.5692878365516663 2940 | }, 2941 | { 2942 | "pos": [ 2943 | 20.679725646972656, 2944 | 16.53737449645996 2945 | ], 2946 | "radius": 0.5022953152656555 2947 | }, 2948 | { 2949 | "pos": [ 2950 | 19.547761917114258, 2951 | 18.702869415283203 2952 | ], 2953 | "radius": 0.6859678030014038 2954 | }, 2955 | { 2956 | "pos": [ 2957 | 9.245253562927246, 2958 | 18.752086639404297 2959 | ], 2960 | "radius": 0.5022953152656555 2961 | }, 2962 | { 2963 | "pos": [ 2964 | 22.763195037841797, 2965 | 15.356196403503418 2966 | ], 2967 | "radius": 0.5022953152656555 2968 | }, 2969 | { 2970 | "pos": [ 2971 | 8.277342796325684, 2972 | 20.06450843811035 2973 | ], 2974 | "radius": 0.5022953152656555 2975 | }, 2976 | { 2977 | "pos": [ 2978 | 0.9277807474136353, 2979 | 19.99888801574707 2980 | ], 2981 | "radius": 0.5022953152656555 2982 | }, 2983 | { 2984 | "pos": [ 2985 | -0.12215551733970642, 2986 | 18.916139602661133 2987 | ], 2988 | "radius": 0.5022953152656555 2989 | }, 2990 | { 2991 | "pos": [ 2992 | -2.1892197132110596, 2993 | 17.63652801513672 2994 | ], 2995 | "radius": 0.5022953152656555 2996 | }, 2997 | { 2998 | "pos": [ 2999 | -3.2391579151153564, 3000 | 17.7021484375 3001 | ], 3002 | "radius": 0.5022953152656555 3003 | }, 3004 | { 3005 | "pos": [ 3006 | 19.761030197143555, 3007 | 17.882606506347656 3008 | ], 3009 | "radius": 0.5745218396186829 3010 | } 3011 | ], 3012 | "rocky_enter": [ 3013 | { 3014 | "left": [ 3015 | 17.52077293395996, 3016 | 12.371183395385742 3017 | ], 3018 | "pos": [ 3019 | 19.040014266967773, 3020 | 9.413249015808105 3021 | ], 3022 | "right": [ 3023 | 20.559255599975586, 3024 | 6.455315589904785 3025 | ] 3026 | }, 3027 | { 3028 | "left": [ 3029 | 21.343446731567383, 3030 | 1.504197120666504 3031 | ], 3032 | "pos": [ 3033 | 17.9632625579834, 3034 | 0.09158354997634888 3035 | ], 3036 | "right": [ 3037 | 14.189659118652344, 3038 | -1.4854440689086914 3039 | ] 3040 | }, 3041 | { 3042 | "left": [ 3043 | 12.131062507629395, 3044 | -0.5228705406188965 3045 | ], 3046 | "pos": [ 3047 | 7.600203514099121, 3048 | 1.624455451965332 3049 | ], 3050 | "right": [ 3051 | 3.904383420944214, 3052 | 3.376028537750244 3053 | ] 3054 | } 3055 | ], 3056 | "rocky_hide": [ 3057 | { 3058 | "left": [ 3059 | 0.6425304412841797, 3060 | 1.4047523736953735 3061 | ], 3062 | "pos": [ 3063 | 2.8401827812194824, 3064 | 1.3874675035476685 3065 | ], 3066 | "right": [ 3067 | 3.193725824356079, 3068 | 1.384686827659607 3069 | ] 3070 | }, 3071 | { 3072 | "left": [ 3073 | -1.0670650005340576, 3074 | 1.3239233493804932 3075 | ], 3076 | "pos": [ 3077 | -1.758042812347412, 3078 | 2.9305593967437744 3079 | ], 3080 | "right": [ 3081 | -2.9751720428466797, 3082 | 5.760583400726318 3083 | ] 3084 | }, 3085 | { 3086 | "left": [ 3087 | 0.545217752456665, 3088 | 6.8446044921875 3089 | ], 3090 | "pos": [ 3091 | 1.045217752456665, 3092 | 6.8446044921875 3093 | ], 3094 | "right": [ 3095 | 2.045217752456665, 3096 | 6.8446044921875 3097 | ] 3098 | } 3099 | ], 3100 | "rocky_leave": [ 3101 | { 3102 | "left": [ 3103 | 2.138941764831543, 3104 | 1.28511381149292 3105 | ], 3106 | "pos": [ 3107 | 2.838735818862915, 3108 | 1.386545181274414 3109 | ], 3110 | "right": [ 3111 | 3.0136842727661133, 3112 | 1.4119030237197876 3113 | ] 3114 | }, 3115 | { 3116 | "left": [ 3117 | 14.059139251708984, 3118 | -2.5992910861968994 3119 | ], 3120 | "pos": [ 3121 | 17.786540985107422, 3122 | 0.4426439702510834 3123 | ], 3124 | "right": [ 3125 | 21.51394271850586, 3126 | 3.484578847885132 3127 | ] 3128 | }, 3129 | { 3130 | "left": [ 3131 | 19.57667350769043, 3132 | 11.846004486083984 3133 | ], 3134 | "pos": [ 3135 | 16.860034942626953, 3136 | 14.228490829467773 3137 | ], 3138 | "right": [ 3139 | 10.30704116821289, 3140 | 19.975452423095703 3141 | ] 3142 | }, 3143 | { 3144 | "left": [ 3145 | -0.5342788696289062, 3146 | 18.376811981201172 3147 | ], 3148 | "pos": [ 3149 | -5.939708709716797, 3150 | 14.72110366821289 3151 | ], 3152 | "right": [ 3153 | -7.954679012298584, 3154 | 13.358373641967773 3155 | ] 3156 | }, 3157 | { 3158 | "left": [ 3159 | -13.382295608520508, 3160 | 15.33887004852295 3161 | ], 3162 | "pos": [ 3163 | -13.132295608520508, 3164 | 15.33887004852295 3165 | ], 3166 | "right": [ 3167 | -12.132295608520508, 3168 | 15.33887004852295 3169 | ] 3170 | } 3171 | ], 3172 | "rocky_bounce1": [ 3173 | { 3174 | "left": [ 3175 | 7.919981002807617, 3176 | 0.4845632314682007 3177 | ], 3178 | "pos": [ 3179 | 7.600203037261963, 3180 | 1.6244566440582275 3181 | ], 3182 | "right": [ 3183 | 7.313545227050781, 3184 | 2.6462879180908203 3185 | ] 3186 | }, 3187 | { 3188 | "left": [ 3189 | 6.591114044189453, 3190 | 4.2168354988098145 3191 | ], 3192 | "pos": [ 3193 | 5.965261936187744, 3194 | 4.173452377319336 3195 | ], 3196 | "right": [ 3197 | 5.359962463378906, 3198 | 4.131494045257568 3199 | ] 3200 | }, 3201 | { 3202 | "left": [ 3203 | 4.8160624504089355, 3204 | 2.6252894401550293 3205 | ], 3206 | "pos": [ 3207 | 4.688748836517334, 3208 | 1.508453369140625 3209 | ], 3210 | "right": [ 3211 | 4.559062480926514, 3212 | 0.37080156803131104 3213 | ] 3214 | } 3215 | ], 3216 | "rocky_bounce2": [ 3217 | { 3218 | "left": [ 3219 | 4.845966339111328, 3220 | 0.8898332118988037 3221 | ], 3222 | "pos": [ 3223 | 4.675220966339111, 3224 | 1.4984796047210693 3225 | ], 3226 | "right": [ 3227 | 4.522160053253174, 3228 | 2.0440866947174072 3229 | ] 3230 | }, 3231 | { 3232 | "left": [ 3233 | 4.154057502746582, 3234 | 2.7746376991271973 3235 | ], 3236 | "pos": [ 3237 | 3.7690999507904053, 3238 | 2.7269411087036133 3239 | ], 3240 | "right": [ 3241 | 3.396784782409668, 3242 | 2.6808109283447266 3243 | ] 3244 | }, 3245 | { 3246 | "left": [ 3247 | 2.973193645477295, 3248 | 1.9665868282318115 3249 | ], 3250 | "pos": [ 3251 | 2.8389270305633545, 3252 | 1.3868240118026733 3253 | ], 3254 | "right": [ 3255 | 2.7009878158569336, 3256 | 0.7912032604217529 3257 | ] 3258 | } 3259 | ], 3260 | "melee_enter": [ 3261 | { 3262 | "left": [ 3263 | 18.09465217590332, 3264 | 12.626460075378418 3265 | ], 3266 | "pos": [ 3267 | 18.692886352539062, 3268 | 9.761260032653809 3269 | ], 3270 | "right": [ 3271 | 19.233102798461914, 3272 | 7.173933029174805 3273 | ] 3274 | }, 3275 | { 3276 | "left": [ 3277 | 20.890491485595703, 3278 | 2.4303579330444336 3279 | ], 3280 | "pos": [ 3281 | 18.854448318481445, 3282 | 2.2967262268066406 3283 | ], 3284 | "right": [ 3285 | 15.794477462768555, 3286 | 2.095890998840332 3287 | ] 3288 | } 3289 | ], 3290 | "ranged_enter": [ 3291 | { 3292 | "left": [ 3293 | 18.86225128173828, 3294 | 13.007002830505371 3295 | ], 3296 | "pos": [ 3297 | 19.570314407348633, 3298 | 9.446393013000488 3299 | ], 3300 | "right": [ 3301 | 20.209707260131836, 3302 | 6.231098651885986 3303 | ] 3304 | }, 3305 | { 3306 | "left": [ 3307 | 21.792659759521484, 3308 | 0.31562232971191406 3309 | ], 3310 | "pos": [ 3311 | 19.382823944091797, 3312 | 0.14955711364746094 3313 | ], 3314 | "right": [ 3315 | 15.76108169555664, 3316 | -0.10002230107784271 3317 | ] 3318 | } 3319 | ] 3320 | } 3321 | --------------------------------------------------------------------------------