Fixed AIObjectiveGoto terminating if previous path was unreachable, BackGroundSpriteManager won't place a sprite if a suitable position isn't found, StatusEffect fire position fix, UI improvements, door convexhull fix, progress on Fabricators & Deconstructors, mapentities sorted by category in edit mode, item descriptions, TutorialMode refactoring to make it easier to add new types of tutorials

This commit is contained in:
Regalis
2015-12-28 13:21:24 +02:00
parent 8c032d8368
commit 92d396e6b2
69 changed files with 1264 additions and 455 deletions

View File

@@ -101,7 +101,9 @@
<Compile Include="Source\GameSession\CargoManager.cs" />
<Compile Include="Source\GameSession\GameModes\GameModePreset.cs" />
<Compile Include="Source\GameSession\GameModes\QuestMode.cs" />
<Compile Include="Source\GameSession\GameModes\TutorialMode.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\BasicTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\TutorialType.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\TutorialMode.cs" />
<Compile Include="Source\GameSession\InfoTextManager.cs" />
<Compile Include="Source\GameSession\ShiftSummary.cs" />
<Compile Include="Source\GUI\GUIDropDown.cs" />
@@ -110,6 +112,7 @@
<Compile Include="Source\Items\Components\Holdable\MeleeWeapon.cs" />
<Compile Include="Source\Items\Components\Holdable\Propulsion.cs" />
<Compile Include="Source\Items\Components\Label.cs" />
<Compile Include="Source\Items\Components\Machines\Deconstructor.cs" />
<Compile Include="Source\Items\Components\Signal\WaterDetector.cs" />
<Compile Include="Source\Items\Components\Signal\WifiComponent.cs" />
<Compile Include="Source\Items\Components\Signal\SignalCheckComponent.cs" />
@@ -427,12 +430,6 @@
<Content Include="Content\Items\Electricity\supercapacitor.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\wifi.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\regex.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\lights.xml">
<SubType>Designer</SubType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -443,6 +440,12 @@
<Content Include="Content\Items\Electricity\monitors.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Fabricators\materials.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Fabricators\materials.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\itemlabel.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -548,21 +551,9 @@
<Content Include="Content\Items\Lockers\lockers.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\and.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\light.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\lightsprite.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\not.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\or.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\Items\Electricity\signalitems.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
@@ -644,6 +635,9 @@
<Content Include="Content\Particles\flames.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\UI\uiButton.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\UI\caret.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -961,6 +955,12 @@
<None Include="Content\Items\Engine\radarPing.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Items\Fabricators\deconstructor.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Items\Fabricators\fabricator.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Content\Items\Medical\bandage.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@@ -6,6 +6,14 @@
<Sprite texture="artifact.png" depth="0.8" sourcerect="0,0,38,60"/>
<Deconstruct time="30">
<Item name="Steel Bar"/>
<Item name="Copper Bar"/>
<Item name="Uranium Bar"/>
<Item name="Uranium Bar"/>
</Deconstruct>
<Body width="36" height="60" density="5"/>
<Holdable slots="RightHand+LeftHand" holdpos="30,-15" handle1="0,10" handle2="0,-10"/>
@@ -17,6 +25,13 @@
<Sprite texture="artifact.png" depth="0.8" sourcerect="74,0,44,61"/>
<Deconstruct time="30">
<Item name="Steel Bar"/>
<Item name="Incendium Bar"/>
<Item name="Incendium Bar"/>
<Item name="Incendium Bar"/>
</Deconstruct>
<Body radius="20" height="20" density="5"/>
<Holdable slots="RightHand+LeftHand" holdpos="30,-15" handle1="0,10" handle2="0,-10">

View File

@@ -1,6 +1,6 @@
<Item
name="Button"
type="Controller"
category="Electrical"
linkable="true"
tags="smallitem"
pickdistance="150.0"

View File

@@ -1,8 +1,10 @@
<Items>
<Item
name="Captain's Cap"
category="Equipment"
pickdistance="150"
tags="smallitem">
tags="smallitem"
description="A token of the Captain's unquestionable authority.">
<Sprite texture ="captainhat.png" depth="0.6"/>
@@ -15,6 +17,7 @@
<Item
name="Captain's Jacket"
category="Equipment"
pickdistance="150"
tags="smallitem">
@@ -35,6 +38,7 @@
<Item
name="Captain's Trousers"
category="Equipment"
pickdistance="150"
tags="smallitem">
@@ -54,8 +58,10 @@
<Item
name="Body Armor"
category="Equipment"
pickdistance="150"
tags="smallitem">
tags="smallitem"
description="While the body armor won't offer adequate protection against most of the inhabitants of the subsurface ocean, it can be extremely useful if there are traitors on board.">
<Sprite texture ="securitygear.png" sourcerect="68,0,60,31" depth="0.6"/>
@@ -70,8 +76,10 @@
<Item
name="Ballistic Helmet"
category="Equipment"
pickdistance="150"
tags="smallitem">
tags="smallitem"
description="While the helmet won't offer adequate protection against most of the inhabitants of the subsurface ocean, it can be extremely useful if there are traitors on board.">
<Sprite texture ="securitygear.png" sourcerect="40,32,34,25" depth="0.6"/>
@@ -84,9 +92,11 @@
<Item
name="Orange Jumpsuit"
category="Equipment"
pickdistance="150"
tags="smallitem"
fireproof="true">
fireproof="true"
description="The fire-resistant fabric offers some protection against fires. Plenty of pockets for carrying any extra gear an engineer might need.">
<Sprite texture = "engigear.png" sourcerect="0,52,50,25" depth="0.6"/>
@@ -110,9 +120,11 @@
<Item
name="Blue Jumpsuit"
category="Equipment"
pickdistance="150"
tags="smallitem"
fireproof="true">
fireproof="true"
description="The fire-resistant fabric offers some protection against fires. Plenty of pockets for carrying any extra gear a mechanic might need.">
<Sprite texture = "engigear.png" sourcerect="53,50,51,25" depth="0.6"/>

View File

@@ -19,9 +19,11 @@
<Item
name="Diving Mask"
category="Equipment"
Tags="smallitem,diving"
pickdistance="200"
price="50">
price="50"
description="Small enough to carry around in case of need, but won't protect you from the water pressure in the event of a full-blown hull breach.">
<Sprite texture ="DivingMask.png" depth="0.5"/>
@@ -46,10 +48,12 @@
<Item
name="Diving Suit"
category="Equipment"
tags="diving"
pickdistance="200"
price="200"
fireproof="true">
fireproof="true"
description="An atmospheric diving suit capable of withstanding the immense pressure under Europa's crust.">
<Sprite texture ="DivingSuit.png" sourcerect="82,0,46,128" depth="0.55"/>
@@ -90,9 +94,11 @@
<Item
name="Underwater Scooter"
category="Equipment"
Tags="smallitem"
pickdistance="200"
price="50">
price="50"
description="A battery-powered underwater propulsion device.">
<Sprite texture ="DivingSuit.png" depth="0.5" sourcerect="22,98,59,32" origin="0.6,0.66"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

View File

@@ -4,6 +4,7 @@
<Item
name="Lamp"
category="Electrical"
Tags="smallitem"
pickdistance="150">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 B

View File

@@ -2,8 +2,10 @@
<Items>
<Item
name="Junction Box"
category="Electrical"
linkable="true"
pickdistance="150">
pickdistance="150"
description="Serves as a hub for power distribution and relaying signals between devices.">
<Sprite texture ="junctionbox.png" depth="0.8"/>
@@ -35,8 +37,10 @@
<Item
name="Battery"
category="Electrical"
linkable="true"
pickdistance="150">
pickdistance="150"
description="Generally used for storing backup power in case of a reactor failure.">
<Sprite texture ="battery.png" depth="0.8"/>
@@ -60,8 +64,10 @@
<Item
name="Supercapacitor"
category="Electrical"
linkable="true"
pickdistance="150">
pickdistance="150"
description="Can accept and deliver charge much faster than batteries.">
<Sprite texture ="supercapacitor.png" depth="0.8"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -4,12 +4,17 @@
<Item
name="Wire"
category="Electrical"
Tags="smallitem,wire"
pickdistance="150"
linkable="true"
canbepicked="true"
price="10">
<Deconstruct time="5">
<Item name="Copper Bar"/>
</Deconstruct>
<Sprite texture ="wire.png" depth="0.55"/>
<Body radius="15"/>
@@ -21,6 +26,7 @@
<Item
name="Red Wire"
category="Electrical"
Tags="smallitem,wire"
spritecolor="1.0,0.0,0.0,1.0"
pickdistance="150"
@@ -28,6 +34,10 @@
canbepicked="true"
price="10">
<Deconstruct time="5">
<Item name="Copper Bar"/>
</Deconstruct>
<Sprite texture ="wire.png" depth="0.55"/>
<Body radius="15"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
@@ -37,6 +47,7 @@
<Item
name="Blue Wire"
category="Electrical"
Tags="smallitem,wire"
spritecolor="0.0,0.6,1.0,1.0"
pickdistance="150"
@@ -44,6 +55,10 @@
canbepicked="true"
price="10">
<Deconstruct time="5">
<Item name="Copper Bar"/>
</Deconstruct>
<Sprite texture ="wire.png" depth="0.55"/>
<Body radius="15"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
@@ -53,6 +68,7 @@
<Item
name="Orange Wire"
category="Electrical"
Tags="smallitem,wire"
spritecolor="1.0,0.5,0.0,1.0"
pickdistance="150"
@@ -60,6 +76,10 @@
canbepicked="true"
price="10">
<Deconstruct time="5">
<Item name="Copper Bar"/>
</Deconstruct>
<Sprite texture ="wire.png" depth="0.55"/>
<Body radius="15"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
@@ -68,13 +88,36 @@
</Item>
<Item
name="And Component"
name="FPGA Circuit"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
price="100"
description="Field-programmable gate array - a multi-purpose circuit which can be reconfigured for use in a large variety of electrical devices.">
<Sprite texture ="and.png" depth="0.8"/>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="32,16,16,16"/>
<Body width="16" height="16"/>
<Holdable selectkey="Action" slots="Any,RightHand,LeftHand"/>
</Item>
<Item
name="And Component"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10"
description="Sends a signal when both inputs receive a signal within a set period of each other.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="0,0,16,16"/>
<AndComponent canbeselected = "true"/>
@@ -97,10 +140,17 @@
<Item
name="Or Component"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
price="10"
description="Sends a signal if either of the inputs receive a signal.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="16,0,16,16"/>
@@ -124,10 +174,17 @@
<Item
name="Not Component"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
price="10"
description="Sends a signal when the input is NOT receiving a signal.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="32,0,16,16"/>
@@ -150,11 +207,17 @@
<Item
name="Light Component"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="48,0,16,16"/>
<LightComponent canbeselected = "true" color="1.0,0.0,0.0,1.0">
@@ -177,10 +240,17 @@
<Item
name="Oxygen Detector"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
price="10"
description="Sends out a value between 0-100 depending on the quality of the surrounding air.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="96,0,31,24"/>
@@ -201,10 +271,17 @@
<Item
name="Water Detector"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
price="10"
description="Sends out a signal when the detector is submerged.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="64,0,31,25"/>
@@ -225,10 +302,17 @@
<Item
name="Signal Check Component"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
price="10"
description="Sends a signal when a signal matching a specific value is received.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="0,16,16,16"/>
@@ -252,10 +336,17 @@
<Item
name="RegEx Find Component"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="10">
price="10"
description="Sends a signal if the received signal matches a specific regular expression pattern.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="16,16,16,16"/>
@@ -277,10 +368,17 @@
<Item
name="Wifi Component"
category="Electrical"
Tags="smallitem"
pickdistance="150"
linkable="true"
price="20">
price="20"
description="Allows remote communication between other Wifi Components that are using the same channel.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="0,32,15,19"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

View File

@@ -4,6 +4,7 @@
<Item
name="Engine"
linkable="true"
category="Machine"
pickdistance="150">
<Sprite texture ="engine.png" depth="0.8"/>
@@ -23,6 +24,7 @@
<Item
name="Navigation Terminal"
linkable="true"
category="Machine"
pickdistance="150">
<Sprite texture ="fabricator.png" depth="0.8"/>
@@ -50,6 +52,7 @@
<Item
name="Sonar Monitor"
linkable="true"
category="Machine"
pickdistance="150">
<Sprite texture ="fabricator.png" depth="0.8"/>

Binary file not shown.

Binary file not shown.

View File

@@ -3,14 +3,35 @@
<Item
name="Fabricator"
linkable="true"
pickdistance="150">
pickdistance="150"
category="Machine"
description="A machine capable of manufacturing a wide range of items out of basic raw materials.">
<Sprite texture ="fabricator.png" depth="0.8"/>
<Fabricator canbeselected = "true">
<fabricableitem name="Harpoon Gun" requireditems="ID Card, Spear"/>
<fabricableitem name="Plasma Cutter" requireditems="Wrench, Spear"/>
</Fabricator>
<GuiFrame rect="0,0,600,400" alignment="Center" color="0.0,0.0,0.0,0.6"/>
<sound file="fabricator.ogg" type="OnActive" range="1000.0" loop="true"/>
<fabricableitem name="Harpoon Gun" requireditems="Steel Bar" requiredtime="20"/>
<fabricableitem name="Plasma Cutter" requireditems="Steel Bar" requiredtime="20"/>
<fabricableitem name="And Component" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Or Component" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Not Component" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Light Component" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Oxygen Detector" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Water Detector" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Signal Check Component" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="RegEx Find Component" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Wifi Component" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Fuel Rod" requireditems="Steel Bar, Uranium Bar"/>
<fabricableitem name="Incendium Fuel Rod" requireditems="Steel Bar, Incendium Bar"/>
</Fabricator>
<ConnectionPanel canbeselected = "true">
<requireditem name="Screwdriver" type="Equipped"/>
@@ -21,4 +42,27 @@
<ItemContainer capacity="5" canbeselected="true" hideitems="true" hudpos="0.8, 0.7" slotsperrow="1"/>
</Item>
<Item
name="Deconstructor"
linkable="true"
pickdistance="150"
category="Machine"
description="Disassembles and breaks down items to reusable components and material bars.">
<Sprite texture ="fabricator.png" depth="0.8"/>
<Deconstructor canbeselected = "true">
<sound file="deconstructor.ogg" type="OnActive" range="1000.0" loop="true"/>
<GuiFrame rect="0,0,300,200" alignment="Center" color="0.0,0.0,0.0,0.6"/>
</Deconstructor>
<ConnectionPanel canbeselected = "true">
<requireditem name="Screwdriver" type="Equipped"/>
<output name="power_in"/>
</ConnectionPanel>
<ItemContainer capacity="5" canbeselected="true" hideitems="true" hudpos="0.5, 0.4" slotsperrow="5"/>
<ItemContainer capacity="10" canbeselected="true" hideitems="true" hudpos="0.5, 0.8" slotsperrow="5"/>
</Item>
</Items>

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Item
name="Steel Bar"
category="Material"
Tags="smallitem"
pickdistance="150"
canbepicked="true"
price="10">
<Sprite texture ="materials.png" sourcerect="0,0,24,12" depth="0.55"/>
<Body width="24" height="12"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
</Item>
<Item
name="Uranium Bar"
category="Material"
Tags="smallitem"
pickdistance="150"
spritecolor="0.2,0.35,0.06,1.0"
canbepicked="true"
price="50">
<Sprite texture ="materials.png" sourcerect="0,0,24,12" depth="0.55"/>
<Body width="24" height="12"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
</Item>
<Item
name="Copper Bar"
category="Material"
Tags="smallitem"
pickdistance="150"
spritecolor="0.78,0.55,0.2,1.0"
canbepicked="true"
price="50">
<Sprite texture ="materials.png" sourcerect="0,0,24,12" depth="0.55"/>
<Body width="24" height="12"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
</Item>
<Item
name="Incendium Bar"
category="Material"
Tags="smallitem"
pickdistance="150"
spritecolor="0.5,0.0,0.0,1.0"
canbepicked="true"
price="50">
<Sprite texture ="materials.png" sourcerect="0,0,24,12" depth="0.55"/>
<Body width="24" height="12"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
</Item>
<Item
name="Fulgurium Bar"
category="Material"
Tags="smallitem"
pickdistance="150"
spritecolor="1.0,0.7,0.05,1.0"
canbepicked="true"
price="50">
<Sprite texture ="materials.png" sourcerect="0,0,24,12" depth="0.55"/>
<Body width="24" height="12"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,0"/>
</Item>
</Items>

View File

@@ -2,9 +2,11 @@
<Items>
<Item
name="Medical Syringe"
category="Equipment"
Tags="smallitem"
pickdistance="150"
price="50">
price="50"
description="A syringe filled with a potent general-purpose medical compound.">
<Sprite texture ="med.png" sourcerect="0,0,24,5" depth="0.6"/>
@@ -17,9 +19,11 @@
<Item
name="Bandage"
category="Equipment"
Tags="smallitem"
pickdistance="150"
price="20">
price="20"
description="Treated with a hemostatic agent that quickly seals most minor wounds.">
<Sprite texture ="med.png" sourcerect="0,14,14,18" depth="0.6"/>

View File

@@ -1,5 +1,6 @@
<Item
name="MiniMap"
category="Machine"
linkable="true">
<Sprite texture ="fabricator.png" depth="0.8"/>

View File

@@ -1,6 +1,7 @@
<Items>
<Item
name="Oxygen Generator"
category="Machine"
linkable="true">
@@ -25,6 +26,7 @@
<Item
name="Vent"
category="Machine"
linkable="true">
<Sprite texture ="vent.png" depth="0.91"/>

View File

@@ -1,6 +1,7 @@
<Item
name="Pump"
linkable="true"
category="Machine"
pickdistance="200">
<Sprite texture ="pump.png" depth="0.8"/>

View File

@@ -2,7 +2,8 @@
<Item
name="Nuclear Reactor"
type ="Reactor"
linkable="true">
linkable="true"
category="Machine">
<trigger/>
@@ -42,6 +43,9 @@
<Containable name="Fuel Rod">
<StatusEffect type="OnContaining" target="This" AvailableFuel="2000.0" disabledeltatime="true"/>
</Containable>
<Containable name="Incendium Fuel Rod">
<StatusEffect type="OnContaining" target="This" AvailableFuel="5000.0" disabledeltatime="true"/>
</Containable>
<Containable name="Heat Absorber"/>
<Containable name="Temperature Control Circuit"/>
</ItemContainer>
@@ -61,6 +65,22 @@
<Pickable slots="RightHand,Any"/>
</Item>
<Item
name="Incendium Fuel Rod"
Tags="smallitem"
pickdistance="150"
spritecolor="0.5,0.0,0.0,1.0"
price="200">
<Sprite texture ="fuelrod.png"/>
<Body radius="6" height="22" density="5"/>
<Holdable handle1="0,0"/>
<Pickable slots="RightHand,Any"/>
</Item>
<Item
name="Heat Absorber"
Tags="smallitem"

View File

@@ -2,9 +2,11 @@
<Items>
<Item
name="Welding Tool"
category="Equipment"
Tags="smallitem"
pickdistance="200"
price="100">
price="100"
description="One of the most crucial tools on board the submarine. Also works underwater.">
<Sprite texture ="weldingtool.png" depth="0.5"/>
@@ -48,9 +50,11 @@
<Item
name="Plasma Cutter"
category="Equipment"
Tags="smallitem"
pickdistance="200"
price="100">
price="100"
description="Cuts through various materials using a jet of ionized oxygen.">
<Sprite texture ="plasmacutter.png" depth="0.5"/>
@@ -85,6 +89,7 @@
<Item
name="Welding Fuel Tank"
category="Equipment"
Tags="smallitem"
pickdistance="150"
price="50">
@@ -102,9 +107,11 @@
<Item
name="Fire Extinguisher"
category="Equipment"
Tags="smallitem"
pickdistance="200"
price="100">
price="100"
description="A handheld carbon dioxide extinguisher.">
<Sprite texture ="extinguisher.png" depth="0.5" sourcerect="0,0,34,64" origin="0.4,0.5"/>
@@ -124,6 +131,7 @@
<Item
name="Screwdriver"
category="Equipment"
Tags="smallitem"
pickdistance="200"
price="10">
@@ -139,6 +147,7 @@
<Item
name="Wrench"
category="Equipment"
Tags="smallitem"
pickdistance="200"
price="10">

View File

@@ -2,6 +2,7 @@
<Items>
<Item
name="C-4 Block"
category="Equipment"
Tags="smallitem,explosive"
pickdistance="150"
price="100">
@@ -19,6 +20,7 @@
<Item
name="Detonator"
category="Equipment"
Tags="smallitem"
pickdistance="150"
price="50">

View File

@@ -1,6 +1,7 @@
<Items>
<Item
name="Railgun"
category="Machine"
focusonselected="true"
offsetonselected="700"
linkable="true"
@@ -26,6 +27,7 @@
<Item
name="Railgun Controller"
category="Machine"
type="Controller"
linkable="true"
pickdistance="150">
@@ -48,6 +50,7 @@
<Item
name="Railgun Loader"
category="Machine"
linkable="true"
pickdistance="150">
@@ -61,6 +64,7 @@
<Item
name="Railgun Shell"
category="Equipment"
pickdistance="200"
price="100">

View File

@@ -3,10 +3,15 @@
<Items>
<Item
name="Spear"
category="Equipment"
pickdistance="200"
pickthroughwalls="true"
price="50">
<Deconstruct time="5">
<Item name="Steel Bar"/>
</Deconstruct>
<Sprite texture="weapons.png" sourcerect="0,50,65,7" depth="0.55"/>
<Body width="64" height="5" density="20"/>
@@ -19,9 +24,14 @@
<Item
name="Harpoon Gun"
category="Equipment"
pickdistance="200"
price="500"
tags="weapon">
<Deconstruct time="10">
<Item name="Steel Bar"/>
</Deconstruct>
<Sprite texture="weapons.png" sourcerect="0,25,98,25" depth="0.5"/>
@@ -44,6 +54,7 @@
<Item
name="Stun Grenade"
category="Equipment"
pickdistance="200"
price="200"
tags="smallitem,weapon">
@@ -61,9 +72,11 @@
<Item
name="Stun Baton"
category="Equipment"
Tags="smallitem,weapon"
pickdistance="150"
price="100">
price="100"
description="If verbal orders are insufficient, a high-voltage shock from a Stun Baton may be enough to beat an unruly crew member into submission.">
<Sprite texture="weapons.png" sourcerect="20,0,77,23" depth="0.5"/>
@@ -85,9 +98,11 @@
<Item
name="Battery Cell"
category="Equipment"
pickdistance="150"
tags="smallitem,loadable"
price="50">
price="50"
description="Used as a power source for various handheld devices. Most submarines have several stationary backup batteries with recharge docks for battery cells.">
<Sprite texture="weapons.png" sourcerect="0,0,20,9" depth="0.8"/>

View File

@@ -2,6 +2,7 @@
<Item
name="ID Card"
category="Equipment"
Tags="smallitem"
pickdistance="150">

View File

@@ -2,7 +2,7 @@
<style>
<GUIFrame
padding="40.0, 40.0, 40.0, 40.0"
color="0.0, 0.0, 0.0, 0.7"
color="0.8, 0.8, 0.8, 0.85"
textcolor="0.0, 0.0, 0.0, 1.0"
@@ -10,15 +10,21 @@
selectedcolor="1.0, 0.82, 0.05, 1.0"
outlinecolor="0.5, 0.57, 0.6, 1.0">
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
</GUIFrame>
<GUIButton
color="0.88, 0.25, 0.15, 0.3"
color="0.88, 0.25, 0.15, 0.8"
textcolor="1.0, 1.0, 1.0, 1.0"
hovercolor="0.88, 0.25, 0.15, 1.0"
selectedcolor="1.0, 0.0, 0.0, 1.0"/>
selectedcolor="1.0, 0.0, 0.0, 1.0">
<Sprite texture="Content/UI/uiButton.png" size="1.0, 1.0" tile="false" maintainaspectratio="false" sourcerect ="0.0, 0.0, 0.0, 71.0"/>
</GUIButton>
<GUITextBlock
textcolor="1.0, 1.0, 1.0, 1.0"
@@ -27,11 +33,9 @@
padding="10.0, 0.0, 10.0, 0.0"/>
<GUIListBox
color="0.5, 0.5, 0.5, 1.0"
color="0.0, 0.0, 0.0, 1.0"
textcolor="1.0, 1.0, 1.0, 1.0"
outlinecolor="0.5, 0.57, 0.6, 1.0">
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
</GUIListBox>
<GUIScrollBar
@@ -50,11 +54,10 @@
</GUIDropDown>
<GUITextBox
color="0.5, 0.5, 0.5, 1.0"
color="0.0, 0.0, 0.0, 1.0"
hovercolor="0.8, 0.8, 0.8, 1.0"
textcolor="1.0, 1.0, 1.0, 1.0"
outlinecolor="0.5, 0.57, 0.6, 1.0">
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
</GUITextBox>
<GUITickBox

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -13,6 +13,7 @@
<Item file="Content\Items\Electricity\signalitems.xml" />
<Item file="Content\Items\Engine\engine.xml" />
<Item file="Content\Items\Fabricators\fabricators.xml" />
<Item file="Content\Items\Fabricators\materials.xml" />
<Item file="Content\Items\Ladder\ladder.xml" />
<Item file="Content\Items\Lockers\lockers.xml" />
<Item file="Content\Items\Medical\medical.xml" />
@@ -25,11 +26,12 @@
<Item file="Content\Items\Weapons\railgun.xml" />
<Item file="Content\Items\Weapons\weapons.xml" />
<Character file="Content\Characters\Crawler\crawler.xml" />
<Character file="Content\Characters\EndWorm\endworm.xml" />
<Character file="Content\Characters\Human\human.xml" />
<Character file="Content\Characters\Mantis\mantis.xml" />
<Character file="Content\Characters\Moloch\moloch.xml" />
<Character file="Content\Characters\Scorpion\scorpion.xml" />
<Character file="Content\Characters\TigerThresher\tigerthresher.xml" />
<Character file="Content\Characters\TigerThresher\tigerthresher.xml" />
<Structure file="Content\Map\StructurePrefabs.xml" />
<Jobs file="Content\Jobs.xml" />
<Executable file="Barotrauma.exe" />

View File

@@ -17,6 +17,10 @@ namespace Barotrauma
private Character character;
private Vector2 currentTarget;
private float findPathTimer;
public SteeringPath CurrentPath
{
get { return currentPath; }
@@ -27,9 +31,10 @@ namespace Barotrauma
get { return pathFinder; }
}
private Vector2 currentTarget;
private float findPathTimer;
public Vector2 CurrentTarget
{
get { return currentTarget; }
}
public IndoorsSteeringManager(ISteerable host, bool canOpenDoors)
: base(host)

View File

@@ -54,13 +54,13 @@ namespace Barotrauma
if (container.Item.inventory == character.Inventory)
{
var containedItems = container.inventory.Items;
var containedItems = container.Inventory.Items;
//if there's already something in the mask (empty oxygen tank?), drop it
var existingItem = containedItems.FirstOrDefault(i => i != null);
if (existingItem != null) existingItem.Drop(character);
character.Inventory.RemoveItem(itemToContain);
container.inventory.TryPutItem(itemToContain, null, false);
container.Inventory.TryPutItem(itemToContain, null, false);
}
else
{

View File

@@ -90,35 +90,42 @@ namespace Barotrauma
{
character.Inventory.TryPutItem(targetItem, targetSlot, false);
}
}
return;
}
for (int i = 0; i<10 && currSearchIndex<Item.ItemList.Count; i++)
for (int i = 0; i<10 && currSearchIndex<Item.ItemList.Count-2; i++)
{
currSearchIndex++;
if (!Item.ItemList[currSearchIndex].HasTag(itemName) && Item.ItemList[currSearchIndex].Name != itemName) continue;
if (IgnoreContainedItems && Item.ItemList[currSearchIndex].container != null) continue;
if (Item.ItemList[currSearchIndex].inventory is CharacterInventory) continue;
targetItem = Item.ItemList[currSearchIndex];
targetItem = Item.ItemList[currSearchIndex];
AddGoToObjective(targetItem);
Item moveToTarget = targetItem;
while (moveToTarget.container != null)
{
moveToTarget = moveToTarget.container;
}
subObjectives.Add(new AIObjectiveGoTo(moveToTarget, character));
return;
}
if (currSearchIndex >= Item.ItemList.Count) canBeCompleted = false;
}
private void AddGoToObjective(Item item)
{
Item moveToTarget = item;
while (moveToTarget.container != null)
{
moveToTarget = moveToTarget.container;
}
AddSubObjective(new AIObjectiveGoTo(moveToTarget, character));
}
public override bool IsDuplicate(AIObjective otherObjective)
{

View File

@@ -22,7 +22,14 @@ namespace Barotrauma
{
if (repeat) return true;
var pathSteering = character.AIController.SteeringManager as IndoorsSteeringManager;
return (pathSteering.CurrentPath == null || !pathSteering.CurrentPath.Unreachable);
//path doesn't exist (= hasn't been searched for yet), assume for now that the target is reachable
if (pathSteering.CurrentPath == null) return true;
//steeringmanager is still targeting some other position, assume for now that the target is reachable
if ((target != null && Vector2.Distance(target.Position, targetPos) > 5.0f) ||
Vector2.Distance(pathSteering.CurrentTarget, targetPos) > 5.0f) return true;
return (!pathSteering.CurrentPath.Unreachable);
}
}

View File

@@ -47,9 +47,11 @@ namespace Barotrauma
for (int i = 0 ; i <amount; i++)
{
BackgroundSpritePrefab prefab = GetRandomPrefab();
Vector2 pos = FindSpritePosition(level, prefab);
Vector2? pos = FindSpritePosition(level, prefab);
var newSprite = new BackgroundSprite(prefab, pos);
if (pos == null) continue;
var newSprite = new BackgroundSprite(prefab, (Vector2)pos);
int n = 0;
@@ -62,16 +64,16 @@ namespace Barotrauma
if (existingSprite.Texture == newSprite.Prefab.Sprite.Texture) break;
}
sprites.Insert(i, newSprite);
sprites.Insert(n, newSprite);
}
}
private Vector2 FindSpritePosition(Level level, BackgroundSpritePrefab prefab)
private Vector2? FindSpritePosition(Level level, BackgroundSpritePrefab prefab)
{
Vector2 randomPos = new Vector2(Rand.Range(0.0f, level.Size.X), Rand.Range(0.0f, level.Size.Y));
var cells = level.GetCells(randomPos);
if (!cells.Any()) return Vector2.Zero;
if (!cells.Any()) return null;
VoronoiCell cell = cells[Rand.Int(cells.Count)];
GraphEdge bestEdge = null;

View File

@@ -235,7 +235,7 @@ namespace Barotrauma
textBlock.Font = GUI.SmallFont;
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
new GUIImage(new Rectangle(-10, -5, 0, 0), HeadSprite, Alignment.Left, frame);
new GUIImage(new Rectangle(-5, -5, 0, 0), HeadSprite, Alignment.Left, frame);
return frame;
}

View File

@@ -213,7 +213,9 @@ namespace Barotrauma
protected virtual void Apply(float deltaTime, Entity entity, List<IPropertyObject> targets)
{
if (explosion != null) explosion.Explode(entity.WorldPosition);
if (Fire) new FireSource(ConvertUnits.ToDisplayUnits(entity.SimPosition));
if (Fire) new FireSource(entity.WorldPosition);
if (sound != null) sound.Play(1.0f, 1000.0f, entity.WorldPosition);

View File

@@ -294,6 +294,7 @@ namespace Barotrauma
if (Character.Controlled != null)
{
Character.Controlled.Health = Character.Controlled.MaxHealth;
Character.Controlled.Oxygen = 100.0f;
Character.Controlled.Bleeding = 0.0f;
}
break;
@@ -365,7 +366,7 @@ namespace Barotrauma
}
break;
case "tutorial":
TutorialMode.StartTutorial();
TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);
break;
case "lobbyscreen":
case "lobby":

View File

@@ -7,6 +7,34 @@ using System.Xml.Linq;
namespace Barotrauma
{
public class UISprite
{
public Sprite Sprite
{
get;
private set;
}
public bool Tile
{
get;
private set;
}
public bool MaintainAspectRatio
{
get;
private set;
}
public UISprite(Sprite sprite, bool tile, bool maintainAspectRatio)
{
Sprite = sprite;
Tile = tile;
MaintainAspectRatio = maintainAspectRatio;
}
}
public class GUIComponentStyle
{
public readonly Vector4 Padding;
@@ -20,12 +48,14 @@ namespace Barotrauma
public readonly Color OutlineColor;
public readonly List<Sprite> Sprites;
public readonly List<UISprite> Sprites;
public readonly bool TileSprites;
public GUIComponentStyle(XElement element)
{
Sprites = new List<Sprite>();
Sprites = new List<UISprite>();
Padding = ToolBox.GetAttributeVector4(element, "padding", Vector4.Zero);
@@ -43,13 +73,17 @@ namespace Barotrauma
colorVector = ToolBox.GetAttributeVector4(element, "outlinecolor", new Vector4(0.0f, 0.0f, 0.0f, 0.0f));
OutlineColor = new Color(colorVector.X, colorVector.Y, colorVector.Z, colorVector.W);
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLower())
{
case "sprite":
Sprites.Add(new Sprite(subElement));
Sprite sprite = new Sprite(subElement);
bool maintainAspect = ToolBox.GetAttributeBool(subElement, "maintainaspectratio",false);
bool tile = ToolBox.GetAttributeBool(subElement, "tile", true);
Sprites.Add(new UISprite(sprite, tile, maintainAspect));
break;
}
}

View File

@@ -17,7 +17,23 @@ namespace Barotrauma
public bool CanBeSelected = true;
public bool Enabled { get; set; }
private bool enabled;
public bool Enabled
{
get
{
return enabled;
}
set
{
if (value == enabled) return;
enabled = value;
frame.Color = enabled ? color : Color.Gray * 0.7f;
}
}
public override Color Color
{
@@ -117,8 +133,6 @@ namespace Barotrauma
if (color!=null) this.color = (Color)color;
this.alignment = alignment;
Enabled = true;
if (parent != null) parent.AddChild(this);
frame = new GUIFrame(Rectangle.Empty, style, this);
@@ -127,6 +141,8 @@ namespace Barotrauma
textBlock = new GUITextBlock(Rectangle.Empty, text,
Color.Transparent, (this.style == null) ? Color.Black : this.style.textColor,
textAlignment, style, this);
Enabled = true;
}
public override void Draw(SpriteBatch spriteBatch)
@@ -175,7 +191,7 @@ namespace Barotrauma
DrawChildren(spriteBatch);
if (!Enabled) GUI.DrawRectangle(spriteBatch, rect, Color.Gray*0.5f, true);
//if (!Enabled) GUI.DrawRectangle(spriteBatch, rect, Color.Gray*0.5f, true);
}
}
}

View File

