📄 g_phys.pas
字号:
// to avoid tiny occilations in sloping corners
//
if (DotProduct(ent^.velocity, primal_velocity) <= 0) then begin
VectorCopy(vec3_origin, ent^.velocity);
result:= blocked;
exit;
end;
end;
result:= blocked;
end;
{/*
============
SV_AddGravity
============
*/}
procedure SV_AddGravity(ent: edict_p);
begin
ent^.velocity[2]:= ent^.velocity[2] - ent^.gravity * sv_gravity^.value, * FRAMETIME;
end;
{/*
===============================================================================
PUSHMOVE
===============================================================================
*/`}
{/*
============
SV_PushEntity
Does not change the entities velocity at all
============
*/}
function SV_PushEntity(ent: edict_p; push: vec3_t): trace_t;
label retry;
var
trace: trace_t;
start, _end: vec3_t;
mask: integer;
begin
VectorCopy(ent^.s.origin, start);
VectorAdd(start, push, _end);
retry:
if (ent^.clipmask > 0) then mask:= ent^.clipmask
else mask:= MASK_SOLID;
trace:= gi.trace(start, ent^.mins, ent^.maxs, _end, ent, mask);
VectorCopy(trace.endpos, ent^.s.origin);
gi.linkentity(ent);
if (trace.fraction <> 1.0 then begin
SV_Impact(ent, @trace);
//if the pushed entity went away and the pusher is still there
if not (trace.ent^.inuse and ent^.inuse) then begin
//move the pusher back and try again
VectorCopy(start, ent^.s.origin);
gi.linkentity(ent);
goto retry;
end;
end;
if ent^.inuse then G_TouchTriggers(ent);
result:= trace;
end;
{delphi-note: converted the C pushed_p variable to _pushed_p since}
{pushed_p is the typed pointer of a record}
type pushed_t: packed record
ent: edict_p;
origin, angles: vec3_t;
deltayaw: single;
end;
pushed_p: ^pushed_t;
var pushed: array[0..MAX_EDICTS -1] of pushed_t;
var _pushed_p: pushed_t;
var obstacle: edict_p;
{/*
============
SV_Push
Objects need to be moved back on a failed push,
otherwise riders would continue to slide.
============
*/}
function SV_Push(pushed: edict_p, _move, amove: vec3_t): qboolean;
begin
{line 533 in C Source}
end;
{/*
================
SV_Physics_Pusher
Bmodel objects don't interact with each other, but
push all box objects
================
*/}
procedure SV_Physics_Pusher(ent: edict_p);
begin
{line 564 in C Source}
end;
//==================================================================
{/*
=============
SV_Physics_None
Non moving objects can only think
=============
*/}
procedure SV_Physics_None(ent: edict_p);
begin
// regular thinking
SV_RunThink(ent);
end;
{/*
=============
SV_Physics_Noclip
A moving object that doesn't obey physics
=============
*/}
procedure SV_Physics_Noclip (ent: edict_p);
begin
// regular thinking
if not SV_RunThink(ent) then exit;
VectorMA (ent^.s.angles, FRAMETIME, ent^.avelocity, ent^.s.angles);
VectorMA (ent^.s.origin, FRAMETIME, ent^.velocity, ent^.s.origin);
gi.linkentity(ent);
end;
{/*
==============================================================================
TOSS / BOUNCE
==============================================================================
*/}
{/*
=============
SV_Physics_Toss
Toss, bounce, and fly movement. When onground, do nothing.
=============
*/}
procedure SV_Physics_Toss(ent: edict_p);
var
trace: trace_t;
_move: vec3_t;
backoff: single;
slave: edict_p;
wasinwater, isinwater: qboolean;
old_origin: vec3_t;
begin
// regular thinking
SV_RunThink(ent);
// if not a team captain, so movement will be handled elsewhere
if ( ent^.flags and FL_TEAMSLAVE) then exit;
if (ent^.velocity[2] > 0) then ent^.groundentity = NIL;
// check for the groundentity going away
if (ent^.groundentity) then
if not ent^.groundentity^.inuse then ent^.groundentity = NIL;
// if onground, return without moving
if ( ent^.groundentity ) then exit;
VectorCopy(ent^.s.origin, old_origin);
SV_CheckVelocity(ent);
// add gravity
if (ent^.movetype <> MOVETYPE_FLY) and (ent^.movetype <> MOVETYPE_FLYMISSILE) then
SV_AddGravity(ent);
// move angles
VectorMA(ent^.s.angles, FRAMETIME, ent^.avelocity, ent^.s.angles);
// move origin
VectorScale(ent^.velocity, FRAMETIME, move);
trace = SV_PushEntity(ent, _move);
if not ent->inuse then exit;
if (trace.fraction < 1) then begin
if (ent^.movetype == MOVETYPE_BOUNCE) then backoff:= 1.5
else backoff:= 1;
ClipVelocity(ent^.velocity, trace.plane.normal, ent^.velocity, backoff);
// stop if on ground
if (trace.plane.normal[2] > 0.7) then begin
if (ent^.velocity[2] < 60 or ent^.movetype) <> MOVETYPE_BOUNCE ) then begin
ent^.groundentity:= trace.ent;
ent^.groundentity_linkcount:= trace.ent->linkcount;
VectorCopy(vec3_origin, ent^.velocity);
VectorCopy(vec3_origin, ent^.avelocity);
end;
end;
//if (ent->touch)
//ent->touch (ent, trace.ent, &trace.plane, trace.surface);
end;
//check for water transition
wasinwater:= (ent^.watertype and MASK_WATER);
ent^.watertype = gi.pointcontents(ent^.s.origin);
isinwater:= ent^.watertype and MASK_WATER;
if (isinwater) then ent^.waterlevel:= 1
else ent^.waterlevel = 0;
if not (wasinwater and isinwater) then
gi.positioned_sound(old_origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0)
else if (wasinwater and not isinwater) then
gi.positioned_sound (ent^.s.origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0);
//move teamslaves
{delphi-note: think this is the right way to do it. The original for instruction is}
{for (slave = ent->teamchain; slave; slave = slave->teamchain)}
slave:= ent^.teamchain;
while slave <> nil do begin
VectorCopy(ent^.s.origin, slave^.s.origin);
gi.linkentity(slave);
slave:= slave^.teamchain;
end;
end;
{/*
===============================================================================
STEPPING MOVEMENT
===============================================================================
*/}
{/*
=============
SV_Physics_Step
Monsters freefall when they don't have a ground entity, otherwise
all movement is done with discrete steps.
This is also used for objects that have become still on the ground, but
will fall if the floor is pulled out from under them.
FIXME: is this true?
=============
*/}
//FIXME: hacked in for E3 demo
const sv_stopspeed = 100
const sv_friction = 6
const sv_waterfriction = 1
procedure SV_AddRotationalFriction(ent: edict_p)
var
n: integer;
adjustment: single;
begin
VectorMA(ent^.s.angles, FRAMETIME, ent^.avelocity, ent^.s.angles);
adjustment:= FRAMETIME * sv_stopspeed * sv_friction;
for n:= 0 to 2 do begin
if (ent^.avelocity[n] > 0) then begin
ent^.avelocity[n]:= ent^.avelocity[n] - adjustment;
if (ent^.avelocity[n] < 0) then ent^.avelocity[n]:= 0;
end else begin
ent^.avelocity[n]:= ent^.avelocity[n] + adjustment;
if (ent^.avelocity[n] > 0) then ent^.avelocity[n] = 0;
end;
end;
end;
procedure SV_Physics_Step(ent: edict_p);
begin
{line 816 in C Source}
end;
//============================================================================
{/*
================
G_RunEntity
================
*/}
procedure G_RunEntity(ent: edict_p)
begin
if assigned(ent^.prethink) then ent^.prethink(ent);
case ent^.movetype of
MOVETYPE_PUSH:
MOVETYPE_STOP: begin
SV_Physics_Pusher(ent);
break;
end;
MOVETYPE_NONE: begin
SV_Physics_None (ent);
break;
end;
MOVETYPE_NOCLIP: begin
SV_Physics_Noclip (ent);
break;
end;
MOVETYPE_STEP: begin
SV_Physics_Step (ent);
break;
end;
MOVETYPE_TOSS:
MOVETYPE_BOUNCE:
MOVETYPE_FLY:
MOVETYPE_FLYMISSILE: begin
SV_Physics_Toss (ent);
break;
end;
else: gi.error ('SV_Physics: bad movetype %i', ent^.movetype);
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -