v0.17.16.0
This commit is contained in:
+18
-1
@@ -189,6 +189,9 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
captain_mechanic.CanSpeak = captain_security.CanSpeak = captain_engineer.CanSpeak = false;
|
captain_mechanic.CanSpeak = captain_security.CanSpeak = captain_engineer.CanSpeak = false;
|
||||||
captain_mechanic.AIController.Enabled = captain_security.AIController.Enabled = captain_engineer.AIController.Enabled = false;
|
captain_mechanic.AIController.Enabled = captain_security.AIController.Enabled = captain_engineer.AIController.Enabled = false;
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Started");
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<CoroutineStatus> UpdateState()
|
public override IEnumerable<CoroutineStatus> UpdateState()
|
||||||
@@ -223,6 +226,7 @@ namespace Barotrauma.Tutorials
|
|||||||
while (!HasOrder(captain_medic, "follow"));
|
while (!HasOrder(captain_medic, "follow"));
|
||||||
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
||||||
RemoveCompletedObjective(0);
|
RemoveCompletedObjective(0);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Objective0");
|
||||||
|
|
||||||
// Submarine
|
// Submarine
|
||||||
do { yield return null; } while (!captain_enteredSubmarineSensor.MotionDetected);
|
do { yield return null; } while (!captain_enteredSubmarineSensor.MotionDetected);
|
||||||
@@ -238,6 +242,8 @@ namespace Barotrauma.Tutorials
|
|||||||
//HighlightOrderOption("jobspecific");
|
//HighlightOrderOption("jobspecific");
|
||||||
} while (!HasOrder(captain_mechanic, "repairsystems") && !HasOrder(captain_mechanic, "repairmechanical") && !HasOrder(captain_mechanic, "repairelectrical"));
|
} while (!HasOrder(captain_mechanic, "repairsystems") && !HasOrder(captain_mechanic, "repairmechanical") && !HasOrder(captain_mechanic, "repairelectrical"));
|
||||||
RemoveCompletedObjective(1);
|
RemoveCompletedObjective(1);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Objective1");
|
||||||
|
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(2, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(2, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(captain_security);
|
GameMain.GameSession.CrewManager.AddCharacter(captain_security);
|
||||||
@@ -250,6 +256,8 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
while (!HasOrder(captain_security, "operateweapons"));
|
while (!HasOrder(captain_security, "operateweapons"));
|
||||||
RemoveCompletedObjective(2);
|
RemoveCompletedObjective(2);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Objective2");
|
||||||
|
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Command));
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(captain_engineer);
|
GameMain.GameSession.CrewManager.AddCharacter(captain_engineer);
|
||||||
@@ -265,6 +273,8 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
while (!HasOrder(captain_engineer, "operatereactor", "powerup"));
|
while (!HasOrder(captain_engineer, "operatereactor", "powerup"));
|
||||||
RemoveCompletedObjective(3);
|
RemoveCompletedObjective(3);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Objective3");
|
||||||
|
|
||||||
do { yield return null; } while (!tutorial_submarineReactor.IsActive); // Wait until reactor on
|
do { yield return null; } while (!tutorial_submarineReactor.IsActive); // Wait until reactor on
|
||||||
TriggerTutorialSegment(4);
|
TriggerTutorialSegment(4);
|
||||||
while (ContentRunning) yield return null;
|
while (ContentRunning) yield return null;
|
||||||
@@ -279,6 +289,8 @@ namespace Barotrauma.Tutorials
|
|||||||
} while (Submarine.MainSub.DockedTo.Any());
|
} while (Submarine.MainSub.DockedTo.Any());
|
||||||
captain_navConsole.UseAutoDocking = false;
|
captain_navConsole.UseAutoDocking = false;
|
||||||
RemoveCompletedObjective(4);
|
RemoveCompletedObjective(4);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Objective4");
|
||||||
|
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(5); // Navigate to destination
|
TriggerTutorialSegment(5); // Navigate to destination
|
||||||
do
|
do
|
||||||
@@ -294,6 +306,8 @@ namespace Barotrauma.Tutorials
|
|||||||
} while (captain_sonar.CurrentMode != Sonar.Mode.Active);
|
} while (captain_sonar.CurrentMode != Sonar.Mode.Active);
|
||||||
do { yield return null; } while (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 4000f);
|
do { yield return null; } while (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 4000f);
|
||||||
RemoveCompletedObjective(5);
|
RemoveCompletedObjective(5);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Objective5");
|
||||||
|
|
||||||
captain_navConsole.UseAutoDocking = true;
|
captain_navConsole.UseAutoDocking = true;
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
TriggerTutorialSegment(6); // Docking
|
TriggerTutorialSegment(6); // Docking
|
||||||
@@ -303,13 +317,16 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
} while (!Submarine.MainSub.AtEndExit || !Submarine.MainSub.DockedTo.Any());
|
} while (!Submarine.MainSub.AtEndExit || !Submarine.MainSub.DockedTo.Any());
|
||||||
RemoveCompletedObjective(6);
|
RemoveCompletedObjective(6);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Objective6");
|
||||||
|
|
||||||
yield return new WaitForSeconds(3f, false);
|
yield return new WaitForSeconds(3f, false);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.GetWithVariable("Captain.Radio.Complete", "[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.GetWithVariable("Captain.Radio.Complete", "[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
|
||||||
SetHighlight(captain_navConsole.Item, false);
|
SetHighlight(captain_navConsole.Item, false);
|
||||||
SetHighlight(captain_sonar.Item, false);
|
SetHighlight(captain_sonar.Item, false);
|
||||||
SetHighlight(captain_statusMonitor, false);
|
SetHighlight(captain_statusMonitor, false);
|
||||||
captain.RemoveActiveObjectiveEntity(captain_navConsole.Item);
|
captain.RemoveActiveObjectiveEntity(captain_navConsole.Item);
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:CaptainTutorial:Completed");
|
||||||
CoroutineManager.StartCoroutine(TutorialCompleted());
|
CoroutineManager.StartCoroutine(TutorialCompleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -198,6 +198,9 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
Item reactorItem = Item.ItemList.Find(i => i.Submarine == Submarine.MainSub && i.GetComponent<Reactor>() != null);
|
Item reactorItem = Item.ItemList.Find(i => i.Submarine == Submarine.MainSub && i.GetComponent<Reactor>() != null);
|
||||||
reactorItem.GetComponent<Reactor>().AutoTemp = true;
|
reactorItem.GetComponent<Reactor>().AutoTemp = true;
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Started");
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<CoroutineStatus> UpdateState()
|
public override IEnumerable<CoroutineStatus> UpdateState()
|
||||||
@@ -281,6 +284,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
SetHighlight(doctor_suppliesCabinet.Item, false);
|
SetHighlight(doctor_suppliesCabinet.Item, false);
|
||||||
RemoveCompletedObjective(0);
|
RemoveCompletedObjective(0);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Objective0");
|
||||||
|
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
|
|
||||||
@@ -294,6 +298,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
RemoveCompletedObjective(1);
|
RemoveCompletedObjective(1);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Objective1");
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
TriggerTutorialSegment(2); //Treat self
|
TriggerTutorialSegment(2); //Treat self
|
||||||
while (doctor.CharacterHealth.GetAfflictionStrength("damage") > 0.01f)
|
while (doctor.CharacterHealth.GetAfflictionStrength("damage") > 0.01f)
|
||||||
@@ -311,6 +316,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
RemoveCompletedObjective(2);
|
RemoveCompletedObjective(2);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Objective2");
|
||||||
SetDoorAccess(doctor_firstDoor, doctor_firstDoorLight, true);
|
SetDoorAccess(doctor_firstDoor, doctor_firstDoorLight, true);
|
||||||
|
|
||||||
while (CharacterHealth.OpenHealthWindow != null)
|
while (CharacterHealth.OpenHealthWindow != null)
|
||||||
@@ -358,6 +364,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(3);
|
RemoveCompletedObjective(3);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Objective3");
|
||||||
SetHighlight(doctor_medBayCabinet.Item, true);
|
SetHighlight(doctor_medBayCabinet.Item, true);
|
||||||
SetDoorAccess(doctor_thirdDoor, doctor_thirdDoorLight, true);
|
SetDoorAccess(doctor_thirdDoor, doctor_thirdDoorLight, true);
|
||||||
patient1.CharacterHealth.UseHealthWindow = true;
|
patient1.CharacterHealth.UseHealthWindow = true;
|
||||||
@@ -401,6 +408,7 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(4);
|
RemoveCompletedObjective(4);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Objective4");
|
||||||
SetHighlight(patient1, false);
|
SetHighlight(patient1, false);
|
||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
|
|
||||||
@@ -442,6 +450,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(5);
|
RemoveCompletedObjective(5);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Objective5");
|
||||||
SetHighlight(patient2, false);
|
SetHighlight(patient2, false);
|
||||||
doctor.RemoveActiveObjectiveEntity(patient2);
|
doctor.RemoveActiveObjectiveEntity(patient2);
|
||||||
CoroutineManager.StopCoroutines("KeepPatient2Alive");
|
CoroutineManager.StopCoroutines("KeepPatient2Alive");
|
||||||
@@ -497,6 +506,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(1.0f, false);
|
yield return new WaitForSeconds(1.0f, false);
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(6);
|
RemoveCompletedObjective(6);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Objective6");
|
||||||
foreach (var patient in subPatients)
|
foreach (var patient in subPatients)
|
||||||
{
|
{
|
||||||
SetHighlight(patient, false);
|
SetHighlight(patient, false);
|
||||||
@@ -504,6 +514,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
// END TUTORIAL
|
// END TUTORIAL
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:DoctorTutorial:Completed");
|
||||||
CoroutineManager.StartCoroutine(TutorialCompleted());
|
CoroutineManager.StartCoroutine(TutorialCompleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -244,6 +244,9 @@ namespace Barotrauma.Tutorials
|
|||||||
engineer_submarineJunctionBox_2.Condition = 0f;
|
engineer_submarineJunctionBox_2.Condition = 0f;
|
||||||
engineer_submarineJunctionBox_3.Indestructible = false;
|
engineer_submarineJunctionBox_3.Indestructible = false;
|
||||||
engineer_submarineJunctionBox_3.Condition = 0f;
|
engineer_submarineJunctionBox_3.Condition = 0f;
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Started");
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<CoroutineStatus> UpdateState()
|
public override IEnumerable<CoroutineStatus> UpdateState()
|
||||||
@@ -317,6 +320,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (!engineer_equipmentCabinet.Inventory.IsEmpty()); // Wait until looted
|
} while (!engineer_equipmentCabinet.Inventory.IsEmpty()); // Wait until looted
|
||||||
RemoveCompletedObjective(0);
|
RemoveCompletedObjective(0);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Objective0");
|
||||||
SetHighlight(engineer_equipmentCabinet.Item, false);
|
SetHighlight(engineer_equipmentCabinet.Item, false);
|
||||||
SetHighlight(engineer_reactor.Item, true);
|
SetHighlight(engineer_reactor.Item, true);
|
||||||
SetDoorAccess(engineer_firstDoor, engineer_firstDoorLight, true);
|
SetDoorAccess(engineer_firstDoor, engineer_firstDoorLight, true);
|
||||||
@@ -352,6 +356,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (engineer_reactor.AvailableFuel == 0);
|
} while (engineer_reactor.AvailableFuel == 0);
|
||||||
RemoveCompletedObjective(1);
|
RemoveCompletedObjective(1);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Objective1");
|
||||||
TriggerTutorialSegment(2);
|
TriggerTutorialSegment(2);
|
||||||
CoroutineManager.StartCoroutine(ReactorOperatedProperly());
|
CoroutineManager.StartCoroutine(ReactorOperatedProperly());
|
||||||
do
|
do
|
||||||
@@ -395,6 +400,7 @@ namespace Barotrauma.Tutorials
|
|||||||
engineer.SelectedConstruction = null;
|
engineer.SelectedConstruction = null;
|
||||||
engineer_reactor.CanBeSelected = false;
|
engineer_reactor.CanBeSelected = false;
|
||||||
RemoveCompletedObjective(2);
|
RemoveCompletedObjective(2);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Objective2");
|
||||||
SetHighlight(engineer_reactor.Item, false);
|
SetHighlight(engineer_reactor.Item, false);
|
||||||
SetHighlight(engineer_brokenJunctionBox, true);
|
SetHighlight(engineer_brokenJunctionBox, true);
|
||||||
SetDoorAccess(engineer_secondDoor, engineer_secondDoorLight, true);
|
SetDoorAccess(engineer_secondDoor, engineer_secondDoorLight, true);
|
||||||
@@ -421,6 +427,7 @@ namespace Barotrauma.Tutorials
|
|||||||
} while (repairableJunctionBoxComponent.IsBelowRepairThreshold); // Wait until repaired
|
} while (repairableJunctionBoxComponent.IsBelowRepairThreshold); // Wait until repaired
|
||||||
SetHighlight(engineer_brokenJunctionBox, false);
|
SetHighlight(engineer_brokenJunctionBox, false);
|
||||||
RemoveCompletedObjective(3);
|
RemoveCompletedObjective(3);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Objective3");
|
||||||
SetDoorAccess(engineer_thirdDoor, engineer_thirdDoorLight, true);
|
SetDoorAccess(engineer_thirdDoor, engineer_thirdDoorLight, true);
|
||||||
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
for (int i = 0; i < engineer_disconnectedJunctionBoxes.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -439,6 +446,7 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(engineer_disconnectedJunctionBoxes[i].Item, false);
|
SetHighlight(engineer_disconnectedJunctionBoxes[i].Item, false);
|
||||||
}
|
}
|
||||||
RemoveCompletedObjective(4);
|
RemoveCompletedObjective(4);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Objective4");
|
||||||
do { yield return null; } while (engineer_workingPump.Item.CurrentHull.WaterPercentage > waterVolumeBeforeOpening); // Wait until drained
|
do { yield return null; } while (engineer_workingPump.Item.CurrentHull.WaterPercentage > waterVolumeBeforeOpening); // Wait until drained
|
||||||
wiringActive = false;
|
wiringActive = false;
|
||||||
SetDoorAccess(engineer_fourthDoor, engineer_fourthDoorLight, true);
|
SetDoorAccess(engineer_fourthDoor, engineer_fourthDoorLight, true);
|
||||||
@@ -465,6 +473,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3); yield return null; } while (repairableJunctionBoxComponent1.IsBelowRepairThreshold || repairableJunctionBoxComponent2.IsBelowRepairThreshold || repairableJunctionBoxComponent3.IsBelowRepairThreshold);
|
do { CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3); yield return null; } while (repairableJunctionBoxComponent1.IsBelowRepairThreshold || repairableJunctionBoxComponent2.IsBelowRepairThreshold || repairableJunctionBoxComponent3.IsBelowRepairThreshold);
|
||||||
CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3);
|
CheckJunctionBoxHighlights(repairableJunctionBoxComponent1, repairableJunctionBoxComponent2, repairableJunctionBoxComponent3);
|
||||||
RemoveCompletedObjective(5);
|
RemoveCompletedObjective(5);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Objective5");
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
|
|
||||||
TriggerTutorialSegment(6); // Powerup reactor
|
TriggerTutorialSegment(6); // Powerup reactor
|
||||||
@@ -474,10 +483,12 @@ namespace Barotrauma.Tutorials
|
|||||||
engineer.RemoveActiveObjectiveEntity(engineer_submarineReactor.Item);
|
engineer.RemoveActiveObjectiveEntity(engineer_submarineReactor.Item);
|
||||||
SetHighlight(engineer_submarineReactor.Item, false);
|
SetHighlight(engineer_submarineReactor.Item, false);
|
||||||
RemoveCompletedObjective(6);
|
RemoveCompletedObjective(6);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Objective6");
|
||||||
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Complete"), ChatMessageType.Radio, null);
|
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Complete"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:EngineerTutorial:Completed");
|
||||||
CoroutineManager.StartCoroutine(TutorialCompleted());
|
CoroutineManager.StartCoroutine(TutorialCompleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
@@ -290,6 +290,9 @@ namespace Barotrauma.Tutorials
|
|||||||
mechanic_ballastPump_2 = Item.ItemList.Find(i => i.HasTag("mechanic_ballastpump_2")).GetComponent<Pump>();
|
mechanic_ballastPump_2 = Item.ItemList.Find(i => i.HasTag("mechanic_ballastpump_2")).GetComponent<Pump>();
|
||||||
mechanic_ballastPump_2.Item.Indestructible = false;
|
mechanic_ballastPump_2.Item.Indestructible = false;
|
||||||
mechanic_ballastPump_2.Item.Condition = 0f;
|
mechanic_ballastPump_2.Item.Condition = 0f;
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Started");
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
@@ -325,6 +328,7 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(mechanic_firstDoor.Item, false);
|
SetHighlight(mechanic_firstDoor.Item, false);
|
||||||
yield return new WaitForSeconds(1.5f, false);
|
yield return new WaitForSeconds(1.5f, false);
|
||||||
RemoveCompletedObjective(0);
|
RemoveCompletedObjective(0);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective0");
|
||||||
|
|
||||||
// Room 2
|
// Room 2
|
||||||
yield return new WaitForSeconds(0.0f, false);
|
yield return new WaitForSeconds(0.0f, false);
|
||||||
@@ -368,6 +372,7 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(mechanic_equipmentCabinet.Item, false);
|
SetHighlight(mechanic_equipmentCabinet.Item, false);
|
||||||
yield return new WaitForSeconds(1.5f, false);
|
yield return new WaitForSeconds(1.5f, false);
|
||||||
RemoveCompletedObjective(1);
|
RemoveCompletedObjective(1);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective1");
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Breach"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Breach"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
// Room 3
|
// Room 3
|
||||||
@@ -391,6 +396,8 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (WallHasDamagedSections(mechanic_brokenWall_1)); // Highlight until repaired
|
do { yield return null; } while (WallHasDamagedSections(mechanic_brokenWall_1)); // Highlight until repaired
|
||||||
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_1);
|
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_1);
|
||||||
RemoveCompletedObjective(2);
|
RemoveCompletedObjective(2);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective2");
|
||||||
|
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select)); // Pump objective
|
TriggerTutorialSegment(3, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select)); // Pump objective
|
||||||
SetHighlight(mechanic_workingPump.Item, true);
|
SetHighlight(mechanic_workingPump.Item, true);
|
||||||
@@ -408,6 +415,8 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(mechanic_workingPump.Item, false);
|
SetHighlight(mechanic_workingPump.Item, false);
|
||||||
do { yield return null; } while (mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
|
do { yield return null; } while (mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
|
||||||
RemoveCompletedObjective(3);
|
RemoveCompletedObjective(3);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective3");
|
||||||
|
|
||||||
SetDoorAccess(mechanic_thirdDoor, mechanic_thirdDoorLight, true);
|
SetDoorAccess(mechanic_thirdDoor, mechanic_thirdDoorLight, true);
|
||||||
//TriggerTutorialSegment(11, GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Up], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Down], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select]); // Ladder objective
|
//TriggerTutorialSegment(11, GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Up], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Down], GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select]); // Ladder objective
|
||||||
//do { yield return null; } while (!mechanic_ladderSensor.MotionDetected);
|
//do { yield return null; } while (!mechanic_ladderSensor.MotionDetected);
|
||||||
@@ -516,6 +525,8 @@ namespace Barotrauma.Tutorials
|
|||||||
|
|
||||||
SetHighlight(mechanic_deconstructor.Item, false);
|
SetHighlight(mechanic_deconstructor.Item, false);
|
||||||
RemoveCompletedObjective(4);
|
RemoveCompletedObjective(4);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective4");
|
||||||
|
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
TriggerTutorialSegment(5); // Fabricate
|
TriggerTutorialSegment(5); // Fabricate
|
||||||
SetHighlight(mechanic_fabricator.Item, true);
|
SetHighlight(mechanic_fabricator.Item, true);
|
||||||
@@ -565,6 +576,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (mechanic.Inventory.FindItemByIdentifier("extinguisher".ToIdentifier()) == null); // Wait until extinguisher is created
|
} while (mechanic.Inventory.FindItemByIdentifier("extinguisher".ToIdentifier()) == null); // Wait until extinguisher is created
|
||||||
RemoveCompletedObjective(5);
|
RemoveCompletedObjective(5);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective5");
|
||||||
SetHighlight(mechanic_fabricator.Item, false);
|
SetHighlight(mechanic_fabricator.Item, false);
|
||||||
SetDoorAccess(mechanic_fourthDoor, mechanic_fourthDoorLight, true);
|
SetDoorAccess(mechanic_fourthDoor, mechanic_fourthDoorLight, true);
|
||||||
|
|
||||||
@@ -574,6 +586,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!mechanic_fire.Removed); // Wait until extinguished
|
do { yield return null; } while (!mechanic_fire.Removed); // Wait until extinguished
|
||||||
yield return new WaitForSeconds(3f, false);
|
yield return new WaitForSeconds(3f, false);
|
||||||
RemoveCompletedObjective(6);
|
RemoveCompletedObjective(6);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective6");
|
||||||
|
|
||||||
if (mechanic.HasEquippedItem("extinguisher".ToIdentifier())) // do not trigger if dropped already
|
if (mechanic.HasEquippedItem("extinguisher".ToIdentifier())) // do not trigger if dropped already
|
||||||
{
|
{
|
||||||
@@ -584,6 +597,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (mechanic.HasEquippedItem("extinguisher".ToIdentifier()));
|
} while (mechanic.HasEquippedItem("extinguisher".ToIdentifier()));
|
||||||
RemoveCompletedObjective(7);
|
RemoveCompletedObjective(7);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective7");
|
||||||
}
|
}
|
||||||
SetDoorAccess(mechanic_fifthDoor, mechanic_fifthDoorLight, true);
|
SetDoorAccess(mechanic_fifthDoor, mechanic_fifthDoorLight, true);
|
||||||
|
|
||||||
@@ -608,6 +622,7 @@ namespace Barotrauma.Tutorials
|
|||||||
} while (!mechanic.HasEquippedItem("divingsuit".ToIdentifier(), slotType: InvSlotType.OuterClothes));
|
} while (!mechanic.HasEquippedItem("divingsuit".ToIdentifier(), slotType: InvSlotType.OuterClothes));
|
||||||
SetHighlight(mechanic_divingSuitContainer.Item, false);
|
SetHighlight(mechanic_divingSuitContainer.Item, false);
|
||||||
RemoveCompletedObjective(8);
|
RemoveCompletedObjective(8);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective8");
|
||||||
SetDoorAccess(tutorial_mechanicFinalDoor, tutorial_mechanicFinalDoorLight, true);
|
SetDoorAccess(tutorial_mechanicFinalDoor, tutorial_mechanicFinalDoorLight, true);
|
||||||
|
|
||||||
// Room 7
|
// Room 7
|
||||||
@@ -650,6 +665,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
} while (repairablePumpComponent.IsBelowRepairThreshold || mechanic_brokenPump.FlowPercentage >= 0 || !mechanic_brokenPump.IsActive);
|
} while (repairablePumpComponent.IsBelowRepairThreshold || mechanic_brokenPump.FlowPercentage >= 0 || !mechanic_brokenPump.IsActive);
|
||||||
RemoveCompletedObjective(9);
|
RemoveCompletedObjective(9);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective9");
|
||||||
SetHighlight(mechanic_brokenPump.Item, false);
|
SetHighlight(mechanic_brokenPump.Item, false);
|
||||||
do { yield return null; } while (mechanic_brokenhull_2.WaterPercentage > waterVolumeBeforeOpening);
|
do { yield return null; } while (mechanic_brokenhull_2.WaterPercentage > waterVolumeBeforeOpening);
|
||||||
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
||||||
@@ -674,9 +690,11 @@ namespace Barotrauma.Tutorials
|
|||||||
do { CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent); yield return null; } while (repairablePumpComponent1.IsBelowRepairThreshold || repairablePumpComponent2.IsBelowRepairThreshold || repairableEngineComponent.IsBelowRepairThreshold);
|
do { CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent); yield return null; } while (repairablePumpComponent1.IsBelowRepairThreshold || repairablePumpComponent2.IsBelowRepairThreshold || repairableEngineComponent.IsBelowRepairThreshold);
|
||||||
CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent);
|
CheckHighlights(repairablePumpComponent1, repairablePumpComponent2, repairableEngineComponent);
|
||||||
RemoveCompletedObjective(10);
|
RemoveCompletedObjective(10);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Objective10");
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Complete"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Complete"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
// END TUTORIAL
|
// END TUTORIAL
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:MechanicTutorial:Completed");
|
||||||
CoroutineManager.StartCoroutine(TutorialCompleted());
|
CoroutineManager.StartCoroutine(TutorialCompleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
@@ -251,6 +251,9 @@ namespace Barotrauma.Tutorials
|
|||||||
officer_subSuperCapacitor_2 = Item.ItemList.Find(i => i.HasTag("officer_subsupercapacitor_2")).GetComponent<PowerContainer>();
|
officer_subSuperCapacitor_2 = Item.ItemList.Find(i => i.HasTag("officer_subsupercapacitor_2")).GetComponent<PowerContainer>();
|
||||||
officer_subAmmoShelf = Item.ItemList.Find(i => i.HasTag("officer_subammoshelf")).GetComponent<ItemContainer>();
|
officer_subAmmoShelf = Item.ItemList.Find(i => i.HasTag("officer_subammoshelf")).GetComponent<ItemContainer>();
|
||||||
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Started");
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<CoroutineStatus> UpdateState()
|
public override IEnumerable<CoroutineStatus> UpdateState()
|
||||||
@@ -310,6 +313,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (!officer_equipmentCabinet.Inventory.IsEmpty()); // Wait until looted
|
} while (!officer_equipmentCabinet.Inventory.IsEmpty()); // Wait until looted
|
||||||
//RemoveCompletedObjective(segments[0]);
|
//RemoveCompletedObjective(segments[0]);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective0");
|
||||||
SetHighlight(officer_equipmentCabinet.Item, false);
|
SetHighlight(officer_equipmentCabinet.Item, false);
|
||||||
do { yield return null; } while (IsSelectedItem(officer_equipmentCabinet.Item));
|
do { yield return null; } while (IsSelectedItem(officer_equipmentCabinet.Item));
|
||||||
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot)); // Equip melee weapon & armor
|
TriggerTutorialSegment(1, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Aim), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot)); // Equip melee weapon & armor
|
||||||
@@ -330,6 +334,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
} while (!officer.HasEquippedItem("stunbaton".ToIdentifier()) || !officer.HasEquippedItem("bodyarmor".ToIdentifier()) || !officer.HasEquippedItem("ballistichelmet1".ToIdentifier()));
|
} while (!officer.HasEquippedItem("stunbaton".ToIdentifier()) || !officer.HasEquippedItem("bodyarmor".ToIdentifier()) || !officer.HasEquippedItem("ballistichelmet1".ToIdentifier()));
|
||||||
RemoveCompletedObjective(1);
|
RemoveCompletedObjective(1);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective1");
|
||||||
SetDoorAccess(officer_firstDoor, officer_firstDoorLight, true);
|
SetDoorAccess(officer_firstDoor, officer_firstDoorLight, true);
|
||||||
|
|
||||||
// Room 3
|
// Room 3
|
||||||
@@ -338,6 +343,7 @@ namespace Barotrauma.Tutorials
|
|||||||
officer_crawler = SpawnMonster("crawler", officer_crawlerSpawnPos);
|
officer_crawler = SpawnMonster("crawler", officer_crawlerSpawnPos);
|
||||||
do { yield return null; } while (!officer_crawler.IsDead);
|
do { yield return null; } while (!officer_crawler.IsDead);
|
||||||
RemoveCompletedObjective(2);
|
RemoveCompletedObjective(2);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective2");
|
||||||
Heal(officer);
|
Heal(officer);
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.CrawlerDead"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.CrawlerDead"), ChatMessageType.Radio, null);
|
||||||
@@ -366,6 +372,8 @@ namespace Barotrauma.Tutorials
|
|||||||
SetHighlight(officer_ammoShelf_1.Item, false);
|
SetHighlight(officer_ammoShelf_1.Item, false);
|
||||||
SetHighlight(officer_ammoShelf_2.Item, false);
|
SetHighlight(officer_ammoShelf_2.Item, false);
|
||||||
RemoveCompletedObjective(3);
|
RemoveCompletedObjective(3);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective3");
|
||||||
|
|
||||||
yield return new WaitForSeconds(2f, false);
|
yield return new WaitForSeconds(2f, false);
|
||||||
TriggerTutorialSegment(4, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect)); // Kill hammerhead
|
TriggerTutorialSegment(4, GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Select), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Shoot), GameSettings.CurrentConfig.KeyMap.KeyBindText(InputType.Deselect)); // Kill hammerhead
|
||||||
officer_hammerhead = SpawnMonster("hammerhead", officer_hammerheadSpawnPos);
|
officer_hammerhead = SpawnMonster("hammerhead", officer_hammerheadSpawnPos);
|
||||||
@@ -401,6 +409,8 @@ namespace Barotrauma.Tutorials
|
|||||||
Heal(officer);
|
Heal(officer);
|
||||||
SetHighlight(officer_coilgunPeriscope, false);
|
SetHighlight(officer_coilgunPeriscope, false);
|
||||||
RemoveCompletedObjective(4);
|
RemoveCompletedObjective(4);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective4");
|
||||||
|
|
||||||
yield return new WaitForSeconds(1f, false);
|
yield return new WaitForSeconds(1f, false);
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.HammerheadDead"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.HammerheadDead"), ChatMessageType.Radio, null);
|
||||||
SetDoorAccess(officer_thirdDoor, officer_thirdDoorLight, true);
|
SetDoorAccess(officer_thirdDoor, officer_thirdDoorLight, true);
|
||||||
@@ -451,6 +461,7 @@ namespace Barotrauma.Tutorials
|
|||||||
yield return null;
|
yield return null;
|
||||||
} while (!shotGunChamber.Inventory.IsFull(takeStacksIntoAccount: true)); // Wait until all six harpoons loaded
|
} while (!shotGunChamber.Inventory.IsFull(takeStacksIntoAccount: true)); // Wait until all six harpoons loaded
|
||||||
RemoveCompletedObjective(5);
|
RemoveCompletedObjective(5);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective5");
|
||||||
SetHighlight(officer_rangedWeaponCabinet.Item, false);
|
SetHighlight(officer_rangedWeaponCabinet.Item, false);
|
||||||
SetDoorAccess(officer_fourthDoor, officer_fourthDoorLight, true);
|
SetDoorAccess(officer_fourthDoor, officer_fourthDoorLight, true);
|
||||||
|
|
||||||
@@ -461,6 +472,7 @@ namespace Barotrauma.Tutorials
|
|||||||
do { yield return null; } while (!officer_mudraptor.IsDead);
|
do { yield return null; } while (!officer_mudraptor.IsDead);
|
||||||
Heal(officer);
|
Heal(officer);
|
||||||
RemoveCompletedObjective(6);
|
RemoveCompletedObjective(6);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective6");
|
||||||
SetDoorAccess(tutorial_securityFinalDoor, tutorial_securityFinalDoorLight, true);
|
SetDoorAccess(tutorial_securityFinalDoor, tutorial_securityFinalDoorLight, true);
|
||||||
|
|
||||||
// Submarine
|
// Submarine
|
||||||
@@ -512,9 +524,11 @@ namespace Barotrauma.Tutorials
|
|||||||
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_1);
|
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_1);
|
||||||
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_2);
|
officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_2);
|
||||||
RemoveCompletedObjective(7);
|
RemoveCompletedObjective(7);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Objective7");
|
||||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Complete"), ChatMessageType.Radio, null);
|
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Complete"), ChatMessageType.Radio, null);
|
||||||
|
|
||||||
yield return new WaitForSeconds(4f, false);
|
yield return new WaitForSeconds(4f, false);
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:OfficerTutorial:Completed");
|
||||||
CoroutineManager.StartCoroutine(TutorialCompleted());
|
CoroutineManager.StartCoroutine(TutorialCompleted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -252,6 +252,8 @@ namespace Barotrauma.Tutorials
|
|||||||
Character.Controlled = character = null;
|
Character.Controlled = character = null;
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:Died");
|
||||||
|
|
||||||
yield return new WaitForSeconds(3.0f);
|
yield return new WaitForSeconds(3.0f);
|
||||||
|
|
||||||
var messageBox = new GUIMessageBox(TextManager.Get("Tutorial.TryAgainHeader"), TextManager.Get("Tutorial.TryAgain"), new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
var messageBox = new GUIMessageBox(TextManager.Get("Tutorial.TryAgainHeader"), TextManager.Get("Tutorial.TryAgain"), new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
||||||
@@ -273,6 +275,8 @@ namespace Barotrauma.Tutorials
|
|||||||
Character.Controlled.ClearInputs();
|
Character.Controlled.ClearInputs();
|
||||||
Character.Controlled = null;
|
Character.Controlled = null;
|
||||||
|
|
||||||
|
GameAnalyticsManager.AddDesignEvent("Tutorial:Completed");
|
||||||
|
|
||||||
yield return new WaitForSeconds(waitBeforeFade);
|
yield return new WaitForSeconds(waitBeforeFade);
|
||||||
|
|
||||||
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, panDuration: fadeOutTime);
|
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, panDuration: fadeOutTime);
|
||||||
|
|||||||
+16
-8
@@ -11,7 +11,13 @@ namespace Barotrauma.Networking
|
|||||||
private bool isActive;
|
private bool isActive;
|
||||||
|
|
||||||
private readonly UInt64 selfSteamID;
|
private readonly UInt64 selfSteamID;
|
||||||
|
private UInt64 ownerKey64 => unchecked((UInt64)ownerKey);
|
||||||
|
|
||||||
|
private UInt64 ReadSteamId(IReadMessage inc)
|
||||||
|
=> inc.ReadUInt64() ^ ownerKey64;
|
||||||
|
private void WriteSteamId(IWriteMessage msg, UInt64 val)
|
||||||
|
=> msg.Write(val ^ ownerKey64);
|
||||||
|
|
||||||
private long sentBytes, receivedBytes;
|
private long sentBytes, receivedBytes;
|
||||||
|
|
||||||
class RemotePeer
|
class RemotePeer
|
||||||
@@ -58,6 +64,8 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (isActive) { return; }
|
if (isActive) { return; }
|
||||||
|
|
||||||
|
this.ownerKey = ownerKey;
|
||||||
|
|
||||||
initializationStep = ConnectionInitialization.SteamTicketAndVersion;
|
initializationStep = ConnectionInitialization.SteamTicketAndVersion;
|
||||||
|
|
||||||
ServerConnection = new PipeConnection(selfSteamID);
|
ServerConnection = new PipeConnection(selfSteamID);
|
||||||
@@ -103,7 +111,7 @@ namespace Barotrauma.Networking
|
|||||||
//known now
|
//known now
|
||||||
int prevBitPosition = msg.Message.BitPosition;
|
int prevBitPosition = msg.Message.BitPosition;
|
||||||
msg.Message.BitPosition = sizeof(ulong) * 8;
|
msg.Message.BitPosition = sizeof(ulong) * 8;
|
||||||
msg.Message.Write(ownerID);
|
WriteSteamId(msg.Message, ownerID);
|
||||||
msg.Message.BitPosition = prevBitPosition;
|
msg.Message.BitPosition = prevBitPosition;
|
||||||
byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
|
byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
|
||||||
Array.Resize(ref msgToSend, msg.Message.LengthBytes);
|
Array.Resize(ref msgToSend, msg.Message.LengthBytes);
|
||||||
@@ -141,8 +149,8 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||||
outMsg.Write(steamId);
|
WriteSteamId(outMsg, steamId);
|
||||||
outMsg.Write(remotePeer.OwnerSteamID);
|
WriteSteamId(outMsg, remotePeer.OwnerSteamID);
|
||||||
outMsg.Write(data, 1, dataLength - 1);
|
outMsg.Write(data, 1, dataLength - 1);
|
||||||
|
|
||||||
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
|
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
|
||||||
@@ -232,7 +240,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (!isActive) { return; }
|
if (!isActive) { return; }
|
||||||
|
|
||||||
UInt64 recipientSteamId = inc.ReadUInt64();
|
UInt64 recipientSteamId = ReadSteamId(inc);
|
||||||
DeliveryMethod deliveryMethod = (DeliveryMethod)inc.ReadByte();
|
DeliveryMethod deliveryMethod = (DeliveryMethod)inc.ReadByte();
|
||||||
|
|
||||||
int p2pDataStart = inc.BytePosition;
|
int p2pDataStart = inc.BytePosition;
|
||||||
@@ -343,8 +351,8 @@ namespace Barotrauma.Networking
|
|||||||
if (packetHeader.IsConnectionInitializationStep())
|
if (packetHeader.IsConnectionInitializationStep())
|
||||||
{
|
{
|
||||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||||
outMsg.Write(selfSteamID);
|
WriteSteamId(outMsg, selfSteamID);
|
||||||
outMsg.Write(selfSteamID);
|
WriteSteamId(outMsg, selfSteamID);
|
||||||
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
|
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
|
||||||
outMsg.Write(Name);
|
outMsg.Write(Name);
|
||||||
|
|
||||||
@@ -436,8 +444,8 @@ namespace Barotrauma.Networking
|
|||||||
IWriteMessage msgToSend = new WriteOnlyMessage();
|
IWriteMessage msgToSend = new WriteOnlyMessage();
|
||||||
byte[] msgData = new byte[msg.LengthBytes];
|
byte[] msgData = new byte[msg.LengthBytes];
|
||||||
msg.PrepareForSending(ref msgData, compressPastThreshold, out bool isCompressed, out int length);
|
msg.PrepareForSending(ref msgData, compressPastThreshold, out bool isCompressed, out int length);
|
||||||
msgToSend.Write(selfSteamID);
|
WriteSteamId(msgToSend, selfSteamID);
|
||||||
msgToSend.Write(selfSteamID);
|
WriteSteamId(msgToSend, selfSteamID);
|
||||||
msgToSend.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
msgToSend.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
||||||
msgToSend.Write((UInt16)length);
|
msgToSend.Write((UInt16)length);
|
||||||
msgToSend.Write(msgData, 0, length);
|
msgToSend.Write(msgData, 0, length);
|
||||||
|
|||||||
@@ -839,16 +839,12 @@ namespace Barotrauma
|
|||||||
arguments += " -nopassword";
|
arguments += " -nopassword";
|
||||||
}
|
}
|
||||||
|
|
||||||
int ownerKey = 0;
|
|
||||||
if (Steam.SteamManager.GetSteamID() != 0)
|
if (Steam.SteamManager.GetSteamID() != 0)
|
||||||
{
|
{
|
||||||
arguments += " -steamid " + Steam.SteamManager.GetSteamID();
|
arguments += " -steamid " + Steam.SteamManager.GetSteamID();
|
||||||
}
|
}
|
||||||
else
|
int ownerKey = Math.Max(CryptoRandom.Instance.Next(), 1);
|
||||||
{
|
arguments += " -ownerkey " + ownerKey;
|
||||||
ownerKey = Math.Max(CryptoRandom.Instance.Next(), 1);
|
|
||||||
arguments += " -ownerkey " + ownerKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
string filename = Path.Combine(
|
string filename = Path.Combine(
|
||||||
Path.GetDirectoryName(exeName),
|
Path.GetDirectoryName(exeName),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.17.15.0</Version>
|
<Version>0.17.16.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.17.15.0</Version>
|
<Version>0.17.16.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.17.15.0</Version>
|
<Version>0.17.16.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.17.15.0</Version>
|
<Version>0.17.16.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.17.15.0</Version>
|
<Version>0.17.16.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace Barotrauma.Networking
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log("Using SteamP2P networking.", ServerLog.MessageType.ServerMessage);
|
Log("Using SteamP2P networking.", ServerLog.MessageType.ServerMessage);
|
||||||
serverPeer = new SteamP2PServerPeer(ownerSteamId.Value, serverSettings);
|
serverPeer = new SteamP2PServerPeer(ownerSteamId.Value, ownerKey.Value, serverSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
serverPeer.OnInitializationComplete = OnInitializationComplete;
|
serverPeer.OnInitializationComplete = OnInitializationComplete;
|
||||||
|
|||||||
+15
-8
@@ -16,14 +16,21 @@ namespace Barotrauma.Networking
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SteamP2PServerPeer(UInt64 steamId, ServerSettings settings)
|
private UInt64 ownerKey64 => unchecked((UInt64)ownerKey.Value);
|
||||||
|
|
||||||
|
private UInt64 ReadSteamId(IReadMessage inc)
|
||||||
|
=> inc.ReadUInt64() ^ ownerKey64;
|
||||||
|
private void WriteSteamId(IWriteMessage msg, UInt64 val)
|
||||||
|
=> msg.Write(val ^ ownerKey64);
|
||||||
|
|
||||||
|
public SteamP2PServerPeer(UInt64 steamId, int ownerKey, ServerSettings settings)
|
||||||
{
|
{
|
||||||
serverSettings = settings;
|
serverSettings = settings;
|
||||||
|
|
||||||
connectedClients = new List<NetworkConnection>();
|
connectedClients = new List<NetworkConnection>();
|
||||||
pendingClients = new List<PendingClient>();
|
pendingClients = new List<PendingClient>();
|
||||||
|
|
||||||
ownerKey = null;
|
this.ownerKey = ownerKey;
|
||||||
|
|
||||||
OwnerSteamID = steamId;
|
OwnerSteamID = steamId;
|
||||||
|
|
||||||
@@ -33,7 +40,7 @@ namespace Barotrauma.Networking
|
|||||||
public override void Start()
|
public override void Start()
|
||||||
{
|
{
|
||||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||||
outMsg.Write(OwnerSteamID);
|
WriteSteamId(outMsg, OwnerSteamID);
|
||||||
outMsg.Write((byte)DeliveryMethod.Reliable);
|
outMsg.Write((byte)DeliveryMethod.Reliable);
|
||||||
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep | PacketHeader.IsServerMessage));
|
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep | PacketHeader.IsServerMessage));
|
||||||
|
|
||||||
@@ -122,8 +129,8 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (!started) { return; }
|
if (!started) { return; }
|
||||||
|
|
||||||
UInt64 senderSteamId = inc.ReadUInt64();
|
UInt64 senderSteamId = ReadSteamId(inc);
|
||||||
UInt64 ownerSteamId = inc.ReadUInt64();
|
UInt64 ownerSteamId = ReadSteamId(inc);
|
||||||
|
|
||||||
PacketHeader packetHeader = (PacketHeader)inc.ReadByte();
|
PacketHeader packetHeader = (PacketHeader)inc.ReadByte();
|
||||||
|
|
||||||
@@ -264,7 +271,7 @@ namespace Barotrauma.Networking
|
|||||||
IWriteMessage msgToSend = new WriteOnlyMessage();
|
IWriteMessage msgToSend = new WriteOnlyMessage();
|
||||||
byte[] msgData = new byte[16];
|
byte[] msgData = new byte[16];
|
||||||
msg.PrepareForSending(ref msgData, compressPastThreshold, out bool isCompressed, out int length);
|
msg.PrepareForSending(ref msgData, compressPastThreshold, out bool isCompressed, out int length);
|
||||||
msgToSend.Write(conn.SteamID);
|
WriteSteamId(msgToSend, conn.SteamID);
|
||||||
msgToSend.Write((byte)deliveryMethod);
|
msgToSend.Write((byte)deliveryMethod);
|
||||||
msgToSend.Write((byte)((isCompressed ? PacketHeader.IsCompressed : PacketHeader.None) | PacketHeader.IsServerMessage));
|
msgToSend.Write((byte)((isCompressed ? PacketHeader.IsCompressed : PacketHeader.None) | PacketHeader.IsServerMessage));
|
||||||
msgToSend.Write((UInt16)length);
|
msgToSend.Write((UInt16)length);
|
||||||
@@ -281,7 +288,7 @@ namespace Barotrauma.Networking
|
|||||||
if (string.IsNullOrWhiteSpace(msg)) { return; }
|
if (string.IsNullOrWhiteSpace(msg)) { return; }
|
||||||
|
|
||||||
IWriteMessage msgToSend = new WriteOnlyMessage();
|
IWriteMessage msgToSend = new WriteOnlyMessage();
|
||||||
msgToSend.Write(steamId);
|
WriteSteamId(msgToSend, steamId);
|
||||||
msgToSend.Write((byte)DeliveryMethod.Reliable);
|
msgToSend.Write((byte)DeliveryMethod.Reliable);
|
||||||
msgToSend.Write((byte)(PacketHeader.IsDisconnectMessage | PacketHeader.IsServerMessage));
|
msgToSend.Write((byte)(PacketHeader.IsDisconnectMessage | PacketHeader.IsServerMessage));
|
||||||
msgToSend.Write(msg);
|
msgToSend.Write(msg);
|
||||||
@@ -318,7 +325,7 @@ namespace Barotrauma.Networking
|
|||||||
protected override void SendMsgInternal(NetworkConnection conn, DeliveryMethod deliveryMethod, IWriteMessage msg)
|
protected override void SendMsgInternal(NetworkConnection conn, DeliveryMethod deliveryMethod, IWriteMessage msg)
|
||||||
{
|
{
|
||||||
IWriteMessage msgToSend = new WriteOnlyMessage();
|
IWriteMessage msgToSend = new WriteOnlyMessage();
|
||||||
msgToSend.Write(conn.SteamID);
|
WriteSteamId(msgToSend, conn.SteamID);
|
||||||
msgToSend.Write((byte)deliveryMethod);
|
msgToSend.Write((byte)deliveryMethod);
|
||||||
msgToSend.Write(msg.Buffer, 0, msg.LengthBytes);
|
msgToSend.Write(msg.Buffer, 0, msg.LengthBytes);
|
||||||
byte[] bufToSend = (byte[])msgToSend.Buffer.Clone();
|
byte[] bufToSend = (byte[])msgToSend.Buffer.Clone();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.17.15.0</Version>
|
<Version>0.17.16.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace Barotrauma
|
|||||||
=> Element.Descendants().Select(e => new ContentXElement(ContentPackage, e));
|
=> Element.Descendants().Select(e => new ContentXElement(ContentPackage, e));
|
||||||
|
|
||||||
public IEnumerable<ContentXElement> GetChildElements(string name)
|
public IEnumerable<ContentXElement> GetChildElements(string name)
|
||||||
=> Elements().Where(e => string.Equals(name, e.Name.LocalName, StringComparison.CurrentCultureIgnoreCase));
|
=> Elements().Where(e => string.Equals(name, e.Name.LocalName, StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
|
||||||
public XAttribute? GetAttribute(string name) => Element.GetAttribute(name);
|
public XAttribute? GetAttribute(string name) => Element.GetAttribute(name);
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private static void UpdateRead()
|
private static void UpdateRead()
|
||||||
{
|
{
|
||||||
Span<byte> msgLengthSpan = stackalloc byte[3];
|
Span<byte> msgLengthSpan = stackalloc byte[4 + 1];
|
||||||
while (!shutDown)
|
while (!shutDown)
|
||||||
{
|
{
|
||||||
CheckPipeConnected(nameof(readStream), readStream);
|
CheckPipeConnected(nameof(readStream), readStream);
|
||||||
@@ -167,8 +167,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (!readBytes(msgLengthSpan)) { shutDown = true; break; }
|
if (!readBytes(msgLengthSpan)) { shutDown = true; break; }
|
||||||
|
|
||||||
int msgLength = msgLengthSpan[0] | (msgLengthSpan[1] << 8);
|
int msgLength = msgLengthSpan[0]
|
||||||
WriteStatus writeStatus = (WriteStatus)msgLengthSpan[2];
|
| (msgLengthSpan[1] << 8)
|
||||||
|
| (msgLengthSpan[2] << 16)
|
||||||
|
| (msgLengthSpan[3] << 24);
|
||||||
|
WriteStatus writeStatus = (WriteStatus)msgLengthSpan[4];
|
||||||
|
|
||||||
if (msgLength > 0)
|
if (msgLength > 0)
|
||||||
{
|
{
|
||||||
@@ -210,12 +213,15 @@ namespace Barotrauma.Networking
|
|||||||
// when the function returns; placing it in the loop
|
// when the function returns; placing it in the loop
|
||||||
// this method is based around would lead to a stack
|
// this method is based around would lead to a stack
|
||||||
// overflow real quick!
|
// overflow real quick!
|
||||||
Span<byte> bytesToWrite = stackalloc byte[3 + msg.Length];
|
Span<byte> bytesToWrite = stackalloc byte[4 + 1 + msg.Length];
|
||||||
|
|
||||||
bytesToWrite[0] = (byte)(msg.Length & 0xFF);
|
bytesToWrite[0] = (byte)(msg.Length & 0xFF);
|
||||||
bytesToWrite[1] = (byte)((msg.Length >> 8) & 0xFF);
|
bytesToWrite[1] = (byte)((msg.Length >> 8) & 0xFF);
|
||||||
bytesToWrite[2] = (byte)writeStatus;
|
bytesToWrite[2] = (byte)((msg.Length >> 16) & 0xFF);
|
||||||
Span<byte> msgSlice = bytesToWrite.Slice(3, msg.Length);
|
bytesToWrite[3] = (byte)((msg.Length >> 24) & 0xFF);
|
||||||
|
|
||||||
|
bytesToWrite[4] = (byte)writeStatus;
|
||||||
|
Span<byte> msgSlice = bytesToWrite.Slice(4 + 1, msg.Length);
|
||||||
|
|
||||||
msg.AsSpan().CopyTo(msgSlice);
|
msg.AsSpan().CopyTo(msgSlice);
|
||||||
|
|
||||||
@@ -269,6 +275,12 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (shutDown) { return; }
|
if (shutDown) { return; }
|
||||||
|
|
||||||
|
if (msg.Length > 0x1fff_ffff)
|
||||||
|
{
|
||||||
|
//This message is extremely long and is close to breaking
|
||||||
|
//ChildServerRelay, so let's not allow this to go through!
|
||||||
|
return;
|
||||||
|
}
|
||||||
msgsToWrite.Enqueue(msg);
|
msgsToWrite.Enqueue(msg);
|
||||||
writeManualResetEvent.Set();
|
writeManualResetEvent.Set();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.17.16.0
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- Added some tutorial information to the data sent to GameAnalytics.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Fixed an exploit that allowed modified clients to execute console commands server-side without the appropriate permissions.
|
||||||
|
- Fixed NPCs spawning without any items when the system language is set to Turkish.
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.17.15.0
|
v0.17.15.0
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user