126 lines
3.0 KiB
JavaScript
Executable File
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 * 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);
|
|
}
|
|
}
|