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