Skip to content

Instantly share code, notes, and snippets.

@Orpheon
Created May 31, 2014 23:10
Show Gist options
  • Select an option

  • Save Orpheon/70e7835f80c697696280 to your computer and use it in GitHub Desktop.

Select an option

Save Orpheon/70e7835f80c697696280 to your computer and use it in GitHub Desktop.
#include "main.h"
#include "move.h"
#include "find_path.h"
#include "load_map.h"
#include "generate_navmesh.h"
#include "navmesh.h"
#include "export_navmesh.h"
#include "data_types.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#define PATH_COMPLETE -1
#define PATH_OUTDATED -2
#include <stdlib.h>
// DEBUGTOOL
//int main()
//{
// Bitmask *map = load_from_file("Maps/ctf_paramental.png");
// printf("\nSize: %i, %i", map->width, map->height);
// int width = 18, height = 35;
// double speed = 4.0;
// Navmesh *mesh = generate_navmesh(map, width, height, speed);
// double path = plan_path(ptr_to_gm(mesh), 1372, 494, 3966, 444);
// printf("\n%d", path);
//// printf("\nUpdate: %d (%d) -> %d", path, path, update_position(mesh, path, 1367, 606));
//// export_navmesh(mesh, "ctf_paramental");
// printf("\n");
//}
//
//double plan_path(double meshptr, double start_x, double start_y, double target_x, double target_y)
//{
// Navmesh *mesh = (Navmesh*) gm_to_ptr(meshptr);
// Rect *start_rect = point_inside_rect(mesh, (int)start_x, (int)start_y);
// Rect *target_rect = point_inside_rect(mesh, (int)target_x, (int)target_y);
// if (start_rect == 0)
// {
// // Our starting point is not inside a rect
// // TODO
// return -1;
// }
// if (target_rect == 0)
// {
// // Our target point is not inside a rect
// // TODO
// return -2;
// }
//
// RectLinkedList *path = find_path(mesh, start_rect, target_rect);
// return ptr_to_gm(path);
//}
double ptr_to_gm(void *p) {
double d;
memcpy(&d, &p, sizeof(void*));
return d;
}
void* gm_to_ptr(double d) {
void *p;
memcpy(&p, &d, sizeof(void*));
return p;
}
__declspec(dllexport) double initialize_mesh(char *mapname)
{
Bitmask *map = load_from_file(mapname);
if ((int)map == -1)
{
// Map not found
return -1;
}
else if ((int)map == -2)
{
// Map contained no wallmask data
return -2;
}
int width = 18, height = 35;
double speed = 4.0;
Navmesh *mesh = generate_navmesh(map, width, height, speed);
return ptr_to_gm(mesh);
}
__declspec(dllexport) double clear_navmesh(double meshptr)
{
Navmesh *mesh = (Navmesh*) gm_to_ptr(meshptr);
destroy_navmesh(mesh);
return 0;
}
__declspec(dllexport) double plan_path(double meshptr, double start_x, double start_y, double target_x, double target_y)
{
Navmesh *mesh = (Navmesh*) gm_to_ptr(meshptr);
Rect *start_rect = point_inside_rect(mesh, (int)start_x, (int)start_y);
Rect *target_rect = point_inside_rect(mesh, (int)target_x, (int)target_y);
if (start_rect == 0)
{
// Our starting point is not inside a rect
// TODO
return -1;
}
if (target_rect == 0)
{
// Our target point is not inside a rect
// TODO
return -2;
}
RectLinkedList *path = find_path(mesh, start_rect, target_rect);
if (path == 0)
{
exit(1);
}
return ptr_to_gm(path);
}
__declspec(dllexport) double get_next_rect_x(double pathptr)
{
RectLinkedList *path = (RectLinkedList*) gm_to_ptr(pathptr);
return 0.5*(path->next->rect->bottomleft.x + path->next->rect->bottomright.x);
}
__declspec(dllexport) double get_next_rect_y(double pathptr)
{
RectLinkedList *path = (RectLinkedList*) gm_to_ptr(pathptr);
return 0.5*(path->next->rect->bottomleft.y + path->next->rect->bottomright.y);
}
__declspec(dllexport) double update_position(double meshptr, double pathptr, double x, double y)
{
Navmesh *mesh = (Navmesh*) gm_to_ptr(meshptr);
RectLinkedList *l = (RectLinkedList*) gm_to_ptr(pathptr);
// The most probable situation is that we're inside the old rect
// If this is the case, no need to do anything
if (l->rect->bottomleft.x <= x && x <= l->rect->bottomright.x)
{
if (l->rect->topleft.y <= y && y <= l->rect->bottomleft.y)
{
// No changes to current path, continue as planned
return pathptr;
}
}
// If not, we're either in the air or in a rect
// Since we want to know what rect if we find one anyway, go through all of them
Rect* current_rect = point_inside_rect(mesh, x, y);
if (current_rect == 0)
{
// We're in the air, don't need to do anything atm
return pathptr;
}
else
{
// We're inside current_rect
// First check whether this is within the path
l = (RectLinkedList*) gm_to_ptr(pathptr);
l = l->next;
while (l != 0)
{
// If this is the rect we're inside
if (l->rect == current_rect)
{
// Ok, we need to shorten the list up to here
// Disconnect the list at the last element and destroy the first part
// TODO
destroy_linked_list((RectLinkedList*) gm_to_ptr(pathptr), l);
// Return the beginning of the updated list
return ptr_to_gm(l);
}
l = l->next;
}
// If we haven't returned previously, this means we've strayed from the path
// Destroy the old path and signal to recreate one
destroy_linked_list((RectLinkedList*) gm_to_ptr(pathptr), 0);
return PATH_OUTDATED;
}
}
__declspec(dllexport) double get_input(double pathptr, double x, double y, double hs, double vs)
{
RectLinkedList *l = (RectLinkedList*) gm_to_ptr(pathptr);
Character c;
c.x = x;
c.y = y;
c.hs = hs;
c.vs = vs;
c.width = 18;
c.height = 36;
c.speed = 4.0;
char *a = get_commands(&c, l->rect, l->next->rect);
if (a[1])
{
return (double)2*a[0];
}
else
{
return (double)a[0];
}
}
__declspec(dllexport) double free_path(double pathptr)
{
RectLinkedList *path = (RectLinkedList*) gm_to_ptr(pathptr);
destroy_linked_list(path, 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment