Merge pull request #188 from Crystalwarrior/moStuff

Motion detectors, ducts, more chem effects and chems, fabricator/deconstructor overhaul, more footsteps, clown hitsounds...
This commit is contained in:
Joonas Rikkonen
2018-01-09 12:11:15 +02:00
committed by GitHub
69 changed files with 1411 additions and 539 deletions

View File

@@ -1,4 +1,5 @@
using FarseerPhysics;
using Barotrauma.Items.Components;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
@@ -20,7 +21,12 @@ namespace Barotrauma
if (impact > 3.0f && limb.HitSound != null && limb.SoundTimer <= 0.0f)
{
limb.SoundTimer = Limb.SoundInterval;
limb.HitSound.Play(volume, impact * 100.0f, limb.WorldPosition);
SoundPlayer.PlaySound(limb.HitSound, volume, impact * 100.0f, limb.WorldPosition);
foreach(WearableSprite wearable in limb.WearingItems)
{
if (limb.type == wearable.Limb && wearable.Sound != null)
SoundPlayer.PlaySound(wearable.Sound, volume, impact * 100.0f, limb.WorldPosition);
}
}
}
else if (body.UserData is Limb || body == Collider.FarseerBody)
@@ -29,7 +35,7 @@ namespace Barotrauma
{
if (impact > ImpactTolerance)
{
SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, Collider);
SoundPlayer.PlayDamageSound("LimbBlunt", strongestImpact, Collider);
}
}

View File

@@ -19,7 +19,7 @@ namespace Barotrauma
private Sound hitSound;
public Sound HitSound
public string HitSound
{
get { return hitSound; }
}
@@ -34,7 +34,7 @@ namespace Barotrauma
LightSource = new LightSource(subElement);
break;
case "sound":
hitSound = Sound.Load(subElement.GetAttributeString("file", ""));
hitSound = subElement.GetAttributeString("file", "");
break;
}
}

View File

@@ -26,7 +26,7 @@ namespace Barotrauma
{
bool singleplayer = GameMain.NetworkMember == null;
bool gameOver = gameSession.CrewManager.GetCharacters().All(c => c.IsDead);
bool gameOver = gameSession.CrewManager.GetCharacters().All(c => c.IsDead || c.IsUnconscious);
bool progress = Submarine.MainSub.AtEndPosition;
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.8f, null);
@@ -36,19 +36,23 @@ namespace Barotrauma
int y = 0;
if (singleplayer)
if (!singleplayer)
{
string summaryText = TextManager.Get(gameOver ? "RoundSummaryGameOver" :
(progress ? "RoundSummaryProgress" : "RoundSummaryReturn"));
summaryText = summaryText
.Replace("[sub]", Submarine.MainSub.Name)
.Replace("[location]", GameMain.GameSession.StartLocation.Name);
var infoText = new GUITextBlock(new Rectangle(0, y, 0, 50), summaryText, "", innerFrame, true);
y += infoText.Rect.Height;
//Game over if everyone dead or didn't progress
gameOver = gameOver || !progress;
SoundPlayer.OverrideMusicType = gameOver ? "crewdead" : "endround";
}
string summaryText = TextManager.Get(gameOver ? "RoundSummaryGameOver" :
(progress ? "RoundSummaryProgress" : "RoundSummaryReturn"));
summaryText = summaryText
.Replace("[sub]", Submarine.MainSub.Name)
.Replace("[location]", GameMain.GameSession.StartLocation.Name);
var infoText = new GUITextBlock(new Rectangle(0, y, 0, 50), summaryText, "", innerFrame, true);
y += infoText.Rect.Height;
if (!string.IsNullOrWhiteSpace(endMessage))
{
var endText = new GUITextBlock(new Rectangle(0, y, 0, 30), endMessage, "", innerFrame, true);

View File

@@ -143,6 +143,10 @@ namespace Barotrauma
{
wasPut = character.SelectedCharacter.Inventory.TryPutItem(doubleClickedItem, Character.Controlled, doubleClickedItem.AllowedSlots, true);
}
else if (character.SelectedBy != null && Character.Controlled == character.SelectedBy && character.SelectedBy.Inventory != null)
{
wasPut = character.SelectedBy.Inventory.TryPutItem(doubleClickedItem, Character.Controlled, doubleClickedItem.AllowedSlots, true);
}
else //doubleclicked and no other inventory is selected
{
//not equipped -> attempt to equip

View File

@@ -111,9 +111,9 @@ namespace Barotrauma.Items.Components
if (!inadequateSkills.Any())
{
text = "Required items:\n";
foreach (Tuple<ItemPrefab, int> ip in targetItem.RequiredItems)
foreach (Tuple<ItemPrefab, int, float, bool> ip in targetItem.RequiredItems)
{
text += " - " + ip.Item1.Name + " x" + ip.Item2 + "\n";
text += " - " + ip.Item1.Name + " x" + ip.Item2 + (ip.Item3 < 1.0f ? ", " + ip.Item3 * 100 + "% condition\n" : "\n");
}
text += "Required time: " + targetItem.RequiredTime + " s";
}

View File

@@ -127,6 +127,7 @@ namespace Barotrauma.Items.Components
if (target.IsDead)
{
texts.Add("Deceased");
texts.Add("Cause of Death: " + target.CauseOfDeath.ToString());
}
else
{

View File

@@ -87,6 +87,10 @@ namespace Barotrauma
DebugConsole.ThrowError("File \"" + file + "\" not found!");
return null;
}
Sound dupe = Sound.loadedSounds.Find(s => s.filePath == file);
if (dupe != null)
return dupe;
return new Sound(file, destroyOnGameEnd);
}
@@ -100,6 +104,9 @@ namespace Barotrauma
{
newSound.baseVolume = element.GetAttributeFloat("volume", 1.0f);
newSound.range = element.GetAttributeFloat("range", 1000.0f);
Sound dupe = Sound.loadedSounds.Find(s => s.filePath == filePath && s.baseVolume == newSound.baseVolume && s.range == newSound.range);
if (dupe != null)
return dupe;
}
return newSound;

View File

@@ -10,26 +10,19 @@ using System.Xml.Linq;
namespace Barotrauma
{
public enum DamageSoundType
{
None,
StructureBlunt, StructureSlash,
LimbBlunt, LimbSlash, LimbArmor
}
public struct DamageSound
{
//the range of inflicted damage where the sound can be played
//(10.0f, 30.0f) would be played when the inflicted damage is between 10 and 30
public readonly Vector2 damageRange;
public readonly DamageSoundType damageType;
public readonly string damageType;
public readonly Sound sound;
public readonly string requiredTag;
public DamageSound(Sound sound, Vector2 damageRange, DamageSoundType damageType, string requiredTag = "")
public DamageSound(Sound sound, Vector2 damageRange, string damageType, string requiredTag = "")
{
this.sound = sound;
this.damageRange = damageRange;
@@ -161,8 +154,7 @@ namespace Barotrauma
Sound damageSound = Sound.Load(subElement.GetAttributeString("file", ""), false);
if (damageSound == null) continue;
DamageSoundType damageSoundType = DamageSoundType.None;
Enum.TryParse<DamageSoundType>(subElement.GetAttributeString("damagesoundtype", "None"), false, out damageSoundType);
string damageSoundType = subElement.GetAttributeString("damagesoundtype", "None");
damageSounds.Add(new DamageSound(
damageSound,
@@ -271,7 +263,7 @@ namespace Barotrauma
public static Sound GetSound(string soundTag)
{
var matchingSounds = miscSounds[soundTag].ToList();
if (matchingSounds.Count == 0) return null;
if (matchingSounds.Count == 0) return Sound.Load(soundTag);
return matchingSounds[Rand.Int(matchingSounds.Count)];
}
@@ -442,14 +434,14 @@ namespace Barotrauma
SplashSounds[splashIndex].Play(1.0f, 800.0f, worldPosition);
}
public static void PlayDamageSound(DamageSoundType damageType, float damage, PhysicsBody body)
public static void PlayDamageSound(string damageType, float damage, PhysicsBody body)
{
Vector2 bodyPosition = body.DrawPosition;
PlayDamageSound(damageType, damage, bodyPosition, 800.0f);
}
public static void PlayDamageSound(DamageSoundType damageType, float damage, Vector2 position, float range = 2000.0f, List<string> tags = null)
public static void PlayDamageSound(string damageType, float damage, Vector2 position, float range = 2000.0f, List<string> tags = null)
{
damage = MathHelper.Clamp(damage+Rand.Range(-10.0f, 10.0f), 0.0f, 100.0f);
var sounds = damageSounds.FindAll(s =>

View File

@@ -295,6 +295,9 @@
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Door\doors.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Door\duct.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Door\hatch.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -740,7 +743,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Data\clientpermissions.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Data\ContentPackages\Vanilla 0.7.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -925,6 +928,9 @@
<None Include="$(MSBuildThisFileDirectory)Content\Items\Button\beep.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Button\switch.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Diving\divingSuit.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -940,6 +946,18 @@
<None Include="$(MSBuildThisFileDirectory)Content\Items\Door\door.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Door\DoorBreak1.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Door\DoorBreak2.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Door\duct.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Door\DuctBreak.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Electricity\powerOn.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -1144,6 +1162,18 @@
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Damage\HitArmor3.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Damage\HitClown1.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Damage\HitClown2.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Damage\HitClown3.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Damage\HitClown4.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Damage\implode.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -1210,6 +1240,45 @@
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\firelarge.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Armor\armor-01.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Armor\armor-02.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Armor\armor-03.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Clown\clown-01.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Clown\clown-02.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Metal\metal-01.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Metal\metal-02.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Metal\metal-03.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Metal\metal-04.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Metal\metal-05.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Metal\metal-06.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\Metal\metal-07.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Footsteps\step.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Music\amb_JD_drone_clattering_machine.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -1336,9 +1405,6 @@
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Water\WaterAmbience2.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\step.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\utg_4.xnb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -1348,9 +1414,24 @@
<None Include="$(MSBuildThisFileDirectory)Content\watershader_opengl.xnb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\Nehalennia.sub" />
<None Include="$(MSBuildThisFileDirectory)Submarines\TutorialSub.sub" />
<None Include="$(MSBuildThisFileDirectory)Submarines\Vellamo.sub" />
<None Include="$(MSBuildThisFileDirectory)Submarines\Aegir Mark III.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\Nehalennia.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\The Blind Carp.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\The Nibbler.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\TutorialSub.sub">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\Vellamo.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\AICharacter.cs" />

View File

@@ -65,7 +65,7 @@
<limb id = "8" radius="5" height="13" mass = "2" type ="LeftFoot" flip="true" pullpos="-5.0,0.0">
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="35,53,16,25" depth="0.14" origin="0.5,0.5"/>
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
<sound file ="Content/step.ogg"/>
<sound file ="footstep_metal"/>
</limb>
<!-- right leg -->
@@ -80,7 +80,7 @@
<limb id = "11" radius="5" height="13" mass = "2" type ="RightFoot" flip="true" pullpos="-5.0,0.0">
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
<sound file ="Content/step.ogg"/>
<sound file ="footstep_metal"/>
</limb>
<!-- head to body -->

View File

@@ -73,7 +73,7 @@
<limb id = "8" radius="5" height="13" mass = "2" type ="LeftFoot" flip="true" pullpos="-5.0,0.0">
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="35,53,16,25" depth="0.14" origin="0.5,0.5"/>
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
<sound file ="Content/step.ogg"/>
<sound file ="footstep_metal"/>
</limb>
<!-- right leg -->
@@ -88,7 +88,7 @@
<limb id = "11" radius="5" height="13" mass = "2" type ="RightFoot" flip="true" pullpos="-5.0,0.0">
<sprite texture="Content/Characters/Human/[GENDER]legs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
<damagedsprite texture="Content/Characters/Human/damagedlegs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
<sound file ="Content/step.ogg"/>
<sound file ="footstep_metal"/>
</limb>

View File

@@ -76,7 +76,7 @@
</limb>
<limb id = "8" radius="5" height="13" mass = "2" type ="LeftFoot" flip="true" pullpos="-5.0,0.0">
<sprite texture="Content/Characters/Husk/legs.png" sourcerect="35,53,16,25" depth="0.14" origin="0.5,0.5"/>
<sound file ="Content/step.ogg"/>
<sound file ="footstep_armor"/>
</limb>
<!-- right leg -->
@@ -88,7 +88,7 @@
</limb>
<limb id = "11" radius="5" height="13" mass = "2" type ="RightFoot" flip="true" pullpos="-5.0,0.0">
<sprite texture="Content/Characters/Husk/legs.png" sourcerect="35,53,16,25" origin="0.5,0.5"/>
<sound file ="Content/step.ogg"/>
<sound file ="footstep_armor"/>
</limb>
<!-- head to body -->

View File

@@ -95,33 +95,40 @@
tags="alien,smallitem,oxygensource"
impacttolerance="8">
<Deconstruct time="20">
<Item name="Steel Bar"/>
<Item name="Liquid Oxygenite" mincondition="0.1"/>
<Item name="Liquid Oxygenite" mincondition="0.5"/>
<Item name="Liquid Oxygenite" mincondition="0.9"/>
</Deconstruct>
<Sprite texture="artifact.png" depth="0.7" sourcerect="119,0,9,32"/>
<Body width="9" height="32" density="15"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,-5">
<Throwable slots="Any,RightHand,LeftHand" handle1="0,-5" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="Always" target="Hull" oxygen="5000.0"/>
<StatusEffect type="OnImpact" target="This" Condition="0.0" setvalue="true">
<sound file="Content/Items/Reactor/explosion.ogg"/>
<Explosion range="600.0" structuredamage="400" damage="300" stun="5" force="20.0"/>
</StatusEffect>
</Holdable>
</Throwable>
</Item>
<Item
name="Sulphurite Shard"
category="Alien"
tags="alien,smallitem"
impacttolerance="8"
spritecolor="1.0,0.0,0.0,1.0">
name="Sulphurite Shard"
category="Alien"
tags="alien,smallitem"
impacttolerance="8"
spritecolor="1.0,0.0,0.0,1.0">
<Deconstruct time="20">
<Item name="Steel Bar"/>
<Item name="Sulphuric Acid"/>
<Item name="Sulphuric Acid"/>
<Item name="Sulphuric Acid"/>
<Item name="Sulphuric Acid" mincondition="0.1"/>
<Item name="Sulphuric Acid" mincondition="0.5"/>
<Item name="Sulphuric Acid" mincondition="0.9"/>
</Deconstruct>
<Sprite texture="artifact.png" depth="0.7" sourcerect="119,0,9,32"/>
@@ -130,7 +137,7 @@
<Body width="8" height="32" density="15"/>
<Holdable slots="Any,RightHand,LeftHand" handle1="0,-5"/>
<Throwable slots="Any,RightHand,LeftHand" handle1="0,-5" throwforce="4.0" aimpos="35,-10"/>
</Item>
<Item
@@ -193,7 +200,7 @@
<Sprite texture="Content/Map/ruins.png" sourcerect="747,0,260,95" depth="0.8" origin="0.5,0.5"/>
<Door canbeselected="true" horizontal="true">
<Door canbepicked="false" canbeselected="true" horizontal="true">
<Sprite texture="Content/Map/ruins.png" sourcerect="0,842,260,54" depth="0.6" origin="0.0,0.5"/>
<sound file="aliendoor.ogg" type="OnUse" range="1000.0"/>
</Door>
@@ -215,7 +222,7 @@
<Sprite texture="Content/Map/ruins.png" sourcerect="746,101,93,259" depth="0.8" origin="0.5,0.5"/>
<Door canbeselected="true">
<Door canbepicked="false" canbeselected="true">
<Sprite texture="Content/Map/ruins.png" sourcerect="842,192,54,259" depth="0.6" origin="0.5,0.0"/>
<sound file="aliendoor.ogg" type="OnUse" range="3000.0"/>
</Door>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,33 +1,66 @@
<Item
name="Button"
category="Electrical"
linkable="true"
tags="smallitem"
price="10">
<Items>
<Item
name="Button"
category="Electrical"
linkable="true"
tags="smallitem"
price="10">
<Sprite texture ="button.png" depth="0.8"/>
<Sprite texture ="button.png" sourcerect="0,0,24,27" depth="0.8"/>
<Deconstruct time="10">
<Item name="Polycarbonate Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Body width="32" height="32" density="40"/>
<Body width="32" height="32" density="40"/>
<Controller direction ="None" canbepicked = "true" msg="Press [E]">
<RequiredItem name="ID Card" type="Picked" msg="UNAUTHORIZED ACCESS"/>
<sound file="beep.ogg" type="OnUse" range="500.0"/>
</Controller>
<Controller direction ="None" canbepicked = "true" msg="Press [E]">
<RequiredItem name="ID Card" type="Picked" msg="UNAUTHORIZED ACCESS"/>
<sound file="beep.ogg" type="OnUse" range="500.0"/>
</Controller>
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
<RequiredItem name="Screwdriver" type="Equipped"/>
<output name="signal_out"/>
</ConnectionPanel>
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
<RequiredItem name="Screwdriver" type="Equipped"/>
<output name="signal_out"/>
</ConnectionPanel>
<Holdable selectkey="Action" slots="Any,RightHand,LeftHand" msg="Detach [Wrench]" PickingTime="10.0"
aimpos="35,-10" handle1="0,0" attachable="true" attachedbydefault="true" aimable="true">
<requireditem name="Wrench" type="Equipped"/>
</Holdable>
</Item>
<Holdable selectkey="Action" slots="Any,RightHand,LeftHand" msg="Detach [Wrench]" PickingTime="10.0"
aimpos="35,-10" handle1="0,0" attachable="true" attachedbydefault="true" aimable="true">
<requireditem name="Wrench" type="Equipped"/>
</Holdable>
</Item>
<Item
name="Switch"
category="Electrical"
linkable="true"
tags="smallitem"
price="10">
<Sprite texture ="button.png" sourcerect="24,0,11,16" depth="0.79"/>
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Body width="16" height="16" density="20"/>
<Controller direction="None" canbepicked="true" msg="Press [E]">
<sound file="switch.ogg" type="OnUse" range="250.0"/>
</Controller>
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
<RequiredItem name="Screwdriver" type="Equipped"/>
<output name="signal_out"/>
</ConnectionPanel>
<Holdable selectkey="Action" slots="Any,RightHand,LeftHand" msg="Detach [Wrench]" PickingTime="10.0"
aimpos="35,-10" handle1="0,0" attachable="true" attachedbydefault="true" aimable="true">
<requireditem name="Wrench" type="Equipped"/>
</Holdable>
</Item>
</Items>

View File

@@ -68,6 +68,14 @@
fireproof="true"
description="An atmospheric diving suit capable of withstanding the immense pressure under Europa's crust.">
<Deconstruct time="30">
<Item name="Steel Bar"/>
<Item name="Aluminium"/>
<Item name="Aluminium"/>
<Item name="Polycarbonate Bar"/>
<Item name="Polycarbonate Bar"/>
</Deconstruct>
<Sprite texture ="DivingSuit.png" sourcerect="85,0,43,128" depth="0.55"/>
<Body width="37" height="113" density="15"/>
@@ -89,8 +97,8 @@
<sprite texture="DivingSuit.png" limb="RightLeg" sourcerect="17,47,21,51" origin="0.5,0.55" hidelimb="true"/>
<sprite texture="DivingSuit.png" limb="LeftLeg" sourcerect="17,47,21,51" origin="0.5,0.55" hidelimb="true"/>
<sprite texture="DivingSuit.png" limb="RightFoot" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
<sprite texture="DivingSuit.png" limb="LeftFoot" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
<sprite texture="DivingSuit.png" limb="RightFoot" sound="footstep_armor" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
<sprite texture="DivingSuit.png" limb="LeftFoot" sound="footstep_armor" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
<StatusEffect type="OnWearing" target="Character" HideFace="true" ObstructVision="true" PressureProtection="100.0" SpeedMultiplier="0.6" LowPassMultiplier="0.2" setvalue="true" disabledeltatime="true"/>
<StatusEffect type="OnWearing" target="Contained,Character" OxygenAvailable="1000.0" Condition="-0.5">
@@ -126,8 +134,9 @@
<Deconstruct time="20">
<Item name="Steel Bar"/>
<Item name="Copper Bar"/>
<Item name="Polycarbonate Bar"/>
<Item name="Polycarbonate Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture ="Scooter.png" depth="0.55"/>

View File

@@ -6,13 +6,16 @@
<Sprite texture ="door.png" sourcerect="1,0,48,208" depth="0.01" origin="0.5,0.5"/>
<Door canbeselected="true" selectkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
<Door canbeselected="true" pickkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
<requireditem name="Crowbar" type="Equipped"/>
<Sprite texture ="door.png" sourcerect="80,0,19,208" depth="0.05" origin="0.5,0.0"/>
<WeldedSprite texture ="door.png" sourcerect="99,0,32,188" depth="0.0" origin="0.5,0.5"/>
<BrokenSprite texture ="door.png" sourcerect="133,0,58,208" depth="0.051" origin="0.5,0.0" scale="true"/>
<sound file="door.ogg" type="OnUse" range="500.0"/>
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
<StatusEffect type="OnBroken" target="This">
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
</StatusEffect>
</Door>
<AiTarget sightrange="500.0"/>
@@ -37,13 +40,16 @@
<Sprite texture="door.png" sourcerect="1,0,48,208" depth="0.01" origin="0.5,0.5"/>
<Door window="0,-32,10,75" canbeselected="true" selectkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
<Door window="0,-32,10,75" canbeselected="true" pickkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
<requireditem name="Crowbar" type="Equipped"/>
<Sprite texture="door.png" sourcerect="56,0,19,208" depth="0.05" origin="0.5,0.0"/>
<WeldedSprite texture="door.png" sourcerect="9,0,32,188" depth="0.0" origin="0.5,0.5"/>
<BrokenSprite texture="door.png" sourcerect="192,0,40,208" depth="0.051" origin="0.5,0.0" scale="true"/>
<sound file="door.ogg" type="OnUse" range="500.0"/>
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
<StatusEffect type="OnBroken" target="This">
<sound file="Content/Items/Door/doorBreak1.ogg" range="3000"/>
</StatusEffect>
</Door>
<AiTarget sightrange="500.0"/>
@@ -68,13 +74,16 @@
<Sprite texture="hatch.png" sourcerect="0,0,128,46" depth="0.01" origin="0.5,0.5"/>
<Door canbeselected="true" horizontal="true" selectkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
<Door canbeselected="true" horizontal="true" pickkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
<requireditem name="Crowbar" type="Equipped"/>
<Sprite texture="hatch.png" sourcerect="128,0,128,19" depth="0.05" origin="0.0,0.5"/>
<WeldedSprite texture="hatch.png" sourcerect="0,56,108,33" depth="0.0" origin="0.5,0.5"/>
<BrokenSprite texture="hatch.png" sourcerect="128,21,128,58" depth="0.051" origin="0.0,0.5" scale="true"/>
<sound file="door.ogg" type="OnUse" range="500.0"/>
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
<StatusEffect type="OnBroken" target="This">
<sound file="Content/Items/Door/doorBreak1.ogg" range="3000"/>
</StatusEffect>
</Door>
<AiTarget sightrange="500.0"/>
@@ -103,6 +112,9 @@
<Sprite texture ="dockingport.png" sourcerect="127,0,112,144" depth="0.05" origin="0.5,0.5"/>
<sound file="dockingport1.ogg" type="OnUse" range="1000.0"/>
<sound file="dockingport2.ogg" type="OnSecondaryUse" range="1000.0"/>
<StatusEffect type="OnBroken" target="This">
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
</StatusEffect>
</DockingPort>
<PowerTransfer/>
@@ -134,6 +146,9 @@
<Sprite texture ="dockingport.png" sourcerect="127,144,48,112" depth="0.05" origin="0.5,0.5"/>
<sound file="dockingport1.ogg" type="OnUse" range="1000.0"/>
<sound file="dockingport2.ogg" type="OnSecondaryUse" range="1000.0"/>
<StatusEffect type="OnBroken" target="This">
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
</StatusEffect>
</DockingPort>
<fixrequirement name="Electrical repairs">
@@ -158,5 +173,39 @@
<output name="state_out"/>
<output name="proximity_sensor"/>
</ConnectionPanel>
</Item>
</Item>
<Item
name="Duct Block"
linkable="true"
>
<Sprite texture ="duct.png" sourcerect="0,0,33,33" depth="0.01" origin="0.5,0.5"/>
<Door canbeselected="true" pickkey="Action" msg="Force Open [Crowbar]" PickingTime="3.0">
<requireditem name="Crowbar" type="Equipped"/>
<Sprite texture ="duct.png" sourcerect="66,0,19,19" depth="0.05" origin="-0.4,0.5"/>
<WeldedSprite texture ="duct.png" sourcerect="33,0,33,33" depth="0.0" origin="0.5,0.5"/>
<BrokenSprite texture="duct.png" sourcerect="0,34,52,52" depth="0.051" origin="0.2,0.5" scale="true"/>
<sound file="duct.ogg" type="OnUse" range="300"/>
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="500.0"/>
<StatusEffect type="OnBroken" target="This">
<sound file="Content/Items/Door/ductBreak.ogg" range="2000"/>
</StatusEffect>
</Door>
<AiTarget sightrange="500.0"/>
<fixrequirement name="Mechanical repairs">
<skill name="Construction" level="30"/>
<item name="Welding Tool"/>
</fixrequirement>
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
<requireditem name="Screwdriver" type="Equipped"/>
<input name="toggle"/>
<input name="set_state"/>
<output name="state_out"/>
</ConnectionPanel>
</Item>
</Items>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -99,6 +99,11 @@
price="100"
description="Field-programmable gate array - a multi-purpose circuit which can be reconfigured for use in a large variety of electrical devices.">
<Deconstruct time="5">
<Item name="Copper Bar"/>
<Item name="Copper Bar"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="32,16,16,16"/>
<Body width="16" height="16" density="30"/>
@@ -335,7 +340,7 @@
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="96,0,31,24"/>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="97,0,31,24"/>
<OxygenDetector canbeselected = "true"/>
@@ -366,7 +371,7 @@
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="64,0,31,25"/>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="65,0,31,24"/>
<WaterDetector canbeselected = "true"/>
@@ -382,6 +387,37 @@
<output name="signal_out"/>
</ConnectionPanel>
</Item>
<Item
name="Motion Detector"
category="Electrical"
Tags="smallitem"
linkable="true"
price="10"
description="Sends out a signal when it detects movement.">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="65,24,31,24"/>
<MotionSensor range="100" canbeselected = "true"/>
<Body width="31" height="24" density="30"/>
<Holdable selectkey="Action" slots="Any,RightHand,LeftHand" msg="Detach [Wrench]" PickingTime="5.0"
aimpos="65,-10" handle1="0,0" attachable="true" aimable="true">
<requireditem name="Wrench" type="Equipped"/>
</Holdable>
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
<requireditem name="Screwdriver,Wire" type="Equipped"/>
<output name="state_out"/>
</ConnectionPanel>
</Item>
<Item
name="Signal Check Component"
@@ -561,7 +597,7 @@
<Item name="FPGA Circuit"/>
</Deconstruct>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="64,32,23,16"/>
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="34,64,23,16"/>
<Body width="20" height="16" density="20"/>

View File

@@ -19,6 +19,9 @@
<RequiredSkill name="Construction" level="30"/>
</fabricableitem>
<fabricableitem name="Spear" requireditems="Steel Bar" requiredtime="10"/>
<fabricableitem name="Revolver Round" requireditems="Copper Bar" requiredtime="10">
<Item name="Aluminium" mincondition="0.5" usecondition="true"/>
</fabricableitem>
<fabricableitem name="Plasma Cutter" requireditems="Steel Bar, Polycarbonate Bar, Aluminium" requiredtime="20">
<RequiredSkill name="Construction" level="30"/>
@@ -33,10 +36,26 @@
<fabricableitem name="Nuclear Shell" requireditems="Steel Bar, Steel Bar, Uranium Bar, Polycarbonate Bar" requiredtime="30">
<RequiredSkill name="Construction" level="40"/>
</fabricableitem>
<fabricableitem name="Depth Charge Shell" requireditems="Steel Bar, Steel Bar" requiredtime="20">
<RequiredSkill name="Construction" level="25"/>
</fabricableitem>
<fabricableitem name="Nuclear Depth Charge" requireditems="Steel Bar, Steel Bar, Uranium Bar" requiredtime="30">
<RequiredSkill name="Construction" level="40"/>
</fabricableitem>
<fabricableitem name="Diving Mask" requireditems="Polycarbonate Bar" requiredtime="20">
<RequiredSkill name="Construction" level="25"/>
</fabricableitem>
<fabricableitem name="Diving Suit" requireditems="Steel Bar, Polycarbonate Bar, Polycarbonate Bar, Aluminium, Aluminium" requiredtime="30">
<RequiredSkill name="Construction" level="40"/>
</fabricableitem>
<fabricableitem name="Fire Extinguisher" requireditems="Steel Bar, Polycarbonate Bar" requiredtime="10"/>
<fabricableitem name="Flashlight" requireditems="Copper Bar, Polycarbonate Bar" requiredtime="10"/>
<fabricableitem name="Wire" requireditems="Copper Bar" requiredtime="5"/>
<fabricableitem name="Button" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<fabricableitem name="Switch" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
<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"/>
@@ -45,6 +64,7 @@
<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="Motion 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="Oscillator" requireditems="Steel Bar, FPGA Circuit" requiredtime="10"/>
@@ -54,25 +74,42 @@
<fabricableitem name="Underwater Scooter" requireditems="Steel Bar, Polycarbonate Bar, Polycarbonate Bar, FPGA Circuit" requiredtime="30"/>
<fabricableitem name="Fulgurium Battery Cell" requireditems="Steel Bar, Fulgurium Bar, Sulphuric Acid" requiredtime="10"/>
<fabricableitem name="Flare" requireditems="Phosphorus,Aluminium" requiredtime="10"/>
<fabricableitem name ="Stun Grenade" requireditems="Steel Bar, Flash Powder, Chloral Hydrate" requiredtime="20">
<RequiredSkill name="Construction" level="30"/>
<fabricableitem name="Fulgurium Battery Cell" requireditems="Steel Bar, Fulgurium Bar" requiredtime="10">
<Item name="Sulphuric Acid" mincondition="0.75"/>
</fabricableitem>
<fabricableitem name ="Incendium Grenade" requireditems="Stun Grenade, Incendium Bar" requiredtime="20">
<fabricableitem name="Flare" requiredtime="10">
<Item name="Phosphorus" mincondition="0.25" usecondition="true"/>
<Item name="Aluminium" mincondition="0.25" usecondition="true"/>
</fabricableitem>
<fabricableitem name ="Stun Grenade" requireditems="Steel Bar" requiredtime="20">
<RequiredSkill name="Construction" level="30"/>
<Item name="Flash Powder" mincondition="0.75"/>
<Item name="Chloral Hydrate" mincondition="0.75"/>
</fabricableitem>
<fabricableitem name ="Incendium Grenade" requireditems="Steel Bar, Incendium Bar" requiredtime="20">
<RequiredSkill name="Construction" level="40"/>
<Item name="Flash Powder" mincondition="0.75"/>
</fabricableitem>
<fabricableitem name ="IC-4 Block" requireditems="C-4 Block, Incendium Bar" requiredtime="20"/>
<fabricableitem name="Battery Cell" requireditems="Steel Bar, Copper Bar, Sulphuric Acid" requiredtime="10"/>
<fabricableitem name="Battery Cell" requireditems="Steel Bar, Copper Bar" requiredtime="10">
<Item name="Sulphuric Acid" mincondition="0.75"/>
</fabricableitem>
<fabricableitem name="Fuel Rod" requireditems="Steel Bar, Uranium Bar"/>
<fabricableitem name="Incendium Fuel Rod" requireditems="Steel Bar, Incendium Bar"/>
<fabricableitem name="Uranium Bar">
<Item name="Uranium Powder" count="3" mincondition="0.75"/>
</fabricableitem>
<fabricableitem name="Oxygen Tank" requireditems="Steel Bar" outcondition="0.0"/>
<fabricableitem name="Welding Fuel Tank" requireditems="Steel Bar" outcondition="0.0"/>
</Fabricator>
<ConnectionPanel selectkey="Action" canbeselected = "true">
@@ -124,6 +161,10 @@
<RequiredSkill name="Medical" level="50"/>
</fabricableitem>
<fabricableitem name="Chloromydride" requireditems="Stabilozine, Erythrozine, Chloral Hydrate" requiredtime="20">
<RequiredSkill name="Medical" level="50"/>
</fabricableitem>
<fabricableitem name="Flash Powder" requireditems="Aluminium, Potassium" requiredtime="25">
<RequiredSkill name="Medical" level="40"/>
</fabricableitem>
@@ -140,11 +181,17 @@
<RequiredSkill name="Medical" level="60"/>
</fabricableitem>
<fabricableitem name="Morbusanide" outcondition="0.25" requiredtime="10">
<RequiredSkill name="Medical" level="60"/>
<Item name="Morbusine" mincondition="0.25"/>
<Item name="Stabilozine" mincondition="0.25"/>
</fabricableitem>
<fabricableitem name="Calyxanide" requireditems="Velonaceps Calyx Eggs, Corrigodone" requiredtime="30">
<RequiredSkill name="Medical" level="60"/>
</fabricableitem>
<fabricableitem name="Liquid Oxygenite" requireditems="Stabilozine, Oxygenite Shard" requiredtime="30">
<fabricableitem name="Sufforin" requireditems="Erythrozine, Flash Powder, Sulphuric Acid" requiredtime="30">
<RequiredSkill name="Medical" level="60"/>
</fabricableitem>
</Fabricator>

View File

@@ -4,7 +4,9 @@
category="Equipment"
tags="smallitem"
description="Allows remote communication between the crew.">
description="Allows remote communication between the crew."
price="10">
<Sprite texture ="headset.png" depth="0.6"/>
@@ -39,6 +41,10 @@
<Body width="10" radius="10" density="10"/>
<Deconstruct time="10">
<Item name="Bike Horn"/>
</Deconstruct>
<Wearable limbtype="Head" slots="Any,Face">
<sprite texture="clownmask.png" limb="Head" origin="0.5,0.5"/>
<StatusEffect type="OnWearing" target="Character" HideFace="true"/>
@@ -56,6 +62,12 @@
<Body width="53" height="18" density="30"/>
<Deconstruct time="40">
<Item name="Bike Horn"/>
<Item name="Bike Horn"/>
<Item name="Bike Horn"/>
</Deconstruct>
<Wearable slots="Any,Torso+Legs">
<sprite texture="clownshirt.png" limb="Torso" sourcerect="0,3,30,58" origin="0.5,0.48" depth="0.02"/>
@@ -72,9 +84,12 @@
<sprite texture="clownpants.png" limb="RightLeg" sourcerect="37,0,28,52" origin="0.55,0.5" depth="0.11" hidelimb="true"/>
<sprite texture="clownpants.png" limb="LeftLeg" sourcerect="37,0,28,52" origin="0.55,0.5" depth="0.15" hidelimb="true"/>
<sprite texture="clownpants.png" limb="RightFoot" sourcerect="65,41,15,39" origin="0.5,0.35" depth="0.11" hidelimb="true"/>
<sprite texture="clownpants.png" limb="LeftFoot" sourcerect="65,41,15,39" origin="0.5,0.35" depth="0.15" hidelimb="true"/>
<sprite texture="clownpants.png" limb="RightFoot" sound="footstep_clown" sourcerect="65,41,15,39" origin="0.5,0.35" depth="0.11" hidelimb="true"/>
<sprite texture="clownpants.png" limb="LeftFoot" sound="footstep_clown" sourcerect="65,41,15,39" origin="0.5,0.35" depth="0.15" hidelimb="true"/>
<!-- HENK -->
<damagemodifier damagetype="Blunt" armorsector="0.0,360.0" damagemultiplier="1.0" damagesound="LimbClown"/>
<damagemodifier damagetype="Slash" armorsector="0.0,360.0" damagemultiplier="1.0" damagesound="LimbClown"/>
</Wearable>
</Item>
</Items>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Items>
<!-- Medical items -->
<Item
name="Medical Syringe"
category="Equipment"
@@ -48,15 +49,20 @@
<Body width="11" height="16" density="20"/>
<MeleeWeapon slots="Any,RightHand,LeftHand"
<MeleeWeapon canBeCombined="true" slots="Any,RightHand,LeftHand"
aimpos="5,0" handle1="-5,0" holdangle="10" reload="1.0">
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
<StatusEffect type="OnUse" target="This, Character" bleeding="-0.1" duration="5.0">
<Sound file="Content/Items/Medical/bandage.ogg" range="500"/>
</StatusEffect>
<StatusEffect type="OnUse" target="This, Character" health="0.1" duration="5.0" checkconditionalalways="true">
<!-- Only give healing effect if their health is more than 50 -->
<Conditional Health="gt 50"/>
</StatusEffect>
</MeleeWeapon>
</Item>
<!-- Ingredients/weak chems -->
<Item
name="Iron Powder"
category="Material"
@@ -67,7 +73,11 @@
<Body width="8" height="16" density="40"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="poison,iron" type="OnUse" target="Character" Health="-2" duration="10">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
@@ -75,7 +85,8 @@
category="Material"
spritecolor="1.0,1.0,0.7,1.0"
Tags="smallitem,chem,medical"
description="A mild stimulant which is used as an incredient in the manufacture of various medicines."
description="A mild stimulant which is used as an ingredient in the manufacture of various medicines."
canuseonself="true"
price="10">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6" />
@@ -83,17 +94,139 @@
<Body width="8" height="17" density="20"/>
<ItemComponent>
<StatusEffect type="OnUse" target="Character" Health="0.1" duration="20"/>
<StatusEffect tags="medical" type="OnUse" target="Character" Health="0.1" duration="20"/>
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
</ItemComponent>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="0.3" Oxygen="0.3" duration="10">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" Health="0.3" Oxygen="0.3" duration="10">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Chlorine"
category="Material"
spritecolor="1.0,1.0,1.0,0.6"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="17" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="poison,chlorine" type="OnUse" target="Character" Health="-0.1" duration="20.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Ethanol"
category="Material"
spritecolor="0.0,0.9,0.1,1.0"
Tags="smallitem,chem,medical"
canuseonself="true"
price="20">
<ItemComponent>
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
<StatusEffect tags="drunk" type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0"/>
</ItemComponent>
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="7" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="drunk" type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Aluminium"
category="Material"
spritecolor="0.7,0.7,0.7,1.0"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Potassium"
category="Material"
spritecolor="0.8,0.8,0.8,1.0"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
<StatusEffect type="InWater" target="This" Condition="0.0" setvalue="true">
<Sound file="Content/Items/Reactor/explosion.ogg"/>
<Explosion range="250.0" structuredamage="10" damage="20" stun="5" force="5.0"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Phosphorus"
category="Material"
spritecolor="0.5,0.0,0.0,1.0"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<!-- Helpful chems -->
<Item
name="Chloromydride"
category="Material"
spritecolor="0.7,0.9,1.0,1.0"
Tags="smallitem,chem,medical"
description="A strong synaptic stimulant and cardiostimulant which is used as a preventative measure against critical condition. Should only be injected once every 30 seconds."
price="50">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6" />
<Body width="8" height="16" density="20"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" health="1.0" bleeding="-0.2" Oxygen="0.6" duration="30" stackable="false" checkconditionalalways="true">
<!-- Rapidly removes bleeding and stabilizes oxygen intake while also counteracting crit damage so they won't die. Doesn't prevent poisons.
EXTREMELY useful to follow up with CPR, especially if they were bleeding before. -->
<Conditional Health="lt 0.1"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Erythrozine"
category="Material"
@@ -107,8 +240,8 @@
<Body width="8" height="16" density="20"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-0.3" Oxygen="2.0" duration="10">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" Health="-0.3" Oxygen="2.0" duration="10">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
@@ -128,12 +261,12 @@
<Body width="8" height="16" density="20"/>
<ItemComponent>
<StatusEffect type="OnUse" target="Character" Bleeding="-0.1" duration="10.0"/>
<StatusEffect tags="medical" type="OnUse" target="Character" Bleeding="-0.1" duration="10.0"/>
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
</ItemComponent>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Bleeding="-0.2" duration="5.0">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" Health="0.3" Bleeding="-0.2" duration="5.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
@@ -155,11 +288,11 @@
<ItemComponent>
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
<StatusEffect type="OnUse" target="Character, This" Health="-0.5" duration="10"/>
<StatusEffect tags="medical" type="OnUse" target="Character, This" Health="-0.5" duration="10"/>
</ItemComponent>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="3.0" duration="5.0">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" Health="3.0" duration="5.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
@@ -178,181 +311,8 @@
<Body width="8" height="16" density="20"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="1.0" Oxygen="2.0" Bleeding="-0.05" duration="60.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Chlorine"
category="Material"
spritecolor="1.0,1.0,1.0,0.6"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="17" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-0.1" duration="20.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Ethanol"
category="Material"
spritecolor="0.0,0.9,0.1,1.0"
Tags="smallitem,chem,medical"
canuseonself="true"
price="20">
<ItemComponent>
<StatusEffect type="OnUse" target="This" Condition="-25.0" disabledeltatime="true"/>
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0"/>
</ItemComponent>
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="7" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="0.8" setvalue="true" duration="20.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Aluminium"
category="Material"
spritecolor="0.7,0.7,0.7,1.0"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Potassium"
category="Material"
spritecolor="0.8,0.8,0.8,1.0"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Flash Powder"
category="Material"
spritecolor="0.1,0.1,0.1,1.0"
Tags="smallitem,chem,explosive"
impacttolerance="8"
price="50">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnImpact" target="This" Condition="0.0" setvalue="true"/>
<StatusEffect type="OnFire" target="this" condition="-50"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0">
<Sound file="Content/Items/Reactor/explosion.ogg"/>
<Explosion range="500" damage="5" stun="3" force="0.1"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Chloral Hydrate"
category="Material"
spritecolor="1.0,1.0,1.0,0.8"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="17" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" Stun="10" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Phosphorus"
category="Material"
spritecolor="0.5,0.0,0.0,1.0"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Sulphuric Acid"
category="Material"
spritecolor="0.5,0.0,0.0,1.0"
Tags="smallitem,chem,medical"
price="50">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="17" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-1.0" duration="60.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Uranium Powder"
category="Material"
spritecolor="0.2,0.35,0.06,1.0"
Tags="smallitem,chem,medical"
price="50">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="25"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" duration="60.0">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" Health="0.5" Oxygen="0.5" Bleeding="-0.025" duration="60.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
@@ -370,27 +330,157 @@
<Body width="8" height="16" density="15"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" SpeedMultiplier="1.5" setvalue="true" duration="60.0">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" SpeedMultiplier="1.5" setvalue="true" duration="60.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Morbusine"
name="Calyxanide"
category="Material"
spritecolor="0.0,0.0,0.0,1.0"
Tags="smallitem,chem,medical"
description="A highly potent neurotoxin."
price="200">
description="An antiparasitic drug used in the treatment of husk parasite infections. Might require higher dosage to cure the infection at later stages."
price="300">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-10.0" duration="60.0">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" HuskInfectionState="-0.2" setvalue="true">
<Conditional HuskInfectionState="lt 1.0"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
<StatusEffect tags="poison,calyxanide" type="OnUse" target="Character" Health="-3.0" duration="10.0">
<!-- Injecting a still-conscious Husk will only piss it off and kill the "conscious" faster -->
<Conditional HuskInfectionState="eq 1.0"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
<StatusEffect tags="poison,calyxanide" type="OnUse" target="Character" Health="-5.0" duration="10.0">
<Conditional SpeciesName="husk"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Morbusanide"
category="Material"
spritecolor="0.0,0.0,0.2,1.0"
Tags="smallitem,chem,medical"
description="A morbusine antidote.">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character">
<RequiredItem name="Medical Syringe" type="Container"/>
<Conditional hasstatustag="morbusine"/>
<Cancel/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Liquid Oxygenite"
category="Material"
spritecolor="0.6,0.8,1.0,1.0"
Tags="smallitem,chem,medical"
impacttolerance="8"
description="A mildy toxic solution that slowly releases oxygen into the bloodstream when injected.">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" />
<Body width="8" height="16" density="20"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="medical" type="OnUse" target="Character" Health="-0.5" Oxygen="10.0" duration="60">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
<StatusEffect type="OnImpact" target="This" Condition="0.0" setvalue="true">
<sound file="Content/Items/Reactor/explosion.ogg"/>
<Explosion range="300.0" structuredamage="50" damage="30" stun="5" force="10.0"/>
</StatusEffect>
</Throwable>
</Item>
<!-- Harmful and toxic chems -->
<Item
name="Flash Powder"
category="Material"
spritecolor="0.1,0.1,0.1,1.0"
Tags="smallitem,chem,explosive"
impacttolerance="8"
price="50">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnImpact" target="This" Condition="0.0" setvalue="true"/>
<StatusEffect type="OnFire" target="this" condition="-50"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0">
<Sound file="Content/Items/Reactor/explosion.ogg"/>
<Explosion range="500" damage="5" stun="3" force="0.1"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Chloral Hydrate"
category="Material"
spritecolor="1.0,1.0,1.0,0.8"
Tags="smallitem,chem,medical"
price="20">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="17" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0" Stun="10" disabledeltatime="true">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Sulphuric Acid"
category="Material"
spritecolor="0.5,0.0,0.0,1.0"
Tags="smallitem,chem,medical"
price="50">
<Sprite texture ="med.png" sourcerect="15,15,8,17" depth="0.6"/>
<Body width="8" height="17" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="poison,acid" type="OnUse" target="Character" Health="-1.0" duration="30.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Uranium Powder"
category="Material"
spritecolor="0.2,0.35,0.06,1.0"
Tags="smallitem,chem,medical"
price="50">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="25"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="poison,uranium" type="OnUse" target="Character" bleeding="0.1" duration="60.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
@@ -402,52 +492,85 @@
spritecolor="0.0,0.0,0.0,1.0"
Tags="smallitem,chem,medical"
description="Dormant eggs of the Europan lifeform colloquially referred to as 'husk parasite'."
price="200">
price="2000">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.01">
<!-- HuskInfectionState must be less than 0.01 so you can't speed up the infection -->
<Conditional HuskInfectionState="lt 0.01"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Calyxanide"
name="Morbusine"
category="Material"
spritecolor="0.0,0.0,0.0,1.0"
Tags="smallitem,chem,medical"
description="An antiparasitic drug used in the treatment of husk parasite infections."
price="300">
description="A highly potent neurotoxin."
price="1000">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.0" setvalue="true">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect tags="poison,morbusine" type="OnUse" target="Character" Health="-5.0" duration="60.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Liquid Oxygenite"
category="Material"
spritecolor="0.6,0.8,1.0,1.0"
Tags="smallitem,chem,medical"
canuseonself="true"
description="A mildy toxic solution that slowly releases oxygen into the bloodstream when injected.">
name="Nitroglycerin"
category="Material"
description="A highly unstable liquid that may explode when subjected to heat or physical shock."
spritecolor="1.0,1.0,1.0,1.0"
Tags="smallitem,chem,medical"
impacttolerance="4">
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6" />
<Sprite texture ="Content/Items/Medical/med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="20"/>
<Body width="25" height="5" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-0.1" Oxygen="10.0" duration="60">
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnImpact" target="This" Condition="0.0" setvalue="true"/>
<StatusEffect type="OnFire" target="This" Condition="-50.0"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0">
<sound file="Content/Items/Reactor/explosion.ogg" range="3000"/>
<Explosion range="600.0" structuredamage="400" damage="300" stun="5" force="20.0" severlimbsprobability="0.4" decal="explosion" decalsize="0.5"/>
</StatusEffect>
<StatusEffect type="OnUse" target="This" Condition="-100.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
<Item
name="Sufforin"
category="Material"
spritecolor="1.0,0.3,0.3,1.0"
Tags="smallitem,chem,medical"
description="A devious poison with a delayed effect.">
<!-- Can only be crafted. Direct counter to Sufforin is Liquid Oxygenite, though it's not strictly an antidote.
Two injections to choke slightly faster than welding fuel. -->
<Sprite texture ="med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="8" height="16" density="10"/>
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" Health="-5.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
<!-- Did You Know? If OxygenAvailable is too low, character will take -5 Oxygen loss per tick, otherwise they restore +10 oxygen. -->
<StatusEffect tags="poison,sufforin" type="OnUse" target="Character" Oxygen="-5.0" OxygenAvailable="-10000.0" Health="-0.5" duration="60.0" delay="20.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>

View File

@@ -61,7 +61,9 @@
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="Uranium Bar" requirefullcondition="true"/>
<Item name="Uranium Powder" mincondition="0.1" maxcondition="0.5"/>
<Item name="Uranium Powder" mincondition="0.1" maxcondition="0.9"/>
<Item name="Uranium Bar" mincondition="0.9"/>
</Deconstruct>
<Sprite texture ="fuelrod.png" depth="0.55"/>
@@ -78,7 +80,7 @@
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="Incendium Bar" requirefullcondition="true"/>
<Item name="Incendium Bar" mincondition="0.95"/>
</Deconstruct>
<Sprite texture ="fuelrod.png" depth="0.55"/>
@@ -92,7 +94,7 @@
<Item
name="Heat Absorber"
Tags="smallitem"
>
price="50">
<Sprite texture ="heatabsorber.png"/>

View File

@@ -181,7 +181,7 @@
<MeleeWeapon slots="Any,RightHand,LeftHand"
aimpos="50,0" handle1="-5,0" holdangle="30" reload="1.0">
<Attack damage="5" stun="0.2" damagetype="Blunt" sound="Content/Items/Weapons/smack.ogg"/>
<Attack damage="5" structuredamage="5" stun="0.2" damagetype="Blunt" sound="Content/Items/Weapons/smack.ogg"/>
</MeleeWeapon>
</Item>
@@ -198,7 +198,7 @@
<MeleeWeapon slots="RightHand+LeftHand,Any"
controlpose="true" aimpos="50,0" handle1="-5,0" handle2="-3,5" holdangle="30" reload="1.7">
<Attack damage="20" stun="0.6" damagetype="Blunt" sound="Content/Items/Weapons/smack.ogg"/>
<Attack damage="20" structuredamage="10" stun="0.6" damagetype="Blunt" sound="Content/Items/Weapons/smack.ogg"/>
</MeleeWeapon>
</Item>
@@ -271,8 +271,10 @@
tags="smallitem">
<Deconstruct time="10">
<Item name="Phosphorus"/>
<Item name="Aluminium"/>
<Item name="Phosphorus" mincondition="0.9" outcondition="0.25"/>
<Item name="Aluminium" mincondition="0.9" outcondition="0.25"/>
<Item name="Phosphorus" mincondition="0.5" maxcondition="0.9" outcondition="0.1"/>
<Item name="Aluminium" mincondition="0.5" maxcondition="0.9" outcondition="0.1"/>
</Deconstruct>

View File

@@ -104,31 +104,4 @@
</input>
</ConnectionPanel>
</Item>
<Item
name="Nitroglycerin"
category="Material"
description="A highly unstable liquid that may explode when subjected to heat or physical shock."
spritecolor="1.0,1.0,1.0,1.0"
Tags="smallitem,chem,medical"
impacttolerance="4">
<Sprite texture ="Content/Items/Medical/med.png" sourcerect="24,16,8,16" depth="0.6"/>
<Body width="25" height="5" density="10"/>
<Throwable slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnImpact" target="This" Condition="0.0" setvalue="true"/>
<StatusEffect type="OnFire" target="This" Condition="-50.0"/>
<StatusEffect type="OnBroken" target="This" Condition="-100.0">
<sound file="Content/Items/Reactor/explosion.ogg" range="3000"/>
<Explosion range="600.0" structuredamage="400" damage="300" stun="5" force="20.0" severlimbsprobability="0.4" decal="explosion" decalsize="0.5"/>
</StatusEffect>
<StatusEffect type="OnUse" target="This" Condition="-100.0">
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
</Item>
</Items>

View File

@@ -144,6 +144,12 @@
price="200"
tags="smallitem,weapon">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="Flash Powder" mincondition="0.9"/>
<Item name="Chloral Hydrate" mincondition="0.9"/>
</Deconstruct>
<Sprite texture="weapons.png" sourcerect="98,0,11,24" depth="0.55"/>
<Body width="11" height="24" density="30"/>
@@ -161,6 +167,12 @@
category="Equipment"
tags="smallitem,weapon">
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="Flash Powder" mincondition="0.9"/>
<Item name="Incendium Bar" mincondition="0.9"/>
</Deconstruct>
<Sprite texture="weapons.png" sourcerect="98,0,11,24" depth="0.55"/>
<Body width="11" height="24" density="30"/>
@@ -222,8 +234,8 @@
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
<Item name="Copper Bar"/>
<Item name="Copper Bar" mincondition="0.5"/>
<Item name="Sulphuric Acid" mincondition="0.9"/>
</Deconstruct>
<Sprite texture="weapons.png" sourcerect="0,0,20,9" depth="0.8"/>
@@ -242,8 +254,8 @@
<Deconstruct time="10">
<Item name="Steel Bar"/>
<Item name="FPGA Circuit"/>
<Item name="Fulgurium Bar"/>
<Item name="Fulgurium Bar" mincondition="0.8"/>
<Item name="Sulphuric Acid" mincondition="0.9"/>
</Deconstruct>
<Sprite texture="weapons.png" sourcerect="0,0,20,9" depth="0.8"/>

View File

@@ -38,7 +38,11 @@
<damagesound file="Content/Sounds/Damage/HitArmor1.ogg" damagerange="5.0,80.0" damagesoundtype="LimbArmor"/>
<damagesound file="Content/Sounds/Damage/HitArmor2.ogg" damagerange="5.0,80.0" damagesoundtype="LimbArmor"/>
<damagesound file="Content/Sounds/Damage/HitArmor3.ogg" damagerange="40.0,100.0" damagesoundtype="LimbArmor"/>
<damagesound file="Content/Sounds/Damage/HitClown1.ogg" damagerange="0.0,40.0" damagesoundtype="LimbClown"/>
<damagesound file="Content/Sounds/Damage/HitClown2.ogg" damagerange="0.0,40.0" damagesoundtype="LimbClown"/>
<damagesound file="Content/Sounds/Damage/HitClown3.ogg" damagerange="25.0,75.0" damagesoundtype="LimbClown"/>
<damagesound file="Content/Sounds/Damage/HitClown4.ogg" damagerange="50.0,100.0" damagesoundtype="LimbClown"/>
<damagesound file="Content/Sounds/Damage/creak1.ogg" damagesoundtype="Pressure"/>
<damagesound file="Content/Sounds/Damage/creak2.ogg" damagesoundtype="Pressure"/>
@@ -52,6 +56,22 @@
<drown file="Content/Sounds/Water/Drown3.ogg"/>
<drown file="Content/Sounds/Water/Drown4.ogg"/>
<footstep file="Content/Sounds/Footsteps/step.ogg"/>
<footstep_metal file="Content/Sounds/Footsteps/Metal/metal-01.ogg"/>
<footstep_metal file="Content/Sounds/Footsteps/Metal/metal-02.ogg"/>
<footstep_metal file="Content/Sounds/Footsteps/Metal/metal-03.ogg"/>
<footstep_metal file="Content/Sounds/Footsteps/Metal/metal-04.ogg"/>
<footstep_metal file="Content/Sounds/Footsteps/Metal/metal-05.ogg"/>
<footstep_metal file="Content/Sounds/Footsteps/Metal/metal-06.ogg"/>
<footstep_metal file="Content/Sounds/Footsteps/Metal/metal-07.ogg"/>
<footstep_armor file="Content/Sounds/Footsteps/Armor/armor-01.ogg"/>
<footstep_armor file="Content/Sounds/Footsteps/Armor/armor-02.ogg"/>
<footstep_armor file="Content/Sounds/Footsteps/Armor/armor-03.ogg"/>
<footstep_clown file="Content/Sounds/Footsteps/Clown/clown-01.ogg"/>
<footstep_clown file="Content/Sounds/Footsteps/Clown/clown-02.ogg"/>
<ambient file="Content/Sounds/Ambient/Ambient1.ogg"/>
<ambient file="Content/Sounds/Ambient/Ambient2.ogg"/>
<ambient file="Content/Sounds/Ambient/Ambient3.ogg"/>

View File

@@ -1000,7 +1000,7 @@ namespace Barotrauma
{
target.AddDamage(CauseOfDeath.Bloodloss, 1.0f, character);
#if CLIENT
SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, 25.0f, targetTorso.body);
SoundPlayer.PlayDamageSound("LimbBlunt", 25.0f, targetTorso.body);
for (int i = 0; i < 4; i++)
{

View File

@@ -371,6 +371,7 @@ namespace Barotrauma
{
if (!MathUtils.IsValid(value)) return;
if (GameMain.Client != null) return;
if (!DoesBleed) return;
float newBleeding = MathHelper.Clamp(value, 0.0f, 5.0f);
//if (newBleeding == bleeding) return;
@@ -1618,6 +1619,15 @@ namespace Barotrauma
lowPassMultiplier = MathHelper.Lerp(lowPassMultiplier, 1.0f, 0.1f);
if (DoesBleed)
{
Health -= bleeding * deltaTime;
Bleeding -= BleedingDecreaseSpeed * deltaTime;
}
if (health <= minHealth) Kill(CauseOfDeath.Bloodloss);
if (!IsDead) LockHands = false;
//CPR stuff is handled in the UpdateCPR function in HumanoidAnimController
}

View File

@@ -49,8 +49,8 @@ namespace Barotrauma
#if CLIENT
[Serialize(DamageSoundType.None, false)]
public DamageSoundType DamageSoundType
[Serialize("", false)]
public string DamageSound
{
get;
private set;

View File

@@ -3,23 +3,19 @@ using System.Xml.Linq;
namespace Barotrauma
{
class DelayedListElement
{
public DelayedEffect Parent;
public Entity Entity;
public List<ISerializableEntity> Targets;
public float StartTimer;
}
class DelayedEffect : StatusEffect
{
public static List<DelayedEffect> List = new List<DelayedEffect>();
public static List<DelayedListElement> DelayList = new List<DelayedListElement>();
private float delay;
private float startTimer;
private Entity entity;
private List<ISerializableEntity> targets;
public float StartTimer
{
get { return startTimer; }
}
public DelayedEffect(XElement element)
: base(element)
{
@@ -28,25 +24,36 @@ namespace Barotrauma
public override void Apply(ActionType type, float deltaTime, Entity entity, List<ISerializableEntity> targets)
{
if (this.type != type) return;
startTimer = delay;
this.entity = entity;
if (this.type != type || !HasRequiredItems(entity)) return;
if (!base.Stackable && DelayList.Find(d => d.Parent == this && d.Entity == entity && d.Targets == targets) != null) return;
this.targets = targets;
DelayedListElement element = new DelayedListElement();
element.Parent = this;
element.StartTimer = delay;
element.Entity = entity;
element.Targets = targets;
List.Add(this);
DelayList.Add(element);
}
public void Update(float deltaTime)
public static void Update(float deltaTime)
{
startTimer -= deltaTime;
for (int i = DelayList.Count - 1; i >= 0; i--)
{
DelayedListElement element = DelayList[i];
if (element.Parent.CheckConditionalAlways && !element.Parent.HasRequiredConditions(element.Targets))
{
DelayList.Remove(element);
continue;
}
if (startTimer > 0.0f) return;
element.StartTimer -= deltaTime;
base.Apply(1.0f, entity, targets);
List.Remove(this);
if (element.StartTimer > 0.0f) continue;
element.Parent.Apply(1.0f, element.Entity, element.Targets);
DelayList.Remove(element);
}
}
}
}
}

View File

@@ -373,13 +373,13 @@ namespace Barotrauma
#if CLIENT
if (playSound)
{
DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
string damageSoundType = (damageType == DamageType.Blunt) ? "LimbBlunt" : "LimbSlash";
foreach (DamageModifier damageModifier in appliedDamageModifiers)
{
if (damageModifier.DamageSoundType != DamageSoundType.None)
if (!string.IsNullOrWhiteSpace(damageModifier.DamageSound))
{
damageSoundType = damageModifier.DamageSoundType;
damageSoundType = damageModifier.DamageSound;
break;
}
}
@@ -594,12 +594,6 @@ namespace Barotrauma
}
#if CLIENT
if (hitSound != null)
{
hitSound.Remove();
hitSound = null;
}
if (LightSource != null)
{
LightSource.Remove();

View File

@@ -9,6 +9,93 @@ using Barotrauma.Particles;
namespace Barotrauma
{
class DurationListElement
{
public StatusEffect Parent;
public Entity Entity;
public List<ISerializableEntity> Targets;
public float StartTimer;
}
partial class PropertyConditional
{
public string Attribute;
public string Operator;
public object Value;
public PropertyConditional(string Attribute, string Operator, object Value)
{
this.Attribute = Attribute;
this.Operator = Operator;
this.Value = Value;
}
public bool Matches(SerializableProperty property)
{
if (property.GetValue() == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "- property.GetValue() returns null!!");
return false;
}
Type type = property.GetValue().GetType();
float? floatValue = null;
float? floatProperty = null;
if (type == typeof(float) || type == typeof(int))
{
floatValue = Convert.ToSingle(Value);
floatProperty = Convert.ToSingle(property.GetValue());
}
switch (Operator)
{
case "==":
if (property.GetValue().Equals(floatValue == null ? Value : floatValue))
return true;
break;
case "!=":
if (property.GetValue().Equals(floatValue == null ? Value : floatValue))
return true;
break;
case ">":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if (floatProperty > floatValue)
return true;
break;
case "<":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if (floatProperty < floatValue)
return true;
break;
case ">=":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if (floatProperty >= floatValue)
return true;
break;
case "<=":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if (floatProperty <= floatValue)
return true;
break;
}
return false;
}
}
partial class StatusEffect
{
[Flags]
@@ -32,15 +119,24 @@ namespace Barotrauma
public string[] propertyNames;
private object[] propertyEffects;
List<PropertyConditional> propertyConditionals;
private bool setValue;
private bool disableDeltaTime;
private HashSet<string> onContainingNames;
private HashSet<string> tags;
private readonly float duration;
public static List<DurationListElement> DurationList = new List<DurationListElement>();
private readonly bool useItem;
public bool CheckConditionalAlways; //Always do the conditional checks for the duration/delay. If false, only check conditional on apply.
public bool Stackable; //Can the same status effect be applied several times to the same targets?
private readonly int useItemCount;
private readonly int cancelStatusEffect;
public readonly ActionType type;
@@ -63,6 +159,24 @@ namespace Barotrauma
get { return onContainingNames; }
}
public string Tags
{
get { return string.Join(",", tags); }
set
{
tags.Clear();
if (value == null) return;
string[] newTags = value.Split(',');
foreach (string tag in newTags)
{
string newTag = tag.Trim();
if (!tags.Contains(newTag)) tags.Add(newTag);
}
}
}
public static StatusEffect Load(XElement element)
{
if (element.Attribute("delay")!=null)
@@ -76,14 +190,16 @@ namespace Barotrauma
protected StatusEffect(XElement element)
{
requiredItems = new List<RelatedItem>();
tags = new HashSet<string>(element.GetAttributeString("tags", "").Split(','));
#if CLIENT
particleEmitters = new List<ParticleEmitter>();
#endif
IEnumerable<XAttribute> attributes = element.Attributes();
IEnumerable<XAttribute> attributes = element.Attributes();
List<XAttribute> propertyAttributes = new List<XAttribute>();
propertyConditionals = new List<PropertyConditional>();
foreach (XAttribute attribute in attributes)
{
switch (attribute.Name.ToString())
@@ -133,6 +249,12 @@ namespace Barotrauma
case "duration":
duration = attribute.GetAttributeFloat(0.0f);
break;
case "stackable":
Stackable = attribute.GetAttributeBool(true);
break;
case "checkconditionalalways":
CheckConditionalAlways = attribute.GetAttributeBool(false);
break;
case "sound":
DebugConsole.ThrowError("Error in StatusEffect " + element.Parent.Name.ToString() +
" - sounds should be defined as child elements of the StatusEffect, not as attributes.");
@@ -167,7 +289,14 @@ namespace Barotrauma
break;
case "use":
case "useitem":
useItem = true;
useItemCount++;
break;
case "cancel":
case "cancelstatuseffect":
//This only works if there's a conditional checking for status effect tags. There is no way to cancel *all* status effects atm.
cancelStatusEffect = 1;
if (subElement.GetAttributeBool("all", false) == true)
cancelStatusEffect = 2;
break;
case "requireditem":
case "requireditems":
@@ -177,6 +306,67 @@ namespace Barotrauma
requiredItems.Add(newRequiredItem);
break;
case "conditional":
IEnumerable<XAttribute> conditionalAttributes = subElement.Attributes();
foreach(XAttribute attribute in conditionalAttributes)
{
string attributeString = XMLExtensions.GetAttributeObject(attribute).ToString();
string atStr = attributeString;
string[] splitString = atStr.Split(' ');
string op = splitString[0];
if (splitString.Length > 0)
{
for (int i=1; i<splitString.Length; i++)
{
atStr = splitString[i] + (i > 1 && i < splitString.Length ? " " : "");
}
}
//thanks xml for not letting me use < or > in attributes :(
switch (op)
{
case "e":
case "eq":
case "equals":
op = "==";
break;
case "ne":
case "neq":
case "notequals":
case "!":
case "!e":
case "!eq":
case "!equals":
op = "!=";
break;
case "gt":
case "greaterthan":
op = ">";
break;
case "lt":
case "lessthan":
op = "<";
break;
case "gte":
case "gteq":
case "greaterthanequals":
op = ">=";
break;
case "lte":
case "lteq":
case "lessthanequals":
op = "<=";
break;
default:
if (op != "==" && op != "!=" && op != ">" && op != "<" && op != ">=" && op != "<=") //Didn't use escape strings or anything
{
atStr = attributeString; //We probably don't even have an operator
op = "==";
}
break;
}
propertyConditionals.Add(new PropertyConditional(attribute.Name.ToString().ToLowerInvariant(), op, atStr));
}
break;
#if CLIENT
case "particleemitter":
particleEmitters.Add(new ParticleEmitter(subElement));
@@ -190,7 +380,7 @@ namespace Barotrauma
}
}
private bool HasRequiredItems(Entity entity)
public virtual bool HasRequiredItems(Entity entity)
{
if (requiredItems == null) return true;
foreach (RelatedItem requiredItem in requiredItems)
@@ -209,21 +399,97 @@ namespace Barotrauma
return true;
}
public virtual bool HasRequiredConditions(List<ISerializableEntity> targets)
{
if (!propertyConditionals.Any()) return true;
foreach (ISerializableEntity target in targets)
{
foreach (PropertyConditional pc in propertyConditionals)
{
if (target == null || target.SerializableProperties == null) continue;
if (!target.SerializableProperties.TryGetValue(pc.Attribute, out SerializableProperty property))
{
//Do special conditional checks
string valStr = pc.Value.ToString();
if (pc.Attribute == "name")
return pc.Operator == "==" ? target.Name == valStr : target.Name != valStr;
if (pc.Attribute == "speciesname" && target is Character)
return pc.Operator == "==" ? ((Character)target).SpeciesName == valStr : ((Character)target).SpeciesName != valStr;
if ((pc.Attribute == "hastag" || pc.Attribute == "hastags") && target is Item)
{
string[] readTags = valStr.Split(',');
int matches = 0;
foreach (string tag in readTags)
if (((Item)target).HasTag(tag)) matches++;
//If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
return pc.Operator == "==" ? matches >= readTags.Length : matches <= 0;
}
List<DurationListElement> durations = DurationList.FindAll(d => d.Targets.Contains(target));
List<DelayedListElement> delays = DelayedEffect.DelayList.FindAll(d => d.Targets.Contains(target));
bool success = false;
if (pc.Attribute == "hasstatustag" || pc.Attribute == "hasstatustags" && (durations.Any() || delays.Any()))
{
string[] readTags = valStr.Split(',');
foreach (DurationListElement duration in durations)
{
int matches = 0;
foreach (string tag in readTags)
if (duration.Parent.HasTag(tag)) matches++;
success = pc.Operator == "==" ? matches >= readTags.Length : matches <= 0;
if (cancelStatusEffect > 0 && success)
DurationList.Remove(duration);
if (cancelStatusEffect != 2) //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
return success;
}
foreach (DelayedListElement delay in delays)
{
int matches = 0;
foreach (string tag in readTags)
if (delay.Parent.HasTag(tag)) matches++;
success = pc.Operator == "==" ? matches >= readTags.Length : matches <= 0;
if (cancelStatusEffect > 0 && success)
DelayedEffect.DelayList.Remove(delay);
if (cancelStatusEffect != 2) //ditto
return success;
}
}
return success;
}
else if (!pc.Matches(property))
return false;
}
}
return true;
}
public virtual void Apply(ActionType type, float deltaTime, Entity entity, ISerializableEntity target)
{
if (this.type != type || !HasRequiredItems(entity)) return;
if (targetNames != null && !targetNames.Contains(target.Name)) return;
if (duration > 0.0f && !Stackable && DurationList.Find(d => d.Parent == this && d.Entity == entity && d.Targets.Contains(target)) != null) return;
List<ISerializableEntity> targets = new List<ISerializableEntity>();
targets.Add(target);
Apply(deltaTime, entity, targets);
if (!HasRequiredConditions(targets)) return;
Apply(type, deltaTime, entity, targets);
}
public virtual void Apply(ActionType type, float deltaTime, Entity entity, List<ISerializableEntity> targets)
{
if (this.type != type || !HasRequiredItems(entity)) return;
if (this.type != type || !HasRequiredItems(entity) || !HasRequiredConditions(targets)) return;
Apply(deltaTime, entity, targets);
}
@@ -251,35 +517,43 @@ namespace Barotrauma
}
#endif
if (useItem)
if (useItemCount > 0)
{
foreach (Item item in targets.FindAll(t => t is Item).Cast<Item>())
for (int i=0; i<useItemCount; i++)
{
item.Use(deltaTime, targets.FirstOrDefault(t => t is Character) as Character);
}
}
foreach (ISerializableEntity target in targets)
{
for (int i = 0; i < propertyNames.Length; i++)
{
SerializableProperty property;
if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property)) continue;
if (duration > 0.0f)
foreach (Item item in targets.FindAll(t => t is Item).Cast<Item>())
{
CoroutineManager.StartCoroutine(
ApplyToPropertyOverDuration(duration, property, propertyEffects[i]), "statuseffect");
}
else
{
ApplyToProperty(property, propertyEffects[i], deltaTime);
item.Use(deltaTime, targets.FirstOrDefault(t => t is Character) as Character);
}
}
}
if (duration > 0.0f)
{
DurationListElement element = new DurationListElement();
element.Parent = this;
element.StartTimer = duration;
element.Entity = entity;
element.Targets = targets;
DurationList.Add(element);
}
else
{
foreach (ISerializableEntity target in targets)
{
for (int i = 0; i < propertyNames.Length; i++)
{
SerializableProperty property;
if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property)) continue;
ApplyToProperty(property, propertyEffects[i], deltaTime);
}
}
}
if (explosion != null) explosion.Explode(entity.WorldPosition);
@@ -308,21 +582,6 @@ namespace Barotrauma
#endif
}
private IEnumerable<object> ApplyToPropertyOverDuration(float duration, SerializableProperty property, object value)
{
float timer = duration;
while (timer > 0.0f)
{
ApplyToProperty(property, value, CoroutineManager.UnscaledDeltaTime);
timer -= CoroutineManager.DeltaTime;
yield return CoroutineStatus.Running;
}
yield return CoroutineStatus.Success;
}
private void ApplyToProperty(SerializableProperty property, object value, float deltaTime)
{
if (disableDeltaTime || setValue) deltaTime = 1.0f;
@@ -359,9 +618,33 @@ namespace Barotrauma
public static void UpdateAll(float deltaTime)
{
for (int i = DelayedEffect.List.Count-1; i>= 0; i--)
DelayedEffect.Update(deltaTime);
for (int i = DurationList.Count - 1; i >= 0; i--)
{
DelayedEffect.List[i].Update(deltaTime);
DurationListElement element = DurationList[i];
if (element.Parent.CheckConditionalAlways && !element.Parent.HasRequiredConditions(element.Targets))
{
DurationList.Remove(element);
continue;
}
foreach (ISerializableEntity target in element.Targets)
{
for (int n = 0; n < element.Parent.propertyNames.Length; n++)
{
SerializableProperty property;
if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(element.Parent.propertyNames[n], out property)) continue;
element.Parent.ApplyToProperty(property, element.Parent.propertyEffects[n], CoroutineManager.UnscaledDeltaTime);
}
}
element.StartTimer -= deltaTime;
if (element.StartTimer > 0.0f) continue;
DurationList.Remove(element);
}
}
@@ -369,5 +652,18 @@ namespace Barotrauma
{
CoroutineManager.StopCoroutines("statuseffect");
}
public void AddTag(string tag)
{
if (tags.Contains(tag)) return;
tags.Add(tag);
}
public bool HasTag(string tag)
{
if (tag == null) return true;
return (tags.Contains(tag) || tags.Contains(tag.ToLowerInvariant()));
}
}
}

View File

@@ -203,8 +203,23 @@ namespace Barotrauma.Items.Components
#endif
}
public override bool HasRequiredItems(Character character, bool addMessage)
{
if (item.Condition <= 0.0f) return true; //For repairing
//this is a bit pointless atm because if canBePicked is false it won't allow you to do Pick() anyway, however it's still good for future-proofing.
return requiredItems.Any() ? base.HasRequiredItems(character, addMessage) : canBePicked;
}
public override bool Pick(Character picker)
{
return item.Condition <= 0.0f ? true : base.Pick(picker);
}
public override bool OnPicked(Character picker)
{
if (item.Condition <= 0.0f) return true; //repairs
SetState(predictedState == null ? !isOpen : !predictedState.Value, false, true); //crowbar function
#if CLIENT
PlaySound(ActionType.OnPicked, item.WorldPosition);
@@ -369,7 +384,7 @@ namespace Barotrauma.Items.Components
if (Math.Sign(diff) != dir)
{
#if CLIENT
SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, 1.0f, body);
SoundPlayer.PlayDamageSound("LimbBlunt", 1.0f, body);
#endif
if (isHorizontal)

View File

@@ -215,6 +215,7 @@ namespace Barotrauma.Items.Components
{
Character targetCharacter = null;
Limb targetLimb = null;
Structure targetStructure = null;
if (f2.Body.UserData is Limb)
{
@@ -224,8 +225,12 @@ namespace Barotrauma.Items.Components
}
else if (f2.Body.UserData is Character)
{
targetCharacter = (Character)f2.Body.UserData;
targetLimb = targetCharacter.AnimController.GetLimb(LimbType.Torso); //Otherwise armor can be bypassed in strange ways
}
else if (f2.Body.UserData is Structure)
{
targetStructure = (Structure)f2.Body.UserData;
}
else
{
@@ -236,14 +241,22 @@ namespace Barotrauma.Items.Components
if (attack != null)
{
if (targetLimb == null)
if (targetLimb != null)
{
attack.DoDamageToLimb(user, targetLimb, item.WorldPosition, 1.0f);
}
else
else if (targetCharacter != null)
{
attack.DoDamage(user, targetCharacter, item.WorldPosition, 1.0f);
}
else if (targetStructure != null)
{
attack.DoDamage(user, targetStructure, item.WorldPosition, 1.0f);
}
else
{
return false;
}
}
RestoreCollision();
@@ -251,7 +264,7 @@ namespace Barotrauma.Items.Components
if (GameMain.Client != null) return true;
if (GameMain.Server != null)
if (GameMain.Server != null && targetCharacter != null) //TODO: Log structure hits
{
GameMain.Server.CreateEntityEvent(item, new object[] { Networking.NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnUse, targetCharacter.ID });
@@ -263,8 +276,9 @@ namespace Barotrauma.Items.Components
logStr += " on " + targetCharacter.LogName + ".";
Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack);
}
ApplyStatusEffects(ActionType.OnUse, 1.0f, targetLimb.character);
if (targetCharacter != null) //TODO: Allow OnUse to happen on structures too maybe??
ApplyStatusEffects(ActionType.OnUse, 1.0f, targetCharacter != null ? targetCharacter : null);
return true;
}

View File

@@ -30,6 +30,8 @@ namespace Barotrauma.Items.Components
protected bool canBePicked;
protected bool canBeSelected;
protected bool canBeCombined;
protected bool removeOnCombined;
public bool WasUsed;
@@ -47,7 +49,7 @@ namespace Barotrauma.Items.Components
private string msg;
[Serialize(0.0f, false)]
[Editable, Serialize(0.0f, false)]
public float PickingTime
{
get;
@@ -103,7 +105,7 @@ namespace Barotrauma.Items.Components
}
}
[Serialize(false, false)]
[Editable, Serialize(false, false)] //Editable for doors to do their magic
public bool CanBePicked
{
get { return canBePicked; }
@@ -124,6 +126,22 @@ namespace Barotrauma.Items.Components
set { canBeSelected = value; }
}
//Transfer conditions between same prefab items
[Serialize(false, false)]
public bool CanBeCombined
{
get { return canBeCombined; }
set { canBeCombined = value; }
}
//Remove item if combination results in 0 condition
[Serialize(false, false)]
public bool RemoveOnCombined
{
get { return removeOnCombined; }
set { removeOnCombined = value; }
}
public InputType PickKey
{
get;
@@ -153,7 +171,7 @@ namespace Barotrauma.Items.Components
get { return name; }
}
[Serialize("", false)]
[Editable, Serialize("", false)]
public string Msg
{
get { return msg; }
@@ -196,7 +214,7 @@ namespace Barotrauma.Items.Components
try
{
string pickKeyStr = element.GetAttributeString("selectkey", "Select");
string pickKeyStr = element.GetAttributeString("pickkey", "Select");
pickKeyStr = ToolBox.ConvertInputType(pickKeyStr);
PickKey = (InputType)Enum.Parse(typeof(InputType),pickKeyStr, true);
}
@@ -323,6 +341,43 @@ namespace Barotrauma.Items.Components
public virtual bool Combine(Item item)
{
if (canBeCombined && this.item.Prefab == item.Prefab && item.Condition > 0.0f && this.item.Condition > 0.0f)
{
float transferAmount = 0.0f;
if (this.Item.Condition <= item.Condition)
transferAmount = Math.Min(item.Condition, this.item.Prefab.Health - this.item.Condition);
else
transferAmount = -Math.Min(this.item.Condition, item.Prefab.Health - item.Condition);
if (transferAmount == 0.0f)
return false;
this.Item.Condition += transferAmount;
item.Condition -= transferAmount;
if (removeOnCombined)
{
if (item.Condition <= 0.0f)
{
if (item.ParentInventory != null)
{
Character owner = (Character)item.ParentInventory.Owner;
if (owner != null && owner.HasSelectedItem(item)) item.Unequip(owner);
item.ParentInventory.RemoveItem(item);
}
Entity.Spawner.AddToRemoveQueue(item);
}
if (this.Item.Condition <= 0.0f)
{
if (this.Item.ParentInventory != null)
{
Character owner = (Character)this.Item.ParentInventory.Owner;
if (owner != null && owner.HasSelectedItem(this.Item)) this.Item.Unequip(owner);
this.Item.ParentInventory.RemoveItem(this.Item);
}
Entity.Spawner.AddToRemoveQueue(this.Item);
}
}
return true;
}
return false;
}
@@ -437,7 +492,7 @@ namespace Barotrauma.Items.Components
return true;
}
public bool HasRequiredItems(Character character, bool addMessage)
public virtual bool HasRequiredItems(Character character, bool addMessage)
{
if (!requiredItems.Any()) return true;
if (character.Inventory == null) return false;

View File

@@ -170,7 +170,7 @@ namespace Barotrauma.Items.Components
if (effect.Targets.HasFlag(StatusEffect.TargetType.This))
effect.Apply(ActionType.OnContaining, deltaTime, item, item.AllPropertyObjects);
if (effect.Targets.HasFlag(StatusEffect.TargetType.Contained))
effect.Apply(ActionType.OnContaining, deltaTime, item, contained.AllPropertyObjects);
effect.Apply(ActionType.OnContaining, deltaTime, item, contained.AllPropertyObjects);
}
}
@@ -192,7 +192,7 @@ namespace Barotrauma.Items.Components
return true;
}
return false;
return false;
}
public override void OnMapLoaded()

View File

@@ -57,7 +57,8 @@ namespace Barotrauma.Items.Components
foreach (DeconstructItem deconstructProduct in targetItem.Prefab.DeconstructItems)
{
if (deconstructProduct.RequireFullCondition && targetItem.Condition < targetItem.Prefab.Health) continue;
float percentageHealth = targetItem.Condition / targetItem.Prefab.Health;
if (percentageHealth <= deconstructProduct.MinCondition || percentageHealth > deconstructProduct.MaxCondition) continue;
var itemPrefab = MapEntityPrefab.Find(deconstructProduct.ItemPrefabName) as ItemPrefab;
if (itemPrefab == null)
@@ -69,11 +70,11 @@ namespace Barotrauma.Items.Components
//container full, drop the items outside the deconstructor
if (containers[1].Inventory.Items.All(i => i != null))
{
Entity.Spawner.AddToSpawnQueue(itemPrefab, item.Position, item.Submarine);
Entity.Spawner.AddToSpawnQueue(itemPrefab, item.Position, item.Submarine, itemPrefab.Health * deconstructProduct.OutCondition);
}
else
{
Entity.Spawner.AddToSpawnQueue(itemPrefab, containers[1].Inventory);
Entity.Spawner.AddToSpawnQueue(itemPrefab, containers[1].Inventory, itemPrefab.Health * deconstructProduct.OutCondition);
}
}