@@ -98,7 +98,7 @@ namespace Barotrauma
}
}
public List<Sprite> sprites;
public List<UISprite> sprites;
//public Alignment SpriteAlignment { get; set; }
//public bool RepeatSpriteX, RepeatSpriteY;
@@ -160,7 +160,7 @@ namespace Barotrauma
Font = GUI.Font;
sprites = new List<Sprite>();
sprites = new List<UISprite>();
children = new List<GUIComponent>();
CanBeFocused = true;
@@ -229,29 +229,38 @@ namespace Barotrauma
flashColor * (flashTimer / FlashDuration), true);
}
GUI.DrawRectangle(spriteBatch, rect, currColor * (currColor.A / 255.0f), true);
if (currColor.A>0.0f && !sprites.Any()) GUI.DrawRectangle(spriteBatch, rect, currColor * (currColor.A / 255.0f), true);
if (sprites != null)
{
foreach (Sprite sprite in sprites)
foreach (UISprite uiSprite in sprites)
{
if (TileSprites)
if (uiSprite.Tile)
{
Vector2 startPos = new Vector2(rect.X, rect.Y);
Vector2 size = new Vector2(Math.Min(sprite.SourceRect.Width,rect.Width), Math.Min(sprite.SourceRect.Height,rect.Height));
Vector2 size = new Vector2(Math.Min(uiSprite.Sprite.SourceRect.Width, rect.Width), Math.Min(uiSprite.Sprite.SourceRect.Height, rect.Height));
if (sprite.size.X == 0.0f) size.X = rect.Width;
if (sprite.size.Y == 0.0f) size.Y = rect.Height;
if (uiSprite.Sprite.size.X == 0.0f) size.X = rect.Width;
if (uiSprite.Sprite.size.Y == 0.0f) size.Y = rect.Height;
sprite.DrawTiled(spriteBatch, startPos, size, currColor * (currColor.A / 255.0f));
uiSprite.Sprite.DrawTiled(spriteBatch, startPos, size, currColor * (currColor.A / 255.0f));
}
else
{
float scale = (float)(rect.Width) / sprite.SourceRect.Width;
if (uiSprite.MaintainAspectRatio)
{
float scale = (float)(rect.Width) / uiSprite.Sprite.SourceRect.Width;
spriteBatch.Draw(uiSprite.Sprite.Texture, rect,
new Rectangle(uiSprite.Sprite.SourceRect.X, uiSprite.Sprite.SourceRect.Y, (int)(uiSprite.Sprite.SourceRect.Width), (int)(rect.Height / scale)),
currColor * (currColor.A / 255.0f), 0.0f, Vector2.Zero, SpriteEffects.None, 0.0f);
}
else
{
spriteBatch.Draw(uiSprite.Sprite.Texture, rect, uiSprite.Sprite.SourceRect, currColor * (currColor.A / 255.0f));
}
spriteBatch.Draw(sprite.Texture, rect,
new Rectangle(sprite.SourceRect.X, sprite.SourceRect.Y, (int)(sprite.SourceRect.Width), (int)(rect.Height / scale)),
currColor * (currColor.A / 255.0f), 0.0f, Vector2.Zero, SpriteEffects.None, 0.0f);
}
}
}
@@ -271,10 +280,13 @@ namespace Barotrauma
int width = 400;
if (toolTipBlock==null || (string)toolTipBlock.userData != ToolTip)
{
string wrappedText = ToolBox.WrapText(ToolTip, width, GUI.SmallFont);
toolTipBlock = new GUITextBlock(new Rectangle(0,0,width, wrappedText.Split('\n').Length*15), ToolTip, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, null, true, GUI.SmallFont);
toolTipBlock.Color = Color.Black*0.7f;
toolTipBlock.OutlineColor = Color.White;
//string wrappedText = ToolBox.WrapText(ToolTip, width, GUI.SmallFont);
toolTipBlock = new GUITextBlock(new Rectangle(0,0,width, 18), ToolTip, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, null, true, GUI.SmallFont);
toolTipBlock.padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
toolTipBlock.rect.Width = (int)(GUI.SmallFont.MeasureString(toolTipBlock.Text).X + 20);
toolTipBlock.rect.Height = toolTipBlock.Text.Split('\n').Length * 18;
toolTipBlock.Color = Color.Black * 0.7f;
//toolTipBlock.OutlineColor = Color.White;
toolTipBlock.userData = ToolTip;
}
@@ -353,7 +365,7 @@ namespace Barotrauma
selectedColor = style.SelectedColor;
padding = style.Padding;
sprites = new List<Sprite>(style.Sprites);
sprites = new List<UISprite>(style.Sprites);
OutlineColor = style.OutlineColor;

View File

