action player_controller(){
VECTOR force;
VECTOR input, abs_dist;
vec_fill(&input, 0);
vec_fill(&abs_dist, 0);
vec_fill(&force, 0);
var movement_speed = 8.5, movement_friction = 0.85;
var foot_height = 0, soil_height = 0, soil_contact = 0;
var jump_height = 16, jump_key_off = 0;
hero_ent = my;
set(my, TRANSLUCENT);
wait(1);
c_setminmax(my);
VECTOR temp;
vec_for_min(&temp, my);
foot_height = (temp.z * my->scale_z) - 2;
while(my)
{
// xy
my->min_x -= 1;
my->max_x += 1;
my->min_y -= 1;
my->max_y += 1;
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.x, vector(camera->pan, 0, 0));
disable_z_glide = 1;
c_move(my, nullvector, vector(input.x*time_step, input.y*time_step, 0), MOVE_FLAGS | IGNORE_MODELS | GLIDE);
disable_z_glide = 0;
my->min_x += 1;
my->max_x -= 1;
my->min_y += 1;
my->max_y -= 1;
// gravity
var oldMaxZ = my->max_z;
my->max_z = 0.025; // flat box/ cylinder like gravity
my->min_z = -0.025;
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); }
}
my->max_z = oldMaxZ;
my->min_z = -oldMaxZ;
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);
}
}