Files
q1k3/source/entity_player.js
T
2021-09-14 11:43:44 +02:00

126 lines
3.0 KiB
JavaScript
Executable File

class entity_player_t extends entity_t {
_init() {
this.s = vec3(12,24,12);
this.f = 10;
this._speed = 3000;
this._step_height = 17;
this._can_jump = 0;
this._can_shoot_at = 0;
this._health = 100;
this._check_against = ENTITY_GROUP_ENEMY;
this._weapons = [new weapon_shotgun_t];
this._weapon_index = 0;
// Map 1 needs some rotation of the starting look-at direction
this._yaw += game_map_index * Math.PI;
this._bob = 0;
game_entity_player = this;
game_entities_friendly.push(this);
}
_update() {
// Mouse look
this._pitch = clamp(this._pitch + mouse_y * m.value * (mi.checked ? -0.00015 : 0.00015), -1.5, 1.5);
this._yaw = (this._yaw + mouse_x * m.value * 0.00015) % (Math.PI*2);
// Acceleration in movement direction
this.a = vec3_mulf(
vec3_rotate_y(
vec3(
keys[key_right] - keys[key_left],
0,
keys[key_up] - keys[key_down]
),
this._yaw
),
this._speed * (this._on_ground ? 1 : 0.3)
);
if (keys[key_jump] && this._on_ground && this._can_jump) {
this.v.y = 400;
this._on_ground = 0;
this._can_jump = 0;
}
if (!keys[key_jump]) {
this._can_jump = 1;
}
this._weapon_index = (
this._weapon_index + keys[key_next] + this._weapons.length - keys[key_prev]
) % this._weapons.length;
let shoot_wait = this._can_shoot_at - game_time,
weapon = this._weapons[this._weapon_index];
// Shoot Weapon
if (keys[key_action] && shoot_wait < 0) {
this._can_shoot_at = game_time + weapon._reload;
if (weapon._needs_ammo && weapon._ammo == 0) {
audio_play(sfx_no_ammo);
}
else {
weapon._shoot(this.p, this._yaw, this._pitch);
game_spawn(entity_light_t, this.p, 10, 0xff)._die_at = game_time + 0.1;
}
}
this._bob += vec3_length(this.a) * 0.0001;
this.f = this._on_ground ? 10 : 2.5;
this._update_physics();
r_camera.x = this.p.x;
r_camera.z = this.p.z;
// Smooth step up on stairs
r_camera.y = this.p.y + 8 - clamp(game_time - this._stepped_up_at, 0, 0.1) * -160;
r_camera_yaw = this._yaw;
r_camera_pitch = this._pitch;
// Draw weapon at camera position at an offset and add the current
// recoil (calculated from shoot_wait and weapon._reload) accounting
// for the current view yaw/pitch
r_draw(
vec3_add(
r_camera,
vec3_rotate_yaw_pitch(
vec3(
0,
-10 + Math.sin(this._bob)*0.3,
12 + clamp(scale(shoot_wait, 0, weapon._reload, 5, 0), 0, 5)
),
this._yaw, this._pitch
)
),
this._yaw + Math.PI/2, this._pitch,
weapon._texture, weapon._model.f[0], weapon._model.f[0], 0,
weapon._model.nv
);
h.textContent = this._health|0;
a.textContent = weapon._needs_ammo ? weapon._ammo : '∞';
// Debug: a light around the player
// r_push_light(vec3_add(this.p, vec3(0,64,0)), 10, 255, 192, 32);
}
_receive_damage(from, amount) {
audio_play(sfx_hurt);
super._receive_damage(from, amount);
}
_kill() {
super._kill();
h.textContent = this._health|0;
title_show_message('YOU DIED');
setTimeout(() => game_init(game_map_index), 2000);
}
}