bool mp_linear_path_object(int path, const double x, const double y, const double stepsize, const int object, const bool solid_only) { enigma::object_collisions* const inst = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); double pathpx = inst->x, pathpy = inst->y, pathpdir = atan2(pathpy - y, x - pathpx)*(180/M_PI); path_clear_points(path); path_add_point(path, pathpx, pathpy, 100); if (fequal(pathpx, x) && fequal(pathpy, y)) return true; double xstep, ystep; bool pathfound; const double max_dist = hypot(x - pathpx, y - pathpy); while (path_get_length(path) < max_dist) { pathfound = false; if (hypot(x - pathpx, y - pathpy) <= stepsize) { if (solid_only ? (place_free(x, y)) : (!place_meeting(x, y, object))) { path_add_point(path, x, y, 100); return true; } return false; } xstep = cos(pathpdir*M_PI/180)*stepsize; ystep = -sin(pathpdir*M_PI/180)*stepsize; if (solid_only ? (place_free(pathpx + xstep, pathpy + ystep)) : (!place_meeting(pathpx + xstep, pathpy + ystep, object))) { pathpx += xstep; pathpy += ystep; path_add_point(path, pathpx, pathpy, 100); pathfound = true; } if (!pathfound) return false; } return false; }
void exe_loadpaths(FILE *exe) { unsigned pathid, pointcount; bool smooth, closed; int x, y, speed, nullhere, precision; if (!fread(&nullhere,4,1,exe)) return; if (nullhere != *(int*)"PTH ") return; // Determine how many paths we have int pathcount; if (!fread(&pathcount,4,1,exe)) return; // Fetch the highest ID we will be using int path_highid, buf; if (!fread(&path_highid,4,1,exe)) return; paths_init(); for (int i = 0; i < pathcount; i++) { if (!fread(&pathid, 4,1,exe)) return; if (!fread(&buf, 4,1,exe)) return; smooth = buf; //to fix int to bool issues if (!fread(&buf, 4,1,exe)) return; closed = buf; if (!fread(&precision, 4,1,exe)) return; if (!fread(&pointcount,4,1,exe)) return; new path(pathid, smooth, closed, precision, pointcount); for (unsigned ii=0;ii<pointcount;ii++) { if (!fread(&x, 4,1,exe)) return; if (!fread(&y, 4,1,exe)) return; if (!fread(&speed, 4,1,exe)) return; path_add_point(pathid, x, y, speed/100); } path_recalculate(pathid); } }
bool mp_potential_path_object(int path, const double x, const double y, const double stepsize, double factor, const int object, const bool solid_only) { enigma::object_collisions* const inst = ((enigma::object_collisions*)enigma::instance_event_iterator->inst); double pathpx = inst->x, pathpy = inst->y, pathpdir = inst->direction; path_clear_points(path); path_add_point(path, pathpx, pathpy, 100); if (fequal(pathpx, x) && fequal(pathpy, y)) return true; if (factor < 1) return false; double dir, xstep, ystep, goaldir; bool pathfound; const double max_dist = factor*hypot(x - pathpx, y - pathpy); while (path_get_length(path) < max_dist) { goaldir = atan2(pathpy - y, x - pathpx)*(180/M_PI); pathfound = false; //direct goal direction dir = (goaldir + 360) %(variant) 360; if (abs((dir - pathpdir + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { if (hypot(x - pathpx, y - pathpy) <= stepsize) { if (solid_only ? (place_free(x, y)) : (!place_meeting(x, y, object))) { path_add_point(path, x, y, 100); return true; } return false; } xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep) && place_free(pathpx + xstep, pathpy + ystep)) : (!place_meeting(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep, object) && !place_meeting(pathpx + xstep, pathpy + ystep, object))) { pathpdir = dir; pathpx += xstep; pathpy += ystep; path_add_point(path, pathpx, pathpy, 100); pathfound = true; } } if (!pathfound) { //alternate either side of the goal direction full circle for (int i = mp_potential::rotstep; i < 180; i += mp_potential::rotstep) { dir = (goaldir - i + 360) %(variant) 360; if (abs((dir - pathpdir + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep) && place_free(pathpx + xstep, pathpy + ystep)) : (!place_meeting(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep, object) && !place_meeting(pathpx + xstep, pathpy + ystep, object))) { pathpdir = dir; pathpx += xstep; pathpy += ystep; path_add_point(path, pathpx, pathpy, 100); pathfound = true; break; } } dir = (goaldir + i + 360) %(variant) 360; if (abs((dir - pathpdir + 540) %(variant) 360 - 180) <= mp_potential::maxrot) { xstep = cos(dir*M_PI/180)*stepsize; ystep = -sin(dir*M_PI/180)*stepsize; if (solid_only ? (place_free(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep) && place_free(pathpx + xstep, pathpy + ystep)) : (!place_meeting(pathpx + mp_potential::ahead*xstep, pathpy + mp_potential::ahead*ystep, object) && !place_meeting(pathpx + xstep, pathpy + ystep, object))) { pathpdir = dir; pathpx += xstep; pathpy += ystep; path_add_point(path, pathpx, pathpy, 100); pathfound = true; break; } } } if (!pathfound) return false; } } return false; }