Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
ComponentSleep.cs
浏览该文件的文档.
1using Engine;
4
5namespace Game {
7 public Dictionary<string, Func<string>> m_conditionsToSleep = [];
8
10
12
14
16
18
20
22
24
25 public double? m_sleepStartTime;
26
27 public float m_sleepFactor;
28
30 public static string fName = "ComponentSleep";
31 public float m_minWetness;
32
33 public float m_messageFactor;
34
35 public bool IsSleeping => m_sleepStartTime.HasValue;
36
37 public float SleepFactor => m_sleepFactor;
38
40
41 public double m_minAutoSleepTime = 180;
42 public bool m_wakeUpWhenWet = true;
43 public bool m_wakeUpWhenInjured = true;
44 public bool m_wakeUpWhenAttacked = true;
45 public float MaxSleepBlackoutFactor = 1f;
46
54 public bool CanSleep(out string reason) {
55 foreach (string condition in m_conditionsToSleep.Keys) {
56 string reasonUnableToSleep = m_conditionsToSleep[condition]();
57 if (!string.IsNullOrEmpty(reasonUnableToSleep)) {
58 reason = reasonUnableToSleep;
59 return false;
60 }
61 }
62 reason = string.Empty;
63 return true;
64 }
65
66 public virtual void Sleep(bool allowManualWakeup) {
67 if (!IsSleeping) {
68 m_sleepStartTime = m_subsystemGameInfo.TotalElapsedGameTime;
69 m_allowManualWakeUp = allowManualWakeup;
70 m_minWetness = float.MaxValue;
71 m_messageFactor = 0f;
72 if (m_componentPlayer.PlayerStats != null) {
73 m_componentPlayer.PlayerStats.TimesWentToSleep++;
74 }
75 }
76 }
77
78 public virtual void WakeUp() {
79 if (m_sleepStartTime.HasValue) {
80 m_sleepStartTime = null;
81 m_componentPlayer.PlayerData.SpawnPosition = m_componentPlayer.ComponentBody.Position + new Vector3(0f, 0.1f, 0f);
82 }
83 }
84
85 public virtual void Update(float dt) {
86 if (IsSleeping && m_componentPlayer.ComponentHealth.Health > 0f) {
88 m_minWetness = MathUtils.Min(m_minWetness, m_componentPlayer.ComponentVitalStats.Wetness);
89 m_componentPlayer.PlayerStats.TimeSlept += m_subsystemGameInfo.TotalElapsedGameTimeDelta;
90 if ((m_componentPlayer.ComponentVitalStats.Sleep >= 1f || m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Creative)
92 m_subsystemTimeOfDay.TimeOfDay,
93 m_subsystemTimeOfDay.DayStart,
94 IntervalUtils.Add(m_subsystemTimeOfDay.DuskStart, -0.1f)
95 )
96 && m_sleepStartTime.HasValue
97 && m_subsystemGameInfo.TotalElapsedGameTime > m_sleepStartTime + m_minAutoSleepTime) {
98 WakeUp();
99 }
101 && m_componentPlayer.ComponentHealth.HealthChange < 0f
102 && (m_componentPlayer.ComponentHealth.Health < 0.5f || m_componentPlayer.ComponentVitalStats.Sleep > 0.5f)) {
103 WakeUp();
104 }
106 && m_componentPlayer.ComponentVitalStats.Wetness > m_minWetness + 0.05f
107 && m_componentPlayer.ComponentVitalStats.Sleep > 0.2f) {
108 WakeUp();
109 m_subsystemTime.QueueGameTimeDelayedExecution(
110 m_subsystemTime.GameTime + 1.0,
111 delegate { m_componentPlayer.ComponentGui.DisplaySmallMessage(LanguageControl.Get(fName, 6), Color.White, true, true); }
112 );
113 }
114 if (m_sleepStartTime.HasValue) {
115 float num = (float)(m_subsystemGameInfo.TotalElapsedGameTime - m_sleepStartTime.Value);
116 if (m_allowManualWakeUp && num > 10f) {
117 if (m_componentPlayer.GameWidget.Input.Any
119 m_componentPlayer.GameWidget.Input.Clear();
120 WakeUp();
121 m_subsystemTime.QueueGameTimeDelayedExecution(
122 m_subsystemTime.GameTime + 2.0,
123 delegate {
124 m_componentPlayer.ComponentGui.DisplaySmallMessage(LanguageControl.Get(fName, 7), Color.White, true, false);
125 }
126 );
127 }
129 m_componentPlayer.ComponentScreenOverlays.Message = LanguageControl.Get(fName, 8);
130 m_componentPlayer.ComponentScreenOverlays.MessageFactor = m_messageFactor;
131 }
133 && num > 5f) {
135 m_componentPlayer.ComponentScreenOverlays.Message = LanguageControl.Get(fName, 9);
136 m_componentPlayer.ComponentScreenOverlays.MessageFactor = m_messageFactor;
137 }
138 }
139 }
140 else {
142 }
143 float sleepBlackoutFactor = MathUtils.Min(m_sleepFactor, MaxSleepBlackoutFactor);
144 m_componentPlayer.ComponentScreenOverlays.BlackoutFactor = MathUtils.Max(
145 m_componentPlayer.ComponentScreenOverlays.BlackoutFactor,
146 sleepBlackoutFactor
147 );
148 if (m_sleepFactor > 0.01f) {
149 m_componentPlayer.ComponentScreenOverlays.FloatingMessage = LanguageControl.Get(fName, 10);
150 m_componentPlayer.ComponentScreenOverlays.FloatingMessageFactor = MathUtils.Saturate(10f * (m_sleepFactor - 0.9f));
151 }
152 }
153
154 public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap) {
155 m_subsystemPlayers = Project.FindSubsystem<SubsystemPlayers>(true);
156 m_subsystemSky = Project.FindSubsystem<SubsystemSky>(true);
157 m_subsystemTime = Project.FindSubsystem<SubsystemTime>(true);
158 m_subsystemUpdate = Project.FindSubsystem<SubsystemUpdate>(true);
159 m_subsystemGameInfo = Project.FindSubsystem<SubsystemGameInfo>(true);
160 m_subsystemTimeOfDay = Project.FindSubsystem<SubsystemTimeOfDay>(true);
161 m_subsystemTerrain = Project.FindSubsystem<SubsystemTerrain>(true);
162 m_componentPlayer = Entity.FindComponent<ComponentPlayer>(true);
163 m_sleepStartTime = valuesDictionary.GetValue<double>("SleepStartTime");
164 m_allowManualWakeUp = valuesDictionary.GetValue<bool>("AllowManualWakeUp");
165 m_componentPlayer.ComponentBody.Attacked += delegate {
167 && IsSleeping
168 && m_componentPlayer.ComponentVitalStats.Sleep > 0.25f) {
169 WakeUp();
170 }
171 };
172 if (m_sleepStartTime == 0.0) {
173 m_sleepStartTime = null;
174 }
175 if (m_sleepStartTime.HasValue) {
176 m_sleepFactor = 1f;
177 m_minWetness = float.MaxValue;
178 }
180 "OnDryLand",
181 delegate {
182 Block block = m_componentPlayer.ComponentBody.StandingOnValue.HasValue
183 ? BlocksManager.Blocks[Terrain.ExtractContents(m_componentPlayer.ComponentBody.StandingOnValue.Value)]
184 : null;
185 if (block == null
186 || m_componentPlayer.ComponentBody.ImmersionDepth > 0f) {
187 return LanguageControl.Get(fName, 1);
188 }
189 return string.Empty;
190 }
191 );
193 "BlockIsComfortable",
194 delegate {
195 Block block = m_componentPlayer.ComponentBody.StandingOnValue.HasValue
196 ? BlocksManager.Blocks[Terrain.ExtractContents(m_componentPlayer.ComponentBody.StandingOnValue.Value)]
197 : null;
198 if (block != null
199 && block.SleepSuitability == 0f) {
200 return LanguageControl.Get(fName, 2);
201 }
202 return string.Empty;
203 }
204 );
206 "TiredEnough",
207 delegate {
208 if (m_componentPlayer.ComponentVitalStats.Sleep > 0.99f) {
209 return LanguageControl.Get(fName, 3);
210 }
211 return string.Empty;
212 }
213 );
215 "NotTooWet",
216 delegate {
217 if (m_componentPlayer.ComponentVitalStats.Wetness > 0.95f) {
218 return LanguageControl.Get(fName, 4);
219 }
220 return string.Empty;
221 }
222 );
224 "Ceiling",
225 delegate {
226 for (int i = -1; i <= 1; i++) {
227 for (int j = -1; j <= 1; j++) {
228 Vector3 start = m_componentPlayer.ComponentBody.Position + new Vector3(i, 1f, j);
229 Vector3 end = new(start.X, 255f, start.Z);
230 if (!m_subsystemTerrain.Raycast(start, end, false, true, (value, _) => Terrain.ExtractContents(value) != 0).HasValue) {
231 return LanguageControl.Get(fName, 5);
232 }
233 }
234 }
235 return string.Empty;
236 }
237 );
238 }
239
240 public override void Save(ValuesDictionary valuesDictionary, EntityToIdMap entityToIdMap) {
241 valuesDictionary.SetValue("SleepStartTime", m_sleepStartTime ?? 0.0);
242 valuesDictionary.SetValue("AllowManualWakeUp", m_allowManualWakeUp);
243 }
244 }
245}
Engine.Vector3 Vector3
static int Min(int x1, int x2)
static float Saturate(float x)
static int Max(int x1, int x2)
static float FrameDuration
定义 Time.cs:46
float SleepSuitability
Dictionary< string, Func< string > > m_conditionsToSleep
SubsystemGameInfo m_subsystemGameInfo
SubsystemPlayers m_subsystemPlayers
SubsystemUpdate m_subsystemUpdate
override void Save(ValuesDictionary valuesDictionary, EntityToIdMap entityToIdMap)
SubsystemTerrain m_subsystemTerrain
SubsystemTimeOfDay m_subsystemTimeOfDay
override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
virtual void Sleep(bool allowManualWakeup)
virtual void Update(float dt)
ComponentPlayer m_componentPlayer
bool CanSleep(out string reason)
为了模组间兼容性,该方法不再建议覆盖。 控制睡觉需要的条件,需要通过控制m_conditionsToSleep更改,具体查看Load()中的添加。 模组作者可以在自己的Component中添加对应的m_...
static bool HasDialogs(Widget parentWidget)
static bool IsBetween(float t, float t1, float t2)
static float Add(float t, float interval)
static string Get(string className, int key)
获取在当前语言类名键对应的字符串
static int ExtractContents(int value)
ValuesDictionary ValuesDictionary