Archived
1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
skcblitz/entity.h
2025-09-02 14:43:36 +02:00

333 lines
11 KiB
C

void ent_position(entity_t *ent, double x, double y, double z) {
ent->last_x = ent->pos_x = x;
ent->last_y = ent->pos_y = y;
ent->last_z = ent->pos_z = z;
AABB_SET(ent->box, x - (ent->width / 2.0), y, z - (ent->width / 2.0), x + (ent->width / 2.0), y + ent->height, z + (ent->width / 2.0));
}
void ent_angle(entity_t *ent, float yaw, float pitch) {
ent->yaw = yaw;
ent->pitch = pitch;
ent->rot_yaw = ((double)yaw) - 90.0;
}
void ent_pos(entity_t *ent, double x, double y, double z, float yaw, float pitch) {
ent_position(ent, x, y, z);
ent_angle(ent, yaw, pitch);
}
void ent_init(entity_t *ent, world_t *world, double x, double y, double z, float yaw, float pitch) {
memset(ent, 0, sizeof(entity_t));
ent->world = world;
ent->speed = 1.0;
ent->eye = 1.8;
ent->width = 0.6;
ent->height = 2.0;
ent->step_height = 0.6;
ent->jump_motion = 0.42;
ent->fly_base_speed = 0.05;
ent->walk_base_speed = 0.1;
ent->air_base_speed = 0.02;
ent->first_tick = 1;
ent_pos(ent, x, y, z, yaw, pitch);
}
void ent_position_vec(entity_t *ent, vec3 pos) {
ent_position(ent, pos[0], pos[1], pos[2]);
}
void ent_position_eye(entity_t *ent, vec3 pos) {
ent_position(ent, pos[0], pos[1] - ent->eye, pos[2]);
}
void ent_getpos(entity_t *ent, vec3 pos) {
VEC3_SET(pos, ent->pos_x, ent->pos_y, ent->pos_z);
}
void ent_geteye(entity_t *ent, vec3 pos) {
VEC3_SET(pos, ent->pos_x, ent->pos_y + ent->eye, ent->pos_z);
}
void ent_angle_cam(entity_t *ent, camera_t *cam) {
ent_angle(ent, cam->yaw, cam->pitch);
}
void ent_tick(entity_t *ent) {
float strafe, forward;
byte jumping, noclip;
double last_mot_y, velo, friction, mot;
double x, y, z;
// double cx, cy, cz;
noclip = (ent == ent->world->entity) && ent->world->noclip && !(ent->world->camonly);
if(noclip)
ent->ground = 0;
ent->last_x = ent->pos_x;
ent->last_y = ent->pos_y;
ent->last_z = ent->pos_z;
ent->first_tick = 0;
if(!(ent->sprinting) && !(ent->sneak) && (ent->forward > 0.0) && /* wld.can_sprint && */ !(ent->use) && ent->sprint)
ent->sprinting = 1;
if(ent->sprinting && (ent->sneak || (ent->forward <= 0.0) || ent->use || ent->collided_h /* || !(wld.can_sprint) */))
ent->sprinting = 0;
// if(wld.can_fly) {
if(noclip) {
if(!(ent->flying))
ent->flying = 1;
}
else if(!(ent->last_jump) && ent->jump) {
if(ent->fly_timer == 0) {
ent->fly_timer = 7;
}
else {
ent->flying ^= 1;
ent->fly_timer = 0;
}
}
// }
ent->last_jump = ent->jump;
if(ent->flying && (ent == ent->world->entity)) {
if(ent->sneak)
ent->motion_y -= ent->fly_speed * 3.0 * (ent->sprint ? 2.0 : 1.0);
if(ent->jump)
ent->motion_y += ent->fly_speed * 3.0 * (ent->sprint ? 2.0 : 1.0);
}
if (ent->fly_timer > 0)
ent->fly_timer -= 1;
if (ent->jump_ticks > 0)
ent->jump_ticks -= 1;
if(fabs(ent->motion_x) < 0.005)
ent->motion_x = 0.0;
if(fabs(ent->motion_y) < 0.005)
ent->motion_y = 0.0;
if(fabs(ent->motion_z) < 0.005)
ent->motion_z = 0.0;
if(ent->blocked) {
jumping = 0;
strafe = 0.0;
forward = 0.0;
}
else if(ent == ent->world->entity) {
strafe = ent->strafe * (ent->sneak ? 0.3 : 1.0) * (ent->use ? 0.2 : 1.0);
forward = ent->forward * (ent->sneak ? 0.3 : 1.0) * (ent->use ? 0.2 : 1.0);
jumping = ent->jump;
}
if(jumping) {
if(ent->ground && ent->jump_ticks == 0) {
ent->motion_y = ent->jump_motion;
if(ent->sprinting) {
double bmot = ent->rot_yaw * M_PI / 180.0;
ent->motion_x -= sin(bmot) * 0.2;
ent->motion_z += cos(bmot) * 0.2;
}
ent->jump_ticks = 10;
}
}
else {
ent->jump_ticks = 0;
}
strafe *= 0.98;
forward *= 0.98;
if(ent->flying) {
last_mot_y = ent->motion_y;
ent->air_speed = ent->fly_speed * (ent->sprinting ? 2.0 : 1.0);
}
velo = 0.91;
if(ent->ground) {
velo *= (1.0 - ent->world->friction) * 0.5 + 0.5;
friction = ent->walk_speed * 0.16277136 / (velo * velo * velo);
}
else {
friction = ent->air_speed;
}
mot = strafe * strafe + forward * forward;
if(mot >= 1.0E-4) {
mot = sqrt(mot);
if(mot < 1.0)
mot = 1.0;
mot = friction / mot;
strafe = strafe * mot;
forward = forward * mot;
double smot = sin(ent->rot_yaw * M_PI / 180.0);
double cmot = cos(ent->rot_yaw * M_PI / 180.0);
ent->motion_x += strafe * cmot - forward * smot;
ent->motion_z += forward * cmot + strafe * smot;
}
velo = 0.91;
if(ent->ground)
velo *= (1.0 - ent->world->friction) * 0.5 + 0.5;
x = ent->motion_x;
y = ent->motion_y;
z = ent->motion_z;
if(noclip) {
AABB_OFFSET(ent->box, x, y, z)
ent->pos_x = (ent->box.x1 + ent->box.x2) / 2.0;
ent->pos_y = ent->box.y1;
ent->pos_z = (ent->box.z1 + ent->box.z2) / 2.0;
}
else {
double last_x, last_y, last_z;
bbox_t box;
bbox_t *list;
int len;
byte step;
if(ent->braked) {
ent->braked = 0;
x *= 0.25;
y *= 0.05000000074505806;
z *= 0.25;
ent->motion_x = ent->motion_y = ent->motion_z = 0.0;
}
last_x = x;
last_y = y;
last_z = z;
if(ent->ground && ent->sneak) {
double shift;
for(shift = 0.05; x != 0.0 && box_get_colliding(ent->world, NULL, box_offset_to(&ent->box, &box, x, -1.0, 0.0)) == 0; last_x = x) {
if(x < shift && x >= -shift)
x = 0.0;
else if(x > 0.0)
x -= shift;
else
x += shift;
}
for(; z != 0.0 && box_get_colliding(ent->world, NULL, box_offset_to(&ent->box, &box, 0.0, -1.0, z)) == 0; last_z = z) {
if(z < shift && z >= -shift)
z = 0.0;
else if(z > 0.0)
z -= shift;
else
z += shift;
}
for(; x != 0.0 && z != 0.0 && box_get_colliding(ent->world, NULL, box_offset_to(&ent->box, &box, x, -1.0, z)) == 0; last_z = z) {
if(x < shift && x >= -shift)
x = 0.0;
else if(x > 0.0)
x -= shift;
else
x += shift;
last_x = x;
if(z < shift && z >= -shift)
z = 0.0;
else if(z > 0.0)
z -= shift;
else
z += shift;
}
}
len = box_get_colliding(ent->world, &list, box_add_coord(&ent->box, &box, x, y, z));
AABB_COPY(ent->box, box);
for(int n = 0; n < len; n++)
y = box_calc_yoff(&list[n], &ent->box, y);
AABB_OFFSET(ent->box, 0.0, y, 0.0);
step = ent->ground || last_y != y && last_y < 0.0;
for(int n = 0; n < len; n++)
x = box_calc_xoff(&list[n], &ent->box, x);
AABB_OFFSET(ent->box, x, 0.0, 0.0);
for(int n = 0; n < len; n++)
z = box_calc_zoff(&list[n], &ent->box, z);
AABB_OFFSET(ent->box, 0.0, 0.0, z);
if(ent->step_height > 0.0 && step && (last_x != x || last_z != z)) {
double step_x = x;
double step_y = y;
double step_z = z;
bbox_t box_prev, box_shift, box_sshift;
double shift_x, shift_y, shift_z;
double shift_sx, shift_sy, shift_sz;
AABB_COPY(ent->box, box_prev);
AABB_COPY(box, ent->box);
y = ent->step_height;
len = box_get_colliding(ent->world, &list, box_add_coord(&ent->box, &box, last_x, y, last_z));
AABB_COPY(ent->box, box_shift);
box_add_coord(&box_shift, &box, last_x, 0.0, last_z);
shift_y = y;
for(int n = 0; n < len; n++)
shift_y = box_calc_yoff(&list[n], &box, shift_y);
AABB_OFFSET(box_shift, 0.0, shift_y, 0.0);
shift_x = last_x;
for(int n = 0; n < len; n++)
shift_x = box_calc_xoff(&list[n], &box_shift, shift_x);
AABB_OFFSET(box_shift, shift_x, 0.0, 0.0);
shift_z = last_z;
for(int n = 0; n < len; n++)
shift_z = box_calc_zoff(&list[n], &box_shift, shift_z);
AABB_OFFSET(box_shift, 0.0, 0.0, shift_z);
AABB_COPY(ent->box, box_sshift);
shift_sy = y;
for(int n = 0; n < len; n++)
shift_sy = box_calc_yoff(&list[n], &box_sshift, shift_sy);
AABB_OFFSET(box_sshift, 0.0, shift_sy, 0.0);
shift_sx = last_x;
for(int n = 0; n < len; n++)
shift_sx = box_calc_xoff(&list[n], &box_sshift, shift_sx);
AABB_OFFSET(box_sshift, shift_sx, 0.0, 0.0);
shift_sz = last_z;
for(int n = 0; n < len; n++)
shift_sz = box_calc_zoff(&list[n], &box_sshift, shift_sz);
AABB_OFFSET(box_sshift, 0.0, 0.0, shift_sz);
if((shift_x * shift_x + shift_z * shift_z) > (shift_sx * shift_sx + shift_sz * shift_sz)) {
x = shift_x;
z = shift_z;
y = -shift_y;
AABB_COPY(box_shift, ent->box);
}
else {
x = shift_sx;
z = shift_sz;
y = -shift_sy;
AABB_COPY(box_sshift, ent->box);
}
for(int n = 0; n < len; n++)
y = box_calc_yoff(&list[n], &ent->box, y);
AABB_OFFSET(ent->box, 0.0, y, 0.0);
if(step_x * step_x + step_z * step_z >= x * x + z * z) {
x = step_x;
y = step_y;
z = step_z;
AABB_COPY(box_prev, ent->box);
}
}
ent->pos_x = (ent->box.x1 + ent->box.x2) / 2.0;
ent->pos_y = ent->box.y1;
ent->pos_z = (ent->box.z1 + ent->box.z2) / 2.0;
ent->collided_h = last_x != x || last_z != z;
ent->collided_v = last_y != y;
ent->ground = ent->collided_v && last_y < 0.0;
ent->collided = ent->collided_h || ent->collided_v;
if(ent->ground) {
if(ent->fall_distance > 0.0) {
// fall_distance ...
ent->fall_distance = 0.0;
}
}
else if(y < 0.0) {
ent->fall_distance = ent->fall_distance - y;
}
if(last_x != x)
ent->motion_x = 0.0;
if(last_z != z)
ent->motion_z = 0.0;
if(last_y != y)
ent->motion_y = 0.0;
}
ent->motion_y -= ent->world->gravity * 0.1;
ent->motion_y *= 0.9800000190734863;
ent->motion_x *= velo;
ent->motion_z *= velo;
if(ent->flying)
ent->motion_y = last_mot_y * 0.6;
ent->walk_speed = ent->walk_base_speed * ent->speed;
ent->air_speed = ent->air_base_speed * ent->speed;
ent->fly_speed = ent->fly_base_speed * ent->speed;
if(ent->sprinting) {
ent->air_speed *= 1.3;
ent->walk_speed *= 1.3;
}
if(ent->ground && ent->flying && !noclip)
ent->flying = 0;
// cx = ent->world->clamp_xz ? CLAMP_VALUE(ent->pos_x, ent->world->global.box.x1, ent->world->global.box.x2) : ent->pos_x;
// cy = ent->world->clamp_y ? CLAMP_VALUE(ent->pos_y, ent->world->global.box.y1, ent->world->global.box.y2) : ent->pos_y;
// cz = ent->world->clamp_xz ? CLAMP_VALUE(ent->pos_z, ent->world->global.box.z1, ent->world->global.box.z2) : ent->pos_z;
// if(cx != ent->pos_x || cy != ent->pos_y || cz != ent->pos_z)
// ent_position(ent, cx, cy, cz);
}