- StartCoroutine returns a handle which can be used to stop a coroutine, and coroutines and be given a name to make accessing them easier

- StatusEffect coroutines are stopped when the round ends
- Fixed GameServer keeping a reference to the TraitorManager after a round ends (causing traitor messages to appear even if traitors aren't on anymore)
- Option to spawn characters near/inside/outside the sub using the spawn command
This commit is contained in:
Regalis
2016-04-06 18:36:26 +03:00
parent 39c9c78266
commit c7545d5816
6 changed files with 114 additions and 43 deletions
+8 -3
View File
@@ -246,13 +246,13 @@ namespace Barotrauma
{ {
ObjectProperty property; ObjectProperty property;
//if (targetNames!=null && !targetNames.Contains(target.Name)) continue;
if (!target.ObjectProperties.TryGetValue(propertyNames[i], out property)) continue; if (!target.ObjectProperties.TryGetValue(propertyNames[i], out property)) continue;
if (duration > 0.0f) if (duration > 0.0f)
{ {
CoroutineManager.StartCoroutine(ApplyToPropertyOverDuration(duration, property, propertyEffects[i])); CoroutineManager.StartCoroutine(
ApplyToPropertyOverDuration(duration, property, propertyEffects[i]), "statuseffect");
} }
else else
{ {
@@ -319,5 +319,10 @@ namespace Barotrauma
DelayedEffect.List[i].Update(deltaTime); DelayedEffect.List[i].Update(deltaTime);
} }
} }
public static void StopAll()
{
CoroutineManager.StopCoroutines("statuseffect");
}
} }
} }
+45 -28
View File
@@ -9,34 +9,52 @@ namespace Barotrauma
Running, Success, Failure Running, Success, Failure
} }
class CoroutineHandle
{
public readonly IEnumerator<object> Coroutine;
public readonly string Name;
public CoroutineHandle(IEnumerator<object> coroutine, string name = "")
{
Coroutine = coroutine;
Name = string.IsNullOrWhiteSpace(name) ? coroutine.ToString() : name;
}
}
// Keeps track of all running coroutines, and runs them till the end. // Keeps track of all running coroutines, and runs them till the end.
static class CoroutineManager static class CoroutineManager
{ {
static readonly List<IEnumerator<object>> Coroutines = new List<IEnumerator<object>>(); static readonly List<CoroutineHandle> Coroutines = new List<CoroutineHandle>();
public static float UnscaledDeltaTime, DeltaTime; public static float UnscaledDeltaTime, DeltaTime;
// Starting a coroutine just means adding an enumerator to the list. public static CoroutineHandle StartCoroutine(IEnumerable<object> func, string name = "")
// You might also want to be able to stop coroutines or delete them,
// which might mean putting them into a dictionary
public static void StartCoroutine(IEnumerable<object> func)
{ {
Coroutines.Add(func.GetEnumerator()); var handle = new CoroutineHandle(func.GetEnumerator(), name);
Coroutines.Add(handle);
return handle;
} }
public static bool IsCoroutineRunning(string name) public static bool IsCoroutineRunning(string name)
{ {
IEnumerator<object> coroutine = Coroutines.FirstOrDefault( return Coroutines.Any(c => c.Name == name);
c => c.ToString().Contains(name));
return coroutine!=null;
} }
public static void StopCoroutine(string name) public static bool IsCoroutineRunning(CoroutineHandle handle)
{ {
IEnumerator<object> coroutine = Coroutines.FirstOrDefault(c => c.ToString().Contains(name)); return Coroutines.Contains(handle);
}
if (coroutine != null) Coroutines.Remove(coroutine); public static void StopCoroutines(string name)
{
Coroutines.RemoveAll(c => c.Name == name);
}
public static void StopCoroutines(CoroutineHandle handle)
{
Coroutines.RemoveAll(c => c == handle);
} }
// Updating just means stepping through all the coroutines // Updating just means stepping through all the coroutines
@@ -47,16 +65,16 @@ namespace Barotrauma
for (int i = Coroutines.Count-1; i>=0; i--) for (int i = Coroutines.Count-1; i>=0; i--)
{ {
if (Coroutines[i].Current != null) if (Coroutines[i].Coroutine.Current != null)
{ {
WaitForSeconds wfs = Coroutines[i].Current as WaitForSeconds; WaitForSeconds wfs = Coroutines[i].Coroutine.Current as WaitForSeconds;
if (wfs != null) if (wfs != null)
{ {
if (!wfs.CheckFinished(unscaledDeltaTime)) continue; if (!wfs.CheckFinished(unscaledDeltaTime)) continue;
} }
else else
{ {
switch ((CoroutineStatus)Coroutines[i].Current) switch ((CoroutineStatus)Coroutines[i].Coroutine.Current)
{ {
case CoroutineStatus.Success: case CoroutineStatus.Success:
Coroutines.RemoveAt(i); Coroutines.RemoveAt(i);
@@ -68,18 +86,18 @@ namespace Barotrauma
} }
} }
try //try
{ //{
Coroutines[i].MoveNext(); Coroutines[i].Coroutine.MoveNext();
} // }
catch (Exception e) // catch (Exception e)
{ // {
#if DEBUG //#if DEBUG
DebugConsole.ThrowError("Coroutine " + Coroutines[i] + " threw an exception: " + e.Message); // DebugConsole.ThrowError("Coroutine " + Coroutines[i] + " threw an exception: " + e.Message);
#endif //#endif
Coroutines.RemoveAt(i); // Coroutines.RemoveAt(i);
} // }
} }
} }
@@ -89,7 +107,6 @@ namespace Barotrauma
{ {
float timer; float timer;
public WaitForSeconds(float time) public WaitForSeconds(float time)
{ {
timer = time; timer = time;
+51 -6
View File
@@ -156,8 +156,7 @@ namespace Barotrauma
NewMessage(" ", Color.Cyan); NewMessage(" ", Color.Cyan);
NewMessage("spawn: spawn a creature at a random spawnpoint", Color.Cyan); NewMessage("spawn [creaturename] [near/inside/outside]: spawn a creature at a random spawnpoint (use the second parameter to only select spawnpoints near/inside/outside the submarine)", Color.Cyan);
NewMessage("spawn: spawn a creature at a random spawnpoint", Color.Cyan);
NewMessage(" ", Color.Cyan); NewMessage(" ", Color.Cyan);
@@ -174,6 +173,7 @@ namespace Barotrauma
NewMessage(" ", Color.Cyan); NewMessage(" ", Color.Cyan);
NewMessage("heal: restore the controlled character to full health", Color.Cyan); NewMessage("heal: restore the controlled character to full health", Color.Cyan);
NewMessage("revive: bring the controlled character back from the dead", Color.Cyan);
NewMessage(" ", Color.Cyan); NewMessage(" ", Color.Cyan);
@@ -196,10 +196,56 @@ namespace Barotrauma
Character spawnedCharacter = null; Character spawnedCharacter = null;
Vector2 spawnPosition = Vector2.Zero;
WayPoint spawnPoint = null;
if (commands.Length > 2)
{
switch (commands[2].ToLower())
{
case "inside":
spawnPoint = WayPoint.GetRandom(SpawnType.Human);
break;
case "outside":
spawnPoint = WayPoint.GetRandom(SpawnType.Enemy);
break;
case "near":
case "close":
if (Submarine.Loaded == null) break;
float closestDist = 0.0f;
foreach (WayPoint wp in WayPoint.WayPointList)
{
if (wp.Submarine != null) continue;
//don't spawn inside hulls
if (Hull.FindHull(wp.WorldPosition, null) != null) continue;
float dist = Vector2.Distance(wp.WorldPosition, Submarine.Loaded.WorldPosition);
if (spawnPoint == null || dist < closestDist)
{
spawnPoint = wp;
closestDist = dist;
}
}
break;
default:
spawnPoint = WayPoint.GetRandom(commands[1].ToLower()=="human" ? SpawnType.Human : SpawnType.Enemy);
break;
}
}
else
{
spawnPoint = WayPoint.GetRandom(commands[1].ToLower() == "human" ? SpawnType.Human : SpawnType.Enemy);
}
spawnPosition = spawnPoint == null ? Vector2.Zero : spawnPoint.WorldPosition;
if (commands[1].ToLower()=="human") if (commands[1].ToLower()=="human")
{ {
WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Human); spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition);
spawnedCharacter = Character.Create(Character.HumanConfigFile, (spawnPoint == null) ? Vector2.Zero : spawnPoint.WorldPosition);
Character.Controlled = spawnedCharacter; Character.Controlled = spawnedCharacter;
if (GameMain.GameSession != null) if (GameMain.GameSession != null)
@@ -212,8 +258,7 @@ namespace Barotrauma
} }
else else
{ {
WayPoint spawnPoint = WayPoint.GetRandom(SpawnType.Enemy); spawnedCharacter = Character.Create("Content/Characters/" + commands[1] + "/" + commands[1] + ".xml", spawnPosition);
spawnedCharacter = Character.Create("Content/Characters/" + commands[1] + "/" + commands[1] + ".xml", (spawnPoint == null) ? Vector2.Zero : spawnPoint.WorldPosition);
} }
if (spawnedCharacter != null && GameMain.Server != null) GameMain.Server.SendCharacterSpawnMessage(spawnedCharacter); if (spawnedCharacter != null && GameMain.Server != null) GameMain.Server.SendCharacterSpawnMessage(spawnedCharacter);
@@ -76,14 +76,14 @@ namespace Barotrauma.Tutorials
{ {
if (Character.Controlled==null) if (Character.Controlled==null)
{ {
CoroutineManager.StopCoroutine("TutorialMode.UpdateState"); CoroutineManager.StopCoroutines("TutorialMode.UpdateState");
infoBox = null; infoBox = null;
} }
else if (Character.Controlled.IsDead) else if (Character.Controlled.IsDead)
{ {
Character.Controlled = null; Character.Controlled = null;
CoroutineManager.StopCoroutine("TutorialMode.UpdateState"); CoroutineManager.StopCoroutines("TutorialMode.UpdateState");
infoBox = null; infoBox = null;
CoroutineManager.StartCoroutine(Dead()); CoroutineManager.StartCoroutine(Dead());
} }
+1 -2
View File
@@ -163,9 +163,8 @@ namespace Barotrauma
TaskManager.EndShift(); TaskManager.EndShift();
currentMission = null; currentMission = null;
//gameMode.End();
//return true; StatusEffect.StopAll();
} }
+6 -1
View File
@@ -934,10 +934,15 @@ namespace Barotrauma.Networking
UpdateCrewFrame(); UpdateCrewFrame();
if (TraitorsEnabled == YesNoMaybe.Yes || (TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f)) if (TraitorsEnabled == YesNoMaybe.Yes ||
(TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f))
{ {
TraitorManager = new TraitorManager(this); TraitorManager = new TraitorManager(this);
} }
else
{
TraitorManager = null;
}
//give some time for the clients to load the map //give some time for the clients to load the map
yield return new WaitForSeconds(2.0f); yield return new WaitForSeconds(2.0f);