⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_view.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
// 99%
{----------------------------------------------------------------------------}
{                                                                            }
{ 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 :  2003-03-24                                                   }
{ Updated by :  Scott Price                                                  }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ 1) unit g_local                                                            }
{ 2) unit p_hud                                                              }
{                                                                            }
{----------------------------------------------------------------------------}
{ NOTES:                                                                     }
{ - Unit completely compared to original Game unit.  CTF defined code NOT    }
{   checked!                                                                 }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ 1) Do more tests                                                           }
{                                                                            }
{----------------------------------------------------------------------------}

unit p_view;

interface

uses g_local;

procedure ClientEndServerFrame (ent : edict_p);  //for p_client

implementation

uses
  p_hud,
  q_shared,
  q_shared_add,
  g_main,
  g_local_add,
  p_weapon,
  g_combat,
  g_items,
  gameunit, m_player, CPas;




{#include "g_local.h"
#include "m_player.h"}



var
  current_player : edict_p;
  current_client : gclient_p;

  forward_, right, up : vec3_t;

  bobcycle : integer;  // odd cycles are right foot going forward
  
  xyspeed,
  bobmove,
  bobfracsin : Single;  // sin(bobfrac*M_PI)

{*
===============
SV_CalcRoll
===============
*}

function SV_CalcRoll (const angles, velocity : vec3_t) : Single;  //only imp
var
  sign,
  side,
  value : Single;
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;


{*
===============
P_DamageFeedback

Handles color blends and view kicks
===============
*}
var
  i : Integer =0;

procedure P_DamageFeedback (player : edict_p);  //only imp
var
  client : gclient_p;
  side,
  realcount, count, kick : Single;
  v                      : vec3_t;
  r, l                   : integer;

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 <> 0) then
    client^.ps.stats[STAT_FLASHES] := client^.ps.stats[STAT_FLASHES] OR 1;
  if ((client^.damage_armor <> 0) and ((player^.flags and FL_GODMODE) = 0) 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 AND PMF_DUCKED) <> 0 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;
    end;
  end;

  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) and
       ((player^.flags and FL_GODMODE) = 0) and
        (client^.invincible_framenum <= level.framenum) ) then
  begin
    r := 1 + (rand() and 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 <> 0) then
    VectorMA (v, client^.damage_parmor/realcount, power_color, v);
  if (client^.damage_armor <> 0) then
    VectorMA (v, client^.damage_armor/realcount,  acolor, v);
  if (client^.damage_blood <> 0) then
    VectorMA (v, 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;


{*
===============
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

===============
*}
procedure SV_CalcViewOffset (ent : edict_p);  //only imp
var
  bob,
  ratio,
  delta : Single;
  angles: vec3_p;
  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 <> 0) 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 AND PMF_DUCKED) <> 0) then
      delta := delta * 6;   // crouching
    angles^[PITCH] := angles^[PITCH] + delta;
    delta := bobfracsin * bob_roll^.value * xyspeed;
    if ((ent^.client^.ps.pmove.pm_flags AND PMF_DUCKED) <> 0) then
      delta := delta * 6;   // crouching
    if (bobcycle and 1) <> 0 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;
  if (v[1] < -14) then
    v[1] := -14
  else if (v[1] > 14) then
    v[1] := 14;
  if (v[2] < -22) then
    v[2] := -22
  else if (v[2] > 30) then
    v[2] := 30;

  VectorCopy (v, ent^.client^.ps.viewoffset);
end;


{*
==============
SV_CalcGunOffset
==============
*}
procedure SV_CalcGunOffset (ent : edict_p);  //only imp
var
  i     : integer;
  delta : Single;
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 and 1) <> 0 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -