#define PRAGMA_POINTER
#define TRACE_FLAGS (IGNORE_ME | IGNORE_PASSABLE | IGNORE_PASSENTS | IGNORE_MAPS | IGNORE_SPRITES | IGNORE_CONTENT)
#define MOVE_FLAGS (IGNORE_ME | IGNORE_PASSABLE | IGNORE_PASSENTS | IGNORE_MAPS | IGNORE_SPRITES | IGNORE_CONTENT)
#define obj_radius skill60
#define obj_type skill61
#define NONE 0
#define NPC 1
void draw_collider(ENTITY *ent, COLOR *c, var radius){
// do elipsoid drawing for debug here
VECTOR temp_pos, temp_next_pos;
vec_fill(&temp_pos, 0);
vec_fill(&temp_next_pos, 0);
int i = 0;
for(i = 0; i < 360; i += 30){
// get current rotational piece
vec_set(&temp_pos, vector(radius, 0, 0));
vec_rotate(&temp_pos, vector(i, 0, 0));
vec_add(&temp_pos, &ent->x);
// get next rotational position
vec_set(&temp_next_pos, vector(radius, 0, 0));
vec_rotate(&temp_next_pos, vector(i + 30, 0, 0));
vec_add(&temp_next_pos, &ent->x);
// draw a "quad" to show the collision shape
draw_line3d(vector(temp_pos.x, temp_pos.y, temp_pos.z - ent->max_z), c, 0);
draw_line3d(vector(temp_pos.x, temp_pos.y, temp_pos.z - ent->max_z), c, 100);
draw_line3d(vector(temp_pos.x, temp_pos.y, temp_pos.z + ent->max_z), c, 100);
draw_line3d(vector(temp_next_pos.x, temp_next_pos.y, temp_next_pos.z + ent->max_z), c, 100);
draw_line3d(vector(temp_next_pos.x, temp_next_pos.y, temp_next_pos.z + ent->max_z), c, 0);
draw_line3d(vector(temp_pos.x, temp_pos.y, temp_pos.z - ent->max_z), c, 0);
draw_line3d(vector(temp_pos.x, temp_pos.y, temp_pos.z - ent->max_z), c, 100);
draw_line3d(vector(temp_next_pos.x, temp_next_pos.y, temp_next_pos.z - ent->max_z), c, 100);
draw_line3d(vector(temp_next_pos.x, temp_next_pos.y, temp_next_pos.z - ent->max_z), c, 0);
}
}
ENTITY *find_closest_collider(ENTITY *ent){
ENTITY *pointer = NULL;
ENTITY *closest = NULL;
var closest_distance = 999999;
for(pointer = ent_next(NULL); pointer; pointer = ent_next(pointer)){
// push only NPCs
if(pointer->obj_type != NPC){ continue; }
// if the next entity is not the same as the looking entity
if(pointer != ent){
// if the distance is closer then the previous closest entity
if(vec_dist(&ent->x, &pointer->x) < closest_distance){
// set new closest distance
closest_distance = vec_dist(&ent->x, &pointer->x);
// you are the closest entity to look at now
closest = pointer;
}
}
}
if(closest != NULL){ return(closest); }
return(NULL);
}
void elipsoid_collision(ENTITY *ent){
ENTITY *collider = NULL;
ent->obj_radius = ent->max_x * 4;
while(ent){
collider = find_closest_collider(ent);
if(collider != NULL){
// distance check on collider and push away of too close (faked elipsoid collision)
if(vec_dist(&ent->x, &collider->x) < ent->obj_radius){
VECTOR temp;
vec_diff(&temp, &collider->x, &ent->x);
ANGLE temp_ang;
vec_to_angle(&temp_ang, &temp); // angle to the player
vec_set(&temp, vector(ent->x + ent->obj_radius * cos(temp_ang.pan), ent->y + ent->obj_radius * sin(temp_ang.pan), 0));
vec_diff(&temp, &temp, &collider->x);
temp.z = 0;
vec_scale(&temp, time_step);
c_move(collider, nullvector, &temp, MOVE_FLAGS | GLIDE);
}
}
wait(1);
}
}
void npc(){
set(my, TRANSLUCENT | LIGHT | UNLIT | POLYGON);
vec_set(&my->scale_x, vector(1, 1, 1));
c_setminmax(my);
my->obj_type = NPC;
}
void main(){
warn_level = 6;
fps_max = 60;
level_load("");
wait(3);
mouse_mode = 4;
sun_light = 0;
camera->arc = 15;
set(camera, ISOMETRIC);
vec_set(&camera->x, vector(0, 0, 128));
vec_set(&camera->pan, vector(0, -90, 0));
ENTITY *hero = ent_create(CUBE_MDL, vector(0, 0, 0), NULL);
set(hero, TRANSLUCENT | LIGHT | UNLIT);
vec_set(&hero->scale_x, vector(1, 1, 1));
c_setminmax(hero);
hero->obj_type = NPC;
elipsoid_collision(hero);
ent_create(CUBE_MDL, vector(0, 32, 0), npc);
ent_create(CUBE_MDL, vector(0, -32, 0), npc);
while(hero){
VECTOR temp;
vec_set(&temp, vector(mouse_pos.x, mouse_pos.y, 128));
vec_for_screen(&temp, camera);
vec_set(&hero->x, &temp);
draw_collider(hero, COLOR_RED, hero->obj_radius);
if(key_space){ fps_max = 20; }
else{ fps_max = 60; }
wait(1);
}
}