@@ -1,5 +1,6 @@
using Microsoft.Xna.Framework;
using System;
using System.Linq;
namespace Barotrauma
{
@@ -45,7 +46,7 @@ namespace Barotrauma
if (state == ComponentState.Selected) currColor = selectedColor;
if (state == ComponentState.Hover) currColor = hoverColor;
GUI.DrawRectangle(spriteBatch, rect, currColor * (currColor.A/255.0f), true);
if (!sprites.Any()) GUI.DrawRectangle(spriteBatch, rect, currColor * (currColor.A/255.0f), true);
base.Draw(spriteBatch);
if (OutlineColor != Color.Transparent)

View File

@@ -59,7 +59,6 @@ namespace Barotrauma
public virtual void Draw(SpriteBatch spriteBatch)
{
//if (timerBar != null) timerBar.Draw(spriteBatch);
}
public virtual void Start()

View File

@@ -1,91 +1,26 @@
using FarseerPhysics;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Items.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma
namespace Barotrauma.Tutorials
{
class TutorialMode : GameMode
class BasicTutorial : TutorialType
{
public readonly CrewManager CrewManager;
private GUIComponent infoBox;
public static void StartTutorial()
public BasicTutorial(string name)
:base (name)
{
Submarine.Load("Content/Map/TutorialSub.sub", "");
GameMain.GameSession = new GameSession(Submarine.Loaded, "", GameModePreset.list.Find(gm => gm.Name.ToLower()=="tutorial"));
GameMain.GameSession.StartShift("tuto");
GameMain.GameSession.TaskManager.Tasks.Clear();
GameMain.GameScreen.Select();
}
public TutorialMode(GameModePreset preset)
: base(preset)
protected override IEnumerable<object> UpdateState()
{
CrewManager = new CrewManager();
}
public override void Start()
{
base.Start();
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 = Character.Create(charInfo, wayPoint.SimPosition);
Character.Controlled = character;
character.GiveJobItems(null);
var idCard = character.Inventory.FindItem("ID Card");
idCard.AddTag("com");
idCard.AddTag("eng");
CrewManager.AddCharacter(character);
//CoroutineManager.StartCoroutine(QuitChecker());
CoroutineManager.StartCoroutine(UpdateState());
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
if (Character.Controlled!=null && Character.Controlled.IsDead)
{
Character.Controlled = null;
CoroutineManager.StopCoroutine("TutorialMode.UpdateState");
infoBox = null;
CoroutineManager.StartCoroutine(Dead());
}
CrewManager.Update(deltaTime);
if (infoBox!=null) infoBox.Update(deltaTime);
}
private IEnumerable<object> UpdateState()
{
Submarine.Loaded.SetPosition(new Vector2(Submarine.Loaded.Position.X, 38500.0f));
//spawn some fish next to the player
GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(2,
GameMain.GameScreen.BackgroundCreatureManager.SpawnSprites(2,
Submarine.Loaded.Position + Character.Controlled.Position);
yield return new WaitForSeconds(4.0f);
@@ -99,7 +34,7 @@ namespace Barotrauma
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 CoroutineStatus.Running;
@@ -111,7 +46,7 @@ namespace Barotrauma
infoBox = CreateInfoFrame("Hold W or S to walk up or down stairs. Use shift to run.", true);
while (infoBox!=null)
while (infoBox != null)
{
yield return CoroutineStatus.Running;
}
@@ -123,7 +58,7 @@ namespace Barotrauma
Reactor reactor = Item.ItemList.Find(i => i.HasTag("tutorialreactor")).GetComponent<Reactor>();
reactor.MeltDownTemp = 20000.0f;
while (Vector2.Distance(Character.Controlled.Position, reactor.Item.Position)>200.0f)
while (Vector2.Distance(Character.Controlled.Position, reactor.Item.Position) > 200.0f)
{
yield return CoroutineStatus.Running;
}
@@ -133,7 +68,7 @@ namespace Barotrauma
while (Character.Controlled.SelectedConstruction != reactor.Item)
{
yield return CoroutineStatus.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.");
@@ -145,9 +80,9 @@ namespace Barotrauma
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("The reactor core has started generating heat, which in turn generates power for the submarine. The power generation is very low at the moment,"
+" because the reactor is set to shut itself down when the temperature rises above 500 degrees Celsius. You can adjust the temperature limit by changing the ''Shutdown Temperature'' in the control panel.", true);
while (infoBox!=null)
+ " because the reactor is set to shut itself down when the temperature rises above 500 degrees Celsius. You can adjust the temperature limit by changing the ''Shutdown Temperature'' in the control panel.", true);
while (infoBox != null)
{
reactor.ShutDownTemp = Math.Min(reactor.ShutDownTemp, 5000.0f);
yield return CoroutineStatus.Running;
@@ -155,10 +90,10 @@ namespace Barotrauma
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 isn't enough power, devices won't function properly (or at all), and if there's too much power, some devices may be damaged."
+" Try to raise the temperature of the reactor close to 3000 degrees by adjusting the fission and cooling rates.", true);
while (Math.Abs(reactor.Temperature-3000.0f) > 100.0f)
+ "If there isn't enough power, devices won't function properly (or at all), and if there's too much power, some devices may be damaged."
+ " Try to raise the temperature of the reactor close to 3000 degrees by adjusting the fission and cooling rates.", true);
while (Math.Abs(reactor.Temperature - 3000.0f) > 100.0f)
{
reactor.AutoTemp = false;
reactor.ShutDownTemp = Math.Min(reactor.ShutDownTemp, 5000.0f);
@@ -167,9 +102,9 @@ namespace Barotrauma
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("Looks like we're up and running! Now you should turn on the ''Automatic temperature control'', which will make the reactor "
+"automatically adjust the temperature to a suitable level. Even though it's an easy way to keep the reactor up and running most of the time, "
+"you should keep in mind that it changes the temperature very slowly and carefully, which may cause issues if there are sudden changes in grid load.");
+ "automatically adjust the temperature to a suitable level. Even though it's an easy way to keep the reactor up and running most of the time, "
+ "you should keep in mind that it changes the temperature very slowly and carefully, which may cause issues if there are sudden changes in grid load.");
while (!reactor.AutoTemp)
{
yield return CoroutineStatus.Running;
@@ -177,7 +112,7 @@ namespace Barotrauma
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("That's the basics of operating the reactor! Now that there's power available for the engines, it's time to get the submarine moving. "
+"Deselect the reactor by pressing E and head to the command room at the right edge of the vessel.");
+ "Deselect the reactor by pressing E and head to the command room at the right edge of the vessel.");
Steering steering = Item.ItemList.Find(i => i.HasTag("tutorialsteering")).GetComponent<Steering>();
Radar radar = steering.Item.GetComponent<Radar>();
@@ -188,19 +123,19 @@ namespace Barotrauma
}
CoroutineManager.StartCoroutine(KeepReactorRunning(reactor));
infoBox = CreateInfoFrame("Select the navigation terminal by walking next to it and pressing E.");
while (Character.Controlled.SelectedConstruction != steering.Item)
{
yield return CoroutineStatus.Running;
}
yield return new WaitForSeconds(0.5f);
infoBox = CreateInfoFrame("There seems to be something wrong with the navigation terminal."+
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.");
+ " 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)
{
@@ -221,15 +156,15 @@ namespace Barotrauma
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 (!HasItem("Wire"))
{
yield return CoroutineStatus.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>();
PowerTransfer junctionBox = Item.ItemList.Find(i => i != null && i.HasTag("tutorialjunctionbox")).GetComponent<PowerTransfer>();
while ((Character.Controlled.SelectedConstruction != junctionBox.Item &&
Character.Controlled.SelectedConstruction != steering.Item) ||
@@ -237,8 +172,8 @@ namespace Barotrauma
{
yield return CoroutineStatus.Running;
}
if (Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.GetComponent<Wire>()!=null) == null)
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.");
@@ -255,13 +190,13 @@ namespace Barotrauma
while (steeringConnection.Wires.FirstOrDefault(w => w != null) == null)
{
yield return CoroutineStatus.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)
while (Character.Controlled.SelectedConstruction != null)
{
yield return CoroutineStatus.Running;
}
@@ -270,16 +205,16 @@ namespace Barotrauma
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 if you don't care for neatly laid out wiring, you can just "
+"run it straight to the junction box.");
+ "run it straight to the junction box.");
while (Character.Controlled.SelectedConstruction == null || Character.Controlled.SelectedConstruction.GetComponent<PowerTransfer>()==null)
while (Character.Controlled.SelectedConstruction == null || Character.Controlled.SelectedConstruction.GetComponent<PowerTransfer>() == null)
{
yield return CoroutineStatus.Running;
}
infoBox = CreateInfoFrame("Connect the wire to the junction box by pulling it to the power connection, the same way you did with the navigation terminal.");
while (radar.Voltage<0.1f)
while (radar.Voltage < 0.1f)
{
yield return CoroutineStatus.Running;
}
@@ -293,7 +228,7 @@ namespace Barotrauma
}
infoBox = CreateInfoFrame("You can take a look at the area around the sub by pressing ''Activate Radar''.");
while (!radar.IsActive)
{
yield return CoroutineStatus.Running;
@@ -310,21 +245,21 @@ namespace Barotrauma
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.", true);
while (infoBox!=null)
+ "The engine at the back of the sub moves it forwards and backwards.", true);
while (infoBox != null)
{
yield return CoroutineStatus.Running;
}
infoBox = CreateInfoFrame("Steer the submarine downwards, heading further into the cavern.");
while (Submarine.Loaded.Position.Y > 31000.0f)
{
yield return CoroutineStatus.Running;
}
yield return new WaitForSeconds(1.0f);
yield return new WaitForSeconds(1.0f);
var moloch = Character.Create("Content/Characters/Moloch/moloch.xml", steering.Item.SimPosition + Vector2.UnitX * 25.0f);
moloch.PlaySound(AIController.AiState.Attack);
@@ -373,14 +308,14 @@ namespace Barotrauma
yield return new WaitForSeconds(0.5f);
Submarine.Loaded.GodMode = true;
Submarine.Loaded.GodMode = true;
var capacitor1 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
var capacitor2 = Item.ItemList.Find(i => i.HasTag("capacitor1")).GetComponent<PowerContainer>();
CoroutineManager.StartCoroutine(KeepEnemyAway(moloch, new PowerContainer[] { capacitor1, capacitor2 }));
infoBox = CreateInfoFrame("The hull has been breached! Close all the doors to the command room to stop the water from flooding the entire sub!");
Door commandDoor1 = Item.ItemList.Find(i => i.HasTag("commanddoor1")).GetComponent<Door>();
Door commandDoor2 = Item.ItemList.Find(i => i.HasTag("commanddoor2")).GetComponent<Door>();
Door commandDoor3 = Item.ItemList.Find(i => i.HasTag("commanddoor3")).GetComponent<Door>();
@@ -390,24 +325,24 @@ namespace Barotrauma
yield return CoroutineStatus.Running;
}
infoBox = CreateInfoFrame("You should quickly find yourself a diving mask or a diving suit. "+
infoBox = CreateInfoFrame("You should quickly find yourself a diving mask or a diving suit. " +
"There are some in the room next to the airlock.");
while (!HasItem("Diving Mask") && !HasItem("Diving Suit"))
{
yield return CoroutineStatus.Running;
yield return CoroutineStatus.Running;
}
if (HasItem("Diving Mask"))
{
infoBox = CreateInfoFrame("The diving mask will let you breathe underwater, but it won't protect from the water pressure outside the sub. "+
infoBox = CreateInfoFrame("The diving mask will let you breathe underwater, but it won't protect from the water pressure outside the sub. " +
"It should be fine for the situation at hand, but you still need to find an oxygen tank and drag it into the same slot as the mask." +
"You should grab one or two from one of the cabinets.");
}
else if (HasItem("Diving Suit"))
{
infoBox = CreateInfoFrame("In addition to letting you breathe underwater, the suit will protect you from the water pressure outside the sub " +
"(unlike the diving mask). However, you still need to drag an oxygen tank into the same slot as the suit to supply oxygen. "+
"(unlike the diving mask). However, you still need to drag an oxygen tank into the same slot as the suit to supply oxygen. " +
"You should grab one or two from one of the cabinets.");
}
@@ -420,35 +355,35 @@ namespace Barotrauma
infoBox = CreateInfoFrame("Now you should stop the creature attacking the submarine before it does any more damage. Head to the railgun room at the upper right corner of the sub.");
var railGun = Item.ItemList.Find(i => i.GetComponent<Turret>()!=null);
var railGun = Item.ItemList.Find(i => i.GetComponent<Turret>() != null);
while (Vector2.Distance(Character.Controlled.Position, railGun.Position)>500)
while (Vector2.Distance(Character.Controlled.Position, railGun.Position) > 500)
{
yield return new WaitForSeconds(1.0f);
}
infoBox = CreateInfoFrame("The railgun requires a large power surge to fire. The reactor can't provide a surge large enough, so we need to use the "
+" supercapacitors in the railgun room. The capacitors need to be charged first; select them and crank up the recharge rate.");
+ " supercapacitors in the railgun room. The capacitors need to be charged first; select them and crank up the recharge rate.");
while (capacitor1.RechargeSpeed<0.5f && capacitor2.RechargeSpeed<0.5f)
while (capacitor1.RechargeSpeed < 0.5f && capacitor2.RechargeSpeed < 0.5f)
{
yield return new WaitForSeconds(1.0f);
}
infoBox = CreateInfoFrame("The capacitors consume large amounts of power when they're being charged at a high rate, so "+
"be careful not to overload the electrical grid or the reactor. They also take some time to recharge, so now is a good "+
infoBox = CreateInfoFrame("The capacitors consume large amounts of power when they're being charged at a high rate, so " +
"be careful not to overload the electrical grid or the reactor. They also take some time to recharge, so now is a good " +
"time to head to the room below and load some shells for the railgun.");
var loader = Item.ItemList.Find(i => i.Name == "Railgun Loader").GetComponent<ItemContainer>();
while (Math.Abs(Character.Controlled.Position.Y - loader.Item.Position.Y)>80)
while (Math.Abs(Character.Controlled.Position.Y - loader.Item.Position.Y) > 80)
{
yield return CoroutineStatus.Running;
}
infoBox = CreateInfoFrame("Grab one of the shells. You can load it by selecting the railgun loader and dragging the shell to. "
+"one of the free slots. You need two hands to carry a shell, so make sure you don't have anything else in either hand.");
+ "one of the free slots. You need two hands to carry a shell, so make sure you don't have anything else in either hand.");
while (loader.Item.ContainedItems.FirstOrDefault(i => i != null && i.Name == "Railgun Shell") == null)
{
@@ -467,7 +402,7 @@ namespace Barotrauma
}
infoBox = CreateInfoFrame("Use the right mouse button to aim and wait for the creature to come closer. When you're ready to shoot, "
+"press the left mouse button.");
+ "press the left mouse button.");
while (!moloch.IsDead)
{
@@ -476,7 +411,7 @@ namespace Barotrauma
Submarine.Loaded.GodMode = false;
infoBox = CreateInfoFrame("The creature has died. Now you should fix the damages in the control room: "+
infoBox = CreateInfoFrame("The creature has died. Now you should fix the damages in the control room: " +
"Grab a welding tool from the closet in the railgun room.");
while (!HasItem("Welding Tool"))
@@ -484,20 +419,20 @@ namespace Barotrauma
yield return CoroutineStatus.Running;
}
infoBox = CreateInfoFrame("The welding tool requires fuel to work. Grab a welding fuel tank and attach it to the tool "+
infoBox = CreateInfoFrame("The welding tool requires fuel to work. Grab a welding fuel tank and attach it to the tool " +
"by dragging it into the same slot.");
do
{
var weldingTool = Character.Controlled.Inventory.Items.FirstOrDefault(i => i != null && i.Name == "Welding Tool");
if (weldingTool != null &&
if (weldingTool != null &&
weldingTool.ContainedItems.FirstOrDefault(contained => contained != null && contained.Name == "Welding Fuel Tank") != null) break;
yield return CoroutineStatus.Running;
} while (true);
infoBox = CreateInfoFrame("You can aim with the tool using the right mouse button and weld using the left button. "+
infoBox = CreateInfoFrame("You can aim with the tool using the right mouse button and weld using the left button. " +
"Head to the command room to fix the leaks there.");
do
@@ -518,7 +453,7 @@ namespace Barotrauma
} while (broken);
infoBox = CreateInfoFrame("Great! However, there's still quite a bit of water inside the sub. It should be pumped out "
+"using the pump in the room at the bottom of the submarine.");
+ "using the pump in the room at the bottom of the submarine.");
Pump pump = Item.ItemList.Find(i => i.HasTag("tutorialpump")).GetComponent<Pump>();
@@ -528,16 +463,16 @@ namespace Barotrauma
}
infoBox = CreateInfoFrame("The two pumps inside the ballast tanks "
+"are connected straight to the navigation terminal and can't be manually controlled unless you mess with their wiring, "+
"so you should only use the pump in the middle room to pump out the water. Select it, turn it on and adjust the pumping speed "+
+ "are connected straight to the navigation terminal and can't be manually controlled unless you mess with their wiring, " +
"so you should only use the pump in the middle room to pump out the water. Select it, turn it on and adjust the pumping speed " +
"to start pumping water out.");
while (pump.Item.CurrentHull.Volume>1000.0f)
while (pump.Item.CurrentHull.Volume > 1000.0f)
{
yield return CoroutineStatus.Running;
}
infoBox = CreateInfoFrame("That was all there is to this tutorial! Now you should be able to handle "+
infoBox = CreateInfoFrame("That was all there is to this tutorial! Now you should be able to handle " +
"most of the basic tasks on board the submarine.");
yield return new WaitForSeconds(4.0f);
@@ -572,34 +507,28 @@ namespace Barotrauma
yield return CoroutineStatus.Success;
}
private IEnumerable<object> Dead()
private bool HasItem(string itemName)
{
yield return new WaitForSeconds(3.0f);
if (Character.Controlled == null) return false;
var messageBox = new GUIMessageBox("You have died", "Do you want to try again?", new string[] { "Yes", "No" });
return Character.Controlled.Inventory.FindItem(itemName) != null;
}
messageBox.Buttons[0].OnClicked += Restart;
messageBox.Buttons[0].OnClicked += messageBox.Close;
messageBox.Buttons[1].OnClicked = GameMain.MainMenuScreen.SelectTab;
messageBox.Buttons[1].OnClicked += messageBox.Close;
protected IEnumerable<object> KeepReactorRunning(Reactor reactor)
{
do
{
reactor.AutoTemp = true;
reactor.ShutDownTemp = 5000.0f;
yield return CoroutineStatus.Running;
} while (Item.ItemList.Contains(reactor.Item));
yield return CoroutineStatus.Success;
}
private bool Restart(GUIButton button, object obj)
{
TutorialMode.StartTutorial();
return true;
}
private bool HasItem(string itemName)
{
if (Character.Controlled == null) return false;
return Character.Controlled.Inventory.Items.FirstOrDefault(i => i != null && i.Name == itemName)!=null;
}
/// <summary>
/// keeps the enemy away from the sub until the capacitors are loaded
@@ -619,7 +548,7 @@ namespace Barotrauma
Vector2 steering = targetPos - enemy.Position;
if (steering != Vector2.Zero) steering = Vector2.Normalize(steering);
enemy.AIController.Steering = steering*2.0f;
enemy.AIController.Steering = steering * 2.0f;
yield return CoroutineStatus.Running;
} while (capacitors.FirstOrDefault(c => c.Charge > 0.4f) == null);
@@ -627,60 +556,5 @@ namespace Barotrauma
yield return CoroutineStatus.Success;
}
private IEnumerable<object> KeepReactorRunning(Reactor reactor)
{
do
{
reactor.AutoTemp = true;
reactor.ShutDownTemp = 5000.0f;
yield return CoroutineStatus.Running;
} while (Item.ItemList.Contains(reactor.Item));
yield return CoroutineStatus.Success;
}
public override void Draw(SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
CrewManager.Draw(spriteBatch);
if (infoBox != null) infoBox.Draw(spriteBatch);
}
private bool CloseInfoFrame(GUIButton button, object userData)
{
infoBox = null;
return true;
}
private GUIComponent CreateInfoFrame(string text, bool hasButton = false)
{
int width = 300;
int height = hasButton ? 110 : 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);
var textBlock = new GUITextBlock(new Rectangle(10, 10, width - 40, height), text, GUI.Style, infoBlock, true);
if (hasButton)
{
var okButton = new GUIButton(new Rectangle(0,-40,80,25), "OK", Alignment.BottomCenter, GUI.Style, textBlock);
okButton.OnClicked = CloseInfoFrame;
}
GUI.PlayMessageSound();
return infoBlock;
}
}
}

View File

@@ -0,0 +1,56 @@
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Items.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Barotrauma.Tutorials;
namespace Barotrauma
{
class TutorialMode : GameMode
{
public TutorialType tutorialType;
public static void StartTutorial(TutorialType tutorialType)
{
Submarine.Load("Content/Map/TutorialSub.sub", "");
tutorialType.Initialize();
}
public TutorialMode(GameModePreset preset)
: base(preset)
{
}
public override void Start()
{
base.Start();
tutorialType.Start();
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
tutorialType.Update(deltaTime);
}
public override void Draw(SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
//CrewManager.Draw(spriteBatch);
tutorialType.Draw(spriteBatch);
}
}
}

View File

@@ -0,0 +1,163 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma.Tutorials
{
class TutorialType
{
public static List<TutorialType> TutorialTypes;
protected GUIComponent infoBox;
public string Name
{
get;
private set;
}
static TutorialType()
{
TutorialTypes = new List<TutorialType>();
TutorialTypes.Add(new BasicTutorial("Basic tutorial"));
}
public TutorialType(string name)
{
this.Name = name;
}
public virtual void Initialize()
{
GameMain.GameSession = new GameSession(Submarine.Loaded, "", GameModePreset.list.Find(gm => gm.Name.ToLower() == "tutorial"));
(GameMain.GameSession.gameMode as TutorialMode).tutorialType = this;
GameMain.GameSession.StartShift("tuto");
GameMain.GameSession.TaskManager.Tasks.Clear();
GameMain.GameScreen.Select();
}
public virtual void Start()
{
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 = Character.Create(charInfo, wayPoint.WorldPosition);
Character.Controlled = character;
character.GiveJobItems(null);
var idCard = character.Inventory.FindItem("ID Card");
idCard.AddTag("com");
idCard.AddTag("eng");
//CoroutineManager.StartCoroutine(QuitChecker());
CoroutineManager.StartCoroutine(UpdateState());
}
public virtual void Update(float deltaTime)
{
if (Character.Controlled != null && Character.Controlled.IsDead)
{
Character.Controlled = null;
CoroutineManager.StopCoroutine("TutorialMode.UpdateState");
infoBox = null;
CoroutineManager.StartCoroutine(Dead());
}
//CrewManager.Update(deltaTime);
if (infoBox != null) infoBox.Update(deltaTime);
}
protected virtual IEnumerable<object> UpdateState()
{
yield return CoroutineStatus.Success;
}
public virtual void Draw(SpriteBatch spriteBatch)
{
if (infoBox != null) infoBox.Draw(spriteBatch);
}
private IEnumerable<object> Dead()
{
yield return new WaitForSeconds(3.0f);
var messageBox = new GUIMessageBox("You have died", "Do you want to try again?", new string[] { "Yes", "No" });
messageBox.Buttons[0].OnClicked += Restart;
messageBox.Buttons[0].OnClicked += messageBox.Close;
messageBox.Buttons[1].OnClicked = GameMain.MainMenuScreen.SelectTab;
messageBox.Buttons[1].OnClicked += messageBox.Close;
yield return CoroutineStatus.Success;
}
protected bool CloseInfoFrame(GUIButton button, object userData)
{
infoBox = null;
return true;
}
protected GUIComponent CreateInfoFrame(string text, bool hasButton = false)
{
int width = 300;
int height = hasButton ? 110 : 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);
var textBlock = new GUITextBlock(new Rectangle(10, 10, width - 40, height), text, GUI.Style, infoBlock, true);
if (hasButton)
{
var okButton = new GUIButton(new Rectangle(0, -40, 80, 25), "OK", Alignment.BottomCenter, GUI.Style, textBlock);
okButton.OnClicked = CloseInfoFrame;
}
GUI.PlayMessageSound();
return infoBlock;
}
private bool Restart(GUIButton button, object obj)
{
TutorialMode.StartTutorial(this);
return true;
}
}
}

View File

@@ -164,7 +164,7 @@ namespace Barotrauma
{
TaskManager.Update(deltaTime);
guiRoot.Update(deltaTime);
//guiRoot.Update(deltaTime);
if (gameMode != null) gameMode.Update(deltaTime);
if (Mission != null) Mission.Update(deltaTime);
@@ -172,7 +172,7 @@ namespace Barotrauma
public void Draw(SpriteBatch spriteBatch)
{
guiRoot.Draw(spriteBatch);
//guiRoot.Draw(spriteBatch);
if (gameMode != null) gameMode.Draw(spriteBatch);
}

View File

@@ -261,14 +261,16 @@ namespace Barotrauma
}
}
if (multiSlot) continue;
UpdateSlot(spriteBatch, slotRect, i, Items[i], i > 4);
if (Items[i]!=null && slotRect.Contains(PlayerInput.MousePosition))
if (Items[i] != null && slotRect.Contains(PlayerInput.MousePosition))
{
toolTip = Items[i].Name;
toolTip = string.IsNullOrEmpty(Items[i].Description) ? Items[i].Name : Items[i].Name + '\n' + Items[i].Description;
highlightedSlot = slotRect;
}
UpdateSlot(spriteBatch, slotRect, i, Items[i], i > 4);
if (draggingItem!=null && draggingItem == Items[i]) draggingItemSlot = slotRect;
}
@@ -305,6 +307,12 @@ namespace Barotrauma
if (!multiSlot) continue;
if (Items[i] != null && slotRect.Contains(PlayerInput.MousePosition))
{
toolTip = string.IsNullOrEmpty(Items[i].Description) ? Items[i].Name : Items[i].Name + '\n' + Items[i].Description;
highlightedSlot = slotRect;
}
UpdateSlot(spriteBatch, slotRect, i, Items[i], i > 4);
}

View File

@@ -189,6 +189,8 @@ namespace Barotrauma.Items.Components
}
}
if (convexHull == null) return;
if (rect.Height == 0)
{
convexHull.Enabled = false;
@@ -219,8 +221,10 @@ namespace Barotrauma.Items.Components
body.SetTransform(body.SimPosition + ConvertUnits.ToSimUnits(amount), 0.0f);
convexHull.Move(amount);
if (convexHull2 != null) convexHull2.Move(amount);
UpdateConvexHulls();
//convexHull.Move(amount);
//if (convexHull2 != null) convexHull2.Move(amount);
}

View File

@@ -144,7 +144,7 @@ namespace Barotrauma.Items.Components
{
if (guiFrame==null)
{
DebugConsole.ThrowError("Error: the component "+name+" in "+item.Name+" doesn't have a guiFrame");
DebugConsole.ThrowError("Error: the component "+name+" in "+item.Name+" doesn't have a GuiFrame component");
guiFrame = new GUIFrame(new Rectangle(0, 0, 100, 100), Color.Black);
}
return guiFrame;

View File

@@ -10,7 +10,7 @@ namespace Barotrauma.Items.Components
class ItemContainer : ItemComponent
{
List<RelatedItem> containableItems;
public ItemInventory inventory;
public ItemInventory Inventory;
private bool hasStatusEffects;
@@ -94,7 +94,7 @@ namespace Barotrauma.Items.Components
public ItemContainer(Item item, XElement element)
: base (item, element)
{
inventory = new ItemInventory(item, this, capacity, hudPos, slotsPerRow);
Inventory = new ItemInventory(item, this, capacity, hudPos, slotsPerRow);
containableItems = new List<RelatedItem>();
foreach (XElement subElement in element.Elements())
@@ -119,7 +119,7 @@ namespace Barotrauma.Items.Components
public void RemoveContained(Item item)
{
inventory.RemoveItem(item);
Inventory.RemoveItem(item);
}
public bool CanBeContained(Item item)
@@ -132,7 +132,7 @@ namespace Barotrauma.Items.Components
{
if (!hasStatusEffects) return;
foreach (Item contained in inventory.Items)
foreach (Item contained in Inventory.Items)
{
if (contained == null || contained.Condition <= 0.0f) continue;
//if (contained.body != null) contained.body.Enabled = false;
@@ -185,7 +185,7 @@ namespace Barotrauma.Items.Components
currentRotation += item.body.Rotation;
}
foreach (Item containedItem in inventory.Items)
foreach (Item containedItem in Inventory.Items)
{
if (containedItem == null) continue;
@@ -204,7 +204,7 @@ namespace Barotrauma.Items.Components
{
if (!drawInventory && false) return;
inventory.Draw(spriteBatch);
Inventory.Draw(spriteBatch);
}
public override bool Pick(Character picker)
@@ -217,7 +217,7 @@ namespace Barotrauma.Items.Components
{
if (containableItems.Find(x => x.MatchesItem(item)) == null) return false;
if (inventory.TryPutItem(item))
if (Inventory.TryPutItem(item))
{
IsActive = true;
if (hideItems || (item.body!=null && !item.body.Enabled)) item.body.Enabled = false;
@@ -239,7 +239,7 @@ namespace Barotrauma.Items.Components
Item item = MapEntity.FindEntityByID(itemIds[i]) as Item;
if (item == null) continue;
inventory.TryPutItem(item, i, false);
Inventory.TryPutItem(item, i, false);
}
itemIds = null;
@@ -249,7 +249,7 @@ namespace Barotrauma.Items.Components
{
base.Remove();
foreach (Item item in inventory.Items)
foreach (Item item in Inventory.Items)
{
if (item == null) continue;
item.Remove();
@@ -280,10 +280,10 @@ namespace Barotrauma.Items.Components
{
XElement componentElement = base.Save(parentElement);
string[] itemIdStrings = new string[inventory.Items.Length];
for (int i = 0; i < inventory.Items.Length; i++)
string[] itemIdStrings = new string[Inventory.Items.Length];
for (int i = 0; i < Inventory.Items.Length; i++)
{
itemIdStrings[i] = (inventory.Items[i]==null) ? "0" : inventory.Items[i].ID.ToString();
itemIdStrings[i] = (Inventory.Items[i]==null) ? "0" : Inventory.Items[i].ID.ToString();
}
componentElement.Add(new XAttribute("contained", string.Join(",",itemIdStrings)));

View File

@@ -0,0 +1,109 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class Deconstructor : ItemComponent
{
GUIProgressBar progressBar;
GUIButton activateButton;
float progressTimer;
ItemContainer container;
public Deconstructor(Item item, XElement element)
: base(item, element)
{
progressBar = new GUIProgressBar(new Rectangle(0,0,200,20), Color.Green, 0.0f, Alignment.BottomCenter, GuiFrame);
activateButton = new GUIButton(new Rectangle(0, 0, 200, 20), "Deconstruct", Alignment.TopCenter, GUI.Style, GuiFrame);
activateButton.OnClicked = Activate;
}
public override void Update(float deltaTime, Camera cam)
{
if (container == null || !container.Inventory.Items.Any(i=>i!=null))
{
progressBar.BarSize = 0.0f;
//activateButton.Enabled = true;
if (container != null) container.Inventory.Locked = false;
IsActive = false;
return;
}
progressTimer += deltaTime;
var targetItem = container.Inventory.Items.FirstOrDefault(i => i != null);
progressBar.BarSize = Math.Min(progressTimer / targetItem.Prefab.DeconstructTime, 1.0f);
if (progressTimer>targetItem.Prefab.DeconstructTime)
{
var containers = item.GetComponents<ItemContainer>();
if (containers.Count<2)
{
DebugConsole.ThrowError("Error in Deconstructor.Update: Deconstructors must have two ItemContainer components!");
return;
}
foreach (string deconstructProduct in targetItem.Prefab.DeconstructItems)
{
var itemPrefab = ItemPrefab.list.FirstOrDefault(ip => ip.Name.ToLower() == deconstructProduct.ToLower()) as ItemPrefab;
if (itemPrefab==null)
{
DebugConsole.ThrowError("Tried to deconstruct item ''"+targetItem.Name+"'' but couldn't find item prefab ''"+deconstructProduct+"''!");
continue;
}
Item.Spawner.QueueItem(itemPrefab, containers[1].Inventory);
}
container.Inventory.RemoveItem(targetItem);
Item.Remover.QueueItem(targetItem);
activateButton.Text = "Deconstruct";
progressBar.BarSize = 0.0f;
progressTimer = 0.0f;
}
}
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
{
GuiFrame.Draw(spriteBatch);
}
private bool Activate(GUIButton button, object obj)
{
container = item.GetComponent<ItemContainer>();
if (container==null)
{
DebugConsole.ThrowError("Error in Deconstructor.Activate: Deconstructors must have two ItemContainer components");
return false;
}
if (IsActive)
{
progressBar.BarSize = 0.0f;
progressTimer = 0.0f;
activateButton.Text = "Deconstruct";
}
else
{
if (!container.Inventory.Items.Any(i => i != null)) return false;
activateButton.Text = "Cancel";
}
IsActive = !IsActive;
container.Inventory.Locked = IsActive;
return true;
}
}
}

View File

@@ -10,17 +10,12 @@ namespace Barotrauma.Items.Components
{
class FabricableItem
{
//public static List<FabricableItem> list = new List<FabricableItem>();
//public readonly string[] FabricatorTags;
public readonly ItemPrefab TargetItem;
public readonly List<ItemPrefab> RequiredItems;
public readonly float RequiredTime;
//ListOrSomething requiredLevels
public FabricableItem(XElement element)
@@ -69,12 +64,12 @@ namespace Barotrauma.Items.Components
if (subElement.Name.ToString() != "fabricableitem") continue;
FabricableItem fabricableItem = new FabricableItem(subElement);
if (fabricableItem.TargetItem != null) fabricableItems.Add(fabricableItem);
if (fabricableItem.TargetItem != null) fabricableItems.Add(fabricableItem);
}
int width = 500, height = 300;
itemList = new GUIListBox(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style);
GuiFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
itemList = new GUIListBox(new Rectangle(0,0,GuiFrame.Rect.Width/2-20,0), GUI.Style, GuiFrame);
itemList.OnSelected = SelectItem;
//structureList.CheckSelected = MapEntityPrefab.GetSelected;
@@ -98,17 +93,28 @@ namespace Barotrauma.Items.Components
FabricableItem targetItem = obj as FabricableItem;
if (targetItem == null) return false;
int width = 200, height = 150;
selectedItemFrame = new GUIFrame(new Rectangle(itemList.Rect.Right - width - 20, GameMain.GraphicsHeight/2-height/2, width, height), Color.Black*0.8f);
//selectedItemFrame.Padding = GUI.style.smallPadding;
if (selectedItemFrame != null) GuiFrame.RemoveChild(selectedItemFrame);
//int width = 200, height = 150;
selectedItemFrame = new GUIFrame(new Rectangle(0,0,(int)(GuiFrame.Rect.Width*0.4f),200), Color.Black*0.8f, Alignment.CenterY | Alignment.Right, null, GuiFrame);
selectedItemFrame.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
if (targetItem.TargetItem.sprite != null)
{
GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), targetItem.TargetItem.sprite, Alignment.CenterX, selectedItemFrame);
GUIImage img = new GUIImage(new Rectangle(10, 0, 40, 40), targetItem.TargetItem.sprite, Alignment.TopLeft, selectedItemFrame);
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
img.Color = targetItem.TargetItem.SpriteColor;
string text = targetItem.TargetItem.Name + "\n";
text += "Required items:\n";
new GUITextBlock(
new Rectangle(60, 0, 0, 25),
targetItem.TargetItem.Name,
Color.Transparent, Color.White,
Alignment.TopLeft,
Alignment.TopLeft, null,
selectedItemFrame, true);
string text = "Required items:\n";
foreach (ItemPrefab ip in targetItem.RequiredItems)
{
text += " - " + ip.Name + "\n";
@@ -116,11 +122,11 @@ namespace Barotrauma.Items.Components
text += "Required time: "+targetItem.RequiredTime+" s";
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0, 0, 0, 25),
new Rectangle(0, 50, 0, 25),
text,
Color.Transparent, Color.White,
Alignment.CenterX | Alignment.CenterY,
Alignment.Left, null,
Alignment.TopLeft,
Alignment.TopLeft, null,
selectedItemFrame);
GUIButton button = new GUIButton(new Rectangle(0,0,100,20), "Create", Color.White, Alignment.CenterX | Alignment.Bottom, GUI.Style, selectedItemFrame);
@@ -159,15 +165,22 @@ namespace Barotrauma.Items.Components
if (timeUntilReady > 0.0f) return;
ItemContainer container = item.GetComponent<ItemContainer>();
var containers = item.GetComponents<ItemContainer>();
if (containers.Count<2)
{
DebugConsole.ThrowError("Error while fabricating a new item: fabricators must have two ItemContainer components");
return;
}
foreach (ItemPrefab ip in fabricatedItem.RequiredItems)
{
var requiredItem = container.inventory.Items.FirstOrDefault(it => it != null && it.Prefab == ip);
container.inventory.RemoveItem(requiredItem);
var requiredItem = containers[0].Inventory.Items.FirstOrDefault(it => it != null && it.Prefab == ip);
containers[0].Inventory.RemoveItem(requiredItem);
}
Item.Spawner.QueueItem(fabricatedItem.TargetItem, item.Position);
Item.Spawner.QueueItem(fabricatedItem.TargetItem, containers[1].Inventory);
itemList.Enabled = true;
IsActive = false;
fabricatedItem = null;
}
@@ -182,20 +195,23 @@ namespace Barotrauma.Items.Components
ItemContainer container = item.GetComponent<ItemContainer>();
foreach (ItemPrefab ip in targetItem.RequiredItems)
{
if (Array.Find(container.inventory.Items, it => it != null && it.Prefab == ip) != null) continue;
if (Array.Find(container.Inventory.Items, it => it != null && it.Prefab == ip) != null) continue;
selectedItemFrame.GetChild<GUIButton>().Enabled = false;
break;
}
}
itemList.Update(0.016f);
itemList.Draw(spriteBatch);
GuiFrame.Update((float)Physics.step);
GuiFrame.Draw(spriteBatch);
if (selectedItemFrame != null)
{
selectedItemFrame.Update(0.016f);
selectedItemFrame.Draw(spriteBatch);
}
//itemList.Update(0.016f);
//itemList.Draw(spriteBatch);
//if (selectedItemFrame != null)
//{
// selectedItemFrame.Update(0.016f);
// selectedItemFrame.Draw(spriteBatch);
//}
}
}
}

View File

@@ -27,6 +27,16 @@ namespace Barotrauma
protected int capacity;
private Vector2 centerPos;
protected int selectedSlot;
public Item[] Items;
public bool Locked;
public Vector2 CenterPos
{
get { return centerPos; }
@@ -38,12 +48,6 @@ namespace Barotrauma
}
}
private Vector2 centerPos;
protected int selectedSlot;
public Item[] Items;
public Inventory(Entity owner, int capacity, Vector2? centerPos = null, int slotsPerRow=5)
{
this.capacity = capacity;
@@ -141,6 +145,8 @@ namespace Barotrauma
public void RemoveItem(Item item)
{
if (item == null) return;
//go through the inventory and remove the item from all slots
for (int n = 0; n < capacity; n++)
{
@@ -224,8 +230,12 @@ namespace Barotrauma
}
}
protected void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle highlightedSlot)
protected void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle highlightedSlot)
{
int maxWidth = 300;
toolTip = ToolBox.WrapText(toolTip, maxWidth, GUI.Font);
Vector2 textSize = GUI.Font.MeasureString(toolTip);
Vector2 rectSize = textSize * 1.2f;
@@ -235,15 +245,15 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch, pos, rectSize, Color.Black * 0.8f, true);
spriteBatch.DrawString(GUI.Font, toolTip,
new Vector2((int)pos.X + rectSize.X * 0.5f, (int)pos.Y + rectSize.Y * 0.5f),
new Vector2((int)(pos.X + rectSize.X * 0.5f), (int)(pos.Y + rectSize.Y * 0.5f)),
Color.White, 0.0f,
new Vector2((int)textSize.X * 0.5f, (int)textSize.Y * 0.5f),
new Vector2((int)(textSize.X * 0.5f), (int)(textSize.Y * 0.5f)),
1.0f, SpriteEffects.None, 0.0f);
}
protected void UpdateSlot(SpriteBatch spriteBatch, Rectangle rect, int slotIndex, Item item, bool isSubSlot, bool drawItem=true)
{
bool mouseOn = rect.Contains(PlayerInput.MousePosition);
bool mouseOn = rect.Contains(PlayerInput.MousePosition) && !Locked;
if (mouseOn)
{
@@ -292,7 +302,7 @@ namespace Barotrauma
Rectangle subRect = rect;
subRect.Height = 40;
selectedSlot = containerRect.Contains(PlayerInput.MousePosition) ? slotIndex : -1;
selectedSlot = containerRect.Contains(PlayerInput.MousePosition) && !Locked ? slotIndex : -1;
GUI.DrawRectangle(spriteBatch, containerRect, Color.Black * 0.8f, true);
GUI.DrawRectangle(spriteBatch, containerRect, Color.White);

View File

@@ -27,6 +27,7 @@ namespace Barotrauma
protected ItemPrefab prefab;
public static ItemSpawner Spawner = new ItemSpawner();
public static ItemRemover Remover = new ItemRemover();
private List<string> tags;
@@ -72,6 +73,11 @@ namespace Barotrauma
get { return prefab.Name; }
}
public string Description
{
get { return prefab.Description; }
}
public override Sprite Sprite
{
get { return prefab.sprite; }
@@ -211,7 +217,7 @@ namespace Barotrauma
get
{
ItemContainer c = GetComponent<ItemContainer>();
return (c == null) ? null : Array.FindAll(c.inventory.Items, i=>i!=null);
return (c == null) ? null : Array.FindAll(c.Inventory.Items, i=>i!=null);
}
}
@@ -296,6 +302,7 @@ namespace Barotrauma
break;
case "trigger":
case "sprite":
case "deconstruct":
break;
case "aitarget":
aiTarget = new AITarget(this);
@@ -329,6 +336,17 @@ namespace Barotrauma
return default(T);
}
public List<T> GetComponents<T>()
{
List<T> components = new List<T>();
foreach (ItemComponent ic in this.components)
{
if (ic is T) components.Add((T)(object)ic);
}
return components;
}
public void RemoveContained(Item contained)
{
@@ -548,7 +566,7 @@ namespace Barotrauma
{
ic.Update(deltaTime, cam);
ic.PlaySound(ActionType.OnActive, WorldPosition);
if (ic.IsActive) ic.PlaySound(ActionType.OnActive, WorldPosition);
//ic.ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
}
else
@@ -1306,8 +1324,8 @@ namespace Barotrauma
break;
case NetworkEventType.InventoryUpdate:
var itemContainer = GetComponent<ItemContainer>();
if (itemContainer == null || itemContainer.inventory == null) return false;
return itemContainer.inventory.FillNetworkData(NetworkEventType.InventoryUpdate, message, data);
if (itemContainer == null || itemContainer.Inventory == null) return false;
return itemContainer.Inventory.FillNetworkData(NetworkEventType.InventoryUpdate, message, data);
case NetworkEventType.ComponentUpdate:
case NetworkEventType.ImportantComponentUpdate:
@@ -1385,8 +1403,8 @@ namespace Barotrauma
case NetworkEventType.InventoryUpdate:
var itemContainer = GetComponent<ItemContainer>();
if (itemContainer == null || itemContainer.inventory == null) return;
itemContainer.inventory.ReadNetworkData(NetworkEventType.DropItem, message, sendingTime);
if (itemContainer == null || itemContainer.Inventory == null) return;
itemContainer.Inventory.ReadNetworkData(NetworkEventType.DropItem, message, sendingTime);
break;
case NetworkEventType.ComponentUpdate:
case NetworkEventType.ImportantComponentUpdate:

View File

@@ -38,6 +38,24 @@ namespace Barotrauma
get { return configFile; }
}
public string Description
{
get;
private set;
}
public List<string> DeconstructItems
{
get;
private set;
}
public float DeconstructTime
{
get;
private set;
}
public float PickDistance
{
get { return pickDistance; }
@@ -48,7 +66,6 @@ namespace Barotrauma
get { return pickThroughWalls; }
}
public override bool IsLinkable
{
get { return isLinkable; }
@@ -83,8 +100,11 @@ namespace Barotrauma
{
if (PlayerInput.LeftButtonClicked())
{
new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this, Submarine.Loaded);
var item = new Item(new Rectangle((int)position.X, (int)position.Y, (int)sprite.size.X, (int)sprite.size.Y), this, Submarine.Loaded);
//constructor.Invoke(lobject);
item.Submarine = Submarine.Loaded;
item.SetTransform(ConvertUnits.ToSimUnits(item.Position - Submarine.Loaded.Position), 0.0f);
item.FindHull();
placePosition = Vector2.Zero;
@@ -112,8 +132,13 @@ namespace Barotrauma
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released)
{
new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.Loaded);
var item = new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.Loaded);
placePosition = Vector2.Zero;
item.Submarine = Submarine.Loaded;
item.SetTransform(ConvertUnits.ToSimUnits(item.Position - Submarine.Loaded.Position), 0.0f);
item.FindHull();
//selected = null;
return;
}
@@ -161,6 +186,8 @@ namespace Barotrauma
name = ToolBox.GetAttributeString(element, "name", "");
if (name == "") DebugConsole.ThrowError("Unnamed item in "+filePath+"!");
Description = ToolBox.GetAttributeString(element, "description", "");
pickThroughWalls = ToolBox.GetAttributeBool(element, "pickthroughwalls", false);
pickDistance = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "pickdistance", 0.0f));
@@ -172,9 +199,13 @@ namespace Barotrauma
focusOnSelected = ToolBox.GetAttributeBool(element, "focusonselected", false);
offsetOnSelected = ToolBox.GetAttributeFloat(element, "offsetonselected", 0.0f);
FireProof = ToolBox.GetAttributeBool(element, "fireproof", false);
MapEntityCategory category;
Enum.TryParse(ToolBox.GetAttributeString(element, "category", "Item"), out category);
Category = category;
string spriteColorStr = ToolBox.GetAttributeString(element, "spritecolor", "1.0,1.0,1.0,1.0");
SpriteColor = new Color(ToolBox.ParseToVector4(spriteColorStr));
@@ -182,6 +213,9 @@ namespace Barotrauma
Triggers = new List<Rectangle>();
DeconstructItems = new List<string>();
DeconstructTime = 1.0f;
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLower())
@@ -189,6 +223,15 @@ namespace Barotrauma
case "sprite":
sprite = new Sprite(subElement, Path.GetDirectoryName(filePath));
size = sprite.size;
break;
case "deconstruct":
DeconstructTime = ToolBox.GetAttributeFloat(subElement, "time", 10.0f);
foreach (XElement deconstructItem in subElement.Elements())
{
DeconstructItems.Add(ToolBox.GetAttributeString(deconstructItem, "name", "not found"));
}
break;
case "trigger":
Rectangle trigger = new Rectangle(0, 0, 10,10);

