Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
SubsystemBodies.cs
浏览该文件的文档.
1using Engine;
3
4namespace Game {
6 public const float m_areaSize = 8f;
7
8 public DynamicArray<ComponentBody> m_componentBodies = [];
9
10 public Dictionary<ComponentBody, Point2> m_areaByComponentBody = [];
11
12 public Dictionary<Point2, DynamicArray<ComponentBody>> m_componentBodiesByArea = [];
13
14 public Dictionary<ComponentBody, Point2>.KeyCollection Bodies => m_areaByComponentBody.Keys;
15
17
18 public void FindBodiesAroundPoint(Vector2 point, float radius, DynamicArray<ComponentBody> result) {
19 int num = (int)MathF.Floor((point.X - radius) / 8f);
20 int num2 = (int)MathF.Floor((point.Y - radius) / 8f);
21 int num3 = (int)MathF.Floor((point.X + radius) / 8f);
22 int num4 = (int)MathF.Floor((point.Y + radius) / 8f);
23 for (int i = num; i <= num3; i++) {
24 for (int j = num2; j <= num4; j++) {
25 if (m_componentBodiesByArea.TryGetValue(new Point2(i, j), out DynamicArray<ComponentBody> value)) {
26 for (int k = 0; k < value.Count; k++) {
27 result.Add(value.Array[k]);
28 }
29 }
30 }
31 }
32 }
33
34 public void FindBodiesInArea(Vector2 corner1, Vector2 corner2, DynamicArray<ComponentBody> result) {
35 Point2 point = new((int)MathF.Floor(corner1.X / 8f), (int)MathF.Floor(corner1.Y / 8f));
36 Point2 point2 = new((int)MathF.Floor(corner2.X / 8f), (int)MathF.Floor(corner2.Y / 8f));
37 int num = MathUtils.Min(point.X, point2.X) - 1;
38 int num2 = MathUtils.Min(point.Y, point2.Y) - 1;
39 int num3 = MathUtils.Max(point.X, point2.X) + 1;
40 int num4 = MathUtils.Max(point.Y, point2.Y) + 1;
41 for (int i = num; i <= num3; i++) {
42 for (int j = num2; j <= num4; j++) {
43 if (m_componentBodiesByArea.TryGetValue(new Point2(i, j), out DynamicArray<ComponentBody> value)) {
44 for (int k = 0; k < value.Count; k++) {
45 result.Add(value.Array[k]);
46 }
47 }
48 }
49 }
50 }
51
52 public BodyRaycastResult? Raycast(Vector3 start, Vector3 end, float inflateAmount, Func<ComponentBody, float, bool> action) {
53 float num = Vector3.Distance(start, end);
54 Ray3 ray = new(start, num > 0f ? (end - start) / num : Vector3.UnitX);
55 Vector2 corner = new(start.X, start.Z);
56 Vector2 corner2 = new(end.X, end.Z);
57 BodyRaycastResult bodyRaycastResult = default;
58 bodyRaycastResult.Ray = ray;
59 bodyRaycastResult.Distance = float.MaxValue;
60 BodyRaycastResult value = bodyRaycastResult;
61 m_componentBodies.Clear();
62 FindBodiesInArea(corner, corner2, m_componentBodies);
63 for (int i = 0; i < m_componentBodies.Count; i++) {
64 ComponentBody componentBody = m_componentBodies.Array[i];
65 if (componentBody == null) {
66 continue;
67 }
68 if (componentBody.IsRaycastTransparent) {
69 continue;
70 }
71 float? num2 = null;
72 bool skipVanilla_ = false;
74 "BodyCountInRaycast",
75 loader => {
76 num2 = loader.BodyCountInRaycast(componentBody, ray, out bool skip);
77 skipVanilla_ |= skip;
78 return false;
79 }
80 );
81 if (!skipVanilla_) {
82 if (inflateAmount > 0f) {
83 BoundingBox boundingBox = componentBody.BoundingBox;
84 boundingBox.Min -= new Vector3(inflateAmount);
85 boundingBox.Max += new Vector3(inflateAmount);
86 num2 = ray.Intersection(boundingBox);
87 }
88 else {
89 num2 = ray.Intersection(componentBody.BoundingBox);
90 }
91 }
92 if (num2.HasValue
93 && num2.Value <= num
94 && num2.Value < value.Distance
95 && action(componentBody, num2.Value)) {
96 value.Distance = num2.Value;
97 value.ComponentBody = componentBody;
98 }
99 }
100 if (value.ComponentBody == null) {
101 return null;
102 }
103 return value;
104 }
105
106 public override void OnEntityAdded(Entity entity) {
107 foreach (ComponentBody item in entity.FindComponents<ComponentBody>()) {
108 AddBody(item);
109 }
110 }
111
112 public override void OnEntityRemoved(Entity entity) {
113 foreach (ComponentBody item in entity.FindComponents<ComponentBody>()) {
114 RemoveBody(item);
115 }
116 }
117
118 public virtual void Update(float dt) {
119 foreach (ComponentBody body in Bodies) {
120 UpdateBody(body);
121 }
122 }
123
124 public void AddBody(ComponentBody componentBody) {
125 Vector3 position = componentBody.Position;
126 Point2 point = new((int)MathF.Floor(position.X / 8f), (int)MathF.Floor(position.Z / 8f));
127 m_areaByComponentBody.Add(componentBody, point);
128 if (!m_componentBodiesByArea.TryGetValue(point, out DynamicArray<ComponentBody> value)) {
129 value = [];
130 m_componentBodiesByArea.Add(point, value);
131 }
132 value.Add(componentBody);
133 componentBody.PositionChanged += ComponentBody_PositionChanged;
134 }
135
136 public void RemoveBody(ComponentBody componentBody) {
137 Point2 key = m_areaByComponentBody[componentBody];
138 m_areaByComponentBody.Remove(componentBody);
139 m_componentBodiesByArea[key].Remove(componentBody);
140 componentBody.PositionChanged -= ComponentBody_PositionChanged;
141 }
142
143 public virtual void UpdateBody(ComponentBody componentBody) {
144 Vector3 position = componentBody.Position;
145 Point2 point = new((int)MathF.Floor(position.X / 8f), (int)MathF.Floor(position.Z / 8f));
146 Point2 point2 = m_areaByComponentBody[componentBody];
147 if (point != point2) {
148 m_areaByComponentBody[componentBody] = point;
149 m_componentBodiesByArea[point2].Remove(componentBody);
150 if (!m_componentBodiesByArea.TryGetValue(point, out DynamicArray<ComponentBody> value)) {
151 value = [];
152 m_componentBodiesByArea.Add(point, value);
153 }
154 value.Add(componentBody);
155 }
156 }
157
158 public void ComponentBody_PositionChanged(ComponentFrame componentFrame) {
159 UpdateBody((ComponentBody)componentFrame);
160 }
161 }
162}
Engine.Vector3 Vector3
static int Min(int x1, int x2)
static int Max(int x1, int x2)
virtual BoundingBox BoundingBox
void RemoveBody(ComponentBody componentBody)
DynamicArray< ComponentBody > m_componentBodies
override void OnEntityRemoved(Entity entity)
Dictionary< Point2, DynamicArray< ComponentBody > > m_componentBodiesByArea
virtual void Update(float dt)
override void OnEntityAdded(Entity entity)
Dictionary< ComponentBody, Point2 > m_areaByComponentBody
void FindBodiesAroundPoint(Vector2 point, float radius, DynamicArray< ComponentBody > result)
virtual void UpdateBody(ComponentBody componentBody)
BodyRaycastResult? Raycast(Vector3 start, Vector3 end, float inflateAmount, Func< ComponentBody, float, bool > action)
void AddBody(ComponentBody componentBody)
Dictionary< ComponentBody, Point2 >.KeyCollection Bodies
void ComponentBody_PositionChanged(ComponentFrame componentFrame)
void FindBodiesInArea(Vector2 corner1, Vector2 corner2, DynamicArray< ComponentBody > result)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
float? Intersection(BoundingBox box)
定义 Ray3.cs:20
static float Distance(Vector3 v1, Vector3 v2)
static readonly Vector3 UnitX