Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Characters/Health/AfflictionPsychosis.cs
3 using Microsoft.Xna.Framework;
4 using System.Collections.Generic;
5 
6 namespace Barotrauma
7 {
8  partial class AfflictionPsychosis : Affliction
9  {
10  const int MaxFakeFireSources = 10;
11  const float MinFakeFireSourceInterval = 30.0f, MaxFakeFireSourceInterval = 240.0f;
12  private float createFireSourceTimer;
13  private readonly List<DummyFireSource> fakeFireSources = new List<DummyFireSource>();
14 
15  public enum FloodType
16  {
17  None,
18  Minor,
19  Major,
20  HideFlooding
21  }
22 
23  const float MinSoundInterval = 60.0f, MaxSoundInterval = 240.0f;
24  private FloodType currentFloodType;
25  private float soundTimer;
26 
27  const float MinFloodInterval = 60.0f, MaxFloodInterval = 240.0f;
28  private float createFloodTimer;
29  private float currentFloodState;
30  private float currentFloodDuration;
31 
32  private float fakeBrokenInterval = 30.0f;
33  private float fakeBrokenTimer = 0.0f;
34 
35  private float invisibleCharacterInterval = 30.0f;
36  private float invisibleCharacterTimer = 0.0f;
37 
39  {
40  get { return currentFloodType; }
41  }
42 
43  partial void UpdateProjSpecific(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
44  {
45  if (Character.Controlled != characterHealth.Character) return;
46  UpdateFloods(deltaTime);
47  UpdateSounds(characterHealth.Character, deltaTime);
48  UpdateFires(characterHealth.Character, deltaTime);
49  UpdateInvisibleCharacters(deltaTime);
50  UpdateFakeBroken(deltaTime);
51  }
52 
53  private void UpdateSounds(Character character, float deltaTime)
54  {
55  if (soundTimer < MathHelper.Lerp(MaxSoundInterval, MinSoundInterval, Strength / 100.0f))
56  {
57  soundTimer += deltaTime;
58  return;
59  }
60 
61  float impactStrength = MathHelper.Lerp(0.1f, 1.0f, Strength / 100.0f);
62  SoundPlayer.PlayDamageSound("StructureBlunt", Rand.Range(10.0f, 1000.0f), character.WorldPosition + Rand.Vector(500.0f));
63  GameMain.GameScreen.Cam.Shake = impactStrength * 10.0f;
64  GameMain.GameScreen.Cam.AngularVelocity = Rand.Range(-impactStrength, impactStrength);
65  soundTimer = 0.0f;
66  }
67 
68  private void UpdateFloods(float deltaTime)
69  {
70  if (currentFloodDuration > 0.0f)
71  {
72  currentFloodDuration -= deltaTime;
73  switch (currentFloodType)
74  {
75  case FloodType.Minor:
76  currentFloodState += deltaTime;
77  //lerp the water surface in all hulls 15 units above the floor within 10 seconds
78  foreach (Hull hull in Hull.HullList)
79  {
80  for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
81  {
82  hull.FakeFireSources[i].Extinguish(deltaTime, 50.0f);
83  }
84  hull.DrawSurface = hull.Rect.Y - hull.Rect.Height + MathHelper.Lerp(0.0f, 15.0f, currentFloodState / 10.0f);
85  }
86  break;
87  case FloodType.Major:
88  currentFloodState += deltaTime;
89  //create a full flood in 10 seconds
90  foreach (Hull hull in Hull.HullList)
91  {
92  for (int i = hull.FakeFireSources.Count - 1; i >= 0; i--)
93  {
94  hull.FakeFireSources[i].Extinguish(deltaTime, 200.0f);
95  }
96  hull.DrawSurface = hull.Rect.Y - MathHelper.Lerp(hull.Rect.Height, 0.0f, currentFloodState / 10.0f);
97  }
98  break;
99  case FloodType.HideFlooding:
100  //hide water inside hulls (the player can't see which hulls are flooded)
101  foreach (Hull hull in Hull.HullList)
102  {
103  hull.DrawSurface = hull.Rect.Y - hull.Rect.Height;
104  }
105  break;
106  }
107  return;
108  }
109 
110  if (createFloodTimer < MathHelper.Lerp(MaxFloodInterval, MinFloodInterval, Strength / 100.0f))
111  {
112  currentFloodType = FloodType.None;
113  createFloodTimer += deltaTime;
114  return;
115  }
116 
117  //probability of a fake flood goes from 0%-100%
118  if (Rand.Range(0.0f, 100.0f) < Strength)
119  {
120  if (Rand.Range(0.0f, 1.0f) < 0.5f)
121  {
122  currentFloodType = FloodType.HideFlooding;
123  currentFloodType = FloodType.Minor;
124  }
125  else
126  {
127  //disabled Major flooding because it's too easy to tell it's fake
128  currentFloodType = FloodType.Minor;// Strength < 50.0f ? FloodType.Minor : FloodType.Major;
129  }
130  currentFloodDuration = Rand.Range(20.0f, 100.0f);
131  }
132  createFloodTimer = 0.0f;
133  }
134 
135  private void UpdateFires(Character character, float deltaTime)
136  {
137  createFireSourceTimer += deltaTime;
138  fakeFireSources.RemoveAll(fs => fs.Removed);
139  if (fakeFireSources.Count < MaxFakeFireSources &&
140  character.Submarine != null &&
141  createFireSourceTimer > MathHelper.Lerp(MaxFakeFireSourceInterval, MinFakeFireSourceInterval, Strength / 100.0f))
142  {
143  Hull fireHull = Hull.HullList.GetRandomUnsynced(h => h.Submarine == character.Submarine);
144  if (fireHull != null)
145  {
146  var fakeFire = new DummyFireSource(Vector2.One * 500.0f, new Vector2(Rand.Range(fireHull.WorldRect.X, fireHull.WorldRect.Right), fireHull.WorldPosition.Y + 1), fireHull, isNetworkMessage: true)
147  {
148  CausedByPsychosis = true,
149  DamagesItems = false,
150  DamagesCharacters = false
151  };
152  fakeFireSources.Add(fakeFire);
153  createFireSourceTimer = 0.0f;
154  }
155  }
156  }
157 
158  private void UpdateInvisibleCharacters(float deltaTime)
159  {
160  invisibleCharacterTimer -= deltaTime;
161  if (invisibleCharacterTimer > 0.0f) { return; }
162 
163  foreach (Character c in Character.CharacterList)
164  {
165  if (c.IsDead || c == Character.Controlled) { continue; }
166  if (c.WorldPosition.X < GameMain.GameScreen.Cam.WorldView.X || c.WorldPosition.X > GameMain.GameScreen.Cam.WorldView.Right) { continue; }
167  if (c.WorldPosition.Y < GameMain.GameScreen.Cam.WorldView.Y - GameMain.GameScreen.Cam.WorldView.Height || c.WorldPosition.Y > GameMain.GameScreen.Cam.WorldView.Y) { continue; }
168  if (Rand.Range(0.0f, 500.0f) < Strength)
169  {
170  c.InvisibleTimer = 60.0f;
171  }
172  }
173 
174  invisibleCharacterTimer = invisibleCharacterInterval;
175  }
176 
177 
178  private void UpdateFakeBroken(float deltaTime)
179  {
180  fakeBrokenTimer -= deltaTime;
181  if (fakeBrokenTimer > 0.0f) { return; }
182 
183  foreach (Item item in Item.ItemList)
184  {
185  var repairable = item.GetComponent<Repairable>();
186  if (repairable == null) { continue; }
187  if (ShouldFakeBrokenItem(item))
188  {
189  repairable.FakeBrokenTimer = 60.0f;
190  }
191  }
192 
193  fakeBrokenTimer = fakeBrokenInterval;
194  }
195 
196  private bool ShouldFakeBrokenItem(Item item)
197  {
198  return Rand.Range(0.0f, 1000.0f) < Strength;
199  }
200  }
201 }
virtual float Strength
Definition: Affliction.cs:31