Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
ComponentLocomotion.cs
浏览该文件的文档.
1using Engine;
4
5namespace Game {
18
19 public Random m_random = new();
25 public float m_jumpOrder;
26 public bool m_lookAutoLevelX;
27 public bool m_lookAutoLevelY;
28 public double m_shoesWarningTime;
30 public float m_minFrictionFactor;
35 public bool m_walking;
36 public bool m_falling;
37 public bool m_climbing;
38 public bool m_jumping;
39 public bool m_swimming;
40 public bool m_flying;
41 public const string fName = "ComponentLocomotion";
42
43 public float AccelerationFactor { get; set; }
44
45 public float WalkSpeed { get; set; }
46
47 public float LadderSpeed { get; set; }
48
49 public float JumpSpeed { get; set; }
50
51 public float FlySpeed { get; set; }
52
53 public float CreativeFlySpeed { get; set; }
54
55 public float SwimSpeed { get; set; }
56
57 public float TurnSpeed { get; set; }
58
59 public float LookSpeed { get; set; }
60
61 public float InAirWalkFactor { get; set; }
62
63 public float? SlipSpeed { get; set; }
64
65 public bool EnableGravityOnDeathOrStun = true;
66
68 get => m_lookAngles;
69 set {
70 value.X = Math.Clamp(value.X, 0f - MathUtils.DegToRad(140f), MathUtils.DegToRad(140f));
71 value.Y = Math.Clamp(value.Y, 0f - MathUtils.DegToRad(82f), MathUtils.DegToRad(82f));
72 m_lookAngles = value;
73 }
74 }
75
76 public int? LadderValue { get; set; }
77
79 get => m_walkOrder;
80 set {
81 m_walkOrder = value;
82 if (m_walkOrder.HasValue) {
83 float num = m_walkOrder.Value.LengthSquared();
84 if (num > 1f) {
85 m_walkOrder = m_walkOrder.Value / MathF.Sqrt(num);
86 }
87 }
88 }
89 }
90
91 public Vector3? FlyOrder {
92 get => m_flyOrder;
93 set {
94 m_flyOrder = value;
95 if (m_flyOrder.HasValue) {
96 float num = m_flyOrder.Value.LengthSquared();
97 if (num > 1f) {
98 m_flyOrder = m_flyOrder.Value / MathF.Sqrt(num);
99 }
100 }
101 }
102 }
103
105 get => m_swimOrder;
106 set {
107 m_swimOrder = value;
108 if (m_swimOrder.HasValue) {
109 float num = m_swimOrder.Value.LengthSquared();
110 if (num > 1f) {
111 m_swimOrder = m_swimOrder.Value / MathF.Sqrt(num);
112 }
113 }
114 }
115 }
116
118 get => m_turnOrder;
119 set => m_turnOrder = value;
120 }
121
123 get => m_lookOrder;
124 set => m_lookOrder = value;
125 }
126
127 public float JumpOrder {
128 get => m_jumpOrder;
129 set => m_jumpOrder = MathUtils.Saturate(value);
130 }
131
132 public Vector3? VrMoveOrder { get; set; }
133
134 public Vector2? VrLookOrder { get; set; }
135
136 public float StunTime { get; set; }
137
138 public Vector2? LastWalkOrder { get; set; }
139
140 public float LastJumpOrder { get; set; }
141
142 public Vector3? LastFlyOrder { get; set; }
143
144 public Vector3? LastSwimOrder { get; set; }
145
146 public Vector2 LastTurnOrder { get; set; }
147
148 public static bool IsCreativeFlyEnabledSet = false;
149
150 public bool IsCreativeFlyEnabled { get; set; }
151
152 public bool AllowShoesWarning = true;
153
154 public UpdateOrder UpdateOrder => UpdateOrder.Locomotion;
155
156 public virtual void Update(float dt) {
157 SlipSpeed = null;
158 /* 禁用创造模式飞行的操作只在开始的时候执行一次
159 * if (m_subsystemGameInfo.WorldSettings.GameMode != 0)
160 {
161 IsCreativeFlyEnabled = false;
162 }*/
163 StunTime = MathUtils.Max(StunTime - dt, 0f);
164 if (m_componentCreature.ComponentHealth.Health > 0f
165 && StunTime <= 0f) {
166 Vector3 position = m_componentCreature.ComponentBody.Position;
167 PlayerStats playerStats = m_componentCreature.PlayerStats;
168 if (playerStats != null) {
169 float x = m_lastPosition.HasValue ? Vector3.Distance(position, m_lastPosition.Value) : 0f;
170 x = MathUtils.Min(x, 25f * m_subsystemTime.PreviousGameTimeDelta);
171 playerStats.DistanceTravelled += x;
172 if (m_componentRider != null
173 && m_componentRider.Mount != null) {
174 playerStats.DistanceRidden += x;
175 }
176 else {
177 if (m_walking) {
178 playerStats.DistanceWalked += x;
179 m_walking = false;
180 }
181 if (m_falling) {
182 playerStats.DistanceFallen += x;
183 m_falling = false;
184 }
185 if (m_climbing) {
186 playerStats.DistanceClimbed += x;
187 m_climbing = false;
188 }
189 if (m_jumping) {
190 playerStats.Jumps++;
191 m_jumping = false;
192 }
193 if (m_swimming) {
194 playerStats.DistanceSwam += x;
195 m_swimming = false;
196 }
197 if (m_flying) {
198 playerStats.DistanceFlown += x;
199 m_flying = false;
200 }
201 }
202 playerStats.DeepestDive = Math.Max(playerStats.DeepestDive, m_componentCreature.ComponentBody.ImmersionDepth);
203 playerStats.LowestAltitude = Math.Min(playerStats.LowestAltitude, position.Y);
204 playerStats.HighestAltitude = Math.Max(playerStats.HighestAltitude, position.Y);
205 playerStats.EasiestModeUsed = (GameMode)MathUtils.Min(
206 (int)m_subsystemGameInfo.WorldSettings.GameMode,
207 (int)playerStats.EasiestModeUsed
208 );
209 }
210 m_lastPosition = position;
212 int x2 = Terrain.ToCell(position.X);
213 int y = Terrain.ToCell(position.Y + 0.2f);
214 int z = Terrain.ToCell(position.Z);
215 int cellValue = m_subsystemTerrain.Terrain.GetCellValue(x2, y, z);
216 int num = Terrain.ExtractContents(cellValue);
217 Block block = BlocksManager.Blocks[num];
219 if (VrLookOrder.HasValue) {
220 LookAngles = new Vector2(LookAngles.X, VrLookOrder.Value.Y);
221 }
222 if (!m_componentCreature.ComponentBody.IsEmbeddedInIce) {
223 Quaternion rotation = m_componentCreature.ComponentBody.Rotation;
224 float num2 = MathF.Atan2(
225 2f * rotation.Y * rotation.W - 2f * rotation.X * rotation.Z,
226 1f - 2f * rotation.Y * rotation.Y - 2f * rotation.Z * rotation.Z
227 );
228 num2 += (0f - TurnSpeed) * TurnOrder.X * dt;
229 if (VrLookOrder.HasValue) {
230 num2 += VrLookOrder.Value.X;
231 }
232 m_componentCreature.ComponentBody.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, num2);
233 if (LadderSpeed > 0f
234 && !LadderValue.HasValue
235 && block is LadderBlock
238 && m_componentCreature.ComponentBody.ParentBody == null) {
239 int face = LadderBlock.GetFace(Terrain.ExtractData(cellValue));
240 if ((face == 0 && m_componentCreature.ComponentBody.CollisionVelocityChange.Z > 0f)
241 || (face == 1 && m_componentCreature.ComponentBody.CollisionVelocityChange.X > 0f)
242 || (face == 2 && m_componentCreature.ComponentBody.CollisionVelocityChange.Z < 0f)
243 || (face == 3 && m_componentCreature.ComponentBody.CollisionVelocityChange.X < 0f)
244 || !m_componentCreature.ComponentBody.StandingOnValue.HasValue) {
245 LadderValue = cellValue;
246 m_ladderActivationTime = m_subsystemTime.GameTime + 0.20000000298023224;
247 m_componentCreature.ComponentCreatureSounds.PlayFootstepSound(1f);
248 }
249 }
250 if (VrMoveOrder.HasValue) {
251 m_componentCreature.ComponentBody.ApplyDirectMove(VrMoveOrder.Value);
252 }
253 if (LadderValue.HasValue) {
254 LadderMovement(dt, cellValue);
255 }
256 else {
257 NormalMovement(dt);
258 }
259 }
260 }
261 else {
262 bool fallsOnDeathOrStun = m_componentCreature.ComponentBody.TerrainCollidable && EnableGravityOnDeathOrStun;
264 "OnLocomotionStopped",
265 loader => {
266 loader.OnLocomotionStopped(this, ref fallsOnDeathOrStun);
267 return false;
268 }
269 );
270 if (fallsOnDeathOrStun) {
271 m_componentCreature.ComponentBody.IsGravityEnabled = true;
272 m_componentCreature.ComponentBody.IsGroundDragEnabled = true;
273 m_componentCreature.ComponentBody.IsWaterDragEnabled = true;
274 }
275 }
281 WalkOrder = null;
282 FlyOrder = null;
283 SwimOrder = null;
285 JumpOrder = 0f;
286 VrMoveOrder = null;
287 VrLookOrder = null;
289 }
290
291 public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap) {
292 m_subsystemTime = Project.FindSubsystem<SubsystemTime>(true);
293 m_subsystemNoise = Project.FindSubsystem<SubsystemNoise>(true);
294 m_subsystemTerrain = Project.FindSubsystem<SubsystemTerrain>(true);
295 m_subsystemGameInfo = Project.FindSubsystem<SubsystemGameInfo>(true);
296 m_componentCreature = Entity.FindComponent<ComponentCreature>(true);
297 m_componentPlayer = Entity.FindComponent<ComponentPlayer>();
298 m_componentLevel = Entity.FindComponent<ComponentLevel>();
300 m_componentMount = Entity.FindComponent<ComponentMount>();
301 m_componentRider = Entity.FindComponent<ComponentRider>();
302 m_componentFactors = Entity.FindComponent<ComponentFactors>();
303 IsCreativeFlyEnabled = valuesDictionary.GetValue<bool>("IsCreativeFlyEnabled");
304 AccelerationFactor = valuesDictionary.GetValue<float>("AccelerationFactor");
305 WalkSpeed = valuesDictionary.GetValue<float>("WalkSpeed");
306 LadderSpeed = valuesDictionary.GetValue<float>("LadderSpeed");
307 JumpSpeed = valuesDictionary.GetValue<float>("JumpSpeed");
308 CreativeFlySpeed = valuesDictionary.GetValue<float>("CreativeFlySpeed");
309 FlySpeed = valuesDictionary.GetValue<float>("FlySpeed");
310 SwimSpeed = valuesDictionary.GetValue<float>("SwimSpeed");
311 TurnSpeed = valuesDictionary.GetValue<float>("TurnSpeed");
312 LookSpeed = valuesDictionary.GetValue<float>("LookSpeed");
313 InAirWalkFactor = valuesDictionary.GetValue<float>("InAirWalkFactor");
314 m_walkSpeedWhenTurning = valuesDictionary.GetValue<float>("WalkSpeedWhenTurning");
315 m_minFrictionFactor = valuesDictionary.GetValue<float>("MinFrictionFactor");
316 m_lookAutoLevelX = valuesDictionary.GetValue<bool>("LookAutoLevelX");
317 m_lookAutoLevelY = valuesDictionary.GetValue<bool>("LookAutoLevelY");
318 float mobWalkSpeedFactor = m_random.Float(0.85f, 1f);
319 float mobFlySpeedFactor = m_random.Float(0.85f, 1f);
320 float mobSwimSpeedFactor = m_random.Float(0.85f, 1f);
321 bool disableCreativeFlyInSurvivalMode = true;
323 "OnComponentLocomotionLoaded",
324 loader => {
325 loader.OnComponentLocomotionLoaded(
326 this,
327 ref mobWalkSpeedFactor,
328 ref mobFlySpeedFactor,
329 ref mobSwimSpeedFactor,
330 ref disableCreativeFlyInSurvivalMode
331 );
332 return false;
333 }
334 );
335 if (m_subsystemGameInfo.WorldSettings.GameMode != GameMode.Creative && disableCreativeFlyInSurvivalMode) {
336 IsCreativeFlyEnabled = false;
337 }
338 if (Entity.FindComponent<ComponentPlayer>() == null) {
339 WalkSpeed *= mobWalkSpeedFactor;
340 FlySpeed *= mobFlySpeedFactor;
341 SwimSpeed *= mobSwimSpeedFactor;
342 }
343 }
344
345 public override void Save(ValuesDictionary valuesDictionary, EntityToIdMap entityToIdMap) {
346 valuesDictionary.SetValue("IsCreativeFlyEnabled", IsCreativeFlyEnabled);
347 }
348
349 public virtual void NormalMovement(float dt) {
350 m_componentCreature.ComponentBody.IsGravityEnabled = true;
351 m_componentCreature.ComponentBody.IsGroundDragEnabled = true;
352 m_componentCreature.ComponentBody.IsWaterDragEnabled = true;
353 Vector3 velocity = m_componentCreature.ComponentBody.Velocity;
354 Vector3 right = m_componentCreature.ComponentBody.Matrix.Right;
355 Vector3 vector = Vector3.Transform(m_componentCreature.ComponentBody.Matrix.Forward, Quaternion.CreateFromAxisAngle(right, LookAngles.Y));
356 if (WalkSpeed > 0f
357 && WalkOrder.HasValue) {
359 Vector3 v = new(WalkOrder.Value.X, 0f, WalkOrder.Value.Y);
360 if (FlyOrder.HasValue) {
361 v += FlyOrder.Value;
362 }
364 || m_componentPlayer == null
365 || m_componentPlayer.ComponentInput.IsControlledByTouch
366 ? Vector3.Normalize(vector + 0.1f * Vector3.UnitY)
367 : Vector3.Normalize(vector * new Vector3(1f, 0f, 1f));
368 Vector3 v3 = CreativeFlySpeed * (right * v.X + Vector3.UnitY * v.Y + v2 * v.Z);
369 float num = v == Vector3.Zero ? 5f : 3f;
370 velocity += MathUtils.Saturate(num * dt) * (v3 - velocity);
371 m_componentCreature.ComponentBody.IsGravityEnabled = false;
372 m_componentCreature.ComponentBody.IsGroundDragEnabled = false;
373 m_flying = true;
374 }
375 else {
376 Vector2 value = WalkOrder.Value;
378 && MathF.Abs(TurnOrder.X) > 0.02f) {
379 value.Y = MathUtils.Max(value.Y, MathUtils.Lerp(0f, m_walkSpeedWhenTurning, MathUtils.Saturate(2f * MathF.Abs(TurnOrder.X))));
380 }
381 float num2 = WalkSpeed;
382 if (m_componentCreature.ComponentBody.ImmersionFactor > 0.2f) {
383 num2 *= 0.66f;
384 }
385 if (value.Y < 0f) {
386 num2 *= 0.6f;
387 }
388 if (m_componentFactors != null) {
389 num2 *= m_componentFactors.SpeedFactor;
390 }
391 if (m_componentMount != null) {
392 ComponentRider rider = m_componentMount.Rider;
393 if (rider != null) {
394 ComponentClothing componentClothing = rider.Entity.FindComponent<ComponentClothing>();
395 if (componentClothing != null) {
396 num2 *= componentClothing.SteedMovementSpeedFactor;
397 }
398 }
399 }
400 Vector3 v4 = value.X * Vector3.Normalize(new Vector3(right.X, 0f, right.Z))
401 + value.Y * Vector3.Normalize(new Vector3(vector.X, 0f, vector.Z));
402 Vector3 vector2 = num2 * v4 + m_componentCreature.ComponentBody.StandingOnVelocity;
403 float num4;
404 if (m_componentCreature.ComponentBody.StandingOnValue.HasValue) {
405 float num3 = MathUtils.Max(
408 );
409 num4 = MathUtils.Saturate(dt * 6f * AccelerationFactor * num3);
410 if (num3 < 0.25f) {
411 SlipSpeed = num2 * value.Length();
412 }
413 m_walking = true;
414 }
415 else {
417 if (m_componentCreature.ComponentBody.ImmersionFactor > 0f) {
418 m_swimming = true;
419 }
420 else {
421 m_falling = true;
422 }
423 }
424 velocity.X += num4 * (vector2.X - velocity.X);
425 velocity.Z += num4 * (vector2.Z - velocity.Z);
426 Vector3 vector3 = value.X * right + value.Y * vector;
427 if (m_componentFactors != null) {
428 vector3 *= m_componentFactors.SpeedFactor;
429 }
430 velocity.Y += 10f * AccelerationFactor * vector3.Y * m_componentCreature.ComponentBody.ImmersionFactor * dt;
431 m_componentCreature.ComponentBody.IsGroundDragEnabled = false;
432 if (m_componentPlayer != null
434 && Time.PeriodicEvent(10.0, 0.0)
436 && m_componentCreature.ComponentBody.StandingOnValue.HasValue
437 && m_componentCreature.ComponentBody.ImmersionFactor < 0.1f) {
438 bool flag = false;
439 int value2 = m_componentPlayer.ComponentClothing.GetClothes(ClothingSlot.Feet).LastOrDefault();
441 if (clothingData != null) {
442 flag = clothingData.MovementSpeedFactor > 1f;
443 }
444 if (!flag
445 && vector2.LengthSquared() / velocity.LengthSquared() > 0.99f
446 && WalkOrder.Value.LengthSquared() > 0.99f) {
447 m_componentPlayer.ComponentGui.DisplaySmallMessage(LanguageControl.Get(fName, 1), Color.White, true, true);
449 }
450 }
451 }
452 }
453 if (FlySpeed > 0f
454 && FlyOrder.HasValue) {
455 Vector3 value3 = FlyOrder.Value;
456 Vector3 v5 = FlySpeed * value3;
457 velocity += MathUtils.Saturate(2f * AccelerationFactor * dt) * (v5 - velocity);
458 m_componentCreature.ComponentBody.IsGravityEnabled = false;
459 m_flying = true;
460 }
461 if (SwimSpeed > 0f
462 && SwimOrder.HasValue
463 && m_componentCreature.ComponentBody.ImmersionFactor > 0.5f) {
464 Vector3 value4 = SwimOrder.Value;
465 Vector3 v6 = SwimSpeed * value4;
466 float num5 = 2f;
467 if (value4.LengthSquared() >= 0.99f) {
468 v6 *= MathUtils.Lerp(1f, 2f, m_swimBurstRemaining);
469 num5 *= MathUtils.Lerp(1f, 4f, m_swimBurstRemaining);
471 }
472 velocity += MathUtils.Saturate(num5 * AccelerationFactor * dt) * (v6 - velocity);
473 m_componentCreature.ComponentBody.IsGravityEnabled = MathF.Abs(value4.Y) <= 0.07f;
474 m_componentCreature.ComponentBody.IsWaterDragEnabled = false;
475 m_componentCreature.ComponentBody.IsGroundDragEnabled = false;
476 m_swimming = true;
477 }
478 if (JumpOrder > 0f
479 && (m_componentCreature.ComponentBody.StandingOnValue.HasValue || m_componentCreature.ComponentBody.ImmersionFactor > 0.5f)) {
480 m_componentCreature.ComponentBody.TargetCrouchFactor = 0f;
481 float num6 = JumpSpeed;
482 if (m_componentFactors != null) {
483 num6 *= 0.25f * (m_componentFactors.SpeedFactor - 1f) + 1f;
484 }
485 velocity.Y = MathUtils.Min(velocity.Y + MathUtils.Saturate(JumpOrder) * num6, num6);
486 m_jumping = true;
487 m_componentCreature.ComponentCreatureSounds.PlayFootstepSound(2f);
488 m_subsystemNoise.MakeNoise(m_componentCreature.ComponentBody, 0.25f, 10f);
489 }
490 if (MathF.Abs(m_componentCreature.ComponentBody.CollisionVelocityChange.Y) > 3f) {
491 m_componentCreature.ComponentCreatureSounds.PlayFootstepSound(2f);
492 m_subsystemNoise.MakeNoise(m_componentCreature.ComponentBody, 0.25f, 10f);
493 }
494 m_componentCreature.ComponentBody.Velocity = velocity;
495 }
496
497 public virtual void LadderMovement(float dt, int value) {
498 m_componentCreature.ComponentBody.IsGravityEnabled = false;
499 Vector3 position = m_componentCreature.ComponentBody.Position;
500 Vector3 velocity = m_componentCreature.ComponentBody.Velocity;
501 int num = Terrain.ExtractContents(value);
502 if (BlocksManager.Blocks[num] is LadderBlock) {
503 LadderValue = value;
504 if (WalkOrder.HasValue) {
505 Vector2 value2 = WalkOrder.Value;
506 float num2 = LadderSpeed * value2.Y;
507 velocity.X = 5f * (MathF.Floor(position.X) + 0.5f - position.X);
508 velocity.Z = 5f * (MathF.Floor(position.Z) + 0.5f - position.Z);
509 velocity.Y += MathUtils.Saturate(20f * dt) * (num2 - velocity.Y);
510 m_climbing = true;
511 }
512 if (m_componentCreature.ComponentBody.StandingOnValue.HasValue
514 LadderValue = null;
515 m_ladderActivationTime = m_subsystemTime.GameTime + 0.20000000298023224;
516 }
517 }
518 else {
519 LadderValue = null;
520 m_ladderActivationTime = m_subsystemTime.GameTime + 0.20000000298023224;
521 }
522 if (JumpOrder > 0f) {
523 m_componentCreature.ComponentCreatureSounds.PlayFootstepSound(2f);
524 velocity += JumpSpeed * m_componentCreature.ComponentBody.Matrix.Forward;
525 m_ladderActivationTime = m_subsystemTime.GameTime + 0.33000001311302185;
526 LadderValue = null;
527 m_jumping = true;
528 }
530 m_componentCreature.ComponentCreatureSounds.PlayFootstepSound(1f);
531 LadderValue = null;
532 }
533 if (m_componentCreature.ComponentBody.ParentBody != null) {
534 LadderValue = null;
535 }
536 m_componentCreature.ComponentBody.Velocity = velocity;
537 }
538 }
539}
Engine.Vector3 Vector3
static int Min(int x1, int x2)
static float Saturate(float x)
static int Max(int x1, int x2)
static float DegToRad(float degrees)
static float Lerp(float x1, float x2, float f)
static bool PeriodicEvent(double period, double offset)
定义 Time.cs:63
static double FrameStartTime
定义 Time.cs:42
float FrictionFactor
virtual ClothingData GetClothingData(int value)
static ClothingSlot Feet
virtual void NormalMovement(float dt)
virtual void LadderMovement(float dt, int value)
override void Save(ValuesDictionary valuesDictionary, EntityToIdMap entityToIdMap)
override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
static int GetFace(int data)
static string Get(string className, int key)
获取在当前语言类名键对应的字符串
static int ExtractContents(int value)
static int ToCell(float x)
static int ExtractData(int value)
ValuesDictionary ValuesDictionary
Component FindComponent(Type type, string name, bool throwOnError)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static void HookActionReverse(string HookName, Func< ModLoader, bool > action)
static Color White
static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
static readonly Vector2 Zero
static Vector3 Transform(Vector3 v, Matrix m)
static Vector3 Normalize(Vector3 v)
static float Distance(Vector3 v1, Vector3 v2)
float LengthSquared()
static readonly Vector3 UnitY