#include <acknex.h>
#include <default.c>
#include <windows.h>
#include <strio.c>
#define PRAGMA_PATH "data"
#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)
ENTITY *hero_ent;
ENTITY *hero_xy_ent;
void level_setup_world(){
sun_light = 0;
sun_angle.pan = 270;
sun_angle.tilt = -25;
vec_set(&d3d_lodfactor, vector(12.5, 25, 50));
camera->clip_near = 1;
camera->clip_far = 45000;
camera->fog_start = 1;
camera->fog_end = 40000;
fog_color = 4;
vec_set(&d3d_fogcolor4.blue, vector(128, 128, 128));
vec_set(&sky_color.blue, &d3d_fogcolor4.blue);
}
void player_xy_collider(){
proc_mode = PROC_LATE;
VECTOR input, abs_dist;
vec_fill(&input, 0);
vec_fill(&abs_dist, 0);
var movement_speed = 8.5, movement_friction = 0.85;
hero_xy_ent = my;
set(my, TRANSLUCENT);
c_setminmax(my);
while(!hero_ent){ wait(1); }
while(my){
input.x = movement_speed * (key_w - key_s);
input.y = movement_speed * (key_a - key_d);
input.z = 0;
if(vec_length(vector(input.x, input.y, 0)) > movement_speed){
var len = sqrt(input.x * input.x + input.y * input.y);
input.x *= ((movement_speed) / len);
input.y *= ((movement_speed) / len);
}
vec_rotate(&input, vector(camera->pan, 0, 0));
accelerate(&abs_dist.x, input.x * time_step, movement_friction);
accelerate(&abs_dist.y, input.y * time_step, movement_friction);
c_move(my, nullvector, vector(abs_dist.x, abs_dist.y, 0), MOVE_FLAGS | IGNORE_MODELS | GLIDE);
if(hero_ent){
hero_ent->x = my->x;
hero_ent->y = my->y;
my->z = hero_ent->z + 16;
}
camera->pan = cycle(camera->pan - mickey.x / 6.5, 0, 360);
camera->tilt = clamp(camera->tilt - mickey.y / 6.5, -90, 90);
camera->x = my->x + fcos((camera->pan), fcos(camera->tilt, -128));
camera->y = my->y + fsin((camera->pan), fcos(camera->tilt, -128));
camera->z = my->z + fsin(camera->tilt, -128);
camera->arc = 90;
wait(1);
}
}
action player_controller(){
VECTOR force;
vec_fill(&force, 0);
var foot_height = 0, soil_height = 0, soil_contact = 0;
var jump_height = 16, jump_key_off = 0;
hero_ent = my;
set(my, INVISIBLE);
my->scale_z = 0.5;
wait(1);
c_setminmax(my);
VECTOR temp;
vec_for_min(&temp, my);
foot_height = (temp.z * my->scale_z) - 0;
ent_create("bbox_npc.mdl", &my->x, player_xy_collider);
while(my){
if(force.z <= 0){
vec_set(&temp, vector(my->x, my->y, my->z - 150 + foot_height));
c_trace(&my->x, &temp, TRACE_FLAGS | IGNORE_MODELS | USE_BOX);
soil_height = temp.z - foot_height;
if(trace_hit){ soil_height = target.z - foot_height; }
}
if(my->z > soil_height + (5 + 20 * soil_contact) * time_step || force.z > 0){
soil_contact = 0;
force.z = maxv(force.z - 4 * time_step, -90);
}
else{
c_move(me, nullvector, vector(0, 0, soil_height - my->z), MOVE_FLAGS | IGNORE_MODELS);
soil_contact = 1;
force.z = 0;
if(key_space){
if(jump_key_off == 0){
jump_key_off = 1;
force.z = jump_height;
}
}
else{ jump_key_off = 0; }
}
if(force.z){
c_move(me, nullvector, vector(0, 0, maxv(force.z * time_step, soil_height - my->z)), MOVE_FLAGS | IGNORE_MODELS);
if(HIT_TARGET && normal.z < -0.5){ force.z = minv(force.z, 0); }
}
wait(1);
}
}
void main(){
video_set(800, 600, 16, 2);
doppler_factor = 0;
warn_level = 6;
fps_max = 60;
fps_min = 30;
time_smooth = 0.9;
freeze_mode = 1;
level_load("def_map.wmb");
wait(3);
freeze_mode = 0;
random_seed(0);
level_setup_world();
}