📄 pmoveunit.pas
字号:
for i := 0 to 2 do
pml.velocity[i] := pml.velocity[i] + accelspeed * wishdir[i];
end;
{*
=============
PM_AddCurrents
=============
*}
procedure PM_AddCurrents(var wishvel: vec3_t);
var
v: vec3_t;
s: Single;
begin
//
// account for ladders
//
if pml.ladder and (Abs(pml.velocity[2]) <= 200) then
begin
if ((pm.viewangles[PITCH] <= -15) and (pm.cmd.forwardmove > 0)) then
wishvel[2] := 200
else if ((pm.viewangles[PITCH] >= 15) and (pm.cmd.forwardmove > 0)) then
wishvel[2] := -200
else if (pm.cmd.upmove > 0) then
wishvel[2] := 200
else if (pm.cmd.upmove < 0) then
wishvel[2] := -200
else
wishvel[2] := 0;
// limit horizontal speed when on a ladder
if (wishvel[0] < -25) then
wishvel[0] := -25
else if (wishvel[0] > 25) then
wishvel[0] := 25;
if (wishvel[1] < -25) then
wishvel[1] := -25
else if (wishvel[1] > 25) then
wishvel[1] := 25;
end;
//
// add water currents
//
if (pm.watertype and MASK_CURRENT <> 0) then
begin
VectorClear(v);
if (pm.watertype and CONTENTS_CURRENT_0 <> 0) then
v[0] := v[0] + 1;
if (pm.watertype and CONTENTS_CURRENT_90 <> 0) then
v[1] := v[1] + 1;
if (pm.watertype and CONTENTS_CURRENT_180 <> 0) then
v[0] := v[0] - 1;
if (pm.watertype and CONTENTS_CURRENT_270 <> 0) then
v[1] := v[1] - 1;
if (pm.watertype and CONTENTS_CURRENT_UP <> 0) then
v[2] := v[2] + 1;
if (pm.watertype and CONTENTS_CURRENT_DOWN <> 0) then
v[2] := v[2] - 1;
s := pm_waterspeed;
if (pm.waterlevel = 1) and (pm.groundentity <> nil) then
s := s / 2;
VectorMA(wishvel, s, v, wishvel);
end;
//
// add conveyor belt velocities
//
if (pm.groundentity <> nil) then
begin
VectorClear(v);
if (pml.groundcontents and CONTENTS_CURRENT_0 <> 0) then
v[0] := v[0] + 1;
if (pml.groundcontents and CONTENTS_CURRENT_90 <> 0) then
v[1] := v[1] + 1;
if (pml.groundcontents and CONTENTS_CURRENT_180 <> 0) then
v[0] := v[0] - 1;
if (pml.groundcontents and CONTENTS_CURRENT_270 <> 0) then
v[1] := v[1] - 1;
if (pml.groundcontents and CONTENTS_CURRENT_UP <> 0) then
v[2] := v[2] + 1;
if (pml.groundcontents and CONTENTS_CURRENT_DOWN <> 0) then
v[2] := v[2] - 1;
VectorMA(wishvel, 100 {* pm->groundentity->speed *}, v, wishvel);
end;
end;
{*
===================
PM_WaterMove
===================
*}
procedure PM_WaterMove;
var
i: Integer;
wishvel: vec3_t;
wishspeed: Single;
wishdir: vec3_t;
begin
//
// user intentions
//
for i := 0 to 2 do
wishvel[i] := pml.forward[i] * pm.cmd.forwardmove + pml.right[i] * pm.cmd.sidemove;
if (pm.cmd.forwardmove = 0) and (pm.cmd.sidemove = 0) and (pm.cmd.upmove = 0) then
wishvel[2] := wishvel[2] - 60 // drift towards bottom
else
wishvel[2] := wishvel[2] + pm.cmd.upmove;
PM_AddCurrents(wishvel);
VectorCopy(wishvel, wishdir);
wishspeed := VectorNormalize(wishdir);
if (wishspeed > pm_maxspeed) then
begin
VectorScale(wishvel, pm_maxspeed / wishspeed, wishvel);
wishspeed := pm_maxspeed;
end;
wishspeed := wishspeed * 0.5;
PM_Accelerate_func(wishdir, wishspeed, pm_wateraccelerate);
PM_StepSlideMove;
end;
{*
===================
PM_AirMove
===================
*}
procedure PM_AirMove;
var
i: Integer;
wishvel: vec3_t;
fmove, smove: Single;
wishdir: vec3_t;
wishspeed: Single;
maxspeed: Single;
begin
fmove := pm.cmd.forwardmove;
smove := pm.cmd.sidemove;
{
pml.forward[2] = 0;
pml.right[2] = 0;
VectorNormalize (pml.forward);
VectorNormalize (pml.right);
}
for i := 0 to 1 do
wishvel[i] := pml.forward[i] * fmove + pml.right[i] * smove;
wishvel[2] := 0;
PM_AddCurrents(wishvel);
VectorCopy(wishvel, wishdir);
wishspeed := VectorNormalize(wishdir);
//
// clamp to server defined max speed
//
// maxspeed = (pm->s.pm_flags & PMF_DUCKED) ? pm_duckspeed : pm_maxspeed;
if (pm.s.pm_flags and PMF_DUCKED) <> 0 then
maxspeed := pm_duckspeed
else
maxspeed := pm_maxspeed;
if (wishspeed > maxspeed) then
begin
VectorScale(wishvel, maxspeed / wishspeed, wishvel);
wishspeed := maxspeed;
end;
if pml.ladder then
begin
PM_Accelerate_func(wishdir, wishspeed, pm_accelerate);
if (wishvel[2] = 0) then
begin
if (pml.velocity[2] > 0) then
begin
pml.velocity[2] := pml.velocity[2] - pm.s.gravity * pml.frametime;
if (pml.velocity[2] < 0) then
pml.velocity[2] := 0;
end
else
begin
pml.velocity[2] := pml.velocity[2] + pm.s.gravity * pml.frametime;
if (pml.velocity[2] > 0) then
pml.velocity[2] := 0;
end;
end;
PM_StepSlideMove;
end
else if (pm.groundentity <> nil) then
begin // walking on ground
pml.velocity[2] := 0; //!!! this is before the accel
PM_Accelerate_func(wishdir, wishspeed, pm_accelerate);
// PGM -- fix for negative trigger_gravity fields
// pml.velocity[2] = 0;
if (pm.s.gravity > 0) then
pml.velocity[2] := 0
else
pml.velocity[2] := pml.velocity[2] - pm.s.gravity * pml.frametime;
// PGM
if (pml.velocity[0] = 0) and (pml.velocity[1] = 0) then
Exit;
PM_StepSlideMove;
end
else
begin // not on ground, so little effect on velocity
if (pm_airaccelerate <> 0) then
PM_AirAccelerate_func(wishdir, wishspeed, pm_accelerate)
else
PM_Accelerate_func(wishdir, wishspeed, 1);
// add gravity
pml.velocity[2] := pml.velocity[2] - pm.s.gravity * pml.frametime;
PM_StepSlideMove;
end;
end;
{*
=============
PM_CatagorizePosition
=============
*}
procedure PM_CatagorizePosition;
var
point: vec3_t;
cont: Integer;
trace: trace_t;
sample1: Integer;
sample2: Integer;
begin
// if the player hull point one unit down is solid, the player
// is on ground
// see if standing on something solid
point[0] := pml.origin[0];
point[1] := pml.origin[1];
point[2] := pml.origin[2] - 0.25;
if (pml.velocity[2] > 180) then //!!ZOID changed from 100 to 180 (ramp accel)
begin
pm.s.pm_flags := pm.s.pm_flags and not PMF_ON_GROUND;
pm.groundentity := nil;
end
else
begin
trace := pm.trace(pml.origin, pm.mins, pm.maxs, point);
pml.groundplane := trace.plane;
pml.groundsurface := trace.surface;
pml.groundcontents := trace.contents;
if (trace.ent = nil) or
((trace.plane.normal[2] < 0.7) and (not trace.startsolid)) then
begin
pm.groundentity := nil;
pm.s.pm_flags := pm.s.pm_flags and not PMF_ON_GROUND;
end
else
begin
pm.groundentity := trace.ent;
// hitting solid ground will end a waterjump
if (pm.s.pm_flags and PMF_TIME_WATERJUMP <> 0) then
begin
pm.s.pm_flags := pm.s.pm_flags and not (PMF_TIME_WATERJUMP or PMF_TIME_LAND or PMF_TIME_TELEPORT);
pm.s.pm_time := 0;
end;
if (pm.s.pm_flags and PMF_ON_GROUND) = 0 then
begin // just hit the ground
pm.s.pm_flags := pm.s.pm_flags or PMF_ON_GROUND;
// don't do landing time if we were just going down a slope
if (pml.velocity[2] < -200) then
begin
pm.s.pm_flags := pm.s.pm_flags or PMF_TIME_LAND;
// don't allow another jump for a little while
if (pml.velocity[2] < -400) then
pm.s.pm_time := 25
else
pm.s.pm_time := 18;
end;
end;
end;
{
if (trace.fraction < 1.0 && trace.ent && pml.velocity[2] < 0)
pml.velocity[2] = 0;
}
if (pm.numtouch < MAXTOUCH) and (trace.ent <> nil) then
begin
pm.touchents[pm.numtouch] := trace.ent;
Inc(pm.numtouch);
end;
end;
//
// get waterlevel, accounting for ducking
//
pm.waterlevel := 0;
pm.watertype := 0;
sample2 := Trunc(pm.viewheight - pm.mins[2]);
sample1 := sample2 div 2;
point[2] := pml.origin[2] + pm.mins[2] + 1;
cont := pm.pointcontents(point);
if (cont and MASK_WATER <> 0) then
begin
pm.watertype := cont;
pm.waterlevel := 1;
point[2] := pml.origin[2] + pm.mins[2] + sample1;
cont := pm.pointcontents(point);
if (cont and MASK_WATER <> 0) then
begin
pm.waterlevel := 2;
point[2] := pml.origin[2] + pm.mins[2] + sample2;
cont := pm.pointcontents(point);
if (cont and MASK_WATER <> 0) then
pm.waterlevel := 3;
end;
end;
end;
{*
=============
PM_CheckJump
=============
*}
procedure PM_CheckJump;
begin
if (pm.s.pm_flags and PMF_TIME_LAND <> 0) then
begin // hasn't been long enough since landing to jump again
Exit;
end;
if (pm.cmd.upmove < 10) then
begin // not holding jump
pm.s.pm_flags := pm.s.pm_flags and not PMF_JUMP_HELD;
Exit;
end;
// must wait for jump to be released
if (pm.s.pm_flags and PMF_JUMP_HELD <> 0) then
Exit;
if (pm.s.pm_type = PM_DEAD) then
Exit;
if (pm.waterlevel >= 2) then
begin // swimming, not jumping
pm.groundentity := nil;
if (pml.velocity[2] <= -300) then
Exit;
if (pm.watertype = CONTENTS_WATER) then
pml.velocity[2] := 100
else if (pm.watertype = CONTENTS_SLIME) then
pml.velocity[2] := 80
else
pml.velocity[2] := 50;
Exit;
end;
if (pm.groundentity = nil) then
Exit; // in air, so no effect
pm.s.pm_flags := pm.s.pm_flags or PMF_JUMP_HELD;
pm.groundentity := nil;
pml.velocity[2] := pml.velocity[2] + 270;
if (pml.velocity[2] < 270) then
pml.velocity[2] := 270;
end;
{*
=============
PM_CheckSpecialMovement
=============
*}
procedure PM_CheckSpecialMovement;
var
spot: vec3_t;
cont: Integer;
flatforward: vec3_t;
trace: trace_t;
begin
if (pm.s.pm_time <> 0) then
Exit;
pml.ladder := False;
// check for ladder
flatforward[0] := pml.forward[0];
flatforward[1] := pml.forward[1];
flatforward[2] := 0;
VectorNormalize(flatforward);
VectorMA(pml.origin, 1, flatforward, spot);
trace := pm.trace(pml.origin, pm.mins, pm.maxs, spot);
if (trace.fraction < 1) and (trace.contents and CONTENTS_LADDER <> 0) then
pml.ladder := True;
// check for water jump
if (pm.waterlevel <> 2) then
Exit;
VectorMA(pml.origin, 30, flatforward, spot);
spot[2] := spot[2] + 4;
cont := pm.pointcontents(spot);
if (cont and CONTENTS_SOLID = 0) then
Exit;
spot[2] := spot[2] + 16;
cont := pm.pointcontents(spot);
if (cont <> 0) then
exit;
// jump out of water
VectorScale(flatforward, 50, pml.velocity);
pml.velocity[2] := 350;
pm.s.pm_flags := pm.s.pm_flags or PMF_TIME_WATERJUMP;
pm.s.pm_time := 255;
end;
{*
===============
PM_FlyMove
===============
*}
procedure PM_FlyMove(doclip: qboolean);
var
speed, drop, friction, control, newspeed: Single;
currentspeed, addspeed, accelspeed: Single;
i: Integer;
wishvel: vec3_t;
fmove, smove: Single;
wishdir: vec3_t;
wishspeed: Single;
end_: vec3_t;
trace: trace_t;
begin
pm.viewheight := 22;
// friction
speed := VectorLength(pml.velocity);
if (speed < 1) then
begin
VectorCopy(vec3_origin, pml.velocity);
end
else
begin
drop := 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -