Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
ComponentEatPickableBehavior.cs
浏览该文件的文档.
1using Engine;
4
5namespace Game {
8
10
12
14
16
17 public Dictionary<Pickable, bool> m_pickables = [];
18
19 public Random m_random = new();
20
21 public float[] m_foodFactors;
22
23 public float m_importanceLevel;
24
26
28
30
31 public double m_eatTime;
32
33 public float m_satiation;
34
35 public float m_blockedTime;
36
37 public int m_blockedCount;
38
39 public const float m_range = 16f;
40
41 public float Satiation => m_satiation;
42
44
45 public override float ImportanceLevel => m_importanceLevel;
46
47 public virtual void Update(float dt) {
48 if (m_satiation > 0f) {
49 m_satiation = MathUtils.Max(m_satiation - 0.01f * m_subsystemTime.GameTimeDelta, 0f);
50 }
51 m_stateMachine.Update();
52 }
53
54 public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap) {
55 m_subsystemTime = Project.FindSubsystem<SubsystemTime>(true);
56 m_subsystemPickables = Project.FindSubsystem<SubsystemPickables>(true);
57 m_componentCreature = Entity.FindComponent<ComponentCreature>(true);
59 m_foodFactors = new float[EnumUtils.GetEnumValues<FoodType>().Max() + 1];
60 foreach (KeyValuePair<string, object> item in valuesDictionary.GetValue<ValuesDictionary>("FoodFactors")) {
61 FoodType foodType = (FoodType)Enum.Parse(typeof(FoodType), item.Key, false);
62 m_foodFactors[(int)foodType] = (float)item.Value;
63 }
64 m_subsystemPickables.PickableAdded += pickable => {
65 if (TryAddPickable(pickable)
66 && m_pickable == null) {
67 m_pickable = pickable;
68 }
69 };
70 m_subsystemPickables.PickableRemoved += pickable => {
71 m_pickables.Remove(pickable);
72 if (m_pickable == pickable) {
73 m_pickable = null;
74 }
75 };
76 m_stateMachine.AddState(
77 "Inactive",
78 delegate {
80 m_pickable = null;
81 },
82 delegate {
83 if (m_satiation < 1f) {
84 if (m_pickable == null) {
86 m_nextFindPickableTime = m_subsystemTime.GameTime + m_random.Float(2f, 4f);
87 m_pickable = FindPickable(m_componentCreature.ComponentBody.Position);
88 }
89 }
90 else {
91 m_importanceLevel = m_random.Float(5f, 10f);
92 }
93 }
94 if (IsActive) {
95 m_stateMachine.TransitionTo("Move");
97 }
98 },
99 null
100 );
101 m_stateMachine.AddState(
102 "Move",
103 delegate {
104 if (m_pickable != null) {
105 float speed = m_satiation == 0f ? m_random.Float(0.5f, 0.7f) : 0.5f;
106 int maxPathfindingPositions = m_satiation == 0f ? 1000 : 500;
107 float num2 = Vector3.Distance(
108 m_componentCreature.ComponentCreatureModel.EyePosition,
109 m_componentCreature.ComponentBody.Position
110 );
111 m_componentPathfinding.SetDestination(
112 m_pickable.Position,
113 speed,
114 1f + num2,
115 maxPathfindingPositions,
116 true,
117 false,
118 true,
119 null
120 );
121 if (m_random.Float(0f, 1f) < 0.66f) {
122 m_componentCreature.ComponentCreatureSounds.PlayIdleSound(true);
123 }
124 }
125 },
126 delegate {
127 if (!IsActive) {
128 m_stateMachine.TransitionTo("Inactive");
129 }
130 else if (m_pickable == null) {
132 }
133 else if (m_componentPathfinding.IsStuck) {
135 m_satiation += 0.75f;
136 }
137 else if (!m_componentPathfinding.Destination.HasValue) {
138 m_stateMachine.TransitionTo("Eat");
139 }
140 else if (Vector3.DistanceSquared(m_componentPathfinding.Destination.Value, m_pickable.Position) > 0.0625f) {
141 m_stateMachine.TransitionTo("PickableMoved");
142 }
143 if (m_random.Float(0f, 1f) < 0.1f * m_subsystemTime.GameTimeDelta) {
144 m_componentCreature.ComponentCreatureSounds.PlayIdleSound(true);
145 }
146 if (m_pickable != null) {
147 m_componentCreature.ComponentCreatureModel.LookAtOrder = m_pickable.Position;
148 }
149 else {
150 m_componentCreature.ComponentCreatureModel.LookRandomOrder = true;
151 }
152 },
153 null
154 );
155 m_stateMachine.AddState(
156 "PickableMoved",
157 null,
158 delegate {
159 if (m_pickable != null) {
160 m_componentCreature.ComponentCreatureModel.LookAtOrder = m_pickable.Position;
161 }
162 if (m_subsystemTime.PeriodicGameTimeEvent(0.25, GetHashCode() % 100 * 0.01)) {
163 m_stateMachine.TransitionTo("Move");
164 }
165 },
166 null
167 );
168 m_stateMachine.AddState(
169 "Eat",
170 delegate {
171 m_eatTime = m_random.Float(4f, 5f);
172 m_blockedTime = 0f;
173 },
174 delegate {
175 if (!IsActive) {
176 m_stateMachine.TransitionTo("Inactive");
177 }
178 if (m_pickable == null) {
180 }
181 if (m_pickable != null) {
183 new Vector3(
184 m_componentCreature.ComponentCreatureModel.EyePosition.X,
185 m_componentCreature.ComponentBody.Position.Y,
186 m_componentCreature.ComponentCreatureModel.EyePosition.Z
187 ),
188 m_pickable.Position
189 )
190 < 0.640000045f) {
191 m_eatTime -= m_subsystemTime.GameTimeDelta;
192 m_blockedTime = 0f;
193 if (m_eatTime <= 0.0) {
194 m_satiation += 1f;
195 m_pickable.Count = MathUtils.Max(m_pickable.Count - 1, 0);
196 if (m_pickable.Count == 0) {
197 m_pickable.ToRemove = true;
199 }
200 else if (m_random.Float(0f, 1f) < 0.5f) {
202 }
204 "OnEatPickable",
205 modLoader => {
206 modLoader.OnEatPickable(this, m_pickable, out bool Dealed);
207 return Dealed;
208 }
209 );
210 }
211 }
212 else {
213 float num = Vector3.Distance(
214 m_componentCreature.ComponentCreatureModel.EyePosition,
215 m_componentCreature.ComponentBody.Position
216 );
217 m_componentPathfinding.SetDestination(
218 m_pickable.Position,
219 0.3f,
220 0.5f + num,
221 0,
222 false,
223 true,
224 false,
225 null
226 );
227 m_blockedTime += m_subsystemTime.GameTimeDelta;
228 }
229 if (m_blockedTime > 3f) {
231 if (m_blockedCount >= 3) {
233 m_satiation += 0.75f;
234 }
235 else {
236 m_stateMachine.TransitionTo("Move");
237 }
238 }
239 }
240 m_componentCreature.ComponentCreatureModel.FeedOrder = true;
241 if (m_random.Float(0f, 1f) < 0.1f * m_subsystemTime.GameTimeDelta) {
242 m_componentCreature.ComponentCreatureSounds.PlayIdleSound(true);
243 }
244 if (m_random.Float(0f, 1f) < 1.5f * m_subsystemTime.GameTimeDelta) {
245 m_componentCreature.ComponentCreatureSounds.PlayFootstepSound(2f);
246 }
247 },
248 null
249 );
250 m_stateMachine.TransitionTo("Inactive");
251 }
252
253 public virtual float GetFoodFactor(FoodType foodType) => m_foodFactors[(int)foodType];
254
255 public virtual Pickable FindPickable(Vector3 position) {
257 m_nextPickablesUpdateTime = m_subsystemTime.GameTime + m_random.Float(2f, 4f);
258 m_pickables.Clear();
259 foreach (Pickable pickable in m_subsystemPickables.Pickables) {
260 TryAddPickable(pickable);
261 }
262 if (m_pickable != null
263 && !m_pickables.ContainsKey(m_pickable)) {
264 m_pickable = null;
265 }
266 }
267 foreach (Pickable key in m_pickables.Keys) {
268 float num = Vector3.DistanceSquared(position, key.Position);
269 if (m_random.Float(0f, 1f) > num / 256f) {
270 return key;
271 }
272 }
273 return null;
274 }
275
276 public virtual bool TryAddPickable(Pickable pickable) {
278 if (m_foodFactors[(int)block.GetFoodType(pickable.Value)] > 0f
279 && Vector3.DistanceSquared(pickable.Position, m_componentCreature.ComponentBody.Position) < 256f) {
280 m_pickables.Add(pickable, true);
281 return true;
282 }
283 return false;
284 }
285 }
286}
static int Max(int x1, int x2)
virtual FoodType GetFoodType(int value)
override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
virtual Pickable FindPickable(Vector3 position)
static IList< int > GetEnumValues(Type type)
static int ExtractContents(int value)
ValuesDictionary ValuesDictionary
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static float DistanceSquared(Vector3 v1, Vector3 v2)
static float Distance(Vector3 v1, Vector3 v2)