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

📄 p_view.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    if (i = YAW) then
      ent.client.ps.gunangles[ROLL] := ent.client.ps.gunangles[ROLL] + 0.1*delta;
    ent.client.ps.gunangles[i] := ent.client.ps.gunangles[i] + 0.2 * delta;
  end;

  // gun height
  VectorClear (ent.client.ps.gunoffset);
//idsoft   ent->ps->gunorigin[2] += bob;

  // gun_x / gun_y / gun_z are development tools
  for i:=0 to 2 do
  begin
(*    ent->client->ps.gunoffset[i] += forward[i]*(gun_y->value);
    ent->client->ps.gunoffset[i] += right[i]*gun_x->value;
    ent->client->ps.gunoffset[i] += up[i]* (-gun_z->value);*)
    ent.client.ps.gunoffset[i] := ent.client.ps.gunoffset[i] + forward[i]*gun_y.value +
                                                               right[i]*gun_x.value +
                                                               up[i]*(-gun_z.value);
  end;
end;//procedure (GAME=CTF)


{*
=============
SV_AddBlend
=============
*}
// (GAME=CTF)
procedure SV_AddBlend (r, g, b, a : float; float *v_blend);
var
  a2, a3 : float;
begin
  if (a <= 0) then
    Exit;
  a2 := v_blend[3] + (1-v_blend[3])*a;	// new total alpha
  a3 := v_blend[3]/a2;		// fraction of color from old

  v_blend[0] := v_blend[0]*a3 + r*(1-a3);
  v_blend[1] := v_blend[1]*a3 + g*(1-a3);
  v_blend[2] := v_blend[2]*a3 + b*(1-a3);
  v_blend[3] := a2;
end;//procedure (GAME=CTF)

{*
=============
SV_CalcBlend
=============
*}
// (GAME=CTF)
procedure SV_CalcBlend (edict_t *ent);
var
  vieworg   : vec3_t;
  contents,
  remaining : integer;
begin
  ent.client.ps.blend[0] := 0;
  ent.client.ps.blend[1] := 0;
  ent.client.ps.blend[2] := 0;
  ent.client.ps.blend[3] := 0;

  // add for contents
  VectorAdd (ent.s.origin, ent.client.ps.viewoffset, vieworg);
  contents := gi.pointcontents (vieworg);
  if (contents AND (CONTENTS_LAVA OR CONTENTS_SLIME OR CONTENTS_WATER) <> 0)
  then ent.client.ps.rdflags := ent.client.ps.rdflags OR RDF_UNDERWATER
  else ent.client.ps.rdflags := ent.client.ps.rdflags AND (NOT RDF_UNDERWATER);

  if (contents AND (CONTENTS_SOLID OR CONTENTS_LAVA) <> 0)
  then SV_AddBlend (1.0, 0.3, 0.0, 0.6, ent.client.ps.blend)
  else
    if (contents AND CONTENTS_SLIME <> 0)
    then SV_AddBlend (0.0, 0.1, 0.05, 0.6, ent.client.ps.blend)
    else
      if (contents AND CONTENTS_WATER <> 0) then
        SV_AddBlend (0.5, 0.3, 0.2, 0.4, ent.client.ps.blend);

  // add for powerups
  if (ent.client.quad_framenum > level.framenum)
  then begin
    remaining := ent.client.quad_framenum - level.framenum;
    if (remaining = 30)	then  // beginning to fade
      gi.sound(ent, CHAN_ITEM, gi.soundindex('items/damage2.wav'), 1, ATTN_NORM, 0);
    if (remaining > 30) OR (remaining & 4) then 
      SV_AddBlend (0, 0, 1, 0.08, ent.client.ps.blend);
  end
  else
    if (ent.client.invincible_framenum > level.framenum)
    then begin
      remaining := ent.client.invincible_framenum - level.framenum;
      if (remaining = 30) then  // beginning to fade
        gi.sound(ent, CHAN_ITEM, gi.soundindex('items/protect2.wav'), 1, ATTN_NORM, 0);
      if (remaining > 30) OR (remaining & 4) then
        SV_AddBlend (1, 1, 0, 0.08, ent.client.ps.blend);
    end
    else
      if (ent.client.enviro_framenum > level.framenum)
      then begin
        remaining := ent.client.enviro_framenum - level.framenum;
        if (remaining = 30) then  // beginning to fade
          gi.sound(ent, CHAN_ITEM, gi.soundindex('items/airout.wav'), 1, ATTN_NORM, 0);
        if (remaining > 30) OR (remaining & 4) then
          SV_AddBlend (0, 1, 0, 0.08, ent.client.ps.blend);
      end
      else
        if (ent.client.breather_framenum > level.framenum) then
        begin
          remaining := ent.client.breather_framenum - level.framenum;
          if (remaining = 30) then  // beginning to fade
            gi.sound(ent, CHAN_ITEM, gi.soundindex('items/airout.wav'), 1, ATTN_NORM, 0);
          if (remaining > 30) OR (remaining & 4)
            SV_AddBlend (0.4, 1, 0.4, 0.04, ent.client.ps.blend);
        end;

  // add for damage
  if (ent.client.damage_alpha > 0) then
    SV_AddBlend (ent.client.damage_blend[0], ent.client.damage_blend[1],
                 ent.client.damage_blend[2], ent.client.damage_alpha, ent.client.ps.blend);

  if (ent.client.bonus_alpha > 0) thne
    SV_AddBlend (0.85, 0.7, 0.3, ent.client.bonus_alpha, ent.client.ps.blend);

  // drop the damage value
  ent.client.damage_alpha := ent.client.damage_alpha - 0.06;
  if (ent.client.damage_alpha < 0) then
    ent.client.damage_alpha := 0;

  // drop the bonus value
  ent.client.bonus_alpha := ent.client.bonus_alpha - 0.1;
  if (ent.client.bonus_alpha < 0) then
    ent.client.bonus_alpha := 0;
end;//procedure (GAME=CTF)

{*
=================
P_FallingDamage
=================
*}
// (GAME <> CTF)
procedure P_FallingDamage (edict_t *ent);
var
  delta  : float;
  damage : integer;
  dir    : vec3_t;
begin
  if (ent.s.modelindex <> 255) then
    Exit;  // not in the player model

  if (ent.movetype = MOVETYPE_NOCLIP) then
    Exit;

  if ((ent.client.oldvelocity[2] < 0) AND (ent.velocity[2] > ent.client.oldvelocity[2]) AND (!ent.groundentity))
  then delta := ent.client.oldvelocity[2]
  else begin
    if (!ent.groundentity) then
      Exit;
    delta := ent.velocity[2] - ent.client.oldvelocity[2];
  end;
  delta := delta*delta * 0.0001;

{$IFDEF CTF}   //onlyCTF
//ZOID
  // never take damage if just release grapple or on grapple
  if ( (level.time - ent.client.ctf_grapplereleasetime <= FRAMETIME * 2) OR
       (ent.client.ctf_grapple AND ent.client.ctf_grapplestate > CTF_GRAPPLE_STATE_FLY) ) then
    Exit;
//ZOID
{$ENDIF}

  // never take falling damage if completely underwater
  if (ent.waterlevel = 3) then
    Exit;
  if (ent.waterlevel = 2) then
    delta := delta * 0.25;
  if (ent.waterlevel = 1) then
    delta := delta * 0.5;

  if (delta < 1) then
    Exit;
  if (delta < 15) then
  begin
    ent.s.event := EV_FOOTSTEP;
    Exit;
  end;

  ent.client.fall_value := delta*0.5;
  if (ent.client.fall_value > 40) then
    ent.client.fall_value := 40;
  ent.client.fall_time := level.time + FALL_TIME;

  if (delta > 30)
  then begin
    if (ent.health > 0) then
      if (delta >= 55)
      then ent.s.event := EV_FALLFAR
      else ent.s.event := EV_FALL;
    ent.pain_debounce_time := level.time;  // no normal pain sound
    damage := (delta-30)/2;
    if (damage < 1) then
      damage := 1;
    VectorSet (dir, 0, 0, 1);

    if (!deathmatch.value OR !((int)dmflags.value & DF_NO_FALLING) ) then
      T_Damage (ent, world, world, dir, ent.s.origin, vec3_origin, damage, 0, 0, MOD_FALLING);
  end
  else begin
    ent.s.event := EV_FALLSHORT;
    Exit;
  end;
