📄 p_view.pas
字号:
//This is "COMMON" file for \GAME\p_hud.pas & \CTF\p_hud.pas
{$DEFINE CTF}
{$IFDEF CTF}
{$ELSE}
{$ENDIF}
// PLEASE, don't modify this file
// 70% complete
{----------------------------------------------------------------------------}
{ }
{ File(s): p_view.c }
{ }
{ Initial conversion by : YgriK (Igor Karpov) - glYgriK@hotbox.ru }
{ Initial conversion on : 04-Feb-2002 }
{ }
{ This File contains part of convertion of Quake2 source to ObjectPascal. }
{ More information about this project can be found at: }
{ http://www.sulaco.co.za/quake2/ }
{ }
{ 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. }
{ }
{----------------------------------------------------------------------------}
{ Updated on : }
{ Updated by : }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ 1) g_local.??? (inc & pas) }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1) Do more tests }
{ }
{----------------------------------------------------------------------------}
#include "g_local.h"
#include "m_player.h"
static edict_t *current_player;
static gclient_t *current_client;
static vec3_t forward, right, up;
float xyspeed;
float bobmove;
int bobcycle; // odd cycles are right foot going forward
float bobfracsin; // sin(bobfrac*M_PI)
{*
===============
SV_CalcRoll
===============
*}
// (GAME=CTF)
function SV_CalcRoll (vec3_t angles, vec3_t velocity) : float;
var
sign,
side,
value : float;
begin
side := DotProduct (velocity, right);
// sign = side < 0 ? -1 : 1;
if side < 0
then sign := -1
else sign := 1;
side := abs(side);
value := sv_rollangle.value;
if (side < sv_rollspeed.value)
then side := side * value / sv_rollspeed.value;
else side := value;
Result := side*sign;
end;//function (GAME=CTF)
{*
===============
P_DamageFeedback
Handles color blends and view kicks
===============
*}
// (GAME=CTF)
procedure P_DamageFeedback (edict_t *player);
var
gclient_t *client;
side;
realcount, count, kick : float;
v : vec3_t;
r, l : integer;
static int i;
const
power_color : vec3_t = (0.0, 1.0, 0.0);
acolor : vec3_t = (1.0, 1.0, 1.0);
bcolor : vec3_t = (1.0, 0.0, 0.0);
begin
client := player.client;
// flash the backgrounds behind the status numbers
client.ps.stats[STAT_FLASHES] := 0;
if (client.damage_blood) then
client.ps.stats[STAT_FLASHES] := client.ps.stats[STAT_FLASHES] OR 1;
if (client.damage_armor AND !(player.flags & FL_GODMODE) AND (client.invincible_framenum <= level.framenum)) then
client.ps.stats[STAT_FLASHES] := client.ps.stats[STAT_FLASHES] OR 2;
// total points of damage shot at the player this frame
count := (client.damage_blood + client.damage_armor + client.damage_parmor);
if (count = 0) then
Exit; // didn't take any damage
// start a pain animation if still in the player model
if (client.anim_priority < ANIM_PAIN) AND (player.s.modelindex = 255) then
begin
client.anim_priority := ANIM_PAIN;
if (client.ps.pmove.pm_flags & PMF_DUCKED)
then begin
player.s.frame := FRAME_crpain1-1;
client.anim_end := FRAME_crpain4;
end
else begin
i := (i+1) MOD 3;
Case i of
0: begin
player.s.frame := FRAME_pain101-1;
client.anim_end := FRAME_pain104;
end;
1: begin
player.s.frame := FRAME_pain201-1;
client.anim_end := FRAME_pain204;
end;
2: begin
player.s.frame := FRAME_pain301-1;
client.anim_end := FRAME_pain304;
end;
end;//case
end;//else
end;//if
realcount := count;
if (count < 10) then
count := 10; // allways make a visible effect
// play an apropriate pain sound
if ((level.time > player.pain_debounce_time) && !(player->flags & FL_GODMODE) && (client.invincible_framenum <= level.framenum)) then
begin
{Y} r = 1 + (rand()&1);
player.pain_debounce_time := level.time + 0.7;
if (player.health < 25)
then l := 25
else
if (player.health < 50)
then l := 50
else
if (player.health < 75)
then l := 75
else l := 100;
gi.sound (player, CHAN_VOICE, gi.soundindex(va('*pain%i_%i.wav', l, r)), 1, ATTN_NORM, 0);
end;
// the total alpha of the blend is allways proportional to count
if (client.damage_alpha < 0) then
client.damage_alpha := 0;
client.damage_alpha := client.damage_alpha + count*0.01;
if (client.damage_alpha < 0.2) then
client.damage_alpha := 0.2;
if (client.damage_alpha > 0.6) then
client.damage_alpha := 0.6; // don't go too saturated
// the color of the blend will vary based on how much was absorbed
// by different armors
VectorClear (v);
if (client.damage_parmor) then
VectorMA (v, (float)client.damage_parmor/realcount, power_color, v);
if (client.damage_armor) then
VectorMA (v, (float)client.damage_armor/realcount, acolor, v);
if (client.damage_blood) then
VectorMA (v, (float)client.damage_blood/realcount, bcolor, v);
VectorCopy (v, client.damage_blend);
//
// calculate view angle kicks
//
kick := abs(client.damage_knockback);
if (kick <> 0) AND (player.health > 0) then // kick of 0 means no view adjust at all
begin
kick := kick * 100 / player.health;
if (kick < count*0.5) then
kick := count*0.5;
if (kick > 50) then
kick := 50;
VectorSubtract (client.damage_from, player.s.origin, v);
VectorNormalize (v);
side := DotProduct (v, right);
client.v_dmg_roll := kick*side*0.3;
side := -DotProduct (v, forward);
client.v_dmg_pitch := kick*side*0.3;
client.v_dmg_time := level.time + DAMAGE_TIME;
end;
//
// clear totals
//
client.damage_blood := 0;
client.damage_armor := 0;
client.damage_parmor := 0;
client.damage_knockback := 0;
end;//procedure (GAME=CTF)
{*
===============
SV_CalcViewOffset
Auto pitching on slopes?
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
===============
*}
// (GAME=CTF)
procedure SV_CalcViewOffset (edict_t *ent);
var
float *angles;
bob,
ratio,
delta : float;
v : vec3_t;
begin
//===================================
// base angles
angles := ent.client.ps.kick_angles;
// if dead, fix the angle and don't add any kick
if (ent.deadflag)
then begin
VectorClear (angles);
ent.client.ps.viewangles[ROLL] := 40;
ent.client.ps.viewangles[PITCH] := -15;
ent.client.ps.viewangles[YAW] := ent.client.killer_yaw;
end
else begin
// add angles based on weapon kick
VectorCopy (ent.client.kick_angles, angles);
// add angles based on damage kick
ratio := (ent.client.v_dmg_time - level.time) / DAMAGE_TIME;
if (ratio < 0) then
begin
ratio := 0;
ent.client.v_dmg_pitch := 0;
ent.client.v_dmg_roll := 0;
end;
angles[PITCH] := angles[PITCH] + ratio * ent.client.v_dmg_pitch;
angles[ROLL] := angles[ROLL] + ratio * ent.client.v_dmg_roll;
// add pitch based on fall kick
ratio := (ent.client.fall_time - level.time) / FALL_TIME;
if (ratio < 0) then
ratio = 0;
angles[PITCH] := angles[PITCH] + ratio * ent.client.fall_value;
// add angles based on velocity
delta := DotProduct (ent.velocity, forward);
angles[PITCH] := angles[PITCH] + delta*run_pitch.value;
delta := DotProduct (ent.velocity, right);
angles[ROLL] := angles[ROLL] + delta*run_roll.value;
// add angles based on bob
delta := bobfracsin * bob_pitch.value * xyspeed;
if (ent.client.ps.pmove.pm_flags & PMF_DUCKED) then
delta := delta * 6; // crouching
angles[PITCH] := angles[PITCH] + delta;
delta := bobfracsin * bob_roll.value * xyspeed;
if (ent.client.ps.pmove.pm_flags & PMF_DUCKED)
delta := delta * 6; // crouching
if (bobcycle & 1) then
delta := -delta;
angles[ROLL] := angles[ROLL] + delta;
end;
//===================================
// base origin
VectorClear (v);
// add view height
v[2] := v[2] + ent.viewheight;
// add fall height
ratio := (ent.client.fall_time - level.time) / FALL_TIME;
if (ratio < 0) then
ratio = 0;
v[2] := v[2] - ratio * ent.client.fall_value * 0.4;
// add bob height
bob := bobfracsin * xyspeed * bob_up.value;
if (bob > 6) then
bob := 6;
//idsoft gi.DebugGraph (bob *2, 255);
v[2] := v[2] + bob;
// add kick offset
VectorAdd (v, ent.client.kick_origin, v);
// absolutely bound offsets
// so the view can never be outside the player box
if (v[0] < -14)
then v[0] := -14
else
if (v[0] > 14)
then v[0] := 14
else
if (v[1] < -14)
then v[1] := -14
else
if (v[1] > 14)
then v[1] := 14
else
if (v[2] < -22)
then v[2] := -22
else
if (v[2] > 30) then
v[2] := 30;
VectorCopy (v, ent.client.ps.viewoffset);
end;//procedure (GAME=CTF)
{*
==============
SV_CalcGunOffset
==============
*}
// (GAME=CTF)
procedure SV_CalcGunOffset (edict_t *ent);
var
i : integer;
delta : float;
begin
// gun angles from bobbing
ent.client.ps.gunangles[ROLL] := xyspeed * bobfracsin * 0.005;
ent.client.ps.gunangles[YAW] := xyspeed * bobfracsin * 0.01;
if (bobcycle & 1) then
begin
ent.client.ps.gunangles[ROLL] := -ent.client.ps.gunangles[ROLL];
ent.client.ps.gunangles[YAW] := -ent.client.ps.gunangles[YAW];
end;
ent.client.ps.gunangles[PITCH] := xyspeed * bobfracsin * 0.005;
// gun angles from delta movement
for i:=0 to 2 do
begin
delta := ent->client->oldviewangles[i] - ent->client->ps.viewangles[i];
if (delta > 180) then
delta := delta - 360;
if (delta < -180) then
delta := delta + 360;
if (delta > 45) then
delta := 45;
if (delta < -45) then
delta := -45;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -