Files
LuaCsForBarotraumaEP/Subsurface/Source/GameSession/GameModes/TutorialMode.cs
2015-08-11 20:23:48 +03:00

343 lines
14 KiB
C#

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Subsurface.Items.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Subsurface
{
class TutorialMode : GameMode
{
public readonly CrewManager CrewManager;
private GUIComponent infoBox;
public static void Start()
{
Submarine.Load("Content/Map/TutorialSub.gz");
Game1.GameSession = new GameSession(Submarine.Loaded, "", GameModePreset.list.Find(gm => gm.Name.ToLower()=="tutorial"));
Game1.GameSession.StartShift(TimeSpan.Zero, "tutorial");
Game1.GameScreen.Select();
}
public TutorialMode(GameModePreset preset)
: base(preset)
{
CrewManager = new CrewManager();
}
public override void Start(TimeSpan duration)
{
base.Start(duration);
WayPoint wayPoint = WayPoint.GetRandom(SpawnType.Cargo, null);
if (wayPoint==null)
{
DebugConsole.ThrowError("A waypoint with the spawntype ''cargo'' is required for the tutorial event");
return;
}
CharacterInfo charInfo = new CharacterInfo(Character.HumanConfigFile, "", Gender.None, JobPrefab.List.Find(jp => jp.Name=="Engineer"));
Character character = new Character(charInfo, wayPoint.SimPosition);
Character.Controlled = character;
character.GiveJobItems(null);
foreach (Item item in character.Inventory.items)
{
if (item == null || item.Name != "ID Card") continue;
item.AddTag("com");
item.AddTag("eng");
break;
}
CrewManager.AddCharacter(character);
CoroutineManager.StartCoroutine(UpdateState());
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
CrewManager.Update(deltaTime);
if (infoBox!=null) infoBox.Update(deltaTime);
}
private IEnumerable<object> UpdateState()
{
yield return new WaitForSeconds(4.0f);
infoBox = CreateInfoFrame("Use WASD to move and mouse to look around");
yield return new WaitForSeconds(5.0f);
//-----------------------------------
infoBox = CreateInfoFrame("Open the door at your right side by highlighting the button next to it with your cursor and pressing E");
Door tutorialDoor = Item.itemList.Find(i => i.HasTag("tutorialdoor")).GetComponent<Door>();
while (!tutorialDoor.IsOpen)
{
yield return Status.Running;
}
yield return new WaitForSeconds(2.0f);
//-----------------------------------
infoBox = CreateInfoFrame("Now it's time to power up the submarine. Go to the upper left corner of the submarine, where you'll find a nuclear reactor.");
Reactor reactor = Item.itemList.Find(i => i.HasTag("tutorialreactor")).GetComponent<Reactor>();
while (Vector2.Distance(Character.Controlled.Position, reactor.Item.Position)>200.0f)
{
yield return Status.Running;
}
infoBox = CreateInfoFrame("Select the reactor by walking next to it and pressing E.");
while (Character.Controlled.SelectedConstruction != reactor.Item)
{
yield return Status.Running;
}
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("This is the control panel of the reactor. Try turning it on by increasing the fission rate.");
while (reactor.FissionRate <= 0.0f)
{
yield return Status.Running;
}
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("The reactor core has started generating heat, which in turn generates power for the submarine. It won't generate much power at the moment, "
+" because the shutdown temperature is set to 500. When the temperature of the reactor raises higher than the shutdown temperature, the reactor will automatically start to cool itself down."
+ " You should increase it to somewhere around 5000.");
while (Math.Abs(reactor.ShutDownTemp-5000.0f) > 400.0f)
{
yield return Status.Running;
}
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("The amount of power generated by the reactor should be kept close to the amount of power consumed by the devices in the submarine. "
+"If there's not enough power, devices won't function properly, and if there's too much power, some devices may be damaged. Turn on ''Automatic temperature control'' to "
+"make the reactor automatically adjust the temperature to a suitable level.");
while (!reactor.AutoTemp)
{
yield return Status.Running;
}
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("That's the basics you need to know to power up the reactor! Now that there's power available for the engines, let's try steering the sub. "
+"Deselect the reactor by pressing E and head to the command room at the left edge of the vessel.");
Steering steering = Item.itemList.Find(i => i.HasTag("tutorialsteering")).GetComponent<Steering>();
Radar radar = steering.Item.GetComponent<Radar>();
while (Vector2.Distance(Character.Controlled.Position, steering.Item.Position) > 150.0f)
{
yield return Status.Running;
}
infoBox = CreateInfoFrame("Select the navigation terminal by walking next to it and pressing E.");
while (Character.Controlled.SelectedConstruction != steering.Item)
{
yield return Status.Running;
}
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("There seems to be something wrong with the navigation terminal."+
" There's nothing on the monitor, so it's probably out of power. The reactor must still be"
+" running or the lights would've gone out, so it's most likely a problem with the wiring."
+" Deselect the terminal by pressing E to start checking the wiring.");
while (Character.Controlled.SelectedConstruction == steering.Item)
{
yield return Status.Running;
}
yield return new WaitForSeconds(1.0f);
infoBox = CreateInfoFrame("You need a screwdriver to check the wiring of the terminal."
+ " Equip a screwdriver by pulling it to either of the slots with a hand symbol, and then select the terminal again by pressing E.");
while (Character.Controlled.SelectedConstruction != steering.Item ||
Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.Name == "Screwdriver") == null)
{
yield return Status.Running;
}
infoBox = CreateInfoFrame("Here you can see all the wires connected to the terminal. Apparently there's no wire"
+ " going into the to the power connection - that's why the monitor isn't working."
+ " You should find a piece of wire to connect it. Try searching some of the cabinets scattered around the sub.");
while (Character.Controlled.Inventory.items.FirstOrDefault(i => i!=null && i.GetComponent<Wire>()!=null)==null)
{
yield return Status.Running;
}
infoBox = CreateInfoFrame("Head back to the navigation terminal to fix the wiring.");
PowerTransfer junctionBox = Item.itemList.Find(i => i!=null && i.HasTag("tutorialjunctionbox")).GetComponent<PowerTransfer>();
while ((Character.Controlled.SelectedConstruction != junctionBox.Item &&
Character.Controlled.SelectedConstruction != steering.Item) ||
Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.Name == "Screwdriver") == null)
{
yield return Status.Running;
}
if (Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.GetComponent<Wire>()!=null) == null)
{
infoBox = CreateInfoFrame("Equip the wire by dragging it to one of the slots with a hand symbol.");
while (Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.GetComponent<Wire>() != null) == null)
{
yield return Status.Running;
}
}
infoBox = CreateInfoFrame("You can see the equipped wire at the middle of the connection panel. Drag it to the power connector.");
var steeringConnection = steering.Item.Connections.Find(c => c.Name.Contains("power"));
var junctionConnection = junctionBox.Item.Connections.Find(c => c.Name.Contains("power"));
while (steeringConnection.Wires.FirstOrDefault(w => w != null) == null)
{
yield return Status.Running;
}
infoBox = CreateInfoFrame("Now you have to connect the other end of the wire to a power source. "
+ "The junction box in the room just below the command room should do.");
while (Character.Controlled.SelectedConstruction!=null)
{
yield return Status.Running;
}
yield return new WaitForSeconds(2.0f);
infoBox = CreateInfoFrame("You can now move the other end of the wire around, and attach it on the wall by left clicking or "
+ "remove the previous attachment by right clicking. Or you can just run the wire straight to the junction box and attach it "
+ " the same way you did to the navigation terminal.");
while (radar.Voltage<0.1f)
{
yield return Status.Running;
}
infoBox = CreateInfoFrame("Great! Now we should be able to get moving.");
while (Character.Controlled.SelectedConstruction != steering.Item)
{
yield return Status.Running;
}
infoBox = CreateInfoFrame("You can take a look at the area around the sub by pressing ''Activate Radar''.");
while (!radar.IsActive)
{
yield return Status.Running;
}
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("The white box in the middle is the submarine, and the white lines outside it are the walls of an underwater cavern. "
+ "Try moving the submarine by clicking somewhere inside the rectangle and draggind the pointer to the direction you want to go to.");
while (steering.CurrTargetVelocity == Vector2.Zero && steering.CurrTargetVelocity.Length() < 40.0f)
{
yield return Status.Running;
}
yield return new WaitForSeconds(4.0f);
infoBox = CreateInfoFrame("The submarine moves up and down by pumping water in and out of the two ballast tanks at the bottom of the submarine. "
+"The engine at the back of the sub moves it forwards and backwards.");
yield return new WaitForSeconds(8.0f);
infoBox = CreateInfoFrame("Steer the submarine downwards, heading further into the cavern.");
while (Submarine.Loaded.Position.Y > 31000.0f)
{
yield return Status.Running;
}
var moloch = new Character("Content/Characters/Moloch/moloch.xml", steering.Item.SimPosition + Vector2.UnitX * 15.0f);
moloch.PlaySound(AIController.AiState.Attack);
//moloch.AIController.
infoBox = CreateInfoFrame("Uh-oh... Something enormous just appeared on the radar.");
Structure window = null;
foreach (Structure s in Structure.wallList)
{
if (s.CastShadow) continue;
if (window == null || s.Rect.Right > window.Rect.Right) window = s;
}
bool broken = false;
do
{
moloch.AIController.SelectTarget(steering.Item);
for (int i = 0; i < window.SectionCount; i++)
{
if (!window.SectionHasHole(i)) continue;
broken = true;
break;
}
yield return new WaitForSeconds(1.0f);
} while (!broken);
yield return Status.Success;
}
public override void Draw(SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
CrewManager.Draw(spriteBatch);
if (infoBox != null) infoBox.Draw(spriteBatch);
}
private GUIComponent CreateInfoFrame(string text)
{
int width = 300;
int height = 80;
string wrappedText = ToolBox.WrapText(text, width, GUI.Font);
height += wrappedText.Split('\n').Length*25;
var infoBlock = new GUIFrame(new Rectangle(-20, 20, width, height), null, Alignment.TopRight, GUI.style);
//infoBlock.Color = infoBlock.Color * 0.8f;
infoBlock.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
infoBlock.Flash(Color.Green);
new GUITextBlock(new Rectangle(10, 10, width - 40, height), text, GUI.style, infoBlock, true);
GUI.PlayMessageSound();
return infoBlock;
}
}
}