end;//procedure (GAME <> CTF)


{*
=============
P_WorldEffects
=============
*}
// (GAME=CTF)
procedure P_WorldEffects;
var
  breather
  envirosuit     : qboolean;
  waterlevel,
  old_waterlevel : integer;
begin
  if (current_player.movetype = MOVETYPE_NOCLIP) then
  begin
    current_player.air_finished := level.time + 12;  // don't need air
    Exit;
  end;

  waterlevel := current_player.waterlevel;
  old_waterlevel := current_client.old_waterlevel;
  current_client.old_waterlevel := waterlevel;

  breather := current_client.breather_framenum > level.framenum;
  envirosuit := current_client.enviro_framenum > level.framenum;

  //
  // if just entered a water volume, play a sound
  //
  if (!old_waterlevel && waterlevel) then
  begin
    PlayerNoise(current_player, current_player.s.origin, PNOISE_SELF);
    if (current_player.watertype & CONTENTS_LAVA)
    then gi.sound (current_player, CHAN_BODY, gi.soundindex('player/lava_in.wav'), 1, ATTN_NORM, 0)
    else
      if (current_player.watertype & CONTENTS_SLIME)
      then gi.sound (current_player, CHAN_BODY, gi.soundindex('player/watr_in.wav'), 1, ATTN_NORM, 0)
      else
        if (current_player.watertype & CONTENTS_WATER) then
         gi.sound (current_player, CHAN_BODY, gi.soundindex('player/watr_in.wav'), 1, ATTN_NORM, 0);
    current_player.flags := current_player.flags OR FL_INWATER;

    // clear damage_debounce, so the pain sound will play immediately
    current_player.damage_debounce_time := level.time - 1;
  end;

  //
  // if just completely exited a water volume, play a sound
  //
  if (old_waterlevel && ! waterlevel) then
  begin
    PlayerNoise(current_player, current_player.s.origin, PNOISE_SELF);
    gi.sound (current_player, CHAN_BODY, gi.soundindex('player/watr_out.wav'), 1, ATTN_NORM, 0);
    current_player.flags := current_player.flags AND (NOT FL_INWATER);
  end;

  //
  // check for head just going under water
  //
  if (old_waterlevel <> 3) AND (waterlevel = 3) then
    gi.sound (current_player, CHAN_BODY, gi.soundindex('player/watr_un.wav'), 1, ATTN_NORM, 0);

  //
  // check for head just coming out of water
  //
  if (old_waterlevel = 3) AND waterlevel <> 3) then
    if (current_player.air_finished < level.time)
    then begin
      // gasp for air
      gi.sound (current_player, CHAN_VOICE, gi.soundindex('player/gasp1.wav'), 1, ATTN_NORM, 0);
      PlayerNoise(current_player, current_player.s.origin, PNOISE_SELF);
    end
    else
      if (current_player.air_finished < level.time + 11) then
    	// just break surface
        gi.sound (current_player, CHAN_VOICE, gi.soundindex('player/gasp2.wav'), 1, ATTN_NORM, 0);


  //
  // check for drowning
  //
  if (waterlevel = 3)
  then begin
    // breather or envirosuit give air
    if (breather OR envirosuit) then
    begin
      current_player.air_finished := level.time + 10;

      if (((int)(current_client.breather_framenum - level.framenum) % 25) == 0) then
      begin
        if (!current_client.breather_sound)
        then gi.sound (current_player, CHAN_AUTO, gi.soundindex('player/u_breath1.wav'), 1, ATTN_NORM, 0)
        else gi.sound (current_player, CHAN_AUTO, gi.soundindex('player/u_breath2.wav'), 1, ATTN_NORM, 0);
        current_client.breather_sound := current_client.breather_sound XOR 1;
        PlayerNoise(current_player, current_player.s.origin, PNOISE_SELF);
        //FIXME: release a bubble?
      end;
    end;

    // if out of air, start drowning
    if (current_player.air_finished < level.time) then
    begin
      // drown!
      if (current_player.client.next_drown_time < level.time) AND (current_player.health > 0) then
      begin
        current_player.client.next_drown_time := level.time + 1;

        // take more damage the longer underwater
        current_player.dmg += 2;
        if (current_player.dmg > 15) then
          current_player.dmg := 15;

        // play a gurp sound instead of a normal pain sound
        if (current_player.health <= current_player.dmg)
        then gi.sound (current_player, CHAN_VOICE, gi.soundindex('player/drown1.wav'), 1, ATTN_NORM, 0);
        else
          if (rand()&1)
          then gi.sound (current_player, CHAN_VOICE, gi.soundindex('*gurp1.wav'), 1, ATTN_NORM, 0)
          else gi.sound (current_player, CHAN_VOICE, gi.soundindex('*gurp2.wav'), 1, ATTN_NORM, 0);

        current_player.pain_debounce_time := level.time;

        T_Damage (current_player, world, world, vec3_origin, current_player.s.origin, vec3_origin, current_player.dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
      end;
    end;
  end
  else begin
    current_player.air_finished := level.time + 12;
    current_player.dmg := 2;
  end;

  //
  // check for sizzle damage
  //
  if (waterlevel AND (current_player.watertype AND (CONTENTS_LAVA OR CONTENTS_SLIME) <> 0) ) then
  begin
    if (current_player.watertype AND CONTENTS_LAVA) <> 0 then
    begin
      if (current_player->health > 0) AND
         (current_player->pain_debounce_time <= level.time) AND
         (current_client->invincible_framenum < level.framenum) then
      begin
        if (rand()&1)
        then gi.sound (current_player, CHAN_VOICE, gi.soundindex('player/burn1.wav'), 1, ATTN_NORM, 0)
        else gi.sound (current_player, CHAN_VOICE, gi.soundindex('player/burn2.wav'), 1, ATTN_NORM, 0);
        current_player.pain_debounce_time := level.time + 1;
      end;

      if (envirosuit)  // take 1/3 damage with envirosuit
      then T_Damage (current_player, world, world, vec3_origin, current_player.s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_LAVA)
      else T_Damage (current_player, world, world, vec3_origin, current_player.s.origin, vec3_origin, 3*waterlevel, 0, 0, MOD_LAVA);
    end;

    if (current_player.watertype AND CONTENTS_SLIME) <> 0 then
      if (!envirosuit) then
      	// no damage from slime with envirosuit
        T_Damage (current_player, world, world, vec3_origin, current_player.s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_SLIME);
  end;
end;//procedure (GAME=CTF)


{*
===============
G_SetClientEffects
===============
*}
// (GAME <> CTF)
procedure G_SetClientEffects (edict_t *ent);
var
  pa_type,
  remaining : integer;
begin
  ent.s.effects := 0;
  ent.s.renderfx := 0;

  if (ent.health <= 0 OR level.intermissiontime) then
    Exit;

  if (ent.powerarmor_time > level.time) then
  begin
    pa_type := PowerArmorType (ent);
    if (pa_type = POWER_ARMOR_SCREEN)
    then ent.s.effects := ent.s.effects OR EF_POWERSCREEN
    else
      if (pa_type = POWER_ARMOR_SHIELD) then
      begin
        ent.s.effects := ent.s.effects OR EF_COLOR_SHELL;
        ent.s.renderfx := ent.s.renderfx OR RF_SHELL_GREEN;
      end;
  end;

{$IFDEF CTF}
//ZOID
  CTFEffects(ent);

⌨️ 快捷键说明

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