Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
ComponentFlyAwayBehavior.cs
浏览该文件的文档.
1using Engine;
4
5namespace Game {
8
10
12
14
16
18
20
21 public DynamicArray<ComponentBody> m_componentBodies = [];
22
23 public Random m_random = new();
24
26
27 public float m_importanceLevel;
28
29 public double m_nextUpdateTime;
30 public float LowHealthToEscape { get; set; }
31
35 public bool AffectedByNoise;
36
40 public bool FanSound;
41
43
44 public override float ImportanceLevel => m_importanceLevel;
45
46 public override bool IsActive {
47 set {
48 base.IsActive = value;
49 if (IsActive) {
50 m_nextUpdateTime = 0.0;
51 }
52 }
53 }
54
55 public virtual void Update(float dt) {
56 if (m_componentCreature.ComponentHealth.HealthChange < 0f) {
57 m_stateMachine.TransitionTo("DangerDetected");
58 }
59 if (m_subsystemTime.GameTime >= m_nextUpdateTime) {
60 m_nextUpdateTime = m_subsystemTime.GameTime + m_random.Float(0.5f, 1f);
61 m_stateMachine.Update();
62 }
63 }
64
65 public virtual void HearNoise(ComponentBody sourceBody, Vector3 sourcePosition, float loudness) {
66 if (loudness >= 0.25f
67 && m_stateMachine.CurrentState != "RunningAway"
68 && AffectedByNoise) {
69 m_stateMachine.TransitionTo("DangerDetected");
70 }
71 }
72
73 public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap) {
74 m_subsystemBodies = Project.FindSubsystem<SubsystemBodies>(true);
75 m_subsystemTerrain = Project.FindSubsystem<SubsystemTerrain>(true);
76 m_subsystemAudio = Project.FindSubsystem<SubsystemAudio>(true);
77 m_subsystemTime = Project.FindSubsystem<SubsystemTime>(true);
78 m_subsystemNoise = Project.FindSubsystem<SubsystemNoise>(true);
79 m_componentCreature = Entity.FindComponent<ComponentCreature>(true);
81 LowHealthToEscape = valuesDictionary.GetValue("LowHealthToEscape", 0.33f);
82 AffectedByNoise = valuesDictionary.GetValue("AffectedByNoise", true);
83 FanSound = valuesDictionary.GetValue("FanSound", true);
84 m_componentCreature.ComponentBody.CollidedWithBody += delegate {
85 if (m_stateMachine.CurrentState != "RunningAway") {
86 m_stateMachine.TransitionTo("DangerDetected");
87 }
88 };
89 m_stateMachine.AddState(
90 "LookingForDanger",
91 null,
92 delegate {
93 if (ScanForDanger()) {
94 m_stateMachine.TransitionTo("DangerDetected");
95 }
96 },
97 null
98 );
99 m_stateMachine.AddState(
100 "DangerDetected",
101 delegate {
102 m_importanceLevel = m_componentCreature.ComponentHealth.Health < LowHealthToEscape ? 300 : 100;
103 m_nextUpdateTime = 0.0;
104 },
105 delegate {
106 if (IsActive) {
107 m_stateMachine.TransitionTo("RunningAway");
108 m_nextUpdateTime = 0.0;
109 }
110 },
111 null
112 );
113 m_stateMachine.AddState(
114 "RunningAway",
115 delegate {
116 m_componentPathfinding.SetDestination(
118 1f,
119 1f,
120 0,
121 false,
122 true,
123 false,
124 null
125 );
126 if (FanSound) {
127 m_subsystemAudio.PlayRandomSound(
128 "Audio/Creatures/Wings",
129 0.8f,
130 m_random.Float(-0.1f, 0.2f),
131 m_componentCreature.ComponentBody.Position,
132 3f,
133 true
134 );
135 }
136 m_componentCreature.ComponentCreatureSounds.PlayPainSound();
137 m_subsystemNoise.MakeNoise(m_componentCreature.ComponentBody, 0.25f, 6f);
138 },
139 delegate {
140 if (!IsActive
141 || !m_componentPathfinding.Destination.HasValue
142 || m_componentPathfinding.IsStuck) {
143 m_stateMachine.TransitionTo("LookingForDanger");
144 }
145 else if (ScoreSafePlace(m_componentCreature.ComponentBody.Position, m_componentPathfinding.Destination.Value, null) < 4f) {
146 m_componentPathfinding.SetDestination(
148 1f,
149 0.5f,
150 0,
151 false,
152 true,
153 false,
154 null
155 );
156 }
157 },
158 delegate { m_importanceLevel = 0f; }
159 );
160 m_stateMachine.TransitionTo("LookingForDanger");
161 }
162
163 public virtual bool ScanForDanger() {
164 Matrix matrix = m_componentCreature.ComponentBody.Matrix;
165 Vector3 translation = matrix.Translation;
166 Vector3 forward = matrix.Forward;
167 if (ScoreSafePlace(translation, translation, forward) < 7f) {
168 return true;
169 }
170 return false;
171 }
172
173 public virtual Vector3 FindSafePlace() {
174 Vector3 position = m_componentCreature.ComponentBody.Position;
175 float num = float.NegativeInfinity;
176 Vector3 result = position;
177 for (int i = 0; i < 20; i++) {
178 int num2 = Terrain.ToCell(position.X + m_random.Float(-20f, 20f));
179 int num3 = Terrain.ToCell(position.Z + m_random.Float(-20f, 20f));
180 for (int num4 = 255; num4 >= 0; num4--) {
181 int cellValue = m_subsystemTerrain.Terrain.GetCellValue(num2, num4, num3);
182 if (BlocksManager.Blocks[Terrain.ExtractContents(cellValue)].IsCollidable_(cellValue)
183 || Terrain.ExtractContents(cellValue) == 18) {
184 Vector3 vector = new(num2 + 0.5f, num4 + 1.1f, num3 + 0.5f);
185 float num5 = ScoreSafePlace(position, vector, null);
186 if (num5 > num) {
187 num = num5;
188 result = vector;
189 }
190 break;
191 }
192 }
193 }
194 return result;
195 }
196
197 public virtual float ScoreSafePlace(Vector3 currentPosition, Vector3 safePosition, Vector3? lookDirection) {
198 float num = 16f;
199 Vector3 position = m_componentCreature.ComponentBody.Position;
200 m_componentBodies.Clear();
201 m_subsystemBodies.FindBodiesAroundPoint(new Vector2(position.X, position.Z), 16f, m_componentBodies);
202 for (int i = 0; i < m_componentBodies.Count; i++) {
203 ComponentBody componentBody = m_componentBodies.Array[i];
204 if (!IsPredator(componentBody.Entity)) {
205 continue;
206 }
207 Vector3 position2 = componentBody.Position;
208 Vector3 v = safePosition - position2;
209 if (!lookDirection.HasValue
210 || 0f - Vector3.Dot(lookDirection.Value, v) > 0f) {
211 if (v.Y >= 4f) {
212 v *= 2f;
213 }
214 num = MathUtils.Min(num, v.Length());
215 }
216 }
217 float num2 = Vector3.Distance(currentPosition, safePosition);
218 if (num2 < 8f) {
219 return num * 0.5f;
220 }
221 return num * MathUtils.Lerp(1f, 0.75f, MathUtils.Saturate(num2 / 20f));
222 }
223
224 public virtual bool IsPredator(Entity entity) {
225 if (entity != Entity) {
226 bool isPredator = false;
227 bool skipVanilla = false;
229 "IsPredator",
230 modLoader => {
231 modLoader.IsPredator(this, entity, out isPredator, out skipVanilla);
232 return false;
233 }
234 );
235 if (skipVanilla) {
236 return isPredator;
237 }
238 ComponentCreature componentCreature = entity.FindComponent<ComponentCreature>();
239 if (componentCreature != null
240 && (componentCreature.Category == CreatureCategory.LandPredator
241 || componentCreature.Category == CreatureCategory.WaterPredator
242 || componentCreature.Category == CreatureCategory.LandOther)) {
243 return true;
244 }
245 }
246 return false;
247 }
248 }
249}
static int Min(int x1, int x2)
static float Saturate(float x)
static float Lerp(float x1, float x2, float f)
virtual bool IsCollidable_(int value)
DynamicArray< ComponentBody > m_componentBodies
bool AffectedByNoise
‹‘Î…˘”∞œÏ
virtual void HearNoise(ComponentBody sourceBody, Vector3 sourcePosition, float loudness)
override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
bool FanSound
≥·∞Ú…»∂Ø…˘“Ù
virtual float ScoreSafePlace(Vector3 currentPosition, Vector3 safePosition, Vector3? lookDirection)
static int ExtractContents(int value)
static int ToCell(float x)
ValuesDictionary ValuesDictionary
Component FindComponent(Type type, string name, bool throwOnError)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
Vector3 Translation
Vector3 Forward
static float Distance(Vector3 v1, Vector3 v2)
static float Dot(Vector3 v1, Vector3 v2)