diff options
Diffstat (limited to '22.c')
-rw-r--r-- | 22.c | 82 |
1 files changed, 77 insertions, 5 deletions
@@ -470,8 +470,6 @@ map_init(struct map * map, char * buf, size_t buflen, enum map_type type) free(map->_buf); return NULL; } - - fprintf(stderr, "Faces initialised\n"); } return map; @@ -695,8 +693,9 @@ int elf_move(struct elf * elf, struct map const * map, int distance) { while (distance > 0) { - int dx = 0, dy = 0, elem; + int dx = 0, dy = 0, elem, fsrcid, fdestid; struct elf newelf; + struct face const * fsrc, * fdest; switch (elf->dir) { case D_NORTH: dy = +1; break; @@ -724,8 +723,81 @@ elf_move(struct elf * elf, struct map const * map, int distance) break; case M_NET: - fprintf(stderr, "Map type not yet supported!\n"); - return -1; + // Find the face at the elf's current position + if ((fsrc = map_face_at(map, elf->x, elf->y)) == NULL) { + fprintf(stderr, "No face at %d,%d\n", elf->x, elf->y); + return -1; + } + fsrcid = fsrc - map->faces; + + // And the face after one more step. + if ((fdest = map_face_at(map, elf->x + dx, elf->y + dy)) == NULL) { + int offset, approach; + + // Find the face that should be next to the + // current one, in the direction the elf is + // travelling. + if ((fdestid = faceid_look(fsrcid, fsrc->dir, elf->dir)) == -1) { + fprintf(stderr, "No face from %d in dir %d\n", + fsrcid, elf->dir); + return -1; + } + fdest = map->faces + fdestid; + + // Find the offset along the face edge we're leaving from + switch (elf->dir) { + case D_NORTH: offset = fsrc->vertices[2].x - 1 - elf->x; break; + case D_SOUTH: offset = elf->x - fsrc->vertices[0].x; break; + case D_EAST: offset = elf->y - fsrc->vertices[1].y; break; + case D_WEST: offset = fsrc->vertices[3].y - 1 - elf->y; break; + } + + // Find the direction we should need to go from + // `dest` to the face we're coming from + approach = faceid_find(fdestid, fdest->dir, fsrcid); + + // Whatever that direction is, we're arriving + // the other way. e.g. if we're travelling from + // face 0 to face 1, and face 0 is supposed to + // be south of face 1, then we're travelling + // north as we arrive on face 1. + switch (approach) { + case D_NORTH: // Approaching from the north, heading south, crossing edge 2->3 + newelf.x = fdest->vertices[3].x + offset; + newelf.y = fdest->vertices[3].y - 1; + newelf.dir = D_SOUTH; + break; + + case D_SOUTH: // Approaching from the south, heading north, crossing edge 0->1 + newelf.x = fdest->vertices[1].x - 1 - offset; + newelf.y = fdest->vertices[1].y; + newelf.dir = D_NORTH; + break; + + case D_EAST: // Approaching from the east, heading west, crossing edge 1->2 + newelf.x = fdest->vertices[2].x - 1; + newelf.y = fdest->vertices[2].y - 1 - offset; + newelf.dir = D_WEST; + break; + + case D_WEST: // Approaching from the west, heading east, crossing edge 3->0 + newelf.x = fdest->vertices[0].x; + newelf.y = fdest->vertices[0].y + offset; + newelf.dir = D_EAST; + break; + + default: + fprintf(stderr, "Unable to get from here to there.\n"); + return -1; + } + } + else { + newelf.x = elf->x + dx; + newelf.y = elf->y + dy; + newelf.dir = elf->dir; + } + elem = map_elem(map, newelf.x, newelf.y); + break; default: fprintf(stderr, "Unknown map type %d\n", map->type); |