View File

@@ -12,10 +12,12 @@ namespace Barotrauma.Items.Components
{
public readonly ItemPrefab TargetItem;
public readonly List<Tuple<ItemPrefab, int>> RequiredItems;
public readonly List<Tuple<ItemPrefab, int, float, bool>> RequiredItems;
public readonly float RequiredTime;
public readonly float OutCondition; //Percentage-based from 0 to 1
public readonly List<Skill> RequiredSkills;
public FabricableItem(XElement element)
@@ -31,8 +33,9 @@ namespace Barotrauma.Items.Components
RequiredSkills = new List<Skill>();
RequiredTime = element.GetAttributeFloat("requiredtime", 1.0f);
RequiredItems = new List<Tuple<ItemPrefab, int>>();
OutCondition = element.GetAttributeFloat("outcondition", 1.0f);
RequiredItems = new List<Tuple<ItemPrefab, int, float, bool>>();
//Backwards compatibility for string lists
string[] requiredItemNames = element.GetAttributeString("requireditems", "").Split(',');
foreach (string requiredItemName in requiredItemNames)
{
@@ -48,12 +51,12 @@ namespace Barotrauma.Items.Components
var existing = RequiredItems.Find(r => r.Item1 == requiredItem);
if (existing == null)
{
RequiredItems.Add(new Tuple<ItemPrefab, int>(requiredItem, 1));
RequiredItems.Add(new Tuple<ItemPrefab, int, float, bool>(requiredItem, 1, 1.0f, false));
}
else
{
RequiredItems.Remove(existing);
RequiredItems.Add(new Tuple<ItemPrefab, int>(requiredItem, existing.Item2 + 1));
RequiredItems.Add(new Tuple<ItemPrefab, int, float, bool>(requiredItem, existing.Item2 + 1, 1.0f, false));
}
}
@@ -66,6 +69,34 @@ namespace Barotrauma.Items.Components
subElement.GetAttributeString("name", ""),
subElement.GetAttributeInt("level", 0)));
break;
case "item": //New system allowing for setting minimal item condition
string requiredItemName = subElement.GetAttributeString("name", "");
float minCondition = subElement.GetAttributeFloat("mincondition", 1.0f);
//Substract mincondition from required item's condition or delete it regardless?
bool useCondition = subElement.GetAttributeBool("usecondition", true);
int count = subElement.GetAttributeInt("count", 1);
if (string.IsNullOrWhiteSpace(requiredItemName)) continue;
ItemPrefab requiredItem = MapEntityPrefab.Find(requiredItemName.Trim()) as ItemPrefab;
if (requiredItem == null)
{
DebugConsole.ThrowError("Error in fabricable item " + name + "! Required item \"" + requiredItemName + "\" not found.");
continue;
}
var existing = RequiredItems.Find(r => r.Item1 == requiredItem);
if (existing == null)
{
RequiredItems.Add(new Tuple<ItemPrefab, int, float, bool>(requiredItem, count, minCondition, useCondition));
}
else
{
RequiredItems.Remove(existing);
RequiredItems.Add(new Tuple<ItemPrefab, int, float, bool>(requiredItem, existing.Item2 + count, minCondition, useCondition));
}
break;
}
}
@@ -236,25 +267,32 @@ namespace Barotrauma.Items.Components
return;
}
foreach (Tuple<ItemPrefab, int> ip in fabricatedItem.RequiredItems)
foreach (Tuple<ItemPrefab, int, float, bool> ip in fabricatedItem.RequiredItems)
{
for (int i = 0; i < ip.Item2; i++)
{
var requiredItem = containers[0].Inventory.Items.FirstOrDefault(it => it != null && it.Prefab == ip.Item1);
var requiredItem = containers[0].Inventory.Items.FirstOrDefault(it => it != null && it.Prefab == ip.Item1 && it.Condition >= ip.Item1.Health * ip.Item3);
if (requiredItem == null) continue;
//Item4 = use condition bool
if (ip.Item4 && requiredItem.Condition - ip.Item1.Health * ip.Item3 > 0.0f) //Leave it behind with reduced condition if it has enough to stay above 0
{
requiredItem.Condition -= ip.Item1.Health * ip.Item3;
continue;
}
Entity.Spawner.AddToRemoveQueue(requiredItem);
containers[0].Inventory.RemoveItem(requiredItem);
}
}
//TODO: apply OutCondition
if (containers[1].Inventory.Items.All(i => i != null))
{
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, item.Position, item.Submarine);
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, item.Position, item.Submarine, fabricatedItem.TargetItem.Health * fabricatedItem.OutCondition);
}
else
{
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, containers[1].Inventory);
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, containers[1].Inventory, fabricatedItem.TargetItem.Health * fabricatedItem.OutCondition);
}
CancelFabricating(null);
@@ -269,11 +307,10 @@ namespace Barotrauma.Items.Components
{
return false;
}
ItemContainer container = item.GetComponent<ItemContainer>();
foreach (Tuple<ItemPrefab, int> ip in fabricableItem.RequiredItems)
foreach (Tuple<ItemPrefab, int, float, bool> ip in fabricableItem.RequiredItems)
{
if (Array.FindAll(container.Inventory.Items, it => it != null && it.Prefab == ip.Item1).Length < ip.Item2) return false;
if (Array.FindAll(container.Inventory.Items, it => it != null && it.Prefab == ip.Item1 && it.Condition >= ip.Item1.Health * ip.Item3).Length < ip.Item2) return false;
}
return true;

View File

@@ -10,19 +10,23 @@ namespace Barotrauma.Items.Components
class WearableSprite
{
public readonly Sprite Sprite;
public readonly LimbType Limb;
public readonly bool HideLimb;
public readonly bool InheritLimbDepth;
public readonly LimbType DepthLimb;
public readonly Wearable WearableComponent;
public readonly string Sound;
public WearableSprite(Wearable item, Sprite sprite, bool hideLimb, bool inheritLimbDepth = true, LimbType depthLimb = LimbType.None)
public WearableSprite(Wearable item, Sprite sprite, LimbType limb, bool hideLimb, bool inheritLimbDepth = true, LimbType depthLimb = LimbType.None, string sound = null)
{
WearableComponent = item;
Sprite = sprite;
Limb = limb;
HideLimb = hideLimb;
InheritLimbDepth = inheritLimbDepth;
DepthLimb = depthLimb;
Sound = sound;
}
}
@@ -66,15 +70,16 @@ namespace Barotrauma.Items.Components
string spritePath = subElement.Attribute("texture").Value;
spritePath = Path.GetDirectoryName(item.Prefab.ConfigFile) + "/" + spritePath;
var sound = subElement.GetAttributeString("sound", "");
var sprite = new Sprite(subElement, "", spritePath);
wearableSprites[i] = new WearableSprite(this, sprite,
subElement.GetAttributeBool("hidelimb", false),
subElement.GetAttributeBool("inheritlimbdepth", true),
(LimbType)Enum.Parse(typeof(LimbType), subElement.GetAttributeString("depthlimb", "None"), true));
limbType[i] = (LimbType)Enum.Parse(typeof(LimbType),
subElement.GetAttributeString("limb", "Head"), true);
wearableSprites[i] = new WearableSprite(this, sprite, limbType[i],
subElement.GetAttributeBool("hidelimb", false),
subElement.GetAttributeBool("inheritlimbdepth", true),
(LimbType)Enum.Parse(typeof(LimbType), subElement.GetAttributeString("depthlimb", "None"), true), sound);
i++;
break;
case "damagemodifier":

View File

@@ -335,18 +335,18 @@ namespace Barotrauma
}
}
public Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine)
public Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine, float? spawnCondition = null)
: this(new Rectangle(
(int)(position.X - itemPrefab.sprite.size.X / 2),
(int)(position.Y + itemPrefab.sprite.size.Y / 2),
(int)itemPrefab.sprite.size.X,
(int)itemPrefab.sprite.size.Y),
itemPrefab, submarine)
itemPrefab, submarine, spawnCondition)
{
}
public Item(Rectangle newRect, ItemPrefab itemPrefab, Submarine submarine)
public Item(Rectangle newRect, ItemPrefab itemPrefab, Submarine submarine, float? spawnCondition = null)
: base(itemPrefab, submarine)
{
prefab = itemPrefab;
@@ -361,8 +361,8 @@ namespace Barotrauma
rect = newRect;
condition = prefab.Health;
lastSentCondition = prefab.Health;
condition = (float)(spawnCondition ?? prefab.Health);
lastSentCondition = condition;
XElement element = prefab.ConfigElement;
if (element == null) return;
@@ -781,7 +781,7 @@ namespace Barotrauma
float surfaceY = CurrentHull.Surface;
return Position.Y < surfaceY;
return CurrentHull.WaterVolume > 0.0f && Position.Y < surfaceY;
}
@@ -826,44 +826,46 @@ namespace Barotrauma
}
}
inWater = IsInWater();
if (inWater) ApplyStatusEffects(ActionType.InWater, deltaTime);
if (body == null || !body.Enabled) return;
System.Diagnostics.Debug.Assert(body.FarseerBody.FixtureList != null);
if (Math.Abs(body.LinearVelocity.X) > 0.01f || Math.Abs(body.LinearVelocity.Y) > 0.01f)
if (body != null && body.Enabled)
{
Submarine prevSub = Submarine;
System.Diagnostics.Debug.Assert(body.FarseerBody.FixtureList != null);
FindHull();
if (Math.Abs(body.LinearVelocity.X) > 0.01f || Math.Abs(body.LinearVelocity.Y) > 0.01f)
{
Submarine prevSub = Submarine;
if (Submarine == null && prevSub != null)
{
body.SetTransform(body.SimPosition + prevSub.SimPosition, body.Rotation);
}
else if (Submarine != null && prevSub == null)
{
body.SetTransform(body.SimPosition - Submarine.SimPosition, body.Rotation);
}
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
FindHull();
if (Math.Abs(body.LinearVelocity.X) > MaxVel || Math.Abs(body.LinearVelocity.Y) > MaxVel)
{
body.LinearVelocity = new Vector2(
MathHelper.Clamp(body.LinearVelocity.X, -MaxVel, MaxVel),
MathHelper.Clamp(body.LinearVelocity.Y, -MaxVel, MaxVel));
if (Submarine == null && prevSub != null)
{
body.SetTransform(body.SimPosition + prevSub.SimPosition, body.Rotation);
}
else if (Submarine != null && prevSub == null)
{
body.SetTransform(body.SimPosition - Submarine.SimPosition, body.Rotation);
}
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
if (Math.Abs(body.LinearVelocity.X) > MaxVel || Math.Abs(body.LinearVelocity.Y) > MaxVel)
{
body.LinearVelocity = new Vector2(
MathHelper.Clamp(body.LinearVelocity.X, -MaxVel, MaxVel),
MathHelper.Clamp(body.LinearVelocity.Y, -MaxVel, MaxVel));
}
}
UpdateNetPosition();
}
UpdateNetPosition();
if (!inWater || ParentInventory != null) return;
inWater = IsInWater();
if (inWater) ApplyStatusEffects(ActionType.InWater, deltaTime);
if (body == null || !body.Enabled || !inWater || ParentInventory != null) return;
ApplyWaterForces();
CurrentHull?.ApplyFlowForces(deltaTime, this);
}
@@ -1104,8 +1106,6 @@ namespace Barotrauma
ic.ApplyStatusEffects(ActionType.OnPicked, 1.0f, picker);
#if CLIENT
ic.PlaySound(ActionType.OnPicked, picker.WorldPosition);
if (picker == Character.Controlled) GUIComponent.ForceMouseOn(null);
#endif

