Skip to content

Commit 41e18ea

Browse files
authored
Merge pull request #167 from ZehMatt/env-physimpact
Port env_physimpact
2 parents 31568bb + 546de6a commit 41e18ea

3 files changed

Lines changed: 132 additions & 1 deletion

File tree

‎Game.Server/PhysObj.cs‎

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
using Game.Shared;
22

3+
using Source;
34
using Source.Common;
5+
using Source.Common.Commands;
6+
using Source.Common.Formats.BSP;
7+
using Source.Common.Mathematics;
8+
using Source.Common.Physics;
9+
10+
using System.Numerics;
11+
12+
using DEFINE = Source.DEFINE<Game.Server.PhysImpact>;
413

514
namespace Game.Server;
615

@@ -13,3 +22,96 @@ public class PhysBox : Breakable
1322
public static readonly SendTable DT_PhysBox = new(DT_BaseEntity, []);
1423
public static readonly new ServerClass ServerClass = new ServerClass(DT_PhysBox);
1524
}
25+
26+
[LinkEntityToClass("env_physimpact")]
27+
public class PhysImpact : PointEntity
28+
{
29+
public const int bitsPHYSIMPACT_NOFALLOFF = 0x00000001;
30+
public const int bitsPHYSIMPACT_INFINITE_LENGTH = 0x00000002;
31+
public const int bitsPHYSIMPACT_IGNORE_MASS = 0x00000004;
32+
public const int bitsPHYSIMPACT_IGNORE_NORMAL = 0x00000008;
33+
34+
public const float DEFAULT_EXPLODE_DISTANCE = 256;
35+
36+
public static readonly ConVar debug_physimpact = new("debug_physimpact", "0");
37+
38+
public static readonly new DataMap DataDesc = new(typeof(PhysImpact), PointEntity.DataDesc, [
39+
DEFINE.KEYFIELD(nameof(Damage), FieldType.Float, "magnitude"),
40+
DEFINE.KEYFIELD(nameof(Distance), FieldType.Float, "distance"),
41+
DEFINE.KEYFIELD(nameof(DirectionEntityName), FieldType.String, "directionentityname"),
42+
43+
DEFINE.INPUTFUNC(FieldType.Void, "Impact", nameof(InputImpact), (INPUTFUNCPTR)((self, data) => ((PhysImpact)self).InputImpact(data))),
44+
]);
45+
public override DataMap? GetDataDescMap() => DataDesc;
46+
47+
float Damage;
48+
float Distance;
49+
string? DirectionEntityName;
50+
51+
public override void Activate() {
52+
base.Activate();
53+
}
54+
55+
public override void Spawn() {
56+
SetMoveType(Source.MoveType.None);
57+
SetSolid(SolidType.None);
58+
SetModelName(null);
59+
60+
if (Distance == 0)
61+
Distance = DEFAULT_EXPLODE_DISTANCE;
62+
}
63+
64+
void PointAtEntity() {
65+
if (string.IsNullOrEmpty(DirectionEntityName))
66+
return;
67+
68+
Util.PointAtNamedEntity(this, DirectionEntityName);
69+
}
70+
71+
public void InputImpact(InputData inputdata) {
72+
if (!string.IsNullOrEmpty(DirectionEntityName))
73+
PointAtEntity();
74+
75+
MathLib.AngleVectors(GetAbsAngles(), out Vector3 dir);
76+
77+
float dist = HasSpawnFlags(bitsPHYSIMPACT_INFINITE_LENGTH) ? MAX_TRACE_LENGTH : Distance;
78+
Vector3 start = GetAbsOrigin();
79+
Vector3 end = start + (dir * dist);
80+
81+
Util.TraceLine(start, end, Mask.Shot, this, Source.CollisionGroup.None, out Trace trace);
82+
if (trace.StartSolid) {
83+
Vector3 startOffset = start + (dir * 0.1f);
84+
Util.TraceLine(startOffset, end, Mask.Shot, this, Source.CollisionGroup.None, out trace);
85+
}
86+
87+
if (trace.Fraction != 1.0) {
88+
if (trace.StartSolid)
89+
trace.Plane.Normal = -dir;
90+
BaseEntity? ent = (BaseEntity?)trace.Ent;
91+
92+
IPhysicsObject? physics = ent?.VPhysicsGetObject();
93+
if (ent != null && physics != null) {
94+
TakeDamageInfo info = new();
95+
info.SetAttacker(this);
96+
info.SetInflictor(this);
97+
info.SetDamage(0);
98+
info.SetDamageForce(vec3_origin);
99+
info.SetDamageType(DamageType.Generic);
100+
101+
ent.DispatchTraceAttack(info, dir, ref trace);
102+
ApplyMultiDamage();
103+
104+
float damage = HasSpawnFlags(bitsPHYSIMPACT_NOFALLOFF | bitsPHYSIMPACT_INFINITE_LENGTH) ?
105+
Damage : (Damage * (1.0f - trace.Fraction));
106+
107+
if (HasSpawnFlags(bitsPHYSIMPACT_IGNORE_MASS))
108+
damage *= physics.GetMass();
109+
110+
if (!HasSpawnFlags(bitsPHYSIMPACT_IGNORE_NORMAL))
111+
dir = -trace.Plane.Normal;
112+
113+
physics.ApplyForceOffset(damage * dir * phys_pushscale.GetFloat(), trace.EndPos);
114+
}
115+
}
116+
}
117+
}

‎Game.Server/Util.cs‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Source.Common.Engine;
1212
using Source.Common.Formats.BSP;
1313
using Source.Common.Mathematics;
14+
using Source.Common.Physics;
1415
using Source.Engine.Server;
1516

1617
using System;
@@ -227,6 +228,34 @@ public static void ClearTrace(ref Trace trace) {
227228
trace.FractionLeftSolid = 0;
228229
}
229230

231+
public static bool PointAtEntity(BaseEntity? dest, BaseEntity? target) {
232+
if (dest == null || target == null)
233+
return false;
234+
235+
Vector3 dir = target.GetAbsOrigin() - dest.GetAbsOrigin();
236+
237+
MathLib.VectorNormalize(ref dir);
238+
239+
MathLib.VectorAngles(dir, out QAngle angles);
240+
dest.SetLocalAngles(angles);
241+
dest.SetAbsAngles(angles);
242+
243+
#if GMOD_DLL
244+
IPhysicsObject? physicsObject = dest.VPhysicsGetObject();
245+
if (physicsObject != null) {
246+
physicsObject.GetPosition(out Vector3 worldPos, out _);
247+
physicsObject.SetPosition(worldPos, angles, true);
248+
}
249+
#endif
250+
251+
return true;
252+
}
253+
254+
public static void PointAtNamedEntity(BaseEntity dest, string? target) {
255+
if (!PointAtEntity(dest, gEntList.FindEntityByName(null, target)))
256+
DevMsg(1, $"{dest.GetClassname()} ({dest.GetDebugName()}) was unable to point at an entity named: {target}\n");
257+
}
258+
230259
public static int DropToFloor(BaseEntity entity, Mask mask) {
231260
entity.SetGroundEntity(null);
232261

‎Game.Shared/TakeDamageInfo.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public static void AddMultiDamage(in TakeDamageInfo info, BaseEntity? entity) {
104104
}
105105
}
106106

107-
static readonly ConVar phys_pushscale = new( "phys_pushscale", "1", FCvar.Replicated);
107+
public static readonly ConVar phys_pushscale = new( "phys_pushscale", "1", FCvar.Replicated);
108108

109109

110110

0 commit comments

Comments
 (0)