View File

@@ -8,30 +8,76 @@ namespace Barotrauma
{
class ItemSpawner
{
private Queue<Pair<ItemPrefab, Vector2>> spawnQueue;
private Queue<Pair<ItemPrefab, object>> spawnQueue;
public ItemSpawner()
{
spawnQueue = new Queue<Pair<ItemPrefab, Vector2>>();
spawnQueue = new Queue<Pair<ItemPrefab, object>>();
}
public void QueueItem(ItemPrefab itemPrefab, Vector2 position)
{
var itemInfo = new Pair<ItemPrefab, Vector2>();
var itemInfo = new Pair<ItemPrefab, object>();
itemInfo.First = itemPrefab;
itemInfo.Second = position;
spawnQueue.Enqueue(itemInfo);
}
public void QueueItem(ItemPrefab itemPrefab, Inventory inventory)
{
var itemInfo = new Pair<ItemPrefab, object>();
itemInfo.First = itemPrefab;
itemInfo.Second = inventory;
spawnQueue.Enqueue(itemInfo);
}
public void Update()
{
while (spawnQueue.Count>0)
{
var itemInfo = spawnQueue.Dequeue();
if (itemInfo.Second is Vector2)
{
new Item(itemInfo.First, (Vector2)itemInfo.Second - Submarine.HiddenSubPosition, null);
}
else if (itemInfo.Second is Inventory)
{
var item = new Item(itemInfo.First, Vector2.Zero, null);
var inventory = itemInfo.Second as Inventory;
inventory.TryPutItem(item, null, false);
}
//!!!!!!!!!!!!!!!!!!!!!!
new Item(itemInfo.First, itemInfo.Second, null);
}
}
}
class ItemRemover
{
private Queue<Item> removeQueue;
public ItemRemover()
{
removeQueue = new Queue<Item>();
}
public void QueueItem(Item item)
{
removeQueue.Enqueue(item);
}
public void Update()
{
while (removeQueue.Count > 0)
{
var item = removeQueue.Dequeue();
item.Remove();
}
}
}

View File

@@ -353,7 +353,7 @@ namespace Barotrauma.Lights
else
{
shadowEffect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, shadowVertexCount*2 - 2);
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, shadowVertexCount * 2 - 2);
}
}

View File

@@ -222,6 +222,7 @@ namespace Barotrauma
}
Item.Spawner.Update();
Item.Remover.Update();
}
public virtual void Update(Camera cam, float deltaTime) { }

View File

@@ -7,6 +7,11 @@ using Microsoft.Xna.Framework.Input;
namespace Barotrauma
{
enum MapEntityCategory
{
Structure, Machine, Item, Electrical, Equipment, Material
}
class MapEntityPrefab
{
public static List<MapEntityPrefab> list = new List<MapEntityPrefab>();
@@ -57,6 +62,12 @@ namespace Barotrauma
get { return resizeVertical; }
}
public MapEntityCategory Category
{
get;
protected set;
}
public Color SpriteColor
{
get;

View File

@@ -138,17 +138,20 @@ namespace Barotrauma
newRect = Submarine.AbsRect(placePosition, placeSize);
//newRect.Width = (int)Math.Max(newRect.Width, Map.gridSize.X);
//newRect.Height = (int)Math.Max(newRect.Height, Map.gridSize.Y);
if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released)
{
new Structure(newRect, this, Submarine.Loaded);
if (Submarine.Loaded != null)
{
newRect.Location -= Submarine.Loaded.Position.ToPoint();
}
var structure = new Structure(newRect, this, Submarine.Loaded);
structure.Submarine = Submarine.Loaded;
selected = null;
return;
}
//position = placePosition;
}
sprite.DrawTiled(spriteBatch, new Vector2(newRect.X, -newRect.Y), new Vector2(newRect.Width, newRect.Height), Color.White);

View File

@@ -70,62 +70,90 @@ namespace Barotrauma
//GUITextBlock physicsBodyCount = new GUITextBlock(new Rectangle(0, 120, 0, 20), "", GUI.Style, GUIpanel);
//physicsBodyCount.TextGetter = GetPhysicsBodyCount;
GUIButton button = new GUIButton(new Rectangle(0, 150, 0, 20), "Items", Alignment.Left, GUI.Style, GUIpanel);
button.UserData = 0;
button.OnClicked = SelectTab;
button = new GUIButton(new Rectangle(0, 180, 0, 20), "Structures", Alignment.Left, GUI.Style, GUIpanel);
button.UserData = 1;
button.OnClicked = SelectTab;
//button = new GUIButton(new Rectangle(0, 180, 0, 20), "Structures", Alignment.Left, GUI.Style, GUIpanel);
//button.UserData = 1;
//button.OnClicked = SelectTab;
button = new GUIButton(new Rectangle(0, 220, 0, 20), "Character mode", Alignment.Left, GUI.Style, GUIpanel);
GUItabs = new GUIComponent[Enum.GetValues(typeof(MapEntityCategory)).Length];
int width = 400, height = 400;
int y = 150;
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
{
var catButton = new GUIButton(new Rectangle(0, y, 0, 20), category.ToString(), Alignment.Left, GUI.Style, GUIpanel);
catButton.UserData = (int)category;
catButton.OnClicked = SelectTab;
y+=25;
GUItabs[(int)category] = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style);
GUItabs[(int)category].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
GUIListBox itemList = new GUIListBox(new Rectangle(0, 0, 0, 0), Color.White * 0.7f, GUI.Style, GUItabs[(int)category]);
itemList.OnSelected = SelectPrefab;
itemList.CheckSelected = MapEntityPrefab.GetSelected;
foreach (MapEntityPrefab ep in MapEntityPrefab.list)
{
if (ep.Category != category) continue;
Color color = ((itemList.CountChildren % 2) == 0) ? Color.Transparent : Color.White * 0.1f;
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, null, itemList);
frame.UserData = ep;
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
frame.Color = color;
frame.HoverColor = Color.Gold * 0.2f;
frame.SelectedColor = Color.Gold * 0.5f;
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(40, 0, 0, 25),
ep.Name,
Color.Transparent, Color.White,
Alignment.Left, Alignment.Left,
null, frame);
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
ItemPrefab ip = ep as ItemPrefab;
if (ip != null && !string.IsNullOrWhiteSpace(ip.Description))
{
textBlock.ToolTip = ip.Description;
}
if (ep.sprite != null)
{
GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), ep.sprite, Alignment.Left, frame);
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
img.Color = ep.SpriteColor;
}
}
}
var button = new GUIButton(new Rectangle(0, y+50, 0, 20), "Character mode", Alignment.Left, GUI.Style, GUIpanel);
button.ToolTip = "Allows you to pick up and use items. Useful for things such as placing items inside closets, turning devices on/off and doing the wiring.";
button.OnClicked = ToggleCharacterMode;
button = new GUIButton(new Rectangle(0, 270, 0, 20), "Generate waypoints", Alignment.Left, GUI.Style, GUIpanel);
button = new GUIButton(new Rectangle(0, y+100, 0, 20), "Generate waypoints", Alignment.Left, GUI.Style, GUIpanel);
button.OnClicked = GenerateWaypoints;
GUItabs = new GUIComponent[2];
int width = 400, height = 400;
GUItabs[0] = new GUIFrame(new Rectangle(GameMain.GraphicsWidth/2-width/2, GameMain.GraphicsHeight/2-height/2, width, height), GUI.Style);
GUItabs[0].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
GUIListBox itemList = new GUIListBox(new Rectangle(0, 0, 0, 0), Color.White * 0.7f, GUI.Style, GUItabs[0]);
itemList.OnSelected = SelectPrefab;
itemList.CheckSelected = MapEntityPrefab.GetSelected;
GUItabs[1] = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style);
GUItabs[1].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
GUIListBox structureList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, GUI.Style, GUItabs[1]);
structureList.OnSelected = SelectPrefab;
structureList.CheckSelected = MapEntityPrefab.GetSelected;
foreach (MapEntityPrefab ep in MapEntityPrefab.list)
{
GUIListBox parent = ((ep as ItemPrefab) == null) ? structureList : itemList;
Color color = ((parent.CountChildren % 2) == 0) ? Color.Transparent : Color.White * 0.1f;
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 50), Color.Transparent, null, parent);
frame.UserData = ep;
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
frame.Color = color;
frame.HoverColor = Color.Gold * 0.2f;
frame.SelectedColor = Color.Gold * 0.5f;
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(40, 0, 0, 25),
ep.Name,
Color.Transparent, Color.White,
Alignment.Left, Alignment.Left,
null, frame);
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
//GUItabs[0] = new GUIFrame(new Rectangle(GameMain.GraphicsWidth/2-width/2, GameMain.GraphicsHeight/2-height/2, width, height), GUI.Style);
//GUItabs[0].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
//GUIListBox itemList = new GUIListBox(new Rectangle(0, 0, 0, 0), Color.White * 0.7f, GUI.Style, GUItabs[0]);
//itemList.OnSelected = SelectPrefab;
//itemList.CheckSelected = MapEntityPrefab.GetSelected;
//GUItabs[1] = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style);
//GUItabs[1].Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
//GUIListBox structureList = new GUIListBox(new Rectangle(0, 0, 0, 0), Color.White * 0.7f, GUI.Style, GUItabs[1]);
//structureList.OnSelected = SelectPrefab;
//structureList.CheckSelected = MapEntityPrefab.GetSelected;
if (ep.sprite != null)
{
GUIImage img = new GUIImage(new Rectangle(0, 0, 40, 40), ep.sprite, Alignment.Left, frame);
img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
img.Color = ep.SpriteColor;
}
}
}
public override void Select()

View File

@@ -254,7 +254,8 @@ namespace Barotrauma
private bool TutorialButtonClicked(GUIButton button, object obj)
{
TutorialMode.StartTutorial();
//!!!!!!!!!!!!!!!!!! placeholder
TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);
return true;
}

Binary file not shown.