View File

@@ -10,12 +10,16 @@ namespace Barotrauma
struct DeconstructItem
{
public readonly string ItemPrefabName;
public readonly bool RequireFullCondition;
public readonly float MinCondition;
public readonly float MaxCondition;
public readonly float OutCondition;
public DeconstructItem(string itemPrefabName, bool requireFullCondition)
public DeconstructItem(string itemPrefabName, float minCondition, float maxCondition, float outCondition)
{
ItemPrefabName = itemPrefabName;
RequireFullCondition = requireFullCondition;
MinCondition = minCondition;
MaxCondition = maxCondition;
OutCondition = outCondition;
}
}
@@ -301,9 +305,14 @@ namespace Barotrauma
{
string deconstructItemName = deconstructItem.GetAttributeString("name", "not found");
bool requireFullCondition = deconstructItem.GetAttributeBool("requirefullcondition", false);
//minCondition does <= check, meaning that below or equeal to min condition will be skipped.
float minCondition = deconstructItem.GetAttributeFloat("mincondition", -0.1f);
//maxCondition does > check, meaning that above this max the deconstruct item will be skipped.
float maxCondition = deconstructItem.GetAttributeFloat("maxcondition", 1.0f);
//Condition of item on creation
float outCondition = deconstructItem.GetAttributeFloat("outcondition", 1.0f);
DeconstructItems.Add(new DeconstructItem(deconstructItemName, requireFullCondition));
DeconstructItems.Add(new DeconstructItem(deconstructItemName, minCondition, maxCondition, outCondition));
}

View File

@@ -518,7 +518,7 @@ namespace Barotrauma
float impact = Vector2.Dot(f2.Body.LinearVelocity, -normal)*f2.Body.Mass*0.1f;
#if CLIENT
SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact,
SoundPlayer.PlayDamageSound("StructureBlunt", impact,
new Vector2(
sections[section].rect.X + sections[section].rect.Width / 2,
sections[section].rect.Y - sections[section].rect.Height / 2), tags: Tags);
@@ -679,7 +679,7 @@ namespace Barotrauma
#if CLIENT
if (playSound)// && !SectionBodyDisabled(i))
{
DamageSoundType damageSoundType = (attack.DamageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
string damageSoundType = (attack.DamageType == DamageType.Blunt) ? "StructureBlunt" : "StructureSlash";
SoundPlayer.PlayDamageSound(damageSoundType, damageAmount, worldPosition, tags: Tags);
}
#endif

View File

@@ -681,7 +681,7 @@ namespace Barotrauma
if (maxDamageStructure != null)
{
SoundPlayer.PlayDamageSound(
DamageSoundType.StructureBlunt,
"StructureBlunt",
impact * 10.0f,
ConvertUnits.ToDisplayUnits(lastContactPoint),
MathHelper.Clamp(maxDamage * 4.0f, 1000.0f, 4000.0f),

View File

@@ -22,24 +22,28 @@ namespace Barotrauma
public readonly Vector2 Position;
public readonly Inventory Inventory;
public readonly Submarine Submarine;
public readonly float Condition;
public ItemSpawnInfo(ItemPrefab prefab, Vector2 worldPosition)
public ItemSpawnInfo(ItemPrefab prefab, Vector2 worldPosition, float? condition = null)
{
Prefab = prefab;
Position = worldPosition;
Condition = (float)(condition ?? prefab.Health);
}
public ItemSpawnInfo(ItemPrefab prefab, Vector2 position, Submarine sub)
public ItemSpawnInfo(ItemPrefab prefab, Vector2 position, Submarine sub, float? condition = null)
{
Prefab = prefab;
Position = position;
Submarine = sub;
Condition = (float)(condition ?? prefab.Health);
}
public ItemSpawnInfo(ItemPrefab prefab, Inventory inventory)
public ItemSpawnInfo(ItemPrefab prefab, Inventory inventory, float? condition = null)
{
Prefab = prefab;
Inventory = inventory;
Condition = (float)(condition ?? prefab.Health);
}
public Entity Spawn()
@@ -48,12 +52,12 @@ namespace Barotrauma
if (Inventory != null)
{
spawnedItem = new Item(Prefab, Vector2.Zero, null);
spawnedItem = new Item(Prefab, Vector2.Zero, null, Condition);
Inventory.TryPutItem(spawnedItem, null, spawnedItem.AllowedSlots);
}
else
{
spawnedItem = new Item(Prefab, Position, Submarine);
spawnedItem = new Item(Prefab, Position, Submarine, Condition);
}
return spawnedItem;
@@ -83,25 +87,25 @@ namespace Barotrauma
removeQueue = new Queue<Entity>();
}
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 worldPosition)
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 worldPosition, float? condition = null)
{
if (GameMain.Client != null) return;
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, worldPosition));
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, worldPosition, condition));
}
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, Submarine sub)
public void AddToSpawnQueue(ItemPrefab itemPrefab, Vector2 position, Submarine sub, float? condition = null)
{
if (GameMain.Client != null) return;
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub));
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub, condition));
}
public void AddToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory)
public void AddToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, float? condition = null)
{
if (GameMain.Client != null) return;
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory));
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory, condition));
}
public void AddToRemoveQueue(Entity entity)

View File

@@ -1509,7 +1509,9 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Running;
} while (cinematic.Running);//(secondsLeft > 0.0f);
#if CLIENT
SoundPlayer.OverrideMusicType = null;
#endif
Submarine.Unload();
entityEventManager.Clear();