📄 playerview.java
字号:
/* * Copyright (C) 1997-2001 Id Software, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. * */// Created on 28.12.2003 by RST.// $Id: PlayerView.java,v 1.5 2005/12/27 21:02:30 salomo Exp $package jake2.game;import jake2.Defines;import jake2.Globals;import jake2.game.monsters.M_Player;import jake2.util.Lib;import jake2.util.Math3D;public class PlayerView { public static edict_t current_player; public static gclient_t current_client; public static float[] forward = { 0, 0, 0 }; public static float[] right = { 0, 0, 0 }; public static float[] up = { 0, 0, 0 }; /** * SV_CalcRoll. */ public static float SV_CalcRoll(float[] angles, float[] velocity) { float sign; float side; float value; side = Math3D.DotProduct(velocity, right); sign = side < 0 ? -1 : 1; side = Math.abs(side); value = GameBase.sv_rollangle.value; if (side < GameBase.sv_rollspeed.value) side = side * value / GameBase.sv_rollspeed.value; else side = value; return side * sign; } /* * =============== * P_DamageFeedback * * Handles color blends and view kicks * =============== */ public static void P_DamageFeedback(edict_t player) { gclient_t client; float side; float realcount, count, kick; float[] v = { 0, 0, 0 }; int r, l; float[] power_color = { 0.0f, 1.0f, 0.0f }; float[] acolor = { 1.0f, 1.0f, 1.0f }; float[] bcolor = { 1.0f, 0.0f, 0.0f }; client = player.client; // flash the backgrounds behind the status numbers client.ps.stats[Defines.STAT_FLASHES] = 0; if (client.damage_blood != 0) client.ps.stats[Defines.STAT_FLASHES] |= 1; if (client.damage_armor != 0 && 0 == (player.flags & Defines.FL_GODMODE) && (client.invincible_framenum <= GameBase.level.framenum)) client.ps.stats[Defines.STAT_FLASHES] |= 2; // total points of damage shot at the player this frame count = (client.damage_blood + client.damage_armor + client.damage_parmor); if (count == 0) return; // didn't take any damage // start a pain animation if still in the player model if ((client.anim_priority < Defines.ANIM_PAIN) & (player.s.modelindex == 255)) { client.anim_priority = Defines.ANIM_PAIN; if ((client.ps.pmove.pm_flags & pmove_t.PMF_DUCKED) != 0) { player.s.frame = M_Player.FRAME_crpain1 - 1; client.anim_end = M_Player.FRAME_crpain4; } else { xxxi = (xxxi + 1) % 3; switch (xxxi) { case 0: player.s.frame = M_Player.FRAME_pain101 - 1; client.anim_end = M_Player.FRAME_pain104; break; case 1: player.s.frame = M_Player.FRAME_pain201 - 1; client.anim_end = M_Player.FRAME_pain204; break; case 2: player.s.frame = M_Player.FRAME_pain301 - 1; client.anim_end = M_Player.FRAME_pain304; break; } } } realcount = count; if (count < 10) count = 10; // always make a visible effect // play an apropriate pain sound if ((GameBase.level.time > player.pain_debounce_time) && 0 == (player.flags & Defines.FL_GODMODE) && (client.invincible_framenum <= GameBase.level.framenum)) { r = 1 + (Lib.rand() & 1); player.pain_debounce_time = GameBase.level.time + 0.7f; if (player.health < 25) l = 25; else if (player.health < 50) l = 50; else if (player.health < 75) l = 75; else l = 100; GameBase.gi.sound(player, Defines.CHAN_VOICE, GameBase.gi .soundindex("*pain" + l + "_" + r + ".wav"), 1, Defines.ATTN_NORM, 0); } // the total alpha of the blend is always proportional to count if (client.damage_alpha < 0) client.damage_alpha = 0; client.damage_alpha += count * 0.01f; if (client.damage_alpha < 0.2f) client.damage_alpha = 0.2f; if (client.damage_alpha > 0.6f) client.damage_alpha = 0.6f; // don't go too saturated // the color of the blend will vary based on how much was absorbed // by different armors // Math3D.VectorClear(v); if (client.damage_parmor != 0) Math3D.VectorMA(v, (float) client.damage_parmor / realcount, power_color, v); if (client.damage_armor != 0) Math3D.VectorMA(v, (float) client.damage_armor / realcount, acolor, v); if (client.damage_blood != 0) Math3D.VectorMA(v, (float) client.damage_blood / realcount, bcolor, v); Math3D.VectorCopy(v, client.damage_blend); // // calculate view angle kicks // kick = Math.abs(client.damage_knockback); if (kick != 0 && player.health > 0) // kick of 0 means no view adjust at // all { kick = kick * 100 / player.health; if (kick < count * 0.5) kick = count * 0.5f; if (kick > 50) kick = 50; Math3D.VectorSubtract(client.damage_from, player.s.origin, v); Math3D.VectorNormalize(v); side = Math3D.DotProduct(v, right); client.v_dmg_roll = kick * side * 0.3f; side = -Math3D.DotProduct(v, forward); client.v_dmg_pitch = kick * side * 0.3f; client.v_dmg_time = GameBase.level.time + Defines.DAMAGE_TIME; } // // clear totals // client.damage_blood = 0; client.damage_armor = 0; client.damage_parmor = 0; client.damage_knockback = 0; } /** * * fall from 128: 400 = 160000 * fall from 256: 580 = 336400 * fall from 384: 720 = 518400 * fall from 512: 800 = 640000 * fall from 640: 960 = * damage = deltavelocity*deltavelocity * 0.0001 */ public static void SV_CalcViewOffset(edict_t ent) { float angles[] = { 0, 0, 0 }; float bob; float ratio; float delta; float[] v = { 0, 0, 0 }; // base angles angles = ent.client.ps.kick_angles; // if dead, fix the angle and don't add any kick if (ent.deadflag != 0) { Math3D.VectorClear(angles); ent.client.ps.viewangles[Defines.ROLL] = 40; ent.client.ps.viewangles[Defines.PITCH] = -15; ent.client.ps.viewangles[Defines.YAW] = ent.client.killer_yaw; } else { // add angles based on weapon kick Math3D.VectorCopy(ent.client.kick_angles, angles); // add angles based on damage kick ratio = (ent.client.v_dmg_time - GameBase.level.time) / Defines.DAMAGE_TIME; if (ratio < 0) { ratio = 0; ent.client.v_dmg_pitch = 0; ent.client.v_dmg_roll = 0; } angles[Defines.PITCH] += ratio * ent.client.v_dmg_pitch; angles[Defines.ROLL] += ratio * ent.client.v_dmg_roll; // add pitch based on fall kick ratio = (ent.client.fall_time - GameBase.level.time) / Defines.FALL_TIME; if (ratio < 0) ratio = 0; angles[Defines.PITCH] += ratio * ent.client.fall_value; // add angles based on velocity delta = Math3D.DotProduct(ent.velocity, forward); angles[Defines.PITCH] += delta * GameBase.run_pitch.value; delta = Math3D.DotProduct(ent.velocity, right); angles[Defines.ROLL] += delta * GameBase.run_roll.value; // add angles based on bob delta = bobfracsin * GameBase.bob_pitch.value * xyspeed; if ((ent.client.ps.pmove.pm_flags & pmove_t.PMF_DUCKED) != 0) delta *= 6; // crouching angles[Defines.PITCH] += delta; delta = bobfracsin * GameBase.bob_roll.value * xyspeed; if ((ent.client.ps.pmove.pm_flags & pmove_t.PMF_DUCKED) != 0) delta *= 6; // crouching if ((bobcycle & 1) != 0) delta = -delta; angles[Defines.ROLL] += delta; } // base origin Math3D.VectorClear(v); // add view height v[2] += ent.viewheight; // add fall height ratio = (ent.client.fall_time - GameBase.level.time) / Defines.FALL_TIME; if (ratio < 0) ratio = 0; v[2] -= ratio * ent.client.fall_value * 0.4; // add bob height bob = bobfracsin * xyspeed * GameBase.bob_up.value; if (bob > 6) bob = 6; //gi.DebugGraph (bob *2, 255); v[2] += bob; // add kick offset Math3D.VectorAdd(v, ent.client.kick_origin, v); // absolutely bound offsets // so the view can never be outside the player box if (v[0] < -14) v[0] = -14; else if (v[0] > 14) v[0] = 14; if (v[1] < -14) v[1] = -14; else if (v[1] > 14) v[1] = 14; if (v[2] < -22) v[2] = -22; else if (v[2] > 30) v[2] = 30; Math3D.VectorCopy(v, ent.client.ps.viewoffset); } /** * Calculates where to draw the gun. */ public static void SV_CalcGunOffset(edict_t ent) { int i; float delta; // gun angles from bobbing ent.client.ps.gunangles[Defines.ROLL] = xyspeed * bobfracsin * 0.005f; ent.client.ps.gunangles[Defines.YAW] = xyspeed * bobfracsin * 0.01f; if ((bobcycle & 1) != 0) { ent.client.ps.gunangles[Defines.ROLL] = -ent.client.ps.gunangles[Defines.ROLL]; ent.client.ps.gunangles[Defines.YAW] = -ent.client.ps.gunangles[Defines.YAW]; } ent.client.ps.gunangles[Defines.PITCH] = xyspeed * bobfracsin * 0.005f; // gun angles from delta movement for (i = 0; i < 3; i++) { delta = ent.client.oldviewangles[i] - ent.client.ps.viewangles[i]; if (delta > 180) delta -= 360; if (delta < -180) delta += 360; if (delta > 45) delta = 45; if (delta < -45) delta = -45; if (i == Defines.YAW) ent.client.ps.gunangles[Defines.ROLL] += 0.1 * delta;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -