Merge pull request #2 from Regalis11/master
Updated to last original master commits
This commit is contained in:
@@ -29,6 +29,8 @@
|
|||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
<ReleaseVersion>0.7.0.1</ReleaseVersion>
|
<ReleaseVersion>0.7.0.1</ReleaseVersion>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||||
@@ -231,9 +233,15 @@
|
|||||||
<Compile Include="Source\Utils\ToolBox.cs" />
|
<Compile Include="Source\Utils\ToolBox.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="GameAnalytics.Mono, Version=1.0.6710.29255, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\GameAnalytics.Mono.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="MonoGame.Framework.WindowsDX">
|
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="MonoGame.Framework.WindowsDX">
|
||||||
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.6.0.1625\lib\net40\MonoGame.Framework.dll</HintPath>
|
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.6.0.1625\lib\net40\MonoGame.Framework.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\Libraries\NuGet\NLog.4.3.8\lib\net45\NLog.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="PresentationCore" />
|
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="PresentationCore" />
|
||||||
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX">
|
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
@@ -247,9 +255,12 @@
|
|||||||
<HintPath>..\..\Libraries\NuGet\OpenTK.2.0.0\lib\net20\OpenTK.dll</HintPath>
|
<HintPath>..\..\Libraries\NuGet\OpenTK.2.0.0\lib\net20\OpenTK.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data.SQLite, Version=1.0.102.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.XML" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="RestSharp">
|
<Reference Include="RestSharp">
|
||||||
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
||||||
@@ -324,6 +335,13 @@
|
|||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="..\BarotraumaShared\BarotraumaShared.projitems" Label="Shared" />
|
<Import Project="..\BarotraumaShared\BarotraumaShared.projitems" Label="Shared" />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets'))" />
|
||||||
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.8.1.2")]
|
[assembly: AssemblyVersion("0.8.1.5")]
|
||||||
[assembly: AssemblyFileVersion("0.8.1.2")]
|
[assembly: AssemblyFileVersion("0.8.1.5")]
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using FarseerPhysics;
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
@@ -17,13 +18,17 @@ namespace Barotrauma
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string hitSoundTag;
|
private float damage, burnt, wetTimer;
|
||||||
|
private float dripParticleTimer;
|
||||||
|
|
||||||
public string HitSoundTag
|
public float Burnt
|
||||||
{
|
{
|
||||||
get { return hitSoundTag; }
|
get { return burnt; }
|
||||||
|
protected set { burnt = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string HitSoundTag { get; private set; }
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
partial void InitProjSpecific(XElement element)
|
||||||
{
|
{
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
@@ -34,19 +39,97 @@ namespace Barotrauma
|
|||||||
LightSource = new LightSource(subElement);
|
LightSource = new LightSource(subElement);
|
||||||
break;
|
break;
|
||||||
case "sound":
|
case "sound":
|
||||||
hitSoundTag = subElement.GetAttributeString("tag", "");
|
HitSoundTag = subElement.GetAttributeString("tag", "");
|
||||||
if (string.IsNullOrWhiteSpace(hitSoundTag))
|
if (string.IsNullOrWhiteSpace(HitSoundTag))
|
||||||
{
|
{
|
||||||
//legacy support
|
//legacy support
|
||||||
hitSoundTag = subElement.GetAttributeString("file", "");
|
HitSoundTag = subElement.GetAttributeString("file", "");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateProjSpecific()
|
partial void AddDamageProjSpecific(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound, List<DamageModifier> appliedDamageModifiers)
|
||||||
{
|
{
|
||||||
|
if (playSound)
|
||||||
|
{
|
||||||
|
string damageSoundType = (damageType == DamageType.Blunt) ? "LimbBlunt" : "LimbSlash";
|
||||||
|
|
||||||
|
foreach (DamageModifier damageModifier in appliedDamageModifiers)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(damageModifier.DamageSound))
|
||||||
|
{
|
||||||
|
damageSoundType = damageModifier.DamageSound;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundPlayer.PlayDamageSound(damageSoundType, amount, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (character.UseBloodParticles)
|
||||||
|
{
|
||||||
|
float bloodParticleAmount = bleedingAmount <= 0.0f ? 0 : (int)Math.Min(amount / 5, 10);
|
||||||
|
float bloodParticleSize = MathHelper.Clamp(amount / 50.0f, 0.1f, 1.0f);
|
||||||
|
|
||||||
|
for (int i = 0; i < bloodParticleAmount; i++)
|
||||||
|
{
|
||||||
|
var blood = GameMain.ParticleManager.CreateParticle(inWater ? "waterblood" : "blood", WorldPosition, Vector2.Zero, 0.0f, character.AnimController.CurrentHull);
|
||||||
|
if (blood != null)
|
||||||
|
{
|
||||||
|
blood.Size *= bloodParticleSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bloodParticleAmount > 0 && character.CurrentHull != null)
|
||||||
|
{
|
||||||
|
character.CurrentHull.AddDecal("blood", WorldPosition, MathHelper.Clamp(bloodParticleSize, 0.5f, 1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (damageType == DamageType.Burn)
|
||||||
|
{
|
||||||
|
Burnt += amount * 10.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
damage += Math.Max(amount, bleedingAmount) / character.MaxHealth * 100.0f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void UpdateProjSpecific(float deltaTime)
|
||||||
|
{
|
||||||
|
if (!body.Enabled) return;
|
||||||
|
|
||||||
|
if (!character.IsDead)
|
||||||
|
{
|
||||||
|
damage = Math.Max(0.0f, damage - deltaTime * 0.1f);
|
||||||
|
Burnt -= deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inWater)
|
||||||
|
{
|
||||||
|
wetTimer = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wetTimer -= deltaTime * 0.1f;
|
||||||
|
if (wetTimer > 0.0f)
|
||||||
|
{
|
||||||
|
dripParticleTimer += wetTimer * deltaTime * Mass * (wetTimer > 0.9f ? 50.0f : 5.0f);
|
||||||
|
if (dripParticleTimer > 1.0f)
|
||||||
|
{
|
||||||
|
float dropRadius = body.BodyShape == PhysicsBody.Shape.Rectangle ? Math.Min(body.width, body.height) : body.radius;
|
||||||
|
GameMain.ParticleManager.CreateParticle(
|
||||||
|
"waterdrop",
|
||||||
|
WorldPosition + Rand.Vector(Rand.Range(0.0f, ConvertUnits.ToDisplayUnits(dropRadius))),
|
||||||
|
ConvertUnits.ToDisplayUnits(body.LinearVelocity),
|
||||||
|
0, character.CurrentHull);
|
||||||
|
dripParticleTimer = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (LightSource != null)
|
if (LightSource != null)
|
||||||
{
|
{
|
||||||
LightSource.ParentSub = body.Submarine;
|
LightSource.ParentSub = body.Submarine;
|
||||||
@@ -73,10 +156,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
body.Dir = Dir;
|
body.Dir = Dir;
|
||||||
|
|
||||||
bool hideLimb = wearingItems.Any(w => w != null && w.HideLimb);
|
bool hideLimb = WearingItems.Any(w => w != null && w.HideLimb);
|
||||||
if (!hideLimb)
|
if (!hideLimb)
|
||||||
{
|
{
|
||||||
body.Draw(spriteBatch, sprite, color, null, scale);
|
body.Draw(spriteBatch, sprite, color, null, Scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -89,7 +172,7 @@ namespace Barotrauma
|
|||||||
LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically;
|
LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (WearableSprite wearable in wearingItems)
|
foreach (WearableSprite wearable in WearingItems)
|
||||||
{
|
{
|
||||||
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
|
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
|
||||||
|
|
||||||
@@ -115,7 +198,7 @@ namespace Barotrauma
|
|||||||
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
||||||
color, origin,
|
color, origin,
|
||||||
-body.DrawRotation,
|
-body.DrawRotation,
|
||||||
scale, spriteEffect, depth);
|
Scale, spriteEffect, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damage > 0.0f && damagedSprite != null && !hideLimb)
|
if (damage > 0.0f && damagedSprite != null && !hideLimb)
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ namespace Barotrauma
|
|||||||
NewMessage(GUI.DisableHUD ? "Disabled HUD" : "Enabled HUD", Color.White);
|
NewMessage(GUI.DisableHUD ? "Disabled HUD" : "Enabled HUD", Color.White);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("followsub", "followsub: Toggle whether the ", (string[] args) =>
|
commands.Add(new Command("followsub", "followsub: Toggle whether the camera should follow the nearest submarine.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Camera.FollowSub = !Camera.FollowSub;
|
Camera.FollowSub = !Camera.FollowSub;
|
||||||
NewMessage(Camera.FollowSub ? "Set the camera to follow the closest submarine" : "Disabled submarine following.", Color.White);
|
NewMessage(Camera.FollowSub ? "Set the camera to follow the closest submarine" : "Disabled submarine following.", Color.White);
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public void ShowMessage(int index)
|
public void ShowMessage(int index)
|
||||||
{
|
{
|
||||||
if (index >= headers.Count && index >= messages.Count) return;
|
if (index >= Headers.Count && index >= Messages.Count) return;
|
||||||
|
|
||||||
string header = index < headers.Count ? headers[index] : "";
|
string header = index < Headers.Count ? Headers[index] : "";
|
||||||
string message = index < messages.Count ? messages[index] : "";
|
string message = index < Messages.Count ? Messages[index] : "";
|
||||||
|
|
||||||
GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
|
GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
|
||||||
|
|
||||||
|
|||||||
@@ -198,7 +198,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static bool QuitClicked(GUIButton button, object obj)
|
private static bool QuitClicked(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
if (button.UserData as string == "save")
|
bool save = button.UserData as string == "save";
|
||||||
|
if (save)
|
||||||
{
|
{
|
||||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||||
}
|
}
|
||||||
@@ -211,10 +212,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
CoroutineManager.StopCoroutines("EndCinematic");
|
CoroutineManager.StopCoroutines("EndCinematic");
|
||||||
|
|
||||||
GameMain.GameSession = null;
|
if (GameMain.GameSession != null)
|
||||||
|
{
|
||||||
|
if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
Mission mission = GameMain.GameSession.Mission;
|
||||||
|
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("QuitRound:" + (save ? "Save" : "NoSave"));
|
||||||
|
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("EndRound:" + (mission == null ? "NoMission" : (mission.Completed ? "MissionCompleted" : "MissionFailed")));
|
||||||
|
}
|
||||||
|
GameMain.GameSession = null;
|
||||||
|
}
|
||||||
|
|
||||||
GameMain.MainMenuScreen.Select();
|
GameMain.MainMenuScreen.Select();
|
||||||
//Game1.MainMenuScreen.SelectTab(null, (int)MainMenuScreen.Tabs.Main);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using GameAnalyticsSDK.Net;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -144,7 +145,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Timing.Accumulator = 0.0f;
|
Timing.Accumulator = 0.0f;
|
||||||
fixedTime = new GameTime();
|
fixedTime = new GameTime();
|
||||||
|
|
||||||
World = new World(new Vector2(0, -9.82f));
|
World = new World(new Vector2(0, -9.82f));
|
||||||
FarseerPhysics.Settings.AllowSleep = true;
|
FarseerPhysics.Settings.AllowSleep = true;
|
||||||
FarseerPhysics.Settings.ContinuousPhysics = false;
|
FarseerPhysics.Settings.ContinuousPhysics = false;
|
||||||
@@ -232,6 +233,31 @@ namespace Barotrauma
|
|||||||
loadingCoroutine = CoroutineManager.StartCoroutine(Load());
|
loadingCoroutine = CoroutineManager.StartCoroutine(Load());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitUserStats()
|
||||||
|
{
|
||||||
|
if (GameSettings.ShowUserStatisticsPrompt)
|
||||||
|
{
|
||||||
|
var userStatsPrompt = new GUIMessageBox(
|
||||||
|
"Do you want to help us make Barotrauma better?",
|
||||||
|
"Do you allow Barotrauma to send usage statistics and error reports to the developers? The data is anonymous, " +
|
||||||
|
"does not contain any personal information and is only used to help us diagnose issues and improve Barotrauma.",
|
||||||
|
new string[] { "Yes", "No" });
|
||||||
|
userStatsPrompt.Buttons[0].OnClicked += (btn, userdata) =>
|
||||||
|
{
|
||||||
|
GameSettings.SendUserStatistics = true;
|
||||||
|
GameAnalyticsManager.Init();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
userStatsPrompt.Buttons[0].OnClicked += userStatsPrompt.Close;
|
||||||
|
userStatsPrompt.Buttons[1].OnClicked += (btn, userdata) => { GameSettings.SendUserStatistics = false; return true; };
|
||||||
|
userStatsPrompt.Buttons[1].OnClicked += userStatsPrompt.Close;
|
||||||
|
}
|
||||||
|
else if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
GameAnalyticsManager.Init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<object> Load()
|
private IEnumerable<object> Load()
|
||||||
{
|
{
|
||||||
if (GameSettings.VerboseLogging)
|
if (GameSettings.VerboseLogging)
|
||||||
@@ -241,6 +267,8 @@ namespace Barotrauma
|
|||||||
GUI.GraphicsDevice = base.GraphicsDevice;
|
GUI.GraphicsDevice = base.GraphicsDevice;
|
||||||
GUI.Init(Content);
|
GUI.Init(Content);
|
||||||
|
|
||||||
|
InitUserStats();
|
||||||
|
|
||||||
GUIComponent.Init(Window);
|
GUIComponent.Init(Window);
|
||||||
DebugConsole.Init(Window);
|
DebugConsole.Init(Window);
|
||||||
DebugConsole.Log(SelectedPackage == null ? "No content package selected" : "Content package \"" + SelectedPackage.Name + "\" selected");
|
DebugConsole.Log(SelectedPackage == null ? "No content package selected" : "Content package \"" + SelectedPackage.Name + "\" selected");
|
||||||
@@ -256,7 +284,7 @@ namespace Barotrauma
|
|||||||
TitleScreen.LoadState = 2.0f;
|
TitleScreen.LoadState = 2.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
Mission.Init();
|
MissionPrefab.Init();
|
||||||
MapEntityPrefab.Init();
|
MapEntityPrefab.Init();
|
||||||
LevelGenerationParams.LoadPresets();
|
LevelGenerationParams.LoadPresets();
|
||||||
TitleScreen.LoadState = 10.0f;
|
TitleScreen.LoadState = 10.0f;
|
||||||
@@ -472,7 +500,7 @@ namespace Barotrauma
|
|||||||
protected override void OnExiting(object sender, EventArgs args)
|
protected override void OnExiting(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
if (NetworkMember != null) NetworkMember.Disconnect();
|
if (NetworkMember != null) NetworkMember.Disconnect();
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalytics.OnStop();
|
||||||
base.OnExiting(sender, args);
|
base.OnExiting(sender, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ namespace Barotrauma
|
|||||||
listBox.ClearChildren();
|
listBox.ClearChildren();
|
||||||
characters.Clear();
|
characters.Clear();
|
||||||
|
|
||||||
WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub, false);
|
WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
|
||||||
|
|
||||||
for (int i = 0; i < waypoints.Length; i++)
|
for (int i = 0; i < waypoints.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ namespace Barotrauma.Lights
|
|||||||
public void UpdateObstructVision(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, Vector2 lookAtPosition)
|
public void UpdateObstructVision(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, Vector2 lookAtPosition)
|
||||||
{
|
{
|
||||||
if (!LosEnabled && !ObstructVision) return;
|
if (!LosEnabled && !ObstructVision) return;
|
||||||
|
if (ViewTarget == null) return;
|
||||||
|
|
||||||
graphics.SetRenderTarget(losTexture);
|
graphics.SetRenderTarget(losTexture);
|
||||||
|
|
||||||
|
|||||||
@@ -691,6 +691,7 @@ namespace Barotrauma.Networking
|
|||||||
string shuttleHash = inc.ReadString();
|
string shuttleHash = inc.ReadString();
|
||||||
|
|
||||||
string modeName = inc.ReadString();
|
string modeName = inc.ReadString();
|
||||||
|
int missionIndex = inc.ReadInt16();
|
||||||
|
|
||||||
bool respawnAllowed = inc.ReadBoolean();
|
bool respawnAllowed = inc.ReadBoolean();
|
||||||
bool loadSecondSub = inc.ReadBoolean();
|
bool loadSecondSub = inc.ReadBoolean();
|
||||||
@@ -750,7 +751,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (campaign == null)
|
if (campaign == null)
|
||||||
{
|
{
|
||||||
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
|
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, missionIndex < 0 ? null : MissionPrefab.List[missionIndex]);
|
||||||
GameMain.GameSession.StartRound(levelSeed, loadSecondSub);
|
GameMain.GameSession.StartRound(levelSeed, loadSecondSub);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -821,7 +822,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName), subHash, false));
|
submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName) + ".sub", subHash, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,7 +884,7 @@ namespace Barotrauma.Networking
|
|||||||
bool allowSpectating = inc.ReadBoolean();
|
bool allowSpectating = inc.ReadBoolean();
|
||||||
|
|
||||||
YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2);
|
YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2);
|
||||||
int missionTypeIndex = inc.ReadRangedInteger(0, Mission.MissionTypes.Count - 1);
|
int missionTypeIndex = inc.ReadRangedInteger(0, MissionPrefab.MissionTypes.Count - 1);
|
||||||
int modeIndex = inc.ReadByte();
|
int modeIndex = inc.ReadByte();
|
||||||
|
|
||||||
string levelSeed = inc.ReadString();
|
string levelSeed = inc.ReadString();
|
||||||
@@ -1440,6 +1441,8 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write((byte)ClientPermissions.Ban);
|
msg.Write((byte)ClientPermissions.Ban);
|
||||||
msg.Write(kickedName);
|
msg.Write(kickedName);
|
||||||
msg.Write(reason);
|
msg.Write(reason);
|
||||||
|
msg.Write(range);
|
||||||
|
msg.Write(duration.HasValue ? duration.Value.TotalSeconds : 0.0); //0 = permaban
|
||||||
|
|
||||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using GameAnalyticsSDK.Net;
|
||||||
|
|
||||||
#if WINDOWS
|
#if WINDOWS
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
@@ -135,7 +136,6 @@ namespace Barotrauma
|
|||||||
sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")");
|
sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")");
|
||||||
sb.AppendLine("\n");
|
sb.AppendLine("\n");
|
||||||
sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! ");
|
sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! ");
|
||||||
sb.AppendLine("If you'd like to help fix the bug that caused the crash, please send this file to the developers on the Undertow Games forums.");
|
|
||||||
sb.AppendLine("\n");
|
sb.AppendLine("\n");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
sb.AppendLine("Game version " + GameMain.Version + " (debug build)");
|
sb.AppendLine("Game version " + GameMain.Version + " (debug build)");
|
||||||
@@ -192,14 +192,25 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text);
|
sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string crashReport = sb.ToString();
|
||||||
|
|
||||||
sw.WriteLine(sb.ToString());
|
sw.WriteLine(crashReport);
|
||||||
sw.Close();
|
sw.Close();
|
||||||
|
|
||||||
if (GameSettings.SaveDebugConsoleLogs) DebugConsole.SaveLogs();
|
if (GameSettings.SaveDebugConsoleLogs) DebugConsole.SaveLogs();
|
||||||
|
|
||||||
CrashMessageBox( "A crash report (\"crashreport.log\") was saved in the root folder of the game."+
|
if (GameSettings.SendUserStatistics)
|
||||||
" If you'd like to help fix this bug, please post the report on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/");
|
{
|
||||||
|
CrashMessageBox( "A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers.");
|
||||||
|
GameAnalytics.AddErrorEvent(EGAErrorSeverity.Error, crashReport);
|
||||||
|
GameAnalytics.OnStop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CrashMessageBox("A crash report (\"crashreport.log\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" +
|
||||||
|
" if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ namespace Barotrauma
|
|||||||
campaignUI.StartRound = StartRound;
|
campaignUI.StartRound = StartRound;
|
||||||
campaignUI.OnLocationSelected = SelectLocation;
|
campaignUI.OnLocationSelected = SelectLocation;
|
||||||
campaignUI.UpdateCharacterLists();
|
campaignUI.UpdateCharacterLists();
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("singleplayer");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddToGUIUpdateList()
|
public override void AddToGUIUpdateList()
|
||||||
|
|||||||
@@ -142,6 +142,8 @@ namespace Barotrauma
|
|||||||
campaignSetupUI.UpdateSubList();
|
campaignSetupUI.UpdateSubList();
|
||||||
|
|
||||||
SelectTab(null, 0);
|
SelectTab(null, 0);
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SelectTab(GUIButton button, object obj)
|
public bool SelectTab(GUIButton button, object obj)
|
||||||
|
|||||||
@@ -501,6 +501,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("multiplayer");
|
||||||
|
|
||||||
if (GameModePreset.list.Count > 0 && modeList.Selected == null) modeList.Select(0);
|
if (GameModePreset.list.Count > 0 && modeList.Selected == null) modeList.Select(0);
|
||||||
|
|
||||||
GameMain.Server.Voting.ResetVotes(GameMain.Server.ConnectedClients);
|
GameMain.Server.Voting.ResetVotes(GameMain.Server.ConnectedClients);
|
||||||
@@ -559,14 +561,18 @@ namespace Barotrauma
|
|||||||
var playYourself = new GUITickBox(new Rectangle(0, 0, 20, 20), TextManager.Get("PlayYourself"), Alignment.TopLeft, myPlayerFrame);
|
var playYourself = new GUITickBox(new Rectangle(0, 0, 20, 20), TextManager.Get("PlayYourself"), Alignment.TopLeft, myPlayerFrame);
|
||||||
playYourself.Selected = GameMain.NetworkMember.CharacterInfo != null;
|
playYourself.Selected = GameMain.NetworkMember.CharacterInfo != null;
|
||||||
playYourself.OnSelected = TogglePlayYourself;
|
playYourself.OnSelected = TogglePlayYourself;
|
||||||
playYourself.UserData = "playyourself";
|
playYourself.UserData = "playyourself";
|
||||||
|
|
||||||
GUIButton toggleHead = new GUIButton(new Rectangle(0, 50, 15, 15), "<", "", myPlayerFrame);
|
GUIButton toggleHead = new GUIButton(new Rectangle(0, 50, 15, 15), "<", "", myPlayerFrame)
|
||||||
toggleHead.UserData = -1;
|
{
|
||||||
toggleHead.OnClicked = ToggleHead;
|
UserData = -1,
|
||||||
toggleHead = new GUIButton(new Rectangle(60, 50, 15, 15), ">", "", myPlayerFrame);
|
OnClicked = ToggleHead
|
||||||
toggleHead.UserData = 1;
|
};
|
||||||
toggleHead.OnClicked = ToggleHead;
|
toggleHead = new GUIButton(new Rectangle(60, 50, 15, 15), ">", "", myPlayerFrame)
|
||||||
|
{
|
||||||
|
UserData = 1,
|
||||||
|
OnClicked = ToggleHead
|
||||||
|
};
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(100, 30, 200, 30), TextManager.Get("Gender"), "", myPlayerFrame);
|
new GUITextBlock(new Rectangle(100, 30, 200, 30), TextManager.Get("Gender"), "", myPlayerFrame);
|
||||||
|
|
||||||
@@ -629,7 +635,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (tickBox.Selected)
|
if (tickBox.Selected)
|
||||||
{
|
{
|
||||||
GameMain.NetworkMember.CharacterInfo = new CharacterInfo(Character.HumanConfigFile, GameMain.NetworkMember.Name, Gender.None, null);
|
GameMain.NetworkMember.CharacterInfo =
|
||||||
|
new CharacterInfo(Character.HumanConfigFile, GameMain.NetworkMember.Name, GameMain.Config.CharacterGender, null);
|
||||||
|
GameMain.NetworkMember.CharacterInfo.HeadSpriteId = GameMain.Config.CharacterHeadIndex;
|
||||||
|
|
||||||
UpdatePlayerFrame(GameMain.NetworkMember.CharacterInfo);
|
UpdatePlayerFrame(GameMain.NetworkMember.CharacterInfo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -688,9 +697,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SetMissionType(int missionTypeIndex)
|
public void SetMissionType(int missionTypeIndex)
|
||||||
{
|
{
|
||||||
if (missionTypeIndex < 0 || missionTypeIndex >= Mission.MissionTypes.Count) return;
|
if (missionTypeIndex < 0 || missionTypeIndex >= MissionPrefab.MissionTypes.Count) return;
|
||||||
|
|
||||||
missionTypeBlock.GetChild<GUITextBlock>().Text = Mission.MissionTypes[missionTypeIndex];
|
missionTypeBlock.GetChild<GUITextBlock>().Text = MissionPrefab.MissionTypes[missionTypeIndex];
|
||||||
missionTypeBlock.UserData = missionTypeIndex;
|
missionTypeBlock.UserData = missionTypeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,8 +710,8 @@ namespace Barotrauma
|
|||||||
int missionTypeIndex = (int)missionTypeBlock.UserData;
|
int missionTypeIndex = (int)missionTypeBlock.UserData;
|
||||||
missionTypeIndex += (int)userData;
|
missionTypeIndex += (int)userData;
|
||||||
|
|
||||||
if (missionTypeIndex < 0) missionTypeIndex = Mission.MissionTypes.Count - 1;
|
if (missionTypeIndex < 0) missionTypeIndex = MissionPrefab.MissionTypes.Count - 1;
|
||||||
if (missionTypeIndex >= Mission.MissionTypes.Count) missionTypeIndex = 0;
|
if (missionTypeIndex >= MissionPrefab.MissionTypes.Count) missionTypeIndex = 0;
|
||||||
|
|
||||||
SetMissionType(missionTypeIndex);
|
SetMissionType(missionTypeIndex);
|
||||||
|
|
||||||
@@ -1247,14 +1256,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool ToggleHead(GUIButton button, object userData)
|
private bool ToggleHead(GUIButton button, object userData)
|
||||||
{
|
{
|
||||||
int dir = (int)userData;
|
|
||||||
|
|
||||||
if (GameMain.NetworkMember.CharacterInfo == null) return true;
|
if (GameMain.NetworkMember.CharacterInfo == null) return true;
|
||||||
|
|
||||||
|
int dir = (int)userData;
|
||||||
GameMain.NetworkMember.CharacterInfo.HeadSpriteId += dir;
|
GameMain.NetworkMember.CharacterInfo.HeadSpriteId += dir;
|
||||||
|
GameMain.Config.CharacterHeadIndex = GameMain.NetworkMember.CharacterInfo.HeadSpriteId;
|
||||||
UpdatePlayerHead(GameMain.NetworkMember.CharacterInfo);
|
UpdatePlayerHead(GameMain.NetworkMember.CharacterInfo);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1262,7 +1269,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Gender gender = (Gender)obj;
|
Gender gender = (Gender)obj;
|
||||||
GameMain.NetworkMember.CharacterInfo.Gender = gender;
|
GameMain.NetworkMember.CharacterInfo.Gender = gender;
|
||||||
|
GameMain.Config.CharacterGender = GameMain.NetworkMember.CharacterInfo.Gender;
|
||||||
UpdatePlayerHead(GameMain.NetworkMember.CharacterInfo);
|
UpdatePlayerHead(GameMain.NetworkMember.CharacterInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -348,6 +348,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
cam.UpdateTransform();
|
cam.UpdateTransform();
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("editor");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Deselect()
|
public override void Deselect()
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (File.Exists(file))
|
if (File.Exists(file))
|
||||||
{
|
{
|
||||||
|
ToolBox.IsProperFilenameCase(file);
|
||||||
return TextureLoader.FromFile(file);
|
return TextureLoader.FromFile(file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="GameAnalytics.Mono.SDK" version="1.1.12" targetFramework="net45" />
|
||||||
<package id="MonoGame.Framework.DesktopGL" version="3.6.0.1625" targetFramework="net45" />
|
<package id="MonoGame.Framework.DesktopGL" version="3.6.0.1625" targetFramework="net45" />
|
||||||
<package id="MonoGame.Framework.WindowsDX" version="3.6.0.1625" targetFramework="net45" />
|
<package id="MonoGame.Framework.WindowsDX" version="3.6.0.1625" targetFramework="net45" />
|
||||||
|
<package id="NLog" version="4.3.8" targetFramework="net45" />
|
||||||
<package id="NVorbis" version="0.8.5.0" targetFramework="net45" />
|
<package id="NVorbis" version="0.8.5.0" targetFramework="net45" />
|
||||||
<package id="OpenTK" version="2.0.0" targetFramework="net45" />
|
<package id="OpenTK" version="2.0.0" targetFramework="net45" />
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
<UseApplicationTrust>false</UseApplicationTrust>
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
<ReleaseVersion>0.7.0.1</ReleaseVersion>
|
<ReleaseVersion>0.7.0.1</ReleaseVersion>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||||
@@ -69,12 +71,21 @@
|
|||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="GameAnalytics.Mono, Version=1.0.6710.29255, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\GameAnalytics.Mono.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\Libraries\NuGet\NLog.4.3.8\lib\net45\NLog.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.XML" />
|
<Reference Include="System.Data.SQLite, Version=1.0.102.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -142,6 +153,13 @@
|
|||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="..\BarotraumaShared\BarotraumaShared.projitems" Label="Shared" />
|
<Import Project="..\BarotraumaShared\BarotraumaShared.projitems" Label="Shared" />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets'))" />
|
||||||
|
</Target>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.8.1.2")]
|
[assembly: AssemblyVersion("0.8.1.5")]
|
||||||
[assembly: AssemblyFileVersion("0.8.1.2")]
|
[assembly: AssemblyFileVersion("0.8.1.5")]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
lock (QueuedCommands)
|
lock (QueuedCommands)
|
||||||
{
|
{
|
||||||
while (QueuedCommands.Count>0)
|
while (QueuedCommands.Count > 0)
|
||||||
{
|
{
|
||||||
ExecuteCommand(QueuedCommands[0]);
|
ExecuteCommand(QueuedCommands[0]);
|
||||||
QueuedCommands.RemoveAt(0);
|
QueuedCommands.RemoveAt(0);
|
||||||
@@ -127,7 +127,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return new string[][]
|
return new string[][]
|
||||||
{
|
{
|
||||||
Mission.MissionTypes.ToArray()
|
MissionPrefab.MissionTypes.ToArray()
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -190,6 +190,16 @@ namespace Barotrauma
|
|||||||
NewMessage(ent.ToString(), Color.Lime);
|
NewMessage(ent.ToString(), Color.Lime);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
//"dummy commands" that only exist so that the server can give clients permissions to use them
|
||||||
|
commands.Add(new Command("control|controlcharacter", "control [character name]: Start controlling the specified character (client-only).", null));
|
||||||
|
commands.Add(new Command("los", "Toggle the line of sight effect on/off (client-only).", null));
|
||||||
|
commands.Add(new Command("lighting|lights", "Toggle lighting on/off (client-only).", null));
|
||||||
|
commands.Add(new Command("debugdraw", "Toggle the debug drawing mode on/off (client-only).", null));
|
||||||
|
commands.Add(new Command("togglehud|hud", "Toggle the character HUD (inventories, icons, buttons, etc) on/off (client-only).", null));
|
||||||
|
commands.Add(new Command("followsub", "Toggle whether the camera should follow the nearest submarine (client-only).", null));
|
||||||
|
commands.Add(new Command("toggleaitargets|aitargets", "Toggle the visibility of AI targets (= targets that enemies can detect and attack/escape from) (client-only).", null));
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
commands.Add(new Command("eventdata", "", (string[] args) =>
|
commands.Add(new Command("eventdata", "", (string[] args) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using FarseerPhysics.Dynamics;
|
using FarseerPhysics.Dynamics;
|
||||||
|
using GameAnalyticsSDK.Net;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -72,12 +73,17 @@ namespace Barotrauma
|
|||||||
Config.Save("config.xml");
|
Config.Save("config.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
GameAnalyticsManager.Init();
|
||||||
|
}
|
||||||
|
|
||||||
GameScreen = new GameScreen();
|
GameScreen = new GameScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
Mission.Init();
|
MissionPrefab.Init();
|
||||||
MapEntityPrefab.Init();
|
MapEntityPrefab.Init();
|
||||||
LevelGenerationParams.LoadPresets();
|
LevelGenerationParams.LoadPresets();
|
||||||
|
|
||||||
@@ -118,6 +124,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void CloseServer()
|
public void CloseServer()
|
||||||
{
|
{
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalytics.OnStop();
|
||||||
Server.Disconnect();
|
Server.Disconnect();
|
||||||
Server = null;
|
Server = null;
|
||||||
}
|
}
|
||||||
@@ -139,25 +146,27 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
DebugConsole.NewMessage("WARNING: Stopwatch frequency under 1500 ticks per second. Expect significant syncing accuracy issues.", Color.Yellow);
|
DebugConsole.NewMessage("WARNING: Stopwatch frequency under 1500 ticks per second. Expect significant syncing accuracy issues.", Color.Yellow);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||||
long prevTicks = stopwatch.ElapsedTicks;
|
long prevTicks = stopwatch.ElapsedTicks;
|
||||||
while (ShouldRun)
|
while (ShouldRun)
|
||||||
{
|
{
|
||||||
long currTicks = stopwatch.ElapsedTicks;
|
long currTicks = stopwatch.ElapsedTicks;
|
||||||
Timing.Accumulator += (double)(currTicks - prevTicks) / frequency;
|
double elapsedTime = (currTicks - prevTicks) / frequency;
|
||||||
|
Timing.Accumulator += elapsedTime;
|
||||||
|
Timing.TotalTime += elapsedTime;
|
||||||
prevTicks = currTicks;
|
prevTicks = currTicks;
|
||||||
while (Timing.Accumulator>=Timing.Step)
|
while (Timing.Accumulator >= Timing.Step)
|
||||||
{
|
{
|
||||||
DebugConsole.Update();
|
DebugConsole.Update();
|
||||||
if (Screen.Selected != null) Screen.Selected.Update((float)Timing.Step);
|
if (Screen.Selected != null) Screen.Selected.Update((float)Timing.Step);
|
||||||
Server.Update((float)Timing.Step);
|
Server.Update((float)Timing.Step);
|
||||||
CoroutineManager.Update((float)Timing.Step, (float)Timing.Step);
|
CoroutineManager.Update((float)Timing.Step, (float)Timing.Step);
|
||||||
|
|
||||||
Timing.Accumulator -= Timing.Step;
|
Timing.Accumulator -= Timing.Step;
|
||||||
}
|
}
|
||||||
int frameTime = (int)(((double)(stopwatch.ElapsedTicks - prevTicks) / frequency)*1000.0);
|
int frameTime = (int)(((double)(stopwatch.ElapsedTicks - prevTicks) / frequency) * 1000.0);
|
||||||
Thread.Sleep(Math.Max(((int)(Timing.Step * 1000.0) - frameTime)/2,0));
|
Thread.Sleep(Math.Max(((int)(Timing.Step * 1000.0) - frameTime) / 2, 0));
|
||||||
}
|
}
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#region Using Statements
|
#region Using Statements
|
||||||
|
|
||||||
|
using GameAnalyticsSDK.Net;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -46,7 +47,6 @@ namespace Barotrauma
|
|||||||
sb.AppendLine("Barotrauma Dedicated Server crash report (generated on " + DateTime.Now + ")");
|
sb.AppendLine("Barotrauma Dedicated Server crash report (generated on " + DateTime.Now + ")");
|
||||||
sb.AppendLine("\n");
|
sb.AppendLine("\n");
|
||||||
sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! ");
|
sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! ");
|
||||||
sb.AppendLine("If you'd like to help fix the bug that caused the crash, please send this file to the developers on the Undertow Games forums.");
|
|
||||||
sb.AppendLine("\n");
|
sb.AppendLine("\n");
|
||||||
sb.AppendLine("Game version " + GameMain.Version);
|
sb.AppendLine("Game version " + GameMain.Version);
|
||||||
sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name);
|
sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name);
|
||||||
@@ -75,11 +75,24 @@ namespace Barotrauma
|
|||||||
sb.AppendLine(" "+DebugConsole.Messages[i].Time+" - "+DebugConsole.Messages[i].Text);
|
sb.AppendLine(" "+DebugConsole.Messages[i].Time+" - "+DebugConsole.Messages[i].Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string crashReport = sb.ToString();
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
Console.Write(sb.ToString());
|
Console.Write(crashReport);
|
||||||
|
|
||||||
sw.WriteLine(sb.ToString());
|
sw.WriteLine(sb.ToString());
|
||||||
sw.Close();
|
sw.Close();
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
GameAnalytics.AddErrorEvent(EGAErrorSeverity.Error, crashReport);
|
||||||
|
GameAnalytics.OnStop();
|
||||||
|
Console.Write("A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.Write("A crash report(\"crashreport.log\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" +
|
||||||
|
" if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,18 +75,18 @@ namespace Barotrauma
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
lastUpdateID++;
|
lastUpdateID++;
|
||||||
missionTypeIndex = Math.Max(0, Math.Min(Mission.MissionTypes.Count() - 1, value));
|
missionTypeIndex = Math.Max(0, Math.Min(MissionPrefab.MissionTypes.Count() - 1, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string MissionTypeName
|
public string MissionTypeName
|
||||||
{
|
{
|
||||||
get { return Mission.MissionTypes[MissionTypeIndex]; }
|
get { return MissionPrefab.MissionTypes[MissionTypeIndex]; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Mission.MissionTypes.Count(); i++)
|
for (int i = 0; i < MissionPrefab.MissionTypes.Count(); i++)
|
||||||
{
|
{
|
||||||
if (Mission.MissionTypes[i].ToLower() == value.ToLower())
|
if (MissionPrefab.MissionTypes[i].ToLower() == value.ToLower())
|
||||||
{
|
{
|
||||||
MissionTypeIndex = i;
|
MissionTypeIndex = i;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="GameAnalytics.Mono.SDK" version="1.1.12" targetFramework="net45" />
|
||||||
|
<package id="NLog" version="4.3.8" targetFramework="net45" />
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -232,6 +232,9 @@
|
|||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Items\SearchLight\SearchLightBase.png">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Items\SearchLight\SearchLightBase.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Weapons\railgunetc2.png">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Content\Texts.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Content\Texts.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -1471,6 +1474,9 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterInfo.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterInfo.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterNetworking.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterNetworking.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\DamageModifier.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\DamageModifier.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Events\Missions\MissionPrefab.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\GameAnalyticsManager.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\Components\Signal\AdderComponent.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\DelayedEffect.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\DelayedEffect.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\HuskInfection.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\HuskInfection.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Jobs\Job.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Jobs\Job.cs" />
|
||||||
|
|||||||
@@ -170,7 +170,7 @@
|
|||||||
|
|
||||||
<StatusEffect type="OnUse" target="This" Condition="-1.0"/>
|
<StatusEffect type="OnUse" target="This" Condition="-1.0"/>
|
||||||
|
|
||||||
<sound file="alienweapon.ogg" type="OnUse" range="800.0" loop="true"/>
|
<sound file="Content/Items/Artifacts/alienweapon.ogg" type="OnUse" range="800.0" loop="true"/>
|
||||||
|
|
||||||
<LightComponent LightColor="0.8,0.7,1.0,1.0" Flicker="0.5" range="500">
|
<LightComponent LightColor="0.8,0.7,1.0,1.0" Flicker="0.5" range="500">
|
||||||
<sprite texture="Content/Items/Electricity/lightsprite.png" origin="0.5,0.5"/>
|
<sprite texture="Content/Items/Electricity/lightsprite.png" origin="0.5,0.5"/>
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
|
|
||||||
<Door canbepicked="false" 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"/>
|
<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"/>
|
<sound file="Content/Items/Artifacts/aliendoor.ogg" type="OnUse" range="1000.0"/>
|
||||||
</Door>
|
</Door>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" msg="Rewire [Screwdriver]">
|
||||||
@@ -233,7 +233,7 @@
|
|||||||
|
|
||||||
<Door canbepicked="false" 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"/>
|
<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"/>
|
<sound file="Content/Items/Artifacts/aliendoor.ogg" type="OnUse" range="3000.0"/>
|
||||||
</Door>
|
</Door>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" msg="Rewire [Screwdriver]">
|
||||||
@@ -288,4 +288,4 @@
|
|||||||
<output name="power_out"/>
|
<output name="power_out"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<Controller direction ="None" canbepicked = "true" msg="Press [E]">
|
<Controller direction ="None" canbepicked = "true" msg="Press [E]">
|
||||||
<RequiredItem name="ID Card" type="Picked" msg="UNAUTHORIZED ACCESS"/>
|
<RequiredItem name="ID Card" type="Picked" msg="UNAUTHORIZED ACCESS"/>
|
||||||
<sound file="beep.ogg" type="OnUse" range="500.0"/>
|
<sound file="Content/Items/Button/beep.ogg" type="OnUse" range="500.0"/>
|
||||||
</Controller>
|
</Controller>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<Body width="12" height="16" density="20"/>
|
<Body width="12" height="16" density="20"/>
|
||||||
|
|
||||||
<Controller direction="None" canbepicked="true" msg="Press [E]">
|
<Controller direction="None" canbepicked="true" msg="Press [E]">
|
||||||
<sound file="switch.ogg" type="OnUse" range="250.0"/>
|
<sound file="Content/Items/Button/switch.ogg" type="OnUse" range="250.0"/>
|
||||||
</Controller>
|
</Controller>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
@@ -63,4 +63,4 @@
|
|||||||
<requireditem name="Wrench" type="Equipped"/>
|
<requireditem name="Wrench" type="Equipped"/>
|
||||||
</Holdable>
|
</Holdable>
|
||||||
</Item>
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
|
|||||||
@@ -11,6 +11,18 @@
|
|||||||
</ItemContainer>
|
</ItemContainer>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Railgun Shell Rack"
|
||||||
|
pickdistance ="120">
|
||||||
|
|
||||||
|
<Sprite texture ="Content/Items/Weapons/railgunetc2.png" depth="0.84" sourcerect="57,97,72,110"/>
|
||||||
|
|
||||||
|
<ItemContainer hideitems="false" drawinventory="true" capacity="3" slotsperrow="3" itempos="17,-49.5" iteminterval="19,0" itemrotation="90" canbeselected = "true">
|
||||||
|
<Containable name="Railgun Shell"/>
|
||||||
|
<Containable name="Nuclear Shell"/>
|
||||||
|
</ItemContainer>
|
||||||
|
</Item>
|
||||||
|
|
||||||
<Item
|
<Item
|
||||||
name="Medicine Cabinet"
|
name="Medicine Cabinet"
|
||||||
linkable="true"
|
linkable="true"
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
|
|
||||||
<Pickable holdpos="30,-15" handle1="0,1" slots="RightHand,LeftHand,Any">
|
<Pickable holdpos="30,-15" handle1="0,1" slots="RightHand,LeftHand,Any">
|
||||||
<StatusEffect type="OnFire" target="This" Condition="-100.0" disabledeltatime="true">
|
<StatusEffect type="OnFire" target="This" Condition="-100.0" disabledeltatime="true">
|
||||||
|
<Conditional Condition="gt 25"/>
|
||||||
<sound file="Content/Items/Reactor/explosion.ogg"/>
|
<sound file="Content/Items/Reactor/explosion.ogg"/>
|
||||||
<Explosion range="250.0" structuredamage="10" damage="20" stun="5" force="3.0"/>
|
<Explosion range="250.0" structuredamage="10" damage="20" stun="5" force="3.0"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
|
<StatusEffect type="OnFire" target="This" Condition="-100.0" disabledeltatime="true"/>
|
||||||
</Pickable>
|
</Pickable>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
@@ -188,7 +190,7 @@
|
|||||||
<Propulsion force="80" usablein="water" particles="bubbles">
|
<Propulsion force="80" usablein="water" particles="bubbles">
|
||||||
<RequiredItems name="Battery Cell,Fulgurium Battery Cell" type="Contained" msg="Battery Cell required"/>
|
<RequiredItems name="Battery Cell,Fulgurium Battery Cell" type="Contained" msg="Battery Cell required"/>
|
||||||
<StatusEffect type="OnUse" target="Contained" Condition="-1.0"/>
|
<StatusEffect type="OnUse" target="Contained" Condition="-1.0"/>
|
||||||
<sound file="scooter.ogg" type="OnUse" range="500.0" loop="true"/>
|
<sound file="Content/Items/Diving/scooter.ogg" type="OnUse" range="500.0" loop="true"/>
|
||||||
<LightComponent LightColor="1.0,1.0,1.0,1.0" Flicker="0.2" range="800">
|
<LightComponent LightColor="1.0,1.0,1.0,1.0" Flicker="0.2" range="800">
|
||||||
<LightTexture texture="Content/Lights/lightcone.png" origin="0.05, 0.5" size="2.0,1.0"/>
|
<LightTexture texture="Content/Lights/lightcone.png" origin="0.05, 0.5" size="2.0,1.0"/>
|
||||||
</LightComponent>
|
</LightComponent>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<Sprite texture ="door.png" sourcerect="80,0,19,208" depth="0.05" origin="0.5,0.0"/>
|
<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"/>
|
<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"/>
|
<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/Door/door.ogg" type="OnUse" range="500.0"/>
|
||||||
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
|
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
|
||||||
<StatusEffect type="OnBroken" target="This">
|
<StatusEffect type="OnBroken" target="This">
|
||||||
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
|
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<Sprite texture="door.png" sourcerect="56,0,19,208" depth="0.05" origin="0.5,0.0"/>
|
<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"/>
|
<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"/>
|
<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/Door/door.ogg" type="OnUse" range="500.0"/>
|
||||||
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
|
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
|
||||||
<StatusEffect type="OnBroken" target="This">
|
<StatusEffect type="OnBroken" target="This">
|
||||||
<sound file="Content/Items/Door/doorBreak1.ogg" range="3000"/>
|
<sound file="Content/Items/Door/doorBreak1.ogg" range="3000"/>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<Sprite texture="hatch.png" sourcerect="128,0,128,19" depth="0.05" origin="0.0,0.5"/>
|
<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"/>
|
<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"/>
|
<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/Door/door.ogg" type="OnUse" range="500.0"/>
|
||||||
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
|
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="2000.0"/>
|
||||||
<StatusEffect type="OnBroken" target="This">
|
<StatusEffect type="OnBroken" target="This">
|
||||||
<sound file="Content/Items/Door/doorBreak1.ogg" range="3000"/>
|
<sound file="Content/Items/Door/doorBreak1.ogg" range="3000"/>
|
||||||
@@ -110,18 +110,24 @@
|
|||||||
|
|
||||||
<DockingPort IsHorizontal="true" DistanceTolerance="128,64" DockedDistance="64">
|
<DockingPort IsHorizontal="true" DistanceTolerance="128,64" DockedDistance="64">
|
||||||
<Sprite texture ="dockingport.png" sourcerect="127,0,112,144" depth="0.05" origin="0.5,0.5"/>
|
<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="Content/Items/Door/dockingport1.ogg" type="OnUse" range="1000.0"/>
|
||||||
<sound file="dockingport2.ogg" type="OnSecondaryUse" range="1000.0"/>
|
<sound file="Content/Items/Door/dockingport2.ogg" type="OnSecondaryUse" range="1000.0"/>
|
||||||
<StatusEffect type="OnBroken" target="This">
|
<StatusEffect type="OnBroken" target="This">
|
||||||
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
|
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
</DockingPort>
|
</DockingPort>
|
||||||
|
|
||||||
|
<fixrequirement name="Electrical repairs">
|
||||||
|
<skill name="Electrical Engineering" level="40"/>
|
||||||
|
<item name="Wire"/>
|
||||||
|
<item name="Screwdriver"/>
|
||||||
|
</fixrequirement>
|
||||||
|
|
||||||
<PowerTransfer/>
|
<PowerTransfer/>
|
||||||
<Wire/>
|
<Wire/>
|
||||||
|
|
||||||
<fixrequirement name="Mechanical repairs">
|
<fixrequirement name="Mechanical repairs">
|
||||||
<skill name="Construction" level="60"/>
|
<skill name="Construction" level="50"/>
|
||||||
<item name="Welding Tool"/>
|
<item name="Welding Tool"/>
|
||||||
</fixrequirement>
|
</fixrequirement>
|
||||||
|
|
||||||
@@ -144,8 +150,8 @@
|
|||||||
|
|
||||||
<DockingPort IsHorizontal="false" DistanceTolerance="64,128" DockedDistance="64">
|
<DockingPort IsHorizontal="false" DistanceTolerance="64,128" DockedDistance="64">
|
||||||
<Sprite texture ="dockingport.png" sourcerect="127,144,48,112" depth="0.05" origin="0.5,0.5"/>
|
<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="Content/Items/Door/dockingport1.ogg" type="OnUse" range="1000.0"/>
|
||||||
<sound file="dockingport2.ogg" type="OnSecondaryUse" range="1000.0"/>
|
<sound file="Content/Items/Door/dockingport2.ogg" type="OnSecondaryUse" range="1000.0"/>
|
||||||
<StatusEffect type="OnBroken" target="This">
|
<StatusEffect type="OnBroken" target="This">
|
||||||
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
|
<sound file="Content/Items/Door/doorBreak2.ogg" range="3000"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
@@ -161,7 +167,7 @@
|
|||||||
<Wire/>
|
<Wire/>
|
||||||
|
|
||||||
<fixrequirement name="Mechanical repairs">
|
<fixrequirement name="Mechanical repairs">
|
||||||
<skill name="Construction" level="60"/>
|
<skill name="Construction" level="50"/>
|
||||||
<item name="Welding Tool"/>
|
<item name="Welding Tool"/>
|
||||||
</fixrequirement>
|
</fixrequirement>
|
||||||
|
|
||||||
@@ -187,7 +193,7 @@
|
|||||||
<Sprite texture ="duct.png" sourcerect="66,0,19,19" depth="0.05" origin="-0.4,0.5"/>
|
<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"/>
|
<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"/>
|
<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/Door/duct.ogg" type="OnUse" range="300"/>
|
||||||
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="500.0"/>
|
<sound file="Content/Items/Tools/crowbar.ogg" type="OnPicked" range="500.0"/>
|
||||||
<StatusEffect type="OnBroken" target="This">
|
<StatusEffect type="OnBroken" target="This">
|
||||||
<sound file="Content/Items/Door/ductBreak.ogg" range="2000"/>
|
<sound file="Content/Items/Door/ductBreak.ogg" range="2000"/>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 22 KiB |
@@ -146,6 +146,39 @@
|
|||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Adder Component"
|
||||||
|
category="Electrical"
|
||||||
|
Tags="smallitem"
|
||||||
|
linkable="false"
|
||||||
|
cargocontainername="Metal Crate"
|
||||||
|
price="10"
|
||||||
|
description="Outputs the sum of the received signals.">
|
||||||
|
|
||||||
|
<Deconstruct time="10">
|
||||||
|
<Item name="Steel Bar"/>
|
||||||
|
<Item name="FPGA Circuit"/>
|
||||||
|
</Deconstruct>
|
||||||
|
|
||||||
|
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="17,80,16,16"/>
|
||||||
|
|
||||||
|
<AdderComponent canbeselected="true"/>
|
||||||
|
|
||||||
|
<Body width="16" height="16" density="30"/>
|
||||||
|
|
||||||
|
<Holdable selectkey="Select" pickkey="Use" 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"/>
|
||||||
|
<input name="signal_in1"/>
|
||||||
|
<input name="signal_in2"/>
|
||||||
|
<output name="signal_out"/>
|
||||||
|
</ConnectionPanel>
|
||||||
|
</Item>
|
||||||
|
|
||||||
<Item
|
<Item
|
||||||
name="Or Component"
|
name="Or Component"
|
||||||
category="Electrical"
|
category="Electrical"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<Engine minvoltage="0.5" powerconsumption="2000.0" maxforce="2000" canbeselected = "true">
|
<Engine minvoltage="0.5" powerconsumption="2000.0" maxforce="2000" canbeselected = "true">
|
||||||
<StatusEffect type="InWater" target="This" condition="-2.0"/>
|
<StatusEffect type="InWater" target="This" condition="-2.0"/>
|
||||||
<GuiFrame rect="0,0,350,160" alignment="Center" style="ItemUI"/>
|
<GuiFrame rect="0,0,350,160" alignment="Center" style="ItemUI"/>
|
||||||
<sound file="engine.ogg" type="OnActive" range="3000.0" volume="CurrentVolume" loop="true"/>
|
<sound file="Content/Items/Engine/engine.ogg" type="OnActive" range="3000.0" volume="CurrentVolume" loop="true"/>
|
||||||
</Engine>
|
</Engine>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
<Engine minvoltage="0.5" powerconsumption="500.0" maxforce="300" canbeselected = "true">
|
<Engine minvoltage="0.5" powerconsumption="500.0" maxforce="300" canbeselected = "true">
|
||||||
<GuiFrame rect="0,0,350,160" alignment="Center" style="ItemUI"/>
|
<GuiFrame rect="0,0,350,160" alignment="Center" style="ItemUI"/>
|
||||||
<sound file="engine.ogg" type="OnActive" range="3000.0" volume="CurrentVolume" loop="true"/>
|
<sound file="Content/Items/Engine/engine.ogg" type="OnActive" range="3000.0" volume="CurrentVolume" loop="true"/>
|
||||||
</Engine>
|
</Engine>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
</Steering>
|
</Steering>
|
||||||
|
|
||||||
<Radar canbeselected = "true" powerconsumption="100" displaybordersize="0.2">
|
<Radar canbeselected = "true" powerconsumption="100" displaybordersize="0.2">
|
||||||
<sound file="radarPing.ogg" type="OnUse" range="4000.0"/>
|
<sound file="Content/Items/Engine/radarPing.ogg" type="OnUse" range="4000.0"/>
|
||||||
<GuiFrame rect="0,0,0.5,0.5" alignment="Center" style="ItemUI" color="0.0,0.0,0.0,0.0"/>
|
<GuiFrame rect="0,0,0.5,0.5" alignment="Center" style="ItemUI" color="0.0,0.0,0.0,0.0"/>
|
||||||
<PingCircle texture="Content/Items/Engine/pingCircle.png" origin="0.5,0.5"/>
|
<PingCircle texture="Content/Items/Engine/pingCircle.png" origin="0.5,0.5"/>
|
||||||
<ScreenOverlay texture="Content/Items/Engine/radarOverlay.png" origin="0.5,0.5"/>
|
<ScreenOverlay texture="Content/Items/Engine/radarOverlay.png" origin="0.5,0.5"/>
|
||||||
@@ -121,4 +121,4 @@
|
|||||||
<input name="power_in"/>
|
<input name="power_in"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<GuiFrame rect="0,0,600,400" alignment="Center" style="ItemUI"/>
|
<GuiFrame rect="0,0,600,400" alignment="Center" style="ItemUI"/>
|
||||||
|
|
||||||
<sound file="fabricator.ogg" type="OnActive" range="1000.0" loop="true"/>
|
<sound file="Content/Items/Fabricators/fabricator.ogg" type="OnActive" range="1000.0" loop="true"/>
|
||||||
|
|
||||||
<fabricableitem name="Harpoon Gun" requireditems="Steel Bar, Polycarbonate Bar, Aluminium" requiredtime="20">
|
<fabricableitem name="Harpoon Gun" requireditems="Steel Bar, Polycarbonate Bar, Aluminium" requiredtime="20">
|
||||||
<RequiredSkill name="Construction" level="30"/>
|
<RequiredSkill name="Construction" level="30"/>
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
|
|
||||||
<GuiFrame rect="0,0,600,400" alignment="Center" style="ItemUI"/>
|
<GuiFrame rect="0,0,600,400" alignment="Center" style="ItemUI"/>
|
||||||
|
|
||||||
<sound file="fabricator.ogg" type="OnActive" range="1000.0" loop="true"/>
|
<sound file="Content/Items/Fabricators/fabricator.ogg" type="OnActive" range="1000.0" loop="true"/>
|
||||||
|
|
||||||
<fabricableitem name="Medical Syringe" requireditems="Steel Bar" requiredtime="10"/>
|
<fabricableitem name="Medical Syringe" requireditems="Steel Bar" requiredtime="10"/>
|
||||||
<fabricableitem name="Chloral Hydrate" requireditems="Chlorine, Ethanol" requiredtime="20">
|
<fabricableitem name="Chloral Hydrate" requireditems="Chlorine, Ethanol" requiredtime="20">
|
||||||
@@ -216,7 +216,7 @@
|
|||||||
<Sprite texture="Content/Items/machines.png" depth="0.8" sourcerect="64,128,64,128"/>
|
<Sprite texture="Content/Items/machines.png" depth="0.8" sourcerect="64,128,64,128"/>
|
||||||
|
|
||||||
<Deconstructor canbeselected = "true" powerconsumption="500.0">
|
<Deconstructor canbeselected = "true" powerconsumption="500.0">
|
||||||
<sound file="deconstructor.ogg" type="OnActive" range="1000.0" loop="true"/>
|
<sound file="Content/Items/Fabricators/deconstructor.ogg" type="OnActive" range="1000.0" loop="true"/>
|
||||||
|
|
||||||
<GuiFrame rect="0,0,300,200" alignment="Center" style="ItemUI"/>
|
<GuiFrame rect="0,0,300,200" alignment="Center" style="ItemUI"/>
|
||||||
</Deconstructor>
|
</Deconstructor>
|
||||||
@@ -229,4 +229,4 @@
|
|||||||
<ItemContainer capacity="5" canbeselected="true" hideitems="true" hudpos="0.5, 0.4" slotsperrow="5"/>
|
<ItemContainer capacity="5" canbeselected="true" hideitems="true" hudpos="0.5, 0.4" slotsperrow="5"/>
|
||||||
<ItemContainer capacity="10" canbeselected="true" hideitems="true" hudpos="0.5, 0.8" slotsperrow="5"/>
|
<ItemContainer capacity="10" canbeselected="true" hideitems="true" hudpos="0.5, 0.8" slotsperrow="5"/>
|
||||||
</Item>
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
<Sprite texture="oxygengenerator.png" depth="0.8" sourcerect="0,0,128,128"/>
|
<Sprite texture="oxygengenerator.png" depth="0.8" sourcerect="0,0,128,128"/>
|
||||||
|
|
||||||
<OxygenGenerator powerconsumption="1000.0" minvoltage="0.5" canbeselected = "true">
|
<OxygenGenerator powerconsumption="1000.0" minvoltage="0.5" canbeselected = "true">
|
||||||
<StatusEffect type="OnActive" target="Contained" targetnames="Oxygen Tank" Condition="0.5"/>
|
<StatusEffect type="OnActive" target="Contained" targetnames="Oxygen Tank" Condition="2.0"/>
|
||||||
<sound file="oxygengenerator.ogg" type="OnActive" range="1000.0" volume="CurrFlow" volumemultiplier="0.001f" loop="true"/>
|
<sound file="Content/Items/OxygenGenerator/oxygengenerator.ogg" type="OnActive" range="1000.0" volume="CurrFlow" volumemultiplier="0.001f" loop="true"/>
|
||||||
</OxygenGenerator>
|
</OxygenGenerator>
|
||||||
|
|
||||||
<trigger/>
|
<trigger/>
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
<Sprite texture="vent.png" depth="0.91" sourcerect="0,0,64,64"/>
|
<Sprite texture="vent.png" depth="0.91" sourcerect="0,0,64,64"/>
|
||||||
|
|
||||||
<Vent>
|
<Vent>
|
||||||
<sound file="ventilation.ogg" type="OnActive" range="600.0" volume="OxygenFlow" volumemultiplier="0.001f" loop="true"/>
|
<sound file="Content/Items/OxygenGenerator/ventilation.ogg" type="OnActive" range="600.0" volume="OxygenFlow" volumemultiplier="0.001f" loop="true"/>
|
||||||
</Vent>
|
</Vent>
|
||||||
|
|
||||||
</Item>
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<Pump canbeselected = "true" maxflow="500" PowerConsumption="300.0" MinVoltage="0.3">
|
<Pump canbeselected = "true" maxflow="500" PowerConsumption="300.0" MinVoltage="0.3">
|
||||||
<GuiFrame rect="0,0,330,145" alignment="Center" style="ItemUI"/>
|
<GuiFrame rect="0,0,330,145" alignment="Center" style="ItemUI"/>
|
||||||
<sound file="pump.ogg" type="OnActive" range="800.0" volume="CurrFlow" volumemultiplier="0.01" loop="true"/>
|
<sound file="Content/Items/Pump/pump.ogg" type="OnActive" range="800.0" volume="CurrFlow" volumemultiplier="0.01" loop="true"/>
|
||||||
</Pump>
|
</Pump>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<Pump canbeselected = "true" maxflow="100" PowerConsumption="60.0" MinVoltage="0.3">
|
<Pump canbeselected = "true" maxflow="100" PowerConsumption="60.0" MinVoltage="0.3">
|
||||||
<GuiFrame rect="0,0,330,145" alignment="Center" style="ItemUI"/>
|
<GuiFrame rect="0,0,330,145" alignment="Center" style="ItemUI"/>
|
||||||
<sound file="pump.ogg" type="OnActive" range="500.0" volume="CurrFlow" volumemultiplier="0.01" loop="true"/>
|
<sound file="Content/Items/Pump/pump.ogg" type="OnActive" range="500.0" volume="CurrFlow" volumemultiplier="0.01" loop="true"/>
|
||||||
</Pump>
|
</Pump>
|
||||||
|
|
||||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
@@ -42,4 +42,4 @@
|
|||||||
<input name="set_targetlevel"/>
|
<input name="set_targetlevel"/>
|
||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<RequiredSkill name="Construction" level="30"/>
|
<RequiredSkill name="Construction" level="30"/>
|
||||||
<StatusEffect type="InWater" target="This" Temperature="-500.0"/>
|
<StatusEffect type="InWater" target="This" Temperature="-500.0"/>
|
||||||
<StatusEffect type="OnActive" target="Contained" targetnames="Fuel Rod, Heat Absorber, Temperature Control Circuit" Condition="-0.1" />
|
<StatusEffect type="OnActive" target="Contained" targetnames="Fuel Rod, Heat Absorber, Temperature Control Circuit" Condition="-0.1" />
|
||||||
<sound file="reactor.ogg" type="OnActive" range="2000.0" volume="FissionRate" volumemultiplier="0.02" loop="true"/>
|
<sound file="Content/Items/Reactor/reactor.ogg" type="OnActive" range="2000.0" volume="FissionRate" volumemultiplier="0.02" loop="true"/>
|
||||||
|
|
||||||
<StatusEffect type="OnBroken" target="This" FissionRate="0.0" disabledeltatime="true">
|
<StatusEffect type="OnBroken" target="This" FissionRate="0.0" disabledeltatime="true">
|
||||||
<Sound file="Content/Items/Reactor/explosion.ogg" range="5000"/>
|
<Sound file="Content/Items/Reactor/explosion.ogg" range="5000"/>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<Sprite texture ="tools.png" sourcerect="0,17,41,17" depth="0.55"/>
|
<Sprite texture ="tools.png" sourcerect="0,17,41,17" depth="0.55"/>
|
||||||
|
|
||||||
<!-- the item takes 10 seconds to break down in a deconstructor and turns into a polycarbonate bar and a steel bar -->
|
<!-- the item takes 10 seconds to break down in a deconstructor and turns into a polycarbonate bar, steel bar and aluminium -->
|
||||||
<Deconstruct time="10">
|
<Deconstruct time="10">
|
||||||
<Item name="Polycarbonate Bar"/>
|
<Item name="Polycarbonate Bar"/>
|
||||||
<Item name="Steel Bar"/>
|
<Item name="Steel Bar"/>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
<ParticleEmitterHitItem particle="weldsmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
<ParticleEmitterHitItem particle="weldsmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
||||||
<ParticleEmitterHitCharacter particle="fleshsmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
<ParticleEmitterHitCharacter particle="fleshsmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
||||||
|
|
||||||
<sound file="weldingTool.ogg" type="OnUse" range="500.0" loop="true"/>
|
<sound file="Content/Items/Tools/weldingTool.ogg" type="OnUse" range="500.0" loop="true"/>
|
||||||
|
|
||||||
<!-- when using, the contained welding fuel tank will detoriate (= lose fuel) -->
|
<!-- when using, the contained welding fuel tank will detoriate (= lose fuel) -->
|
||||||
<StatusEffect type="OnUse" target="Contained" targetnames="Welding Fuel Tank" Condition="-1.0"/>
|
<StatusEffect type="OnUse" target="Contained" targetnames="Welding Fuel Tank" Condition="-1.0"/>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
<!-- construction skill 20 required to use the item -->
|
<!-- construction skill 20 required to use the item -->
|
||||||
<RequiredSkill name="Construction" level="20"/>
|
<RequiredSkill name="Construction" level="20"/>
|
||||||
|
<!-- if the skill requirement isn't met the welding fuel will be used 3 times as fast -->
|
||||||
<StatusEffect type="OnFailure" target="Contained" targetnames="Welding Fuel Tank,Oxygen Tank" Condition="-3.0"/>
|
<StatusEffect type="OnFailure" target="Contained" targetnames="Welding Fuel Tank,Oxygen Tank" Condition="-3.0"/>
|
||||||
|
|
||||||
<LightComponent LightColor="1.0,0.9,0.7,1.0" Flicker="0.5">
|
<LightComponent LightColor="1.0,0.9,0.7,1.0" Flicker="0.5">
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
<ParticleEmitterHitItem particle="plasmasmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
<ParticleEmitterHitItem particle="plasmasmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
||||||
<ParticleEmitterHitCharacter particle="fleshsmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
<ParticleEmitterHitCharacter particle="fleshsmoke" particlespersecond="3" anglemin="-5" anglemax="5" velocitymin="10" velocitymax="100"/>
|
||||||
|
|
||||||
<sound file="plasmaCutter.ogg" type="OnUse" range="500.0" loop="true"/>
|
<sound file="Content/Items/Tools/plasmaCutter.ogg" type="OnUse" range="500.0" loop="true"/>
|
||||||
|
|
||||||
<Fixable name="structure"/>
|
<Fixable name="structure"/>
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
<RepairTool extinquishamount="60.0" range="500" barrelpos="21,25">
|
<RepairTool extinquishamount="60.0" range="500" barrelpos="21,25">
|
||||||
<ParticleEmitter particle="extinguisher" velocitymin="500.0" velocitymax="650.0" particlespersecond="50"/>
|
<ParticleEmitter particle="extinguisher" velocitymin="500.0" velocitymax="650.0" particlespersecond="50"/>
|
||||||
<StatusEffect type="OnUse" target="This" Condition="-2.0"/>
|
<StatusEffect type="OnUse" target="This" Condition="-2.0"/>
|
||||||
<sound file="extinguisher.ogg" type="OnUse" range="500.0" loop="true"/>
|
<sound file="Content/Items/Tools/extinguisher.ogg" type="OnUse" range="500.0" loop="true"/>
|
||||||
</RepairTool>
|
</RepairTool>
|
||||||
|
|
||||||
<Propulsion force="-20" usablein="water" particles="bubbles"/>
|
<Propulsion force="-20" usablein="water" particles="bubbles"/>
|
||||||
@@ -330,7 +330,7 @@
|
|||||||
|
|
||||||
<StatusEffect type="OnBroken" target="This" IsOn="false"/>
|
<StatusEffect type="OnBroken" target="This" IsOn="false"/>
|
||||||
|
|
||||||
<sound file="flare.ogg" type="OnActive" range="800.0" loop="true"/>
|
<sound file="Content/Items/Tools/flare.ogg" type="OnActive" range="800.0" loop="true"/>
|
||||||
</LightComponent>
|
</LightComponent>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,7 @@
|
|||||||
category="Machine"
|
category="Machine"
|
||||||
type="Controller"
|
type="Controller"
|
||||||
linkable="true"
|
linkable="true"
|
||||||
disableitemusagewhenselected="true"
|
disableitemusagewhenselected="true">
|
||||||
>
|
|
||||||
|
|
||||||
<Sprite texture ="railgunetc.png" depth="0.8" sourcerect="182,0,61,97"/>
|
<Sprite texture ="railgunetc.png" depth="0.8" sourcerect="182,0,61,97"/>
|
||||||
|
|
||||||
@@ -55,11 +54,34 @@
|
|||||||
</ConnectionPanel>
|
</ConnectionPanel>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Rear Railgun Controller"
|
||||||
|
category="Machine"
|
||||||
|
type="Controller"
|
||||||
|
linkable="true"
|
||||||
|
disableitemusagewhenselected="true" >
|
||||||
|
|
||||||
|
<Sprite texture ="railgunetc2.png" depth="0.8" sourcerect="188,0,57,96"/>
|
||||||
|
|
||||||
|
<Controller UserPos="35, -50.0" direction ="Left" canbeselected = "true">
|
||||||
|
<limbposition limb="Head" position="-5,-62"/>
|
||||||
|
<limbposition limb="Torso" position="-5,-108"/>
|
||||||
|
<limbposition limb="LeftHand" position="43,-85"/>
|
||||||
|
<limbposition limb="RightHand" position="43,-85"/>
|
||||||
|
</Controller>
|
||||||
|
|
||||||
|
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||||
|
<requireditem name="Screwdriver,Wire" type="Equipped"/>
|
||||||
|
<input name="power_in"/>
|
||||||
|
<output name="position_out"/>
|
||||||
|
<output name="trigger_out"/>
|
||||||
|
</ConnectionPanel>
|
||||||
|
</Item>
|
||||||
|
|
||||||
<Item
|
<Item
|
||||||
name="Railgun Loader"
|
name="Railgun Loader"
|
||||||
category="Machine"
|
category="Machine"
|
||||||
linkable="true"
|
linkable="true">
|
||||||
>
|
|
||||||
|
|
||||||
<Sprite texture ="railgunetc.png" depth="0.8" sourcerect="0,0,177,128"/>
|
<Sprite texture ="railgunetc.png" depth="0.8" sourcerect="0,0,177,128"/>
|
||||||
|
|
||||||
@@ -69,6 +91,48 @@
|
|||||||
<Containable name="Ancient Weapon"/>
|
<Containable name="Ancient Weapon"/>
|
||||||
</ItemContainer>
|
</ItemContainer>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Railgun Single Loader"
|
||||||
|
category="Machine"
|
||||||
|
linkable="true">
|
||||||
|
|
||||||
|
<Sprite texture ="railgunetc2.png" depth="0.8" sourcerect="131,2,46,128"/>
|
||||||
|
|
||||||
|
<ItemContainer hideitems="false" drawinventory="true" capacity="1" slotsperrow="1" itempos="23,-76" iteminterval="0,0" itemrotation="90" canbeselected = "true">
|
||||||
|
<Containable name="Railgun Shell"/>
|
||||||
|
<Containable name="Nuclear Shell"/>
|
||||||
|
<Containable name="Ancient Weapon"/>
|
||||||
|
</ItemContainer>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Forward Railgun Loader"
|
||||||
|
category="Machine"
|
||||||
|
linkable="true">
|
||||||
|
|
||||||
|
<Sprite texture ="railgunetc2.png" depth="0.8" sourcerect="1,2,128,46"/>
|
||||||
|
|
||||||
|
<ItemContainer hideitems="false" drawinventory="true" capacity="1" slotsperrow="1" itempos="49.5,-22.7" iteminterval="0,0" itemrotation="0" canbeselected = "true">
|
||||||
|
<Containable name="Railgun Shell"/>
|
||||||
|
<Containable name="Nuclear Shell"/>
|
||||||
|
<Containable name="Ancient Weapon"/>
|
||||||
|
</ItemContainer>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Rear Railgun Loader"
|
||||||
|
category="Machine"
|
||||||
|
linkable="true">
|
||||||
|
|
||||||
|
<Sprite texture ="railgunetc2.png" depth="0.8" sourcerect="1,50,128,46"/>
|
||||||
|
|
||||||
|
<ItemContainer hideitems="false" drawinventory="true" capacity="1" slotsperrow="1" itempos="76,-22.7" iteminterval="0,0" itemrotation="180" canbeselected = "true">
|
||||||
|
<Containable name="Railgun Shell"/>
|
||||||
|
<Containable name="Nuclear Shell"/>
|
||||||
|
<Containable name="Ancient Weapon"/>
|
||||||
|
</ItemContainer>
|
||||||
|
</Item>
|
||||||
|
|
||||||
<Item
|
<Item
|
||||||
name="Railgun Shell"
|
name="Railgun Shell"
|
||||||
@@ -86,7 +150,7 @@
|
|||||||
<Body width="87" height="18" density="30"/>
|
<Body width="87" height="18" density="30"/>
|
||||||
|
|
||||||
<Holdable slots="RightHand+LeftHand" holdpos="0,-50" handle1="-10,0" handle2="10,0" aimable="false"/>
|
<Holdable slots="RightHand+LeftHand" holdpos="0,-50" handle1="-10,0" handle2="10,0" aimable="false"/>
|
||||||
|
|
||||||
<Projectile characterusable="false" launchimpulse="80.0">
|
<Projectile characterusable="false" launchimpulse="80.0">
|
||||||
<Attack damage="100" bleedingdamage="10" structuredamage="200" damagetype="Blunt" severlimbsprobability="1.0"/>
|
<Attack damage="100" bleedingdamage="10" structuredamage="200" damagetype="Blunt" severlimbsprobability="1.0"/>
|
||||||
|
|
||||||
@@ -94,7 +158,9 @@
|
|||||||
<ParticleEmitter particle="bubbles" anglemin="0" anglemax="360" particleamount="10" velocitymin="0" velocitymax="50" scalemin="2" scalemax="5"/>
|
<ParticleEmitter particle="bubbles" anglemin="0" anglemax="360" particleamount="10" velocitymin="0" velocitymax="50" scalemin="2" scalemax="5"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
|
|
||||||
<StatusEffect type="OnImpact" target="Contained" Condition="-100.0"/>
|
<StatusEffect type="OnImpact" target="Contained">
|
||||||
|
<Use/>
|
||||||
|
</StatusEffect>
|
||||||
</Projectile>
|
</Projectile>
|
||||||
|
|
||||||
<ItemContainer hideitems="true" capacity="1" canbeselected = "true">
|
<ItemContainer hideitems="true" capacity="1" canbeselected = "true">
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
@@ -43,8 +43,8 @@
|
|||||||
holdpos="35,-10" aimpos="35,-10" handle1="-15,-6" handle2="26,7"/>
|
holdpos="35,-10" aimpos="35,-10" handle1="-15,-6" handle2="26,7"/>
|
||||||
|
|
||||||
<RangedWeapon barrelpos="49,10" spread="1" unskilledspread="10">
|
<RangedWeapon barrelpos="49,10" spread="1" unskilledspread="10">
|
||||||
<Sound file="harpoon1.ogg" type="OnUse"/>
|
<Sound file="Content/Items/Weapons/harpoon1.ogg" type="OnUse"/>
|
||||||
<Sound file="harpoon2.ogg" type="OnUse"/>
|
<Sound file="Content/Items/Weapons/harpoon2.ogg" type="OnUse"/>
|
||||||
<StatusEffect type="OnUse">
|
<StatusEffect type="OnUse">
|
||||||
<Explosion range="150.0" force="5" shockwave="false" smoke="false" flames="false" flash="false" sparks="false" camerashake="5.0"/>
|
<Explosion range="150.0" force="5" shockwave="false" smoke="false" flames="false" flash="false" sparks="false" camerashake="5.0"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
aimpos="90,10" handle1="-10,-7"/>
|
aimpos="90,10" handle1="-10,-7"/>
|
||||||
|
|
||||||
<RangedWeapon barrelpos="30,20" spread="0" unskilledspread="10">
|
<RangedWeapon barrelpos="30,20" spread="0" unskilledspread="10">
|
||||||
<Sound file="syringegun.ogg" type="OnUse"/>
|
<Sound file="Content/Items/Weapons/syringegun.ogg" type="OnUse"/>
|
||||||
<RequiredItems name="Medical Syringe" type="Contained" msg="Please load a Syringe"/>
|
<RequiredItems name="Medical Syringe" type="Contained" msg="Please load a Syringe"/>
|
||||||
<RequiredSkill name="Weapons" level="15"/>
|
<RequiredSkill name="Weapons" level="15"/>
|
||||||
<RequiredSkill name="Medical" level="30"/>
|
<RequiredSkill name="Medical" level="30"/>
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
aimpos="90,10" handle1="-11,-7"/>
|
aimpos="90,10" handle1="-11,-7"/>
|
||||||
|
|
||||||
<RangedWeapon barrelpos="14,6" spread="0" unskilledspread="2">
|
<RangedWeapon barrelpos="14,6" spread="0" unskilledspread="2">
|
||||||
<Sound file="revolver.ogg" type="OnUse" range="3000"/>
|
<Sound file="Content/Items/Weapons/revolver.ogg" type="OnUse" range="3000"/>
|
||||||
<StatusEffect type="OnUse">
|
<StatusEffect type="OnUse">
|
||||||
<Explosion range="150.0" force="5" shockwave="false" smoke="false" flames="false" sparks="false" camerashake="5.0"/>
|
<Explosion range="150.0" force="5" shockwave="false" smoke="false" flames="false" sparks="false" camerashake="5.0"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
@@ -300,7 +300,7 @@
|
|||||||
<Holdable slots="Any,RightHand,LeftHand" aimpos="100,0" handle1="-5,0"/>
|
<Holdable slots="Any,RightHand,LeftHand" aimpos="100,0" handle1="-5,0"/>
|
||||||
|
|
||||||
<RangedWeapon reload="2">
|
<RangedWeapon reload="2">
|
||||||
<Sound file="honk.ogg" type="OnUse"/>
|
<Sound file="Content/Items/Weapons/honk.ogg" type="OnUse"/>
|
||||||
</RangedWeapon>
|
</RangedWeapon>
|
||||||
|
|
||||||
</Item>
|
</Item>
|
||||||
|
|||||||
@@ -103,10 +103,10 @@
|
|||||||
|
|
||||||
<Job name="Assistant" description="Assistants don't have any specific responsibilities or areas of expertise. This job is a good choice for newcomers who want to get a hang of working on board the submarine without taking up tasks that they aren't qualified for." allowalways="true" minkarma="0.0">
|
<Job name="Assistant" description="Assistants don't have any specific responsibilities or areas of expertise. This job is a good choice for newcomers who want to get a hang of working on board the submarine without taking up tasks that they aren't qualified for." allowalways="true" minkarma="0.0">
|
||||||
<Skills>
|
<Skills>
|
||||||
<Skill name="Weapons" level="20,30"/>
|
<Skill name="Weapons" level="20,32"/>
|
||||||
<Skill name="Construction" level="20,30"/>
|
<Skill name="Construction" level="20,32"/>
|
||||||
<Skill name="Electrical Engineering" level="20,30"/>
|
<Skill name="Electrical Engineering" level="20,32"/>
|
||||||
<Skill name="Medical" level="10,20"/>
|
<Skill name="Medical" level="10,22"/>
|
||||||
</Skills>
|
</Skills>
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="ID Card" equip="true"/>
|
<Item name="ID Card" equip="true"/>
|
||||||
@@ -117,4 +117,4 @@
|
|||||||
</Item>
|
</Item>
|
||||||
</Items>
|
</Items>
|
||||||
</Job>
|
</Job>
|
||||||
</Jobs>
|
</Jobs>
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ namespace Barotrauma
|
|||||||
public EnemyAIController(Character c, string file) : base(c)
|
public EnemyAIController(Character c, string file) : base(c)
|
||||||
{
|
{
|
||||||
targetMemories = new Dictionary<AITarget, AITargetMemory>();
|
targetMemories = new Dictionary<AITarget, AITargetMemory>();
|
||||||
|
outsideSteering = new SteeringManager(this);
|
||||||
|
insideSteering = new IndoorsSteeringManager(this, false);
|
||||||
|
steeringManager = outsideSteering;
|
||||||
|
state = AIState.None;
|
||||||
|
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(file);
|
XDocument doc = XMLExtensions.TryLoadXml(file);
|
||||||
if (doc == null || doc.Root == null) return;
|
if (doc == null || doc.Root == null) return;
|
||||||
@@ -103,13 +107,6 @@ namespace Barotrauma
|
|||||||
fleeHealthThreshold = aiElement.GetAttributeFloat("fleehealththreshold", 0.0f);
|
fleeHealthThreshold = aiElement.GetAttributeFloat("fleehealththreshold", 0.0f);
|
||||||
|
|
||||||
attachToWalls = aiElement.GetAttributeBool("attachtowalls", false);
|
attachToWalls = aiElement.GetAttributeBool("attachtowalls", false);
|
||||||
|
|
||||||
outsideSteering = new SteeringManager(this);
|
|
||||||
insideSteering = new IndoorsSteeringManager(this, false);
|
|
||||||
|
|
||||||
steeringManager = outsideSteering;
|
|
||||||
|
|
||||||
state = AIState.None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SelectTarget(AITarget target)
|
public override void SelectTarget(AITarget target)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace Barotrauma
|
|||||||
public float Range { get; private set; }
|
public float Range { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float DamageRange { get; private set; }
|
public float DamageRange { get; set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float Duration { get; private set; }
|
public float Duration { get; private set; }
|
||||||
|
|||||||
@@ -1948,8 +1948,21 @@ namespace Barotrauma
|
|||||||
|
|
||||||
AnimController.Frozen = false;
|
AnimController.Frozen = false;
|
||||||
|
|
||||||
GameServer.Log(LogName+" has died (Cause of death: "+causeOfDeath+")", ServerLog.MessageType.Attack);
|
GameServer.Log(LogName + " has died (Cause of death: " + causeOfDeath + ")", ServerLog.MessageType.Attack);
|
||||||
|
if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
string characterType = "Unknown";
|
||||||
|
if (this == controlled)
|
||||||
|
characterType = "Player";
|
||||||
|
else if (IsRemotePlayer)
|
||||||
|
characterType = "RemotePlayer";
|
||||||
|
else if (AIController is EnemyAIController)
|
||||||
|
characterType = "Enemy";
|
||||||
|
else if (AIController is HumanAIController)
|
||||||
|
characterType = "AICrew";
|
||||||
|
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("Kill:" + characterType + ":" + SpeciesName + ":" + causeOfDeath);
|
||||||
|
}
|
||||||
|
|
||||||
if (OnDeath != null) OnDeath(this, causeOfDeath);
|
if (OnDeath != null) OnDeath(this, causeOfDeath);
|
||||||
|
|
||||||
KillProjSpecific();
|
KillProjSpecific();
|
||||||
|
|||||||
@@ -51,12 +51,6 @@ namespace Barotrauma
|
|||||||
//the physics body of the limb
|
//the physics body of the limb
|
||||||
public PhysicsBody body;
|
public PhysicsBody body;
|
||||||
|
|
||||||
private readonly int refJointIndex;
|
|
||||||
|
|
||||||
private readonly float steerForce;
|
|
||||||
|
|
||||||
private readonly bool doesFlip;
|
|
||||||
|
|
||||||
protected readonly Vector2 stepOffset;
|
protected readonly Vector2 stepOffset;
|
||||||
|
|
||||||
public Sprite sprite, damagedSprite;
|
public Sprite sprite, damagedSprite;
|
||||||
@@ -69,8 +63,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public readonly bool ignoreCollisions;
|
public readonly bool ignoreCollisions;
|
||||||
|
|
||||||
private float damage, burnt;
|
|
||||||
|
|
||||||
private bool isSevered;
|
private bool isSevered;
|
||||||
private float severedFadeOutTimer;
|
private float severedFadeOutTimer;
|
||||||
|
|
||||||
@@ -81,16 +73,9 @@ namespace Barotrauma
|
|||||||
public const float SoundInterval = 0.4f;
|
public const float SoundInterval = 0.4f;
|
||||||
|
|
||||||
public readonly Attack attack;
|
public readonly Attack attack;
|
||||||
|
private List<DamageModifier> damageModifiers;
|
||||||
|
|
||||||
private Direction dir;
|
private Direction dir;
|
||||||
|
|
||||||
private List<WearableSprite> wearingItems;
|
|
||||||
|
|
||||||
private Vector2 animTargetPos;
|
|
||||||
|
|
||||||
private float scale;
|
|
||||||
|
|
||||||
private List<DamageModifier> damageModifiers;
|
|
||||||
|
|
||||||
public float AttackTimer;
|
public float AttackTimer;
|
||||||
|
|
||||||
@@ -100,17 +85,13 @@ namespace Barotrauma
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
isSevered = value;
|
isSevered = value;
|
||||||
if (isSevered)
|
#if CLIENT
|
||||||
{
|
if (isSevered) damage = 100.0f;
|
||||||
damage = 100.0f;
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DoesFlip
|
public bool DoesFlip { get; private set; }
|
||||||
{
|
|
||||||
get { return doesFlip; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 WorldPosition
|
public Vector2 WorldPosition
|
||||||
{
|
{
|
||||||
@@ -132,21 +113,12 @@ namespace Barotrauma
|
|||||||
get { return body.Rotation; }
|
get { return body.Rotation; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Scale
|
public float Scale { get; private set; }
|
||||||
{
|
|
||||||
get { return scale; }
|
|
||||||
}
|
|
||||||
|
|
||||||
//where an animcontroller is trying to pull the limb, only used for debug visualization
|
//where an animcontroller is trying to pull the limb, only used for debug visualization
|
||||||
public Vector2 AnimTargetPos
|
public Vector2 AnimTargetPos { get; private set; }
|
||||||
{
|
|
||||||
get { return animTargetPos; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public float SteerForce
|
public float SteerForce { get; private set; }
|
||||||
{
|
|
||||||
get { return steerForce; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Mass
|
public float Mass
|
||||||
{
|
{
|
||||||
@@ -166,38 +138,25 @@ namespace Barotrauma
|
|||||||
set { dir = (value==-1.0f) ? Direction.Left : Direction.Right; }
|
set { dir = (value==-1.0f) ? Direction.Left : Direction.Right; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int RefJointIndex
|
public int RefJointIndex { get; private set; }
|
||||||
{
|
|
||||||
get { return refJointIndex; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 StepOffset
|
public Vector2 StepOffset
|
||||||
{
|
{
|
||||||
get { return stepOffset; }
|
get { return stepOffset; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Burnt
|
public List<WearableSprite> WearingItems { get; private set; }
|
||||||
{
|
|
||||||
get { return burnt; }
|
|
||||||
protected set { burnt = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<WearableSprite> WearingItems
|
|
||||||
{
|
|
||||||
get { return wearingItems; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Limb (Character character, XElement element, float scale = 1.0f)
|
public Limb (Character character, XElement element, float scale = 1.0f)
|
||||||
{
|
{
|
||||||
this.character = character;
|
this.character = character;
|
||||||
|
|
||||||
wearingItems = new List<WearableSprite>();
|
WearingItems = new List<WearableSprite>();
|
||||||
|
|
||||||
dir = Direction.Right;
|
dir = Direction.Right;
|
||||||
|
DoesFlip = element.GetAttributeBool("flip", false);
|
||||||
|
|
||||||
doesFlip = element.GetAttributeBool("flip", false);
|
Scale = scale;
|
||||||
|
|
||||||
this.scale = scale;
|
|
||||||
|
|
||||||
body = new PhysicsBody(element, scale);
|
body = new PhysicsBody(element, scale);
|
||||||
|
|
||||||
@@ -217,7 +176,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
body.UserData = this;
|
body.UserData = this;
|
||||||
|
|
||||||
refJointIndex = -1;
|
RefJointIndex = -1;
|
||||||
|
|
||||||
Vector2 pullJointPos = Vector2.Zero;
|
Vector2 pullJointPos = Vector2.Zero;
|
||||||
|
|
||||||
@@ -240,7 +199,7 @@ namespace Barotrauma
|
|||||||
stepOffset = element.GetAttributeVector2("stepoffset", Vector2.Zero) * scale;
|
stepOffset = element.GetAttributeVector2("stepoffset", Vector2.Zero) * scale;
|
||||||
stepOffset = ConvertUnits.ToSimUnits(stepOffset);
|
stepOffset = ConvertUnits.ToSimUnits(stepOffset);
|
||||||
|
|
||||||
refJointIndex = element.GetAttributeInt("refjoint", -1);
|
RefJointIndex = element.GetAttributeInt("refjoint", -1);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -254,7 +213,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GameMain.World.AddJoint(pullJoint);
|
GameMain.World.AddJoint(pullJoint);
|
||||||
|
|
||||||
steerForce = element.GetAttributeFloat("steerforce", 0.0f);
|
SteerForce = element.GetAttributeFloat("steerforce", 0.0f);
|
||||||
|
|
||||||
if (element.Attribute("mouthpos") != null)
|
if (element.Attribute("mouthpos") != null)
|
||||||
{
|
{
|
||||||
@@ -329,12 +288,12 @@ namespace Barotrauma
|
|||||||
public void MoveToPos(Vector2 pos, float force, bool pullFromCenter=false)
|
public void MoveToPos(Vector2 pos, float force, bool pullFromCenter=false)
|
||||||
{
|
{
|
||||||
Vector2 pullPos = body.SimPosition;
|
Vector2 pullPos = body.SimPosition;
|
||||||
if (pullJoint!=null && !pullFromCenter)
|
if (pullJoint != null && !pullFromCenter)
|
||||||
{
|
{
|
||||||
pullPos = pullJoint.WorldAnchorA;
|
pullPos = pullJoint.WorldAnchorA;
|
||||||
}
|
}
|
||||||
|
|
||||||
animTargetPos = pos;
|
AnimTargetPos = pos;
|
||||||
|
|
||||||
body.MoveToPos(pos, force, pullPos);
|
body.MoveToPos(pos, force, pullPos);
|
||||||
}
|
}
|
||||||
@@ -352,7 +311,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (WearableSprite wearable in wearingItems)
|
foreach (WearableSprite wearable in WearingItems)
|
||||||
{
|
{
|
||||||
foreach (DamageModifier damageModifier in wearable.WearableComponent.DamageModifiers)
|
foreach (DamageModifier damageModifier in wearable.WearableComponent.DamageModifiers)
|
||||||
{
|
{
|
||||||
@@ -370,54 +329,13 @@ namespace Barotrauma
|
|||||||
bleedingAmount *= damageModifier.BleedingMultiplier;
|
bleedingAmount *= damageModifier.BleedingMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CLIENT
|
AddDamageProjSpecific(position, damageType, amount, bleedingAmount, playSound, appliedDamageModifiers);
|
||||||
if (playSound)
|
|
||||||
{
|
|
||||||
string damageSoundType = (damageType == DamageType.Blunt) ? "LimbBlunt" : "LimbSlash";
|
|
||||||
|
|
||||||
foreach (DamageModifier damageModifier in appliedDamageModifiers)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(damageModifier.DamageSound))
|
|
||||||
{
|
|
||||||
damageSoundType = damageModifier.DamageSound;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundPlayer.PlayDamageSound(damageSoundType, amount, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (character.UseBloodParticles)
|
|
||||||
{
|
|
||||||
float bloodParticleAmount = bleedingAmount <= 0.0f ? 0 : (int)Math.Min(amount / 5, 10);
|
|
||||||
float bloodParticleSize = MathHelper.Clamp(amount / 50.0f, 0.1f, 1.0f);
|
|
||||||
|
|
||||||
for (int i = 0; i < bloodParticleAmount; i++)
|
|
||||||
{
|
|
||||||
var blood = GameMain.ParticleManager.CreateParticle(inWater ? "waterblood" : "blood", WorldPosition, Vector2.Zero, 0.0f, character.AnimController.CurrentHull);
|
|
||||||
if (blood != null)
|
|
||||||
{
|
|
||||||
blood.Size *= bloodParticleSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bloodParticleAmount > 0 && character.CurrentHull != null)
|
|
||||||
{
|
|
||||||
character.CurrentHull.AddDecal("blood", WorldPosition, MathHelper.Clamp(bloodParticleSize, 0.5f, 1.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (damageType == DamageType.Burn)
|
|
||||||
{
|
|
||||||
Burnt += amount * 10.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
damage += Math.Max(amount,bleedingAmount) / character.MaxHealth * 100.0f;
|
|
||||||
|
|
||||||
return new AttackResult(amount, bleedingAmount, appliedDamageModifiers);
|
return new AttackResult(amount, bleedingAmount, appliedDamageModifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void AddDamageProjSpecific(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound, List<DamageModifier> appliedDamageModifiers);
|
||||||
|
|
||||||
public bool SectorHit(Vector2 armorSector, Vector2 simPosition)
|
public bool SectorHit(Vector2 armorSector, Vector2 simPosition)
|
||||||
{
|
{
|
||||||
if (armorSector == Vector2.Zero) return false;
|
if (armorSector == Vector2.Zero) return false;
|
||||||
@@ -435,10 +353,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Update(float deltaTime)
|
public void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
UpdateProjSpecific();
|
UpdateProjSpecific(deltaTime);
|
||||||
|
|
||||||
if (!character.IsDead) damage = Math.Max(0.0f, damage - deltaTime * 0.1f);
|
|
||||||
if (burnt > 0.0f) Burnt -= deltaTime;
|
|
||||||
|
|
||||||
if (LinearVelocity.X > 500.0f)
|
if (LinearVelocity.X > 500.0f)
|
||||||
{
|
{
|
||||||
@@ -463,17 +378,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (character.IsDead) return;
|
if (character.IsDead) return;
|
||||||
|
|
||||||
damage = Math.Max(0.0f, damage - deltaTime * 0.1f);
|
|
||||||
SoundTimer -= deltaTime;
|
SoundTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateProjSpecific();
|
partial void UpdateProjSpecific(float deltaTime);
|
||||||
|
|
||||||
public void ActivateDamagedSprite()
|
|
||||||
{
|
|
||||||
damage = 100.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateAttack(float deltaTime, Vector2 attackPosition, IDamageable damageTarget)
|
public void UpdateAttack(float deltaTime, Vector2 attackPosition, IDamageable damageTarget)
|
||||||
{
|
{
|
||||||
float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackPosition));
|
float dist = ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackPosition));
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Execute(string[] args)
|
public void Execute(string[] args)
|
||||||
{
|
{
|
||||||
|
if (onExecute == null) return;
|
||||||
onExecute(args);
|
onExecute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +101,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (onClientRequestExecute == null)
|
if (onClientRequestExecute == null)
|
||||||
{
|
{
|
||||||
|
if (onExecute == null) return;
|
||||||
onExecute(args);
|
onExecute(args);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -247,11 +249,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("spawnitem", "spawnitem [itemname] [cursor/inventory]: Spawn an item at the position of the cursor, in the inventory of the controlled character or at a random spawnpoint if the last parameter is omitted.",
|
commands.Add(new Command("spawnitem", "spawnitem [itemname] [cursor/inventory/random/[name]]: Spawn an item at the position of the cursor, in the inventory of the controlled character, in the inventory of the client with the given name, or at a random spawnpoint if the last parameter is omitted or \"random\".",
|
||||||
(string[] args) =>
|
(string[] args) =>
|
||||||
{
|
{
|
||||||
string errorMsg;
|
SpawnItem(args, GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), Character.Controlled, out string errorMsg);
|
||||||
SpawnItem(args, GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), out errorMsg);
|
|
||||||
if (!string.IsNullOrWhiteSpace(errorMsg))
|
if (!string.IsNullOrWhiteSpace(errorMsg))
|
||||||
{
|
{
|
||||||
ThrowError(errorMsg);
|
ThrowError(errorMsg);
|
||||||
@@ -260,20 +261,18 @@ namespace Barotrauma
|
|||||||
null,
|
null,
|
||||||
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||||
{
|
{
|
||||||
string errorMsg;
|
SpawnItem(args, cursorWorldPos, client.Character, out string errorMsg);
|
||||||
SpawnItem(args, cursorWorldPos, out errorMsg);
|
|
||||||
if (!string.IsNullOrWhiteSpace(errorMsg))
|
if (!string.IsNullOrWhiteSpace(errorMsg))
|
||||||
{
|
{
|
||||||
ThrowError(errorMsg);
|
GameMain.Server.SendConsoleMessage(errorMsg, client);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
List<string> itemNames = new List<string>();
|
List<string> itemNames = new List<string>();
|
||||||
foreach (MapEntityPrefab prefab in MapEntityPrefab.List)
|
foreach (MapEntityPrefab prefab in MapEntityPrefab.List)
|
||||||
{
|
{
|
||||||
ItemPrefab itemPrefab = prefab as ItemPrefab;
|
if (prefab is ItemPrefab itemPrefab) itemNames.Add(itemPrefab.Name);
|
||||||
if (itemPrefab != null) itemNames.Add(itemPrefab.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new string[][]
|
return new string[][]
|
||||||
@@ -283,6 +282,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
commands.Add(new Command("disablecrewai", "disablecrewai: Disable the AI of the NPCs in the crew.", (string[] args) =>
|
commands.Add(new Command("disablecrewai", "disablecrewai: Disable the AI of the NPCs in the crew.", (string[] args) =>
|
||||||
{
|
{
|
||||||
HumanAIController.DisableCrewAI = true;
|
HumanAIController.DisableCrewAI = true;
|
||||||
@@ -849,8 +849,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (args.Length < 2) return;
|
if (args.Length < 2) return;
|
||||||
|
|
||||||
int id;
|
int.TryParse(args[0], out int id);
|
||||||
int.TryParse(args[0], out id);
|
|
||||||
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
|
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
@@ -891,8 +890,7 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id;
|
int.TryParse(args[0], out int id);
|
||||||
int.TryParse(args[0], out id);
|
|
||||||
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
|
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
@@ -1019,11 +1017,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
commands.Add(new Command("kickid", "kickid [id]: Kick the player with the specified client ID out of the server.", (string[] args) =>
|
commands.Add(new Command("kickid", "kickid [id]: Kick the player with the specified client ID out of the server.", (string[] args) =>
|
||||||
{
|
{
|
||||||
if (GameMain.Server == null || args.Length == 0) return;
|
if (GameMain.NetworkMember == null || args.Length == 0) return;
|
||||||
|
|
||||||
int id = 0;
|
int.TryParse(args[0], out int id);
|
||||||
int.TryParse(args[0], out id);
|
var client = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == id);
|
||||||
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
|
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
ThrowError("Client id \"" + id + "\" not found.");
|
ThrowError("Client id \"" + id + "\" not found.");
|
||||||
@@ -1032,7 +1029,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
ShowQuestionPrompt("Reason for kicking \"" + client.Name + "\"?", (reason) =>
|
ShowQuestionPrompt("Reason for kicking \"" + client.Name + "\"?", (reason) =>
|
||||||
{
|
{
|
||||||
GameMain.Server.KickPlayer(client.Name, reason);
|
GameMain.NetworkMember.KickPlayer(client.Name, reason);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -1073,17 +1070,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server.", (string[] args) =>
|
commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server.", (string[] args) =>
|
||||||
{
|
{
|
||||||
if (GameMain.Server == null || args.Length == 0) return;
|
if (GameMain.NetworkMember == null || args.Length == 0) return;
|
||||||
|
|
||||||
int id = 0;
|
int.TryParse(args[0], out int id);
|
||||||
int.TryParse(args[0], out id);
|
var client = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == id);
|
||||||
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
|
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
ThrowError("Client id \"" + id + "\" not found.");
|
ThrowError("Client id \"" + id + "\" not found.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowQuestionPrompt("Reason for banning \"" + client.Name + "\"?", (reason) =>
|
ShowQuestionPrompt("Reason for banning \"" + client.Name + "\"?", (reason) =>
|
||||||
{
|
{
|
||||||
ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
|
ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
|
||||||
@@ -1091,8 +1087,7 @@ namespace Barotrauma
|
|||||||
TimeSpan? banDuration = null;
|
TimeSpan? banDuration = null;
|
||||||
if (!string.IsNullOrWhiteSpace(duration))
|
if (!string.IsNullOrWhiteSpace(duration))
|
||||||
{
|
{
|
||||||
TimeSpan parsedBanDuration;
|
if (!TryParseTimeSpan(duration, out TimeSpan parsedBanDuration))
|
||||||
if (!TryParseTimeSpan(duration, out parsedBanDuration))
|
|
||||||
{
|
{
|
||||||
ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
|
ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
|
||||||
return;
|
return;
|
||||||
@@ -1100,7 +1095,7 @@ namespace Barotrauma
|
|||||||
banDuration = parsedBanDuration;
|
banDuration = parsedBanDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameMain.Server.BanPlayer(client.Name, reason, false, banDuration);
|
GameMain.NetworkMember.BanPlayer(client.Name, reason, false, banDuration);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
@@ -1117,8 +1112,7 @@ namespace Barotrauma
|
|||||||
TimeSpan? banDuration = null;
|
TimeSpan? banDuration = null;
|
||||||
if (!string.IsNullOrWhiteSpace(duration))
|
if (!string.IsNullOrWhiteSpace(duration))
|
||||||
{
|
{
|
||||||
TimeSpan parsedBanDuration;
|
if (!TryParseTimeSpan(duration, out TimeSpan parsedBanDuration))
|
||||||
if (!TryParseTimeSpan(duration, out parsedBanDuration))
|
|
||||||
{
|
{
|
||||||
ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
|
ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
|
||||||
return;
|
return;
|
||||||
@@ -1139,23 +1133,72 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(string[] args) =>
|
||||||
|
{
|
||||||
|
#if CLIENT
|
||||||
|
if (GameMain.Client == null || args.Length == 0) return;
|
||||||
|
ShowQuestionPrompt("Reason for banning the ip \"" + args[0] + "\"?", (reason) =>
|
||||||
|
{
|
||||||
|
ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
|
||||||
|
{
|
||||||
|
TimeSpan? banDuration = null;
|
||||||
|
if (!string.IsNullOrWhiteSpace(duration))
|
||||||
|
{
|
||||||
|
if (!TryParseTimeSpan(duration, out TimeSpan parsedBanDuration))
|
||||||
|
{
|
||||||
|
ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
banDuration = parsedBanDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMain.Client.SendConsoleCommand(
|
||||||
|
"banip " +
|
||||||
|
args[0] + " " +
|
||||||
|
(banDuration.HasValue ? banDuration.Value.TotalSeconds.ToString() : "0") + " " +
|
||||||
|
reason);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
(Client client, Vector2 cursorPos, string[] args) =>
|
||||||
|
{
|
||||||
|
if (args.Length < 1) return;
|
||||||
|
var clients = GameMain.Server.ConnectedClients.FindAll(c => c.Connection.RemoteEndPoint.Address.ToString() == args[0]);
|
||||||
|
TimeSpan? duration = null;
|
||||||
|
if (args.Length > 1)
|
||||||
|
{
|
||||||
|
if (double.TryParse(args[1], out double durationSeconds))
|
||||||
|
{
|
||||||
|
if (durationSeconds > 0) duration = TimeSpan.FromSeconds(durationSeconds);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameMain.Server.SendConsoleMessage("\"" + args[1] + "\" is not a valid ban duration.", client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string reason = "";
|
||||||
|
if (args.Length > 2) reason = string.Join(" ", args.Skip(2));
|
||||||
|
|
||||||
|
if (clients.Count == 0)
|
||||||
|
{
|
||||||
|
GameMain.Server.BanList.BanPlayer("Unnamed", args[0], reason, duration);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Client cl in clients)
|
||||||
|
{
|
||||||
|
GameMain.Server.BanClient(cl, reason, false, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("teleportcharacter|teleport", "teleport [character name]: Teleport the specified character to the position of the cursor. If the name parameter is omitted, the controlled character will be teleported.", (string[] args) =>
|
commands.Add(new Command("teleportcharacter|teleport", "teleport [character name]: Teleport the specified character to the position of the cursor. If the name parameter is omitted, the controlled character will be teleported.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Character tpCharacter = null;
|
Character tpCharacter = (args.Length == 0) ? Character.Controlled : FindMatchingCharacter(args, false);
|
||||||
|
|
||||||
if (args.Length == 0)
|
|
||||||
{
|
|
||||||
tpCharacter = Character.Controlled;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tpCharacter = FindMatchingCharacter(args, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tpCharacter == null) return;
|
if (tpCharacter == null) return;
|
||||||
|
|
||||||
var cam = GameMain.GameScreen.Cam;
|
var cam = GameMain.GameScreen.Cam;
|
||||||
@@ -1167,17 +1210,7 @@ namespace Barotrauma
|
|||||||
null,
|
null,
|
||||||
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||||
{
|
{
|
||||||
Character tpCharacter = null;
|
Character tpCharacter = (args.Length == 0) ? client.Character : FindMatchingCharacter(args, false);
|
||||||
|
|
||||||
if (args.Length == 0)
|
|
||||||
{
|
|
||||||
tpCharacter = client.Character;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tpCharacter = FindMatchingCharacter(args, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tpCharacter == null) return;
|
if (tpCharacter == null) return;
|
||||||
|
|
||||||
var cam = GameMain.GameScreen.Cam;
|
var cam = GameMain.GameScreen.Cam;
|
||||||
@@ -1216,7 +1249,7 @@ namespace Barotrauma
|
|||||||
Submarine.LockX = !Submarine.LockX;
|
Submarine.LockX = !Submarine.LockX;
|
||||||
}, null, null));
|
}, null, null));
|
||||||
|
|
||||||
commands.Add(new Command("locky", "loxky: Lock vertical movement of the main submarine.", (string[] args) =>
|
commands.Add(new Command("locky", "locky: Lock vertical movement of the main submarine.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Submarine.LockY = !Submarine.LockY;
|
Submarine.LockY = !Submarine.LockY;
|
||||||
}, null, null));
|
}, null, null));
|
||||||
@@ -1234,18 +1267,29 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
commands.Add(new Command("findentityids", "findentityids [entityname]", (string[] args) =>
|
||||||
|
{
|
||||||
|
if (args.Length == 0) return;
|
||||||
|
args[0] = args[0].ToLowerInvariant();
|
||||||
|
foreach (MapEntity mapEntity in MapEntity.mapEntityList)
|
||||||
|
{
|
||||||
|
if (mapEntity.Name.ToLowerInvariant() == args[0])
|
||||||
|
{
|
||||||
|
ThrowError(mapEntity.ID + ": " + mapEntity.Name.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (Character character in Character.CharacterList)
|
||||||
|
{
|
||||||
|
if (character.Name.ToLowerInvariant() == args[0] || character.SpeciesName.ToLowerInvariant() == args[0])
|
||||||
|
{
|
||||||
|
ThrowError(character.ID + ": " + character.Name.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("heal", "heal [character name]: Restore the specified character to full health. If the name parameter is omitted, the controlled character will be healed.", (string[] args) =>
|
commands.Add(new Command("heal", "heal [character name]: Restore the specified character to full health. If the name parameter is omitted, the controlled character will be healed.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Character healedCharacter = null;
|
Character healedCharacter = (args.Length == 0) ? Character.Controlled : FindMatchingCharacter(args);
|
||||||
if (args.Length == 0)
|
|
||||||
{
|
|
||||||
healedCharacter = Character.Controlled;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
healedCharacter = FindMatchingCharacter(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (healedCharacter != null)
|
if (healedCharacter != null)
|
||||||
{
|
{
|
||||||
healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
|
healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
|
||||||
@@ -1257,16 +1301,7 @@ namespace Barotrauma
|
|||||||
null,
|
null,
|
||||||
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||||
{
|
{
|
||||||
Character healedCharacter = null;
|
Character healedCharacter = (args.Length == 0) ? client.Character : FindMatchingCharacter(args);
|
||||||
if (args.Length == 0)
|
|
||||||
{
|
|
||||||
healedCharacter = client.Character;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
healedCharacter = FindMatchingCharacter(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (healedCharacter != null)
|
if (healedCharacter != null)
|
||||||
{
|
{
|
||||||
healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
|
healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
|
||||||
@@ -1285,16 +1320,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
commands.Add(new Command("revive", "revive [character name]: Bring the specified character back from the dead. If the name parameter is omitted, the controlled character will be revived.", (string[] args) =>
|
commands.Add(new Command("revive", "revive [character name]: Bring the specified character back from the dead. If the name parameter is omitted, the controlled character will be revived.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Character revivedCharacter = null;
|
Character revivedCharacter = (args.Length == 0) ? Character.Controlled : FindMatchingCharacter(args);
|
||||||
if (args.Length == 0)
|
|
||||||
{
|
|
||||||
revivedCharacter = Character.Controlled;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
revivedCharacter = FindMatchingCharacter(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (revivedCharacter == null) return;
|
if (revivedCharacter == null) return;
|
||||||
|
|
||||||
revivedCharacter.Revive(false);
|
revivedCharacter.Revive(false);
|
||||||
@@ -1313,16 +1339,7 @@ namespace Barotrauma
|
|||||||
null,
|
null,
|
||||||
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||||
{
|
{
|
||||||
Character revivedCharacter = null;
|
Character revivedCharacter = (args.Length == 0) ? client.Character : FindMatchingCharacter(args);
|
||||||
if (args.Length == 0)
|
|
||||||
{
|
|
||||||
revivedCharacter = client.Character;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
revivedCharacter = FindMatchingCharacter(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (revivedCharacter == null) return;
|
if (revivedCharacter == null) return;
|
||||||
|
|
||||||
revivedCharacter.Revive(false);
|
revivedCharacter.Revive(false);
|
||||||
@@ -1358,16 +1375,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
commands.Add(new Command("ragdoll", "ragdoll [character name]: Force-ragdoll the specified character. If the name parameter is omitted, the controlled character will be ragdolled.", (string[] args) =>
|
commands.Add(new Command("ragdoll", "ragdoll [character name]: Force-ragdoll the specified character. If the name parameter is omitted, the controlled character will be ragdolled.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Character ragdolledCharacter = null;
|
Character ragdolledCharacter = (args.Length == 0) ? Character.Controlled : FindMatchingCharacter(args);
|
||||||
if (args.Length == 0)
|
if (ragdolledCharacter != null)
|
||||||
{
|
{
|
||||||
ragdolledCharacter = Character.Controlled;
|
ragdolledCharacter.IsForceRagdolled = !ragdolledCharacter.IsForceRagdolled;
|
||||||
}
|
}
|
||||||
else
|
},
|
||||||
{
|
null,
|
||||||
ragdolledCharacter = FindMatchingCharacter(args);
|
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||||
}
|
{
|
||||||
|
Character ragdolledCharacter = (args.Length == 0) ? client.Character : FindMatchingCharacter(args);
|
||||||
if (ragdolledCharacter != null)
|
if (ragdolledCharacter != null)
|
||||||
{
|
{
|
||||||
ragdolledCharacter.IsForceRagdolled = !ragdolledCharacter.IsForceRagdolled;
|
ragdolledCharacter.IsForceRagdolled = !ragdolledCharacter.IsForceRagdolled;
|
||||||
@@ -1477,20 +1494,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
commands.Add(new Command("kill", "kill [character]: Immediately kills the specified character.", (string[] args) =>
|
commands.Add(new Command("kill", "kill [character]: Immediately kills the specified character.", (string[] args) =>
|
||||||
{
|
{
|
||||||
Character killedCharacter = null;
|
Character killedCharacter = (args.Length == 0) ? Character.Controlled : FindMatchingCharacter(args);
|
||||||
if (args.Length == 0)
|
killedCharacter?.AddDamage(CauseOfDeath.Damage, killedCharacter.MaxHealth * 2, null);
|
||||||
{
|
},
|
||||||
killedCharacter = Character.Controlled;
|
null,
|
||||||
}
|
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||||
else
|
{
|
||||||
{
|
Character killedCharacter = (args.Length == 0) ? client.Character : FindMatchingCharacter(args);
|
||||||
killedCharacter = FindMatchingCharacter(args);
|
killedCharacter?.AddDamage(CauseOfDeath.Damage, killedCharacter.MaxHealth * 2, null);
|
||||||
}
|
|
||||||
|
|
||||||
if (killedCharacter != null)
|
|
||||||
{
|
|
||||||
killedCharacter.AddDamage(CauseOfDeath.Damage, killedCharacter.MaxHealth * 2, null);
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("killmonsters", "killmonsters: Immediately kills all AI-controlled enemies in the level.", (string[] args) =>
|
commands.Add(new Command("killmonsters", "killmonsters: Immediately kills all AI-controlled enemies in the level.", (string[] args) =>
|
||||||
@@ -2120,7 +2131,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SpawnItem(string[] args, Vector2 cursorPos, out string errorMsg)
|
private static void SpawnItem(string[] args, Vector2 cursorPos, Character controlledCharacter, out string errorMsg)
|
||||||
{
|
{
|
||||||
errorMsg = "";
|
errorMsg = "";
|
||||||
if (args.Length < 1) return;
|
if (args.Length < 1) return;
|
||||||
@@ -2128,23 +2139,48 @@ namespace Barotrauma
|
|||||||
Vector2? spawnPos = null;
|
Vector2? spawnPos = null;
|
||||||
Inventory spawnInventory = null;
|
Inventory spawnInventory = null;
|
||||||
|
|
||||||
int extraParams = 0;
|
if (args.Length > 1)
|
||||||
switch (args.Last())
|
|
||||||
{
|
{
|
||||||
case "cursor":
|
switch (args[1])
|
||||||
extraParams = 1;
|
{
|
||||||
spawnPos = cursorPos;
|
case "cursor":
|
||||||
break;
|
spawnPos = cursorPos;
|
||||||
case "inventory":
|
break;
|
||||||
extraParams = 1;
|
case "inventory":
|
||||||
spawnInventory = Character.Controlled == null ? null : Character.Controlled.Inventory;
|
spawnInventory = controlledCharacter?.Inventory;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
extraParams = 0;
|
//Check if last arg matches the name of an in-game player
|
||||||
break;
|
if (GameMain.Server != null)
|
||||||
|
{
|
||||||
|
var client = GameMain.Server.ConnectedClients.Find(c => c.Name.ToLower() == args.Last().ToLower());
|
||||||
|
if (client == null)
|
||||||
|
{
|
||||||
|
NewMessage("No player found with the name \"" + args.Last() + "\". Spawning item at random location. If the player you want to give the item to has a space in their name, try surrounding their name with quotes (\").", Color.Red);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (client.Character == null)
|
||||||
|
{
|
||||||
|
errorMsg = "The player \"" + args.Last() + "\" is connected, but hasn't spawned yet.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//If the last arg matches the name of an in-game player, set the destination to their inventory.
|
||||||
|
spawnInventory = client.Character.Inventory;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var matchingCharacter = FindMatchingCharacter(args.Skip(1).ToArray());
|
||||||
|
if (matchingCharacter?.Inventory != null) spawnInventory = matchingCharacter.Inventory;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string itemName = string.Join(" ", args.Take(args.Length - extraParams)).ToLowerInvariant();
|
string itemName = args[0];
|
||||||
|
|
||||||
var itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
|
var itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
|
||||||
if (itemPrefab == null)
|
if (itemPrefab == null)
|
||||||
@@ -2162,7 +2198,6 @@ namespace Barotrauma
|
|||||||
if (spawnPos != null)
|
if (spawnPos != null)
|
||||||
{
|
{
|
||||||
Entity.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos);
|
Entity.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (spawnInventory != null)
|
else if (spawnInventory != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private int requiredDeliveryAmount;
|
private int requiredDeliveryAmount;
|
||||||
|
|
||||||
public CargoMission(XElement element, Location[] locations)
|
public CargoMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
itemConfig = element.Element("Items");
|
itemConfig = prefab.ConfigElement.Element("Items");
|
||||||
|
|
||||||
requiredDeliveryAmount = element.GetAttributeInt("requireddeliveryamount", 0);
|
requiredDeliveryAmount = prefab.ConfigElement.GetAttributeInt("requireddeliveryamount", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitItems()
|
private void InitItems()
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
if (descriptions == null) return "";
|
||||||
|
|
||||||
if (GameMain.NetworkMember==null || GameMain.NetworkMember.Character==null)
|
if (GameMain.NetworkMember==null || GameMain.NetworkMember.Character==null)
|
||||||
{
|
{
|
||||||
//non-team-specific description
|
//non-team-specific description
|
||||||
@@ -47,20 +49,20 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (winner == -1) return "";
|
if (winner == -1) return "";
|
||||||
|
|
||||||
return successMessage
|
return base.SuccessMessage
|
||||||
.Replace("[loser]", teamNames[1 - winner])
|
.Replace("[loser]", teamNames[1 - winner])
|
||||||
.Replace("[winner]", teamNames[winner]);
|
.Replace("[winner]", teamNames[winner]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CombatMission(XElement element, Location[] locations)
|
public CombatMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
descriptions = new string[]
|
descriptions = new string[]
|
||||||
{
|
{
|
||||||
element.GetAttributeString("descriptionneutral", ""),
|
prefab.ConfigElement.GetAttributeString("descriptionneutral", ""),
|
||||||
element.GetAttributeString("description1", ""),
|
prefab.ConfigElement.GetAttributeString("description1", ""),
|
||||||
element.GetAttributeString("description2", "")
|
prefab.ConfigElement.GetAttributeString("description2", "")
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < descriptions.Length; i++)
|
for (int i = 0; i < descriptions.Length; i++)
|
||||||
@@ -73,8 +75,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
teamNames = new string[]
|
teamNames = new string[]
|
||||||
{
|
{
|
||||||
element.GetAttributeString("teamname1", "Team A"),
|
prefab.ConfigElement.GetAttributeString("teamname1", "Team A"),
|
||||||
element.GetAttributeString("teamname2", "Team B")
|
prefab.ConfigElement.GetAttributeString("teamname2", "Team B")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +1,18 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
partial class Mission
|
partial class Mission
|
||||||
{
|
{
|
||||||
public static List<string> MissionTypes = new List<string>() { "Random" };
|
|
||||||
|
|
||||||
private string name;
|
|
||||||
|
|
||||||
private string description;
|
|
||||||
|
|
||||||
protected bool completed;
|
protected bool completed;
|
||||||
|
|
||||||
protected string successMessage;
|
private readonly MissionPrefab prefab;
|
||||||
protected string failureMessage;
|
|
||||||
|
|
||||||
protected string radarLabel;
|
|
||||||
|
|
||||||
protected List<string> headers;
|
|
||||||
protected List<string> messages;
|
|
||||||
|
|
||||||
private int reward;
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return name; }
|
get { return prefab.Name; }
|
||||||
}
|
|
||||||
|
|
||||||
public virtual string Description
|
|
||||||
{
|
|
||||||
get { return description; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Reward
|
|
||||||
{
|
|
||||||
get { return reward; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Completed
|
public bool Completed
|
||||||
@@ -48,109 +21,101 @@ namespace Barotrauma
|
|||||||
set { completed = value; }
|
set { completed = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int Reward
|
||||||
|
{
|
||||||
|
get { return prefab.Reward; }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool AllowRespawn
|
public virtual bool AllowRespawn
|
||||||
{
|
{
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string RadarLabel
|
|
||||||
{
|
|
||||||
get { return radarLabel; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Vector2 RadarPosition
|
public virtual Vector2 RadarPosition
|
||||||
{
|
{
|
||||||
get { return Vector2.Zero; }
|
get { return Vector2.Zero; }
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual public string SuccessMessage
|
public string RadarLabel
|
||||||
{
|
{
|
||||||
get { return successMessage; }
|
get { return prefab.RadarLabel; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> Headers
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> Messages
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string SuccessMessage
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FailureMessage
|
public string FailureMessage
|
||||||
{
|
{
|
||||||
get { return failureMessage; }
|
get;
|
||||||
|
protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Init()
|
public virtual string Description
|
||||||
{
|
{
|
||||||
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
|
get;
|
||||||
foreach (string file in files)
|
protected set;
|
||||||
{
|
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(file);
|
|
||||||
if (doc == null || doc.Root == null) continue;
|
|
||||||
|
|
||||||
foreach (XElement element in doc.Root.Elements())
|
|
||||||
{
|
|
||||||
string missionTypeName = element.Name.ToString();
|
|
||||||
missionTypeName = missionTypeName.Replace("Mission", "");
|
|
||||||
|
|
||||||
if (!MissionTypes.Contains(missionTypeName)) MissionTypes.Add(missionTypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mission(XElement element, Location[] locations)
|
public MissionPrefab Prefab
|
||||||
{
|
{
|
||||||
name = element.GetAttributeString("name", "");
|
get { return prefab; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mission(MissionPrefab prefab, Location[] locations)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.Assert(locations.Length == 2);
|
||||||
|
|
||||||
description = element.GetAttributeString("description", "");
|
this.prefab = prefab;
|
||||||
|
|
||||||
reward = element.GetAttributeInt("reward", 1);
|
Description = prefab.Description;
|
||||||
|
SuccessMessage = prefab.SuccessMessage;
|
||||||
successMessage = element.GetAttributeString("successmessage",
|
FailureMessage = prefab.FailureMessage;
|
||||||
"Mission completed successfully");
|
Headers = new List<string>(prefab.Headers);
|
||||||
failureMessage = element.GetAttributeString("failuremessage",
|
Messages = new List<string>(prefab.Messages);
|
||||||
"Mission failed");
|
|
||||||
|
|
||||||
radarLabel = element.GetAttributeString("radarlabel", "");
|
|
||||||
|
|
||||||
messages = new List<string>();
|
|
||||||
headers = new List<string>();
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (subElement.Name.ToString().ToLowerInvariant() != "message") continue;
|
|
||||||
headers.Add(subElement.GetAttributeString("header", ""));
|
|
||||||
messages.Add(subElement.GetAttributeString("text", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int n = 0; n < 2; n++)
|
for (int n = 0; n < 2; n++)
|
||||||
{
|
{
|
||||||
description = description.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
if (Description != null) Description = Description.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
|
if (SuccessMessage != null) SuccessMessage = SuccessMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
successMessage = successMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
if (FailureMessage != null) FailureMessage = FailureMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
failureMessage = failureMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
for (int m = 0; m < Messages.Count; m++)
|
||||||
|
|
||||||
for (int m = 0; m < messages.Count; m++)
|
|
||||||
{
|
{
|
||||||
messages[m] = messages[m].Replace("[location" + (n + 1) + "]", locations[n].Name);
|
Messages[m] = Messages[m].Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Mission LoadRandom(Location[] locations, string seed, string missionType = "", bool isSinglePlayer = false)
|
||||||
|
{
|
||||||
|
return LoadRandom(locations, new MTRandom(ToolBox.StringToInt(seed)), missionType, isSinglePlayer);
|
||||||
|
}
|
||||||
|
|
||||||
public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false)
|
public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false)
|
||||||
{
|
{
|
||||||
|
//todo: use something else than strings to define the mission type
|
||||||
missionType = missionType.ToLowerInvariant();
|
missionType = missionType.ToLowerInvariant();
|
||||||
|
|
||||||
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
|
List<MissionPrefab> allowedMissions = new List<MissionPrefab>();
|
||||||
string configFile = files[rand.Next(files.Count)];
|
|
||||||
|
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(configFile);
|
|
||||||
if (doc == null) return null;
|
|
||||||
|
|
||||||
int eventCount = doc.Root.Elements().Count();
|
|
||||||
//int[] commonness = new int[eventCount];
|
|
||||||
float[] eventProbability = new float[eventCount];
|
|
||||||
|
|
||||||
float probabilitySum = 0.0f;
|
|
||||||
|
|
||||||
List<XElement> matchingElements = new List<XElement>();
|
|
||||||
|
|
||||||
if (missionType == "random")
|
if (missionType == "random")
|
||||||
{
|
{
|
||||||
matchingElements = doc.Root.Elements().ToList();
|
allowedMissions.AddRange(MissionPrefab.List);
|
||||||
|
if (GameMain.Server != null)
|
||||||
|
{
|
||||||
|
allowedMissions.RemoveAll(mission => !GameMain.Server.AllowedRandomMissionTypes.Any(a => mission.TypeMatches(a)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (missionType == "none")
|
else if (missionType == "none")
|
||||||
{
|
{
|
||||||
@@ -158,68 +123,31 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (string.IsNullOrWhiteSpace(missionType))
|
else if (string.IsNullOrWhiteSpace(missionType))
|
||||||
{
|
{
|
||||||
matchingElements = doc.Root.Elements().ToList();
|
allowedMissions.AddRange(MissionPrefab.List);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matchingElements = doc.Root.Elements().ToList().FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType);
|
allowedMissions = MissionPrefab.List.FindAll(m => m.TypeMatches(missionType));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSinglePlayer)
|
if (isSinglePlayer)
|
||||||
{
|
{
|
||||||
matchingElements.RemoveAll(m => m.GetAttributeBool("multiplayeronly", false));
|
allowedMissions.RemoveAll(m => m.MultiplayerOnly);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matchingElements.RemoveAll(m => m.GetAttributeBool("singleplayeronly", false));
|
allowedMissions.RemoveAll(m => m.SingleplayerOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
float probabilitySum = allowedMissions.Sum(m => m.Commonness);
|
||||||
foreach (XElement element in matchingElements)
|
|
||||||
{
|
|
||||||
eventProbability[i] = element.GetAttributeInt("commonness", 1);
|
|
||||||
|
|
||||||
probabilitySum += eventProbability[i];
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
float randomNumber = (float)rand.NextDouble() * probabilitySum;
|
float randomNumber = (float)rand.NextDouble() * probabilitySum;
|
||||||
|
foreach (MissionPrefab missionPrefab in allowedMissions)
|
||||||
i = 0;
|
|
||||||
foreach (XElement element in matchingElements)
|
|
||||||
{
|
{
|
||||||
if (randomNumber <= eventProbability[i])
|
if (randomNumber <= missionPrefab.Commonness)
|
||||||
{
|
{
|
||||||
Type t;
|
return missionPrefab.Instantiate(locations);
|
||||||
string type = element.Name.ToString();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
t = Type.GetType("Barotrauma." + type, true, true);
|
|
||||||
if (t == null)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\".");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\".");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstructorInfo constructor = t.GetConstructor(new[] { typeof(XElement), typeof(Location[]) });
|
|
||||||
|
|
||||||
object instance = constructor.Invoke(new object[] { element, locations });
|
|
||||||
|
|
||||||
Mission mission = (Mission)instance;
|
|
||||||
|
|
||||||
return mission;
|
|
||||||
}
|
}
|
||||||
|
randomNumber -= missionPrefab.Commonness;
|
||||||
randomNumber -= eventProbability[i];
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -251,7 +179,7 @@ namespace Barotrauma
|
|||||||
var mode = GameMain.GameSession.GameMode as CampaignMode;
|
var mode = GameMain.GameSession.GameMode as CampaignMode;
|
||||||
if (mode == null) return;
|
if (mode == null) return;
|
||||||
|
|
||||||
mode.Money += reward;
|
mode.Money += Reward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
class MissionPrefab
|
||||||
|
{
|
||||||
|
public static List<MissionPrefab> List = new List<MissionPrefab>();
|
||||||
|
public static List<string> MissionTypes = new List<string>() { "Random" };
|
||||||
|
|
||||||
|
private string name;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type missionType;
|
||||||
|
private ConstructorInfo constructor;
|
||||||
|
|
||||||
|
public virtual string Description { get; private set; }
|
||||||
|
|
||||||
|
public bool MultiplayerOnly { get; private set; }
|
||||||
|
public bool SingleplayerOnly { get; private set; }
|
||||||
|
|
||||||
|
public float Commonness { get; private set; }
|
||||||
|
|
||||||
|
public int Reward { get; private set; }
|
||||||
|
|
||||||
|
public string RadarLabel { get; private set; }
|
||||||
|
|
||||||
|
public List<string> Headers { get; private set; }
|
||||||
|
public List<string> Messages { get; private set; }
|
||||||
|
|
||||||
|
public string SuccessMessage { get; private set; }
|
||||||
|
public string FailureMessage { get; private set; }
|
||||||
|
|
||||||
|
public XElement ConfigElement { get; private set; }
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
XDocument doc = XMLExtensions.TryLoadXml(file);
|
||||||
|
if (doc?.Root == null) continue;
|
||||||
|
|
||||||
|
foreach (XElement element in doc.Root.Elements())
|
||||||
|
{
|
||||||
|
string missionTypeName = element.Name.ToString();
|
||||||
|
missionTypeName = missionTypeName.Replace("Mission", "");
|
||||||
|
|
||||||
|
List.Add(new MissionPrefab(element));
|
||||||
|
if (!MissionTypes.Contains(missionTypeName)) MissionTypes.Add(missionTypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MissionPrefab(XElement element)
|
||||||
|
{
|
||||||
|
ConfigElement = element;
|
||||||
|
|
||||||
|
name = element.GetAttributeString("name", "");
|
||||||
|
Description = element.GetAttributeString("description", "");
|
||||||
|
Commonness = element.GetAttributeFloat("commonness", 1.0f);
|
||||||
|
SingleplayerOnly = element.GetAttributeBool("singleplayeronly", false);
|
||||||
|
MultiplayerOnly = element.GetAttributeBool("multiplayeronly", false);
|
||||||
|
|
||||||
|
Reward = element.GetAttributeInt("reward", 1);
|
||||||
|
|
||||||
|
SuccessMessage = element.GetAttributeString("successmessage", "Mission completed successfully");
|
||||||
|
FailureMessage = element.GetAttributeString("failuremessage", "Mission failed");
|
||||||
|
RadarLabel = element.GetAttributeString("radarlabel", "");
|
||||||
|
|
||||||
|
Messages = new List<string>();
|
||||||
|
Headers = new List<string>();
|
||||||
|
foreach (XElement subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (subElement.Name.ToString().ToLowerInvariant() != "message") continue;
|
||||||
|
Headers.Add(subElement.GetAttributeString("header", ""));
|
||||||
|
Messages.Add(subElement.GetAttributeString("text", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
string type = element.Name.ToString();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
missionType = Type.GetType("Barotrauma." + type, true, true);
|
||||||
|
if (missionType == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in mission prefab " + Name + "! Could not find a mission class of the type \"" + type + "\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in mission prefab " + Name + "! Could not find a mission class of the type \"" + type + "\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
constructor = missionType.GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]) });
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mission Instantiate(Location[] locations)
|
||||||
|
{
|
||||||
|
return constructor?.Invoke(new object[] { this, locations }) as Mission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TypeMatches(string typeName)
|
||||||
|
{
|
||||||
|
//TODO: use enums instead of strings?
|
||||||
|
typeName = typeName.ToLowerInvariant();
|
||||||
|
return missionType.Name.ToString().Replace("Mission", "").ToLowerInvariant() == typeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,10 +18,10 @@ namespace Barotrauma
|
|||||||
get { return monster != null && !monster.IsDead ? radarPosition : Vector2.Zero; }
|
get { return monster != null && !monster.IsDead ? radarPosition : Vector2.Zero; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonsterMission(XElement element, Location[] locations)
|
public MonsterMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
monsterFile = element.GetAttributeString("monsterfile", "");
|
monsterFile = prefab.ConfigElement.GetAttributeString("monsterfile", "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using FarseerPhysics;
|
using FarseerPhysics;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -23,10 +22,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SalvageMission(XElement element, Location[] locations)
|
public SalvageMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
string itemName = element.GetAttributeString("itemname", "");
|
string itemName = prefab.ConfigElement.GetAttributeString("itemname", "");
|
||||||
|
|
||||||
itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
|
itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
|
||||||
if (itemPrefab == null)
|
if (itemPrefab == null)
|
||||||
@@ -35,10 +34,10 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string spawnPositionTypeStr = element.GetAttributeString("spawntype", "");
|
string spawnPositionTypeStr = prefab.ConfigElement.GetAttributeString("spawntype", "");
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
|
if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
|
||||||
!Enum.TryParse<Level.PositionType>(spawnPositionTypeStr, true, out spawnPositionType))
|
!Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType))
|
||||||
{
|
{
|
||||||
spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
|
spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using GameAnalyticsSDK.Net;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
public static class GameAnalyticsManager
|
||||||
|
{
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
#if DEBUB
|
||||||
|
GameAnalytics.SetEnabledInfoLog(true);
|
||||||
|
#endif
|
||||||
|
GameAnalytics.ConfigureBuild(GameMain.Version.ToString());
|
||||||
|
GameAnalytics.ConfigureAvailableCustomDimensions01("singleplayer", "multiplayer", "editor");
|
||||||
|
GameAnalytics.Initialize("a3a073c20982de7c15d21e840e149122", "9010ad9a671233b8d9610d76cec8c897d9ff3ba7");
|
||||||
|
|
||||||
|
string contentPackageName = GameMain.Config?.SelectedContentPackage?.Name;
|
||||||
|
if (!string.IsNullOrEmpty(contentPackageName))
|
||||||
|
{
|
||||||
|
GameAnalytics.AddDesignEvent("ContentPackage:" +
|
||||||
|
contentPackageName.Replace(":", "").Substring(0, Math.Min(32, contentPackageName.Length)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,9 +16,22 @@
|
|||||||
: base(preset, param)
|
: base(preset, param)
|
||||||
{
|
{
|
||||||
Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation };
|
Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation };
|
||||||
|
if (param is string)
|
||||||
MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed));
|
{
|
||||||
mission = Mission.LoadRandom(locations, rand, param as string);
|
mission = Mission.LoadRandom(locations, GameMain.NetLobbyScreen.LevelSeed, (string)param);
|
||||||
|
}
|
||||||
|
else if (param is MissionPrefab)
|
||||||
|
{
|
||||||
|
mission = ((MissionPrefab)param).Instantiate(locations);
|
||||||
|
}
|
||||||
|
else if (param is Mission)
|
||||||
|
{
|
||||||
|
mission = (Mission)param;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new System.ArgumentException("Unrecognized MissionMode parameter \"" + param + "\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-7
@@ -55,13 +55,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override void Start()
|
public override void Start()
|
||||||
{
|
{
|
||||||
base.Start();
|
base.Start();
|
||||||
|
|
||||||
if (GameMain.Server != null)
|
|
||||||
{
|
|
||||||
CargoManager.CreateItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
lastUpdateID++;
|
lastUpdateID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +108,9 @@ namespace Barotrauma
|
|||||||
codeWords = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt);
|
codeWords = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt);
|
||||||
codeResponse = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt);
|
codeResponse = ToolBox.GetRandomLine(wordsTxt) + ", " + ToolBox.GetRandomLine(wordsTxt);
|
||||||
|
|
||||||
while (traitorCount-- >= 0)
|
while (traitorCount-- > 0)
|
||||||
{
|
{
|
||||||
if (traitorCandidates.Count <= 0)
|
if (traitorCandidates.Count <= 0) break;
|
||||||
break;
|
|
||||||
|
|
||||||
int traitorIndex = Rand.Int(traitorCandidates.Count);
|
int traitorIndex = Rand.Int(traitorCandidates.Count);
|
||||||
Character traitorCharacter = traitorCandidates[traitorIndex];
|
Character traitorCharacter = traitorCandidates[traitorIndex];
|
||||||
|
|||||||
@@ -91,27 +91,35 @@ namespace Barotrauma
|
|||||||
set { savePath = value; }
|
set { savePath = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset = null, string missionType = "")
|
|
||||||
|
public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset, string missionType = "")
|
||||||
|
: this(submarine, savePath)
|
||||||
|
{
|
||||||
|
GameMode = gameModePreset.Instantiate(missionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset, MissionPrefab missionPrefab)
|
||||||
|
: this(submarine, savePath)
|
||||||
|
{
|
||||||
|
GameMode = gameModePreset.Instantiate(missionPrefab);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameSession(Submarine submarine, string savePath)
|
||||||
{
|
{
|
||||||
Submarine.MainSub = submarine;
|
Submarine.MainSub = submarine;
|
||||||
|
this.submarine = submarine;
|
||||||
GameMain.GameSession = this;
|
GameMain.GameSession = this;
|
||||||
|
|
||||||
EventManager = new EventManager(this);
|
EventManager = new EventManager(this);
|
||||||
|
|
||||||
this.savePath = savePath;
|
this.savePath = savePath;
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
CrewManager = new CrewManager();
|
CrewManager = new CrewManager();
|
||||||
|
|
||||||
infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", "", null);
|
infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", "", null);
|
||||||
infoButton.OnClicked = ToggleInfoFrame;
|
infoButton.OnClicked = ToggleInfoFrame;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gameModePreset != null) GameMode = gameModePreset.Instantiate(missionType);
|
|
||||||
this.submarine = submarine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public GameSession(Submarine selectedSub, string saveFile, XDocument doc)
|
public GameSession(Submarine selectedSub, string saveFile, XDocument doc)
|
||||||
: this(selectedSub, saveFile)
|
: this(selectedSub, saveFile)
|
||||||
{
|
{
|
||||||
@@ -218,8 +226,22 @@ namespace Barotrauma
|
|||||||
|
|
||||||
EventManager.StartRound(level);
|
EventManager.StartRound(level);
|
||||||
|
|
||||||
if (GameMode != null) GameMode.MsgBox();
|
if (GameMode != null)
|
||||||
|
{
|
||||||
|
GameMode.MsgBox();
|
||||||
|
if (GameMode is MultiPlayerCampaign campaign && GameMain.Server != null)
|
||||||
|
{
|
||||||
|
campaign.CargoManager.CreateItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("Submarine:" + submarine.Name);
|
||||||
|
GameAnalyticsSDK.Net.GameAnalytics.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start,
|
||||||
|
GameMode.Name, (Mission == null ? "None" : Mission.GetType().ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
roundSummary = new RoundSummary(this);
|
roundSummary = new RoundSummary(this);
|
||||||
|
|
||||||
@@ -231,6 +253,11 @@ namespace Barotrauma
|
|||||||
public void EndRound(string endMessage)
|
public void EndRound(string endMessage)
|
||||||
{
|
{
|
||||||
if (Mission != null) Mission.End();
|
if (Mission != null) Mission.End();
|
||||||
|
if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
GameAnalyticsSDK.Net.GameAnalytics.AddProgressionEvent((Mission == null || Mission.Completed) ? GameAnalyticsSDK.Net.EGAProgressionStatus.Complete : GameAnalyticsSDK.Net.EGAProgressionStatus.Fail,
|
||||||
|
GameMode.Name, (Mission == null ? "None" : Mission.GetType().ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (roundSummary != null)
|
if (roundSummary != null)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
|||||||
public bool EnableSplashScreen { get; set; }
|
public bool EnableSplashScreen { get; set; }
|
||||||
|
|
||||||
//public bool FullScreenEnabled { get; set; }
|
//public bool FullScreenEnabled { get; set; }
|
||||||
|
|
||||||
private KeyOrMouse[] keyMapping;
|
private KeyOrMouse[] keyMapping;
|
||||||
|
|
||||||
private WindowMode windowMode;
|
private WindowMode windowMode;
|
||||||
@@ -51,8 +51,37 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool unsavedSettings;
|
private int characterHeadIndex;
|
||||||
|
public int CharacterHeadIndex
|
||||||
|
{
|
||||||
|
get { return characterHeadIndex; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == characterHeadIndex) return;
|
||||||
|
// Begin saving coroutine. Remove any existing save coroutines if one is running.
|
||||||
|
if (CoroutineManager.IsCoroutineRunning("saveCoroutine")) { CoroutineManager.StopCoroutines("saveCoroutine"); }
|
||||||
|
CoroutineManager.StartCoroutine(ApplyUnsavedChanges(), "saveCoroutine");
|
||||||
|
|
||||||
|
characterHeadIndex = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Gender characterGender;
|
||||||
|
public Gender CharacterGender
|
||||||
|
{
|
||||||
|
get { return characterGender; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == characterGender) return;
|
||||||
|
// Begin saving coroutine. Remove any existing save coroutines if one is running.
|
||||||
|
if (CoroutineManager.IsCoroutineRunning("saveCoroutine")) { CoroutineManager.StopCoroutines("saveCoroutine"); }
|
||||||
|
CoroutineManager.StartCoroutine(ApplyUnsavedChanges(), "saveCoroutine");
|
||||||
|
|
||||||
|
characterGender = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool unsavedSettings;
|
||||||
public bool UnsavedSettings
|
public bool UnsavedSettings
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -125,6 +154,18 @@ namespace Barotrauma
|
|||||||
public static bool VerboseLogging { get; set; }
|
public static bool VerboseLogging { get; set; }
|
||||||
public static bool SaveDebugConsoleLogs { get; set; }
|
public static bool SaveDebugConsoleLogs { get; set; }
|
||||||
|
|
||||||
|
private static bool sendUserStatistics;
|
||||||
|
public static bool SendUserStatistics
|
||||||
|
{
|
||||||
|
get { return sendUserStatistics; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
sendUserStatistics = value;
|
||||||
|
GameMain.Config.Save("config.xml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static bool ShowUserStatisticsPrompt { get; private set; }
|
||||||
|
|
||||||
public GameSettings(string filePath)
|
public GameSettings(string filePath)
|
||||||
{
|
{
|
||||||
ContentPackage.LoadAll(ContentPackage.Folder);
|
ContentPackage.LoadAll(ContentPackage.Folder);
|
||||||
@@ -143,6 +184,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
VerboseLogging = doc.Root.GetAttributeBool("verboselogging", false);
|
VerboseLogging = doc.Root.GetAttributeBool("verboselogging", false);
|
||||||
SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", false);
|
SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", false);
|
||||||
|
if (doc.Root.Attribute("senduserstatistics") == null)
|
||||||
|
{
|
||||||
|
ShowUserStatisticsPrompt = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (doc == null)
|
if (doc == null)
|
||||||
{
|
{
|
||||||
@@ -210,18 +259,15 @@ namespace Barotrauma
|
|||||||
case "keymapping":
|
case "keymapping":
|
||||||
foreach (XAttribute attribute in subElement.Attributes())
|
foreach (XAttribute attribute in subElement.Attributes())
|
||||||
{
|
{
|
||||||
InputType inputType;
|
if (Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType))
|
||||||
if (Enum.TryParse(attribute.Name.ToString(), true, out inputType))
|
|
||||||
{
|
{
|
||||||
int mouseButton;
|
if (int.TryParse(attribute.Value.ToString(), out int mouseButton))
|
||||||
if (int.TryParse(attribute.Value.ToString(), out mouseButton))
|
|
||||||
{
|
{
|
||||||
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
|
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Keys key;
|
if (Enum.TryParse(attribute.Value.ToString(), true, out Keys key))
|
||||||
if (Enum.TryParse(attribute.Value.ToString(), true, out key))
|
|
||||||
{
|
{
|
||||||
keyMapping[(int)inputType] = new KeyOrMouse(key);
|
keyMapping[(int)inputType] = new KeyOrMouse(key);
|
||||||
}
|
}
|
||||||
@@ -238,6 +284,9 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case "player":
|
case "player":
|
||||||
defaultPlayerName = subElement.GetAttributeString("name", "");
|
defaultPlayerName = subElement.GetAttributeString("name", "");
|
||||||
|
characterHeadIndex = subElement.GetAttributeInt("headindex", Rand.Int(10));
|
||||||
|
characterGender = subElement.GetAttributeString("gender", Rand.Range(0.0f, 1.0f) < 0.5f ? "male" : "female")
|
||||||
|
.ToLowerInvariant() == "male" ? Gender.Male : Gender.Female;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,10 +308,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
case "contentpackage":
|
case "contentpackage":
|
||||||
string path = subElement.GetAttributeString("path", "");
|
string path = subElement.GetAttributeString("path", "");
|
||||||
|
|
||||||
|
|
||||||
SelectedContentPackage = ContentPackage.list.Find(cp => cp.Path == path);
|
SelectedContentPackage = ContentPackage.list.Find(cp => cp.Path == path);
|
||||||
|
|
||||||
if (SelectedContentPackage == null) SelectedContentPackage = new ContentPackage(path);
|
if (SelectedContentPackage == null) SelectedContentPackage = new ContentPackage(path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -287,7 +334,8 @@ namespace Barotrauma
|
|||||||
new XAttribute("soundvolume", soundVolume),
|
new XAttribute("soundvolume", soundVolume),
|
||||||
new XAttribute("verboselogging", VerboseLogging),
|
new XAttribute("verboselogging", VerboseLogging),
|
||||||
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
|
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
|
||||||
new XAttribute("enablesplashscreen", EnableSplashScreen));
|
new XAttribute("enablesplashscreen", EnableSplashScreen),
|
||||||
|
new XAttribute("senduserstatistics", sendUserStatistics));
|
||||||
|
|
||||||
if (WasGameUpdated)
|
if (WasGameUpdated)
|
||||||
{
|
{
|
||||||
@@ -344,8 +392,10 @@ namespace Barotrauma
|
|||||||
gameplay.Add(jobPreferences);
|
gameplay.Add(jobPreferences);
|
||||||
doc.Root.Add(gameplay);
|
doc.Root.Add(gameplay);
|
||||||
|
|
||||||
var playerElement = new XElement("player");
|
var playerElement = new XElement("player",
|
||||||
playerElement.Add(new XAttribute("name", defaultPlayerName ?? ""));
|
new XAttribute("name", defaultPlayerName ?? ""),
|
||||||
|
new XAttribute("headindex", characterHeadIndex),
|
||||||
|
new XAttribute("gender", characterGender));
|
||||||
doc.Root.Add(playerElement);
|
doc.Root.Add(playerElement);
|
||||||
|
|
||||||
doc.Save(filePath);
|
doc.Save(filePath);
|
||||||
|
|||||||
@@ -179,7 +179,6 @@ namespace Barotrauma.Items.Components
|
|||||||
return (picker != null);
|
return (picker != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool Combine(Item item)
|
public override bool Combine(Item item)
|
||||||
{
|
{
|
||||||
if (!containableItems.Any(x => x.MatchesItem(item))) return false;
|
if (!containableItems.Any(x => x.MatchesItem(item))) return false;
|
||||||
@@ -195,6 +194,42 @@ namespace Barotrauma.Items.Components
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetContainedItemPositions()
|
||||||
|
{
|
||||||
|
Vector2 simPos = item.SimPosition;
|
||||||
|
Vector2 displayPos = item.Position;
|
||||||
|
|
||||||
|
foreach (Item contained in Inventory.Items)
|
||||||
|
{
|
||||||
|
if (contained == null) continue;
|
||||||
|
|
||||||
|
if (contained.body != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
contained.body.FarseerBody.SetTransformIgnoreContacts(ref simPos, 0.0f);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError("SetTransformIgnoreContacts threw an exception in SetContainedItemPositions", e);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contained.Rect =
|
||||||
|
new Rectangle(
|
||||||
|
(int)(displayPos.X - contained.Rect.Width / 2.0f),
|
||||||
|
(int)(displayPos.Y + contained.Rect.Height / 2.0f),
|
||||||
|
contained.Rect.Width, contained.Rect.Height);
|
||||||
|
|
||||||
|
contained.Submarine = item.Submarine;
|
||||||
|
contained.CurrentHull = item.CurrentHull;
|
||||||
|
|
||||||
|
contained.SetContainedItemPositions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnMapLoaded()
|
public override void OnMapLoaded()
|
||||||
{
|
{
|
||||||
if (itemIds == null) return;
|
if (itemIds == null) return;
|
||||||
|
|||||||
@@ -99,7 +99,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||||
|
|
||||||
if (hull1 == null) return;
|
//check the hull if the item is movable
|
||||||
|
if (item.body != null) GetHull();
|
||||||
|
if (hull1 == null) return;
|
||||||
|
|
||||||
float powerFactor = currPowerConsumption <= 0.0f ? 1.0f : voltage;
|
float powerFactor = currPowerConsumption <= 0.0f ? 1.0f : voltage;
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,26 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnItemLoaded()
|
||||||
|
{
|
||||||
|
if (attack != null && attack.DamageRange <= 0.0f && item.body != null)
|
||||||
|
{
|
||||||
|
switch (item.body.BodyShape)
|
||||||
|
{
|
||||||
|
case PhysicsBody.Shape.Circle:
|
||||||
|
attack.DamageRange = item.body.radius;
|
||||||
|
break;
|
||||||
|
case PhysicsBody.Shape.Capsule:
|
||||||
|
attack.DamageRange = item.body.height / 2 + item.body.radius;
|
||||||
|
break;
|
||||||
|
case PhysicsBody.Shape.Rectangle:
|
||||||
|
attack.DamageRange = new Vector2(item.body.width / 2.0f, item.body.height / 2.0f).Length();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
attack.DamageRange = ConvertUnits.ToDisplayUnits(attack.DamageRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Use(float deltaTime, Character character = null)
|
public override bool Use(float deltaTime, Character character = null)
|
||||||
{
|
{
|
||||||
if (character != null && !characterUsable) return false;
|
if (character != null && !characterUsable) return false;
|
||||||
@@ -196,7 +216,6 @@ namespace Barotrauma.Items.Components
|
|||||||
if (OnProjectileCollision(fixture, normal))
|
if (OnProjectileCollision(fixture, normal))
|
||||||
{
|
{
|
||||||
hitSomething = true;
|
hitSomething = true;
|
||||||
//Character.Controlled.AnimController.Teleport(point - Character.Controlled.SimPosition, Vector2.Zero);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,8 +300,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Character character = null;
|
Character character = null;
|
||||||
if (attack != null)
|
if (attack != null)
|
||||||
{
|
{
|
||||||
var submarine = target.Body.UserData as Submarine;
|
if (target.Body.UserData is Submarine submarine)
|
||||||
if (submarine != null)
|
|
||||||
{
|
{
|
||||||
item.Move(-submarine.Position);
|
item.Move(-submarine.Position);
|
||||||
item.Submarine = submarine;
|
item.Submarine = submarine;
|
||||||
@@ -290,9 +308,8 @@ namespace Barotrauma.Items.Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Limb limb = target.Body.UserData as Limb;
|
|
||||||
Structure structure;
|
Structure structure;
|
||||||
if (limb != null)
|
if (target.Body.UserData is Limb limb)
|
||||||
{
|
{
|
||||||
attackResult = attack.DoDamageToLimb(User, limb, item.WorldPosition, 1.0f);
|
attackResult = attack.DoDamageToLimb(User, limb, item.WorldPosition, 1.0f);
|
||||||
if (limb.character != null)
|
if (limb.character != null)
|
||||||
@@ -350,13 +367,12 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
contained.SetTransform(item.SimPosition, contained.body.Rotation);
|
contained.SetTransform(item.SimPosition, contained.body.Rotation);
|
||||||
}
|
}
|
||||||
//contained.Condition = 0.0f; //Let the freaking .xml handle it jeez
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RemoveOnHit)
|
if (RemoveOnHit)
|
||||||
{
|
{
|
||||||
Item.Spawner.AddToRemoveQueue(item);
|
Entity.Spawner.AddToRemoveQueue(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Items.Components
|
||||||
|
{
|
||||||
|
class AdderComponent : ItemComponent
|
||||||
|
{
|
||||||
|
//an array to keep track of how long ago a signal was received on both inputs
|
||||||
|
protected float[] timeSinceReceived;
|
||||||
|
|
||||||
|
protected float[] receivedSignal;
|
||||||
|
|
||||||
|
|
||||||
|
//the output is sent if both inputs have received a signal within the timeframe
|
||||||
|
protected float timeFrame;
|
||||||
|
|
||||||
|
[InGameEditable, Serialize(0.0f, true)]
|
||||||
|
public float TimeFrame
|
||||||
|
{
|
||||||
|
get { return timeFrame; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
timeFrame = Math.Max(0.0f, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdderComponent(Item item, XElement element)
|
||||||
|
: base(item, element)
|
||||||
|
{
|
||||||
|
timeSinceReceived = new float[] { Math.Max(timeFrame * 2.0f, 0.1f), Math.Max(timeFrame * 2.0f, 0.1f) };
|
||||||
|
receivedSignal = new float[2];
|
||||||
|
IsActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float deltaTime, Camera cam)
|
||||||
|
{
|
||||||
|
bool sendOutput = true;
|
||||||
|
for (int i = 0; i < timeSinceReceived.Length; i++)
|
||||||
|
{
|
||||||
|
if (timeSinceReceived[i] > timeFrame) sendOutput = false;
|
||||||
|
timeSinceReceived[i] += deltaTime;
|
||||||
|
}
|
||||||
|
if (sendOutput)
|
||||||
|
{
|
||||||
|
item.SendSignal(0, (receivedSignal[0] + receivedSignal[1]).ToString(), "signal_out", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||||
|
{
|
||||||
|
switch (connection.Name)
|
||||||
|
{
|
||||||
|
case "signal_in1":
|
||||||
|
float.TryParse(signal, out receivedSignal[0]);
|
||||||
|
timeSinceReceived[0] = 0.0f;
|
||||||
|
break;
|
||||||
|
case "signal_in2":
|
||||||
|
float.TryParse(signal, out receivedSignal[1]);
|
||||||
|
timeSinceReceived[1] = 0.0f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,49 +10,51 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
const int SignalQueueSize = 500;
|
const int SignalQueueSize = 500;
|
||||||
|
|
||||||
//the output is sent if both inputs have received a signal within the timeframe
|
private Queue<Pair<string, float>> signalQueue;
|
||||||
private TimeSpan delay;
|
|
||||||
|
|
||||||
private Queue<Tuple<string, DateTime>> signalQueue;
|
|
||||||
|
|
||||||
[InGameEditable, Serialize(1.0f, true)]
|
[InGameEditable(MinValueFloat = 0.0f, MaxValueFloat = 60.0f), Serialize(1.0f, true)]
|
||||||
public float Delay
|
public float Delay
|
||||||
{
|
{
|
||||||
get { return (float)delay.TotalSeconds; }
|
get;
|
||||||
set
|
set;
|
||||||
{
|
|
||||||
float seconds = MathHelper.Clamp(value, 0.0f, 60.0f);
|
|
||||||
|
|
||||||
delay = new TimeSpan(0,0,0,0, (int)(seconds*1000.0f));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[InGameEditable(ToolTip = "Should the component discard previously received signals when a new one is received."), Serialize(false, true)]
|
||||||
|
public bool ResetWhenSignalReceived
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
public DelayComponent(Item item, XElement element)
|
public DelayComponent(Item item, XElement element)
|
||||||
: base (item, element)
|
: base (item, element)
|
||||||
{
|
{
|
||||||
signalQueue = new Queue<Tuple<string, DateTime>>();
|
signalQueue = new Queue<Pair<string, float>>();
|
||||||
|
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime, Camera cam)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
while (signalQueue.Any() && signalQueue.Peek().Item2 + delay <= DateTime.Now)
|
foreach (var val in signalQueue)
|
||||||
|
{
|
||||||
|
val.Second -= deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (signalQueue.Count > 0 && signalQueue.Peek().Second <= 0.0f)
|
||||||
{
|
{
|
||||||
var signalOut = signalQueue.Dequeue();
|
var signalOut = signalQueue.Dequeue();
|
||||||
|
item.SendSignal(0, signalOut.First, "signal_out", null);
|
||||||
item.SendSignal(0, signalOut.Item1, "signal_out", null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f)
|
||||||
{
|
{
|
||||||
switch (connection.Name)
|
switch (connection.Name)
|
||||||
{
|
{
|
||||||
case "signal_in":
|
case "signal_in":
|
||||||
if (signalQueue.Count >= SignalQueueSize) return;
|
if (signalQueue.Count >= SignalQueueSize) return;
|
||||||
|
if (ResetWhenSignalReceived) signalQueue.Clear();
|
||||||
signalQueue.Enqueue(new Tuple<string, DateTime>(signal, DateTime.Now));
|
signalQueue.Enqueue(Pair<string, float>.Create(signal, Delay));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,14 +49,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override void Update(float deltaTime, Camera cam)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
if (motionDetected)
|
string signalOut = motionDetected ? output : falseOutput;
|
||||||
{
|
|
||||||
item.SendSignal(1, output, "state_out", null);
|
if (!string.IsNullOrEmpty(signalOut)) item.SendSignal(1, signalOut, "state_out", null);
|
||||||
}
|
|
||||||
else if (!string.IsNullOrWhiteSpace(falseOutput))
|
|
||||||
{
|
|
||||||
item.SendSignal(1, falseOutput, "state_out", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTimer -= deltaTime;
|
updateTimer -= deltaTime;
|
||||||
if (updateTimer > 0.0f) return;
|
if (updateTimer > 0.0f) return;
|
||||||
|
|||||||
@@ -315,9 +315,9 @@ namespace Barotrauma
|
|||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
return (GameMain.DebugDraw) ? Name + "(ID: " + ID + ")" : Name;
|
return (GameMain.DebugDraw) ? Name + " (ID: " + ID + ")" : Name;
|
||||||
#elif SERVER
|
#elif SERVER
|
||||||
return Name + "(ID: " + ID + ")";
|
return Name + " (ID: " + ID + ")";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +602,7 @@ namespace Barotrauma
|
|||||||
foreach (Item item in ItemList) item.FindHull();
|
foreach (Item item in ItemList) item.FindHull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Hull FindHull()
|
public Hull FindHull()
|
||||||
{
|
{
|
||||||
if (parentInventory != null && parentInventory.Owner != null)
|
if (parentInventory != null && parentInventory.Owner != null)
|
||||||
{
|
{
|
||||||
@@ -648,39 +648,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SetContainedItemPositions()
|
public void SetContainedItemPositions()
|
||||||
{
|
{
|
||||||
if (ownInventory == null) return;
|
foreach (ItemComponent component in components)
|
||||||
|
|
||||||
Vector2 simPos = SimPosition;
|
|
||||||
Vector2 displayPos = Position;
|
|
||||||
|
|
||||||
foreach (Item contained in ownInventory.Items)
|
|
||||||
{
|
{
|
||||||
if (contained == null) continue;
|
(component as ItemContainer)?.SetContainedItemPositions();
|
||||||
|
|
||||||
if (contained.body != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
contained.body.FarseerBody.SetTransformIgnoreContacts(ref simPos, 0.0f);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
DebugConsole.ThrowError("SetTransformIgnoreContacts threw an exception in SetContainedItemPositions", e);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contained.Rect =
|
|
||||||
new Rectangle(
|
|
||||||
(int)(displayPos.X - contained.Rect.Width / 2.0f),
|
|
||||||
(int)(displayPos.Y + contained.Rect.Height / 2.0f),
|
|
||||||
contained.Rect.Width, contained.Rect.Height);
|
|
||||||
|
|
||||||
contained.Submarine = Submarine;
|
|
||||||
contained.CurrentHull = CurrentHull;
|
|
||||||
|
|
||||||
contained.SetContainedItemPositions();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,7 +774,7 @@ namespace Barotrauma
|
|||||||
private bool IsInWater()
|
private bool IsInWater()
|
||||||
{
|
{
|
||||||
if (CurrentHull == null) return true;
|
if (CurrentHull == null) return true;
|
||||||
|
|
||||||
float surfaceY = CurrentHull.Surface;
|
float surfaceY = CurrentHull.Surface;
|
||||||
|
|
||||||
return CurrentHull.WaterVolume > 0.0f && Position.Y < surfaceY;
|
return CurrentHull.WaterVolume > 0.0f && Position.Y < surfaceY;
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace Barotrauma
|
|||||||
if (distSqr > displayRangeSqr) continue;
|
if (distSqr > displayRangeSqr) continue;
|
||||||
|
|
||||||
//ignore reactors (don't want to blow them up)
|
//ignore reactors (don't want to blow them up)
|
||||||
if (item.GetComponent<Reactor>() == null) continue;
|
if (item.GetComponent<Reactor>() != null) continue;
|
||||||
|
|
||||||
float distFactor = 1.0f - (float)Math.Sqrt(distSqr) / displayRange;
|
float distFactor = 1.0f - (float)Math.Sqrt(distSqr) / displayRange;
|
||||||
|
|
||||||
|
|||||||
@@ -664,19 +664,20 @@ namespace Barotrauma
|
|||||||
float damageAmount = 0.0f;
|
float damageAmount = 0.0f;
|
||||||
for (int i = 0; i < SectionCount; i++)
|
for (int i = 0; i < SectionCount; i++)
|
||||||
{
|
{
|
||||||
if (Vector2.DistanceSquared(SectionPosition(i, true), worldPosition) <= attack.DamageRange * attack.DamageRange)
|
Rectangle sectionRect = sections[i].rect;
|
||||||
|
sectionRect.Y -= sections[i].rect.Height;
|
||||||
|
if (MathUtils.CircleIntersectsRectangle(transformedPos, attack.DamageRange, sectionRect))
|
||||||
{
|
{
|
||||||
damageAmount = attack.GetStructureDamage(deltaTime);
|
damageAmount = attack.GetStructureDamage(deltaTime);
|
||||||
AddDamage(i, damageAmount, attacker);
|
AddDamage(i, damageAmount, attacker);
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
|
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (playSound)// && !SectionBodyDisabled(i))
|
if (playSound)
|
||||||
{
|
{
|
||||||
string damageSoundType = (attack.DamageType == DamageType.Blunt) ? "StructureBlunt" : "StructureSlash";
|
string damageSoundType = (attack.DamageType == DamageType.Blunt) ? "StructureBlunt" : "StructureSlash";
|
||||||
SoundPlayer.PlayDamageSound(damageSoundType, damageAmount, worldPosition, tags: Tags);
|
SoundPlayer.PlayDamageSound(damageSoundType, damageAmount, worldPosition, tags: Tags);
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ namespace Barotrauma
|
|||||||
return wayPoints[Rand.Int(wayPoints.Count, (useSyncedRand ? Rand.RandSync.Server : Rand.RandSync.Unsynced))];
|
return wayPoints[Rand.Int(wayPoints.Count, (useSyncedRand ? Rand.RandSync.Server : Rand.RandSync.Unsynced))];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew, Submarine submarine, bool tryAssignWayPoint = true)
|
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew, Submarine submarine)
|
||||||
{
|
{
|
||||||
List<WayPoint> subWayPoints = WayPointList.FindAll(wp => wp.Submarine == submarine);
|
List<WayPoint> subWayPoints = WayPointList.FindAll(wp => wp.Submarine == submarine);
|
||||||
|
|
||||||
@@ -524,29 +524,24 @@ namespace Barotrauma
|
|||||||
assignedWayPoints[i] = wp;
|
assignedWayPoints[i] = wp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assignedWayPoints[i] != null) continue;
|
if (assignedWayPoints[i] != null) continue;
|
||||||
|
|
||||||
if (tryAssignWayPoint)
|
//try to assign a spawnpoint that isn't meant for any specific job
|
||||||
|
var nonJobSpecificPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human && wp.assignedJob == null);
|
||||||
|
if (nonJobSpecificPoints.Any())
|
||||||
{
|
{
|
||||||
//try to assign a spawnpoint that isn't meant for any specific job
|
assignedWayPoints[i] = nonJobSpecificPoints[Rand.Int(nonJobSpecificPoints.Count, Rand.RandSync.Server)];
|
||||||
var nonJobSpecificPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human && wp.assignedJob == null);
|
|
||||||
|
|
||||||
if (nonJobSpecificPoints.Any())
|
|
||||||
{
|
|
||||||
assignedWayPoints[i] = nonJobSpecificPoints[Rand.Int(nonJobSpecificPoints.Count, Rand.RandSync.Server)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assignedWayPoints[i] != null) continue;
|
if (assignedWayPoints[i] != null) continue;
|
||||||
|
|
||||||
//everything else failed -> just give a random spawnpoint
|
//everything else failed -> just give a random spawnpoint inside the sub
|
||||||
assignedWayPoints[i] = GetRandom(SpawnType.Human);
|
assignedWayPoints[i] = GetRandom(SpawnType.Human, null, submarine, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < assignedWayPoints.Length; i++ )
|
for (int i = 0; i < assignedWayPoints.Length; i++)
|
||||||
{
|
{
|
||||||
if (assignedWayPoints[i]==null)
|
if (assignedWayPoints[i] == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Couldn't find a waypoint for " + crew[i].Name + "!");
|
DebugConsole.ThrowError("Couldn't find a waypoint for " + crew[i].Name + "!");
|
||||||
assignedWayPoints[i] = WayPointList[0];
|
assignedWayPoints[i] = WayPointList[0];
|
||||||
|
|||||||
@@ -29,10 +29,20 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public byte TeamID = 0;
|
public byte TeamID = 0;
|
||||||
|
|
||||||
public Character Character;
|
private Character character;
|
||||||
|
public Character Character
|
||||||
|
{
|
||||||
|
get { return character; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
character = value;
|
||||||
|
if (character != null) HasSpawned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
public CharacterInfo CharacterInfo;
|
public CharacterInfo CharacterInfo;
|
||||||
public NetConnection Connection { get; set; }
|
public NetConnection Connection { get; set; }
|
||||||
public bool InGame;
|
public bool InGame;
|
||||||
|
public bool HasSpawned; //has the client spawned as a character during the current round
|
||||||
|
|
||||||
public UInt16 LastRecvGeneralUpdate = 0;
|
public UInt16 LastRecvGeneralUpdate = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,8 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.NetLobbyScreen.RandomizeSettings();
|
GameMain.NetLobbyScreen.RandomizeSettings();
|
||||||
started = true;
|
started = true;
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("GameServer:Start");
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,11 +780,21 @@ namespace Barotrauma.Networking
|
|||||||
case ClientPermissions.Ban:
|
case ClientPermissions.Ban:
|
||||||
string bannedName = inc.ReadString().ToLowerInvariant();
|
string bannedName = inc.ReadString().ToLowerInvariant();
|
||||||
string banReason = inc.ReadString();
|
string banReason = inc.ReadString();
|
||||||
|
bool range = inc.ReadBoolean();
|
||||||
|
double durationSeconds = inc.ReadDouble();
|
||||||
|
|
||||||
var bannedClient = connectedClients.Find(cl => cl != sender && cl.Name.ToLowerInvariant() == bannedName);
|
var bannedClient = connectedClients.Find(cl => cl != sender && cl.Name.ToLowerInvariant() == bannedName);
|
||||||
if (bannedClient != null)
|
if (bannedClient != null)
|
||||||
{
|
{
|
||||||
Log("Client \"" + sender.Name + "\" banned \"" + bannedClient.Name + "\".", ServerLog.MessageType.ServerMessage);
|
Log("Client \"" + sender.Name + "\" banned \"" + bannedClient.Name + "\".", ServerLog.MessageType.ServerMessage);
|
||||||
BanClient(bannedClient, string.IsNullOrEmpty(banReason) ? "Banned by " + sender.Name : banReason, false);
|
if (durationSeconds > 0)
|
||||||
|
{
|
||||||
|
BanClient(bannedClient, string.IsNullOrEmpty(banReason) ? "Banned by " + sender.Name : banReason, range, TimeSpan.FromSeconds(durationSeconds));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BanClient(bannedClient, string.IsNullOrEmpty(banReason) ? "Banned by " + sender.Name : banReason, range);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ClientPermissions.EndRound:
|
case ClientPermissions.EndRound:
|
||||||
@@ -993,7 +1005,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
outmsg.WriteRangedInteger(0, 2, (int)TraitorsEnabled);
|
outmsg.WriteRangedInteger(0, 2, (int)TraitorsEnabled);
|
||||||
|
|
||||||
outmsg.WriteRangedInteger(0, Mission.MissionTypes.Count - 1, (GameMain.NetLobbyScreen.MissionTypeIndex));
|
outmsg.WriteRangedInteger(0, MissionPrefab.MissionTypes.Count - 1, (GameMain.NetLobbyScreen.MissionTypeIndex));
|
||||||
|
|
||||||
outmsg.Write((byte)GameMain.NetLobbyScreen.SelectedModeIndex);
|
outmsg.Write((byte)GameMain.NetLobbyScreen.SelectedModeIndex);
|
||||||
outmsg.Write(GameMain.NetLobbyScreen.LevelSeed);
|
outmsg.Write(GameMain.NetLobbyScreen.LevelSeed);
|
||||||
@@ -1213,7 +1225,7 @@ namespace Barotrauma.Networking
|
|||||||
//don't instantiate a new gamesession if we're playing a campaign
|
//don't instantiate a new gamesession if we're playing a campaign
|
||||||
if (campaign == null || GameMain.GameSession == null)
|
if (campaign == null || GameMain.GameSession == null)
|
||||||
{
|
{
|
||||||
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
|
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, MissionPrefab.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.GameSession.GameMode.Mission != null &&
|
if (GameMain.GameSession.GameMode.Mission != null &&
|
||||||
@@ -1341,11 +1353,12 @@ namespace Barotrauma.Networking
|
|||||||
List<Character> characters = new List<Character>();
|
List<Character> characters = new List<Character>();
|
||||||
foreach (Client client in ConnectedClients)
|
foreach (Client client in ConnectedClients)
|
||||||
{
|
{
|
||||||
if (client.Character != null)
|
if (client.Character != null) characters.Add(client.Character);
|
||||||
characters.Add(client.Character);
|
|
||||||
}
|
}
|
||||||
var max = (int)Math.Round(characters.Count * 0.2f, 1);
|
if (Character != null) characters.Add(Character);
|
||||||
var traitorCount = Math.Max(1, TraitorsEnabled == YesNoMaybe.Maybe ? Rand.Int(max) + 1 : max);
|
|
||||||
|
int max = Math.Max(TraitorUseRatio ? (int)Math.Round(characters.Count * TraitorRatio, 1) : 1, 1);
|
||||||
|
int traitorCount = Rand.Int(max + 1);
|
||||||
TraitorManager = new TraitorManager(this, traitorCount);
|
TraitorManager = new TraitorManager(this, traitorCount);
|
||||||
|
|
||||||
if (TraitorManager.TraitorList.Count > 0)
|
if (TraitorManager.TraitorList.Count > 0)
|
||||||
@@ -1357,6 +1370,8 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("Traitors:" + (TraitorManager == null ? "Disabled" : "Enabled"));
|
||||||
|
|
||||||
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients);
|
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients);
|
||||||
|
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
@@ -1402,6 +1417,8 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash);
|
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash);
|
||||||
|
|
||||||
msg.Write(selectedMode.Name);
|
msg.Write(selectedMode.Name);
|
||||||
|
msg.Write((short)(GameMain.GameSession.GameMode?.Mission == null ?
|
||||||
|
-1 : MissionPrefab.List.IndexOf(GameMain.GameSession.GameMode.Mission.Prefab)));
|
||||||
|
|
||||||
MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||||
|
|
||||||
@@ -1495,6 +1512,7 @@ namespace Barotrauma.Networking
|
|||||||
foreach (Client client in connectedClients)
|
foreach (Client client in connectedClients)
|
||||||
{
|
{
|
||||||
client.Character = null;
|
client.Character = null;
|
||||||
|
client.HasSpawned = false;
|
||||||
client.InGame = false;
|
client.InGame = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1614,6 +1632,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
client.Character = null;
|
client.Character = null;
|
||||||
|
client.HasSpawned = false;
|
||||||
client.InGame = false;
|
client.InGame = false;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(msg)) msg = client.Name + " has left the server";
|
if (string.IsNullOrWhiteSpace(msg)) msg = client.Name + " has left the server";
|
||||||
@@ -2063,9 +2082,17 @@ namespace Barotrauma.Networking
|
|||||||
if (jobPrefab != null) jobPreferences.Add(jobPrefab);
|
if (jobPrefab != null) jobPreferences.Add(jobPrefab);
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.CharacterInfo = new CharacterInfo(Character.HumanConfigFile, sender.Name, gender);
|
sender.CharacterInfo = new CharacterInfo(Character.HumanConfigFile, sender.Name, gender)
|
||||||
sender.CharacterInfo.HeadSpriteId = headSpriteId;
|
{
|
||||||
sender.JobPreferences = jobPreferences;
|
HeadSpriteId = headSpriteId
|
||||||
|
};
|
||||||
|
|
||||||
|
//if the client didn't provide job preferences, we'll use the preferences that are randomly assigned in the Client constructor
|
||||||
|
Debug.Assert(sender.JobPreferences.Count > 0);
|
||||||
|
if (jobPreferences.Count > 0)
|
||||||
|
{
|
||||||
|
sender.JobPreferences = jobPreferences;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AssignJobs(List<Client> unassigned, bool assignHost)
|
public void AssignJobs(List<Client> unassigned, bool assignHost)
|
||||||
@@ -2110,6 +2137,7 @@ namespace Barotrauma.Networking
|
|||||||
//if any of the players has chosen a job that is Always Allowed, give them that job
|
//if any of the players has chosen a job that is Always Allowed, give them that job
|
||||||
for (int i = unassigned.Count - 1; i >= 0; i--)
|
for (int i = unassigned.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
|
if (unassigned[i].JobPreferences.Count == 0) continue;
|
||||||
if (!unassigned[i].JobPreferences[0].AllowAlways) continue;
|
if (!unassigned[i].JobPreferences[0].AllowAlways) continue;
|
||||||
unassigned[i].AssignedJob = unassigned[i].JobPreferences[0];
|
unassigned[i].AssignedJob = unassigned[i].JobPreferences[0];
|
||||||
unassigned.RemoveAt(i);
|
unassigned.RemoveAt(i);
|
||||||
@@ -2138,47 +2166,49 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//find a suitable job for the rest of the players
|
//attempt to give the clients a job they have in their job preferences
|
||||||
foreach (Client c in unassigned)
|
for (int i = unassigned.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
foreach (JobPrefab preferredJob in c.JobPreferences)
|
foreach (JobPrefab preferredJob in unassigned[i].JobPreferences)
|
||||||
{
|
{
|
||||||
//the maximum number of players that can have this job hasn't been reached yet
|
//the maximum number of players that can have this job hasn't been reached yet
|
||||||
// -> assign it to the client
|
// -> assign it to the client
|
||||||
if (assignedClientCount[preferredJob] < preferredJob.MaxNumber && c.Karma >= preferredJob.MinKarma)
|
if (assignedClientCount[preferredJob] < preferredJob.MaxNumber && unassigned[i].Karma >= preferredJob.MinKarma)
|
||||||
{
|
{
|
||||||
c.AssignedJob = preferredJob;
|
unassigned[i].AssignedJob = preferredJob;
|
||||||
assignedClientCount[preferredJob]++;
|
assignedClientCount[preferredJob]++;
|
||||||
|
unassigned.RemoveAt(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//none of the jobs the client prefers are available anymore
|
}
|
||||||
else if (preferredJob == c.JobPreferences.Last())
|
}
|
||||||
{
|
|
||||||
//find all jobs that are still available
|
|
||||||
var remainingJobs = JobPrefab.List.FindAll(jp => assignedClientCount[preferredJob] < jp.MaxNumber && c.Karma >= jp.MinKarma);
|
|
||||||
|
|
||||||
//all jobs taken, give a random job
|
//give random jobs to rest of the clients
|
||||||
if (remainingJobs.Count == 0)
|
foreach (Client c in unassigned)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Failed to assign a suitable job for \"" + c.Name + "\" (all jobs already have the maximum numbers of players). Assigning a random job...");
|
//find all jobs that are still available
|
||||||
int jobIndex = Rand.Range(0,JobPrefab.List.Count);
|
var remainingJobs = JobPrefab.List.FindAll(jp => assignedClientCount[jp] < jp.MaxNumber && c.Karma >= jp.MinKarma);
|
||||||
int skips = 0;
|
|
||||||
while (c.Karma < JobPrefab.List[jobIndex].MinKarma)
|
//all jobs taken, give a random job
|
||||||
{
|
if (remainingJobs.Count == 0)
|
||||||
jobIndex++;
|
{
|
||||||
skips++;
|
DebugConsole.ThrowError("Failed to assign a suitable job for \"" + c.Name + "\" (all jobs already have the maximum numbers of players). Assigning a random job...");
|
||||||
if (jobIndex >= JobPrefab.List.Count) jobIndex -= JobPrefab.List.Count;
|
int jobIndex = Rand.Range(0, JobPrefab.List.Count);
|
||||||
if (skips >= JobPrefab.List.Count) break;
|
int skips = 0;
|
||||||
}
|
while (c.Karma < JobPrefab.List[jobIndex].MinKarma)
|
||||||
c.AssignedJob = JobPrefab.List[jobIndex];
|
{
|
||||||
assignedClientCount[c.AssignedJob]++;
|
jobIndex++;
|
||||||
}
|
skips++;
|
||||||
else //some jobs still left, choose one of them by random
|
if (jobIndex >= JobPrefab.List.Count) jobIndex -= JobPrefab.List.Count;
|
||||||
{
|
if (skips >= JobPrefab.List.Count) break;
|
||||||
c.AssignedJob = remainingJobs[Rand.Range(0, remainingJobs.Count)];
|
|
||||||
assignedClientCount[c.AssignedJob]++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
c.AssignedJob = JobPrefab.List[jobIndex];
|
||||||
|
assignedClientCount[c.AssignedJob]++;
|
||||||
|
}
|
||||||
|
else //some jobs still left, choose one of them by random
|
||||||
|
{
|
||||||
|
c.AssignedJob = remainingJobs[Rand.Range(0, remainingJobs.Count)];
|
||||||
|
assignedClientCount[c.AssignedJob]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2236,7 +2266,11 @@ namespace Barotrauma.Networking
|
|||||||
Log("Shutting down the server...", ServerLog.MessageType.ServerMessage);
|
Log("Shutting down the server...", ServerLog.MessageType.ServerMessage);
|
||||||
log.Save();
|
log.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GameSettings.SendUserStatistics)
|
||||||
|
{
|
||||||
|
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("GameServer:ShutDown");
|
||||||
|
}
|
||||||
server.Shutdown("The server has been shut down");
|
server.Shutdown("The server has been shut down");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,6 +254,12 @@ namespace Barotrauma.Networking
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<string> AllowedRandomMissionTypes
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
[Serialize(60f, true)]
|
[Serialize(60f, true)]
|
||||||
public float AutoBanTime
|
public float AutoBanTime
|
||||||
{
|
{
|
||||||
@@ -287,6 +293,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
doc.Root.SetAttributeValue("TraitorsEnabled", TraitorsEnabled.ToString());
|
doc.Root.SetAttributeValue("TraitorsEnabled", TraitorsEnabled.ToString());
|
||||||
|
|
||||||
|
doc.Root.SetAttributeValue("AllowedRandomMissionTypes", string.Join(",", AllowedRandomMissionTypes));
|
||||||
|
|
||||||
#if SERVER
|
#if SERVER
|
||||||
doc.Root.SetAttributeValue("password", password);
|
doc.Root.SetAttributeValue("password", password);
|
||||||
#endif
|
#endif
|
||||||
@@ -334,18 +342,22 @@ namespace Barotrauma.Networking
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
subSelectionMode = SelectionMode.Manual;
|
subSelectionMode = SelectionMode.Manual;
|
||||||
Enum.TryParse<SelectionMode>(doc.Root.GetAttributeString("SubSelection", "Manual"), out subSelectionMode);
|
Enum.TryParse(doc.Root.GetAttributeString("SubSelection", "Manual"), out subSelectionMode);
|
||||||
Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote;
|
Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote;
|
||||||
|
|
||||||
modeSelectionMode = SelectionMode.Manual;
|
modeSelectionMode = SelectionMode.Manual;
|
||||||
Enum.TryParse<SelectionMode>(doc.Root.GetAttributeString("ModeSelection", "Manual"), out modeSelectionMode);
|
Enum.TryParse(doc.Root.GetAttributeString("ModeSelection", "Manual"), out modeSelectionMode);
|
||||||
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
|
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
|
||||||
|
|
||||||
var traitorsEnabled = TraitorsEnabled;
|
var traitorsEnabled = TraitorsEnabled;
|
||||||
Enum.TryParse<YesNoMaybe>(doc.Root.GetAttributeString("TraitorsEnabled", "No"), out traitorsEnabled);
|
Enum.TryParse(doc.Root.GetAttributeString("TraitorsEnabled", "No"), out traitorsEnabled);
|
||||||
TraitorsEnabled = traitorsEnabled;
|
TraitorsEnabled = traitorsEnabled;
|
||||||
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
|
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
|
||||||
|
|
||||||
|
AllowedRandomMissionTypes = doc.Root.GetAttributeStringArray(
|
||||||
|
"AllowedRandomMissionTypes",
|
||||||
|
MissionPrefab.MissionTypes.ToArray()).ToList();
|
||||||
|
|
||||||
if (GameMain.NetLobbyScreen != null
|
if (GameMain.NetLobbyScreen != null
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
&& GameMain.NetLobbyScreen.ServerMessage != null
|
&& GameMain.NetLobbyScreen.ServerMessage != null
|
||||||
|
|||||||
@@ -204,8 +204,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
respawnShuttle.Velocity = Vector2.Zero;
|
respawnShuttle.Velocity = Vector2.Zero;
|
||||||
|
|
||||||
shuttleSteering.AutoPilot = false;
|
if (shuttleSteering != null)
|
||||||
shuttleSteering.MaintainPos = false;
|
{
|
||||||
|
shuttleSteering.AutoPilot = false;
|
||||||
|
shuttleSteering.MaintainPos = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateTransporting(float deltaTime)
|
private void UpdateTransporting(float deltaTime)
|
||||||
@@ -264,7 +267,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.TopBarrier);
|
respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.TopBarrier);
|
||||||
|
|
||||||
shuttleSteering.SetDestinationLevelStart();
|
if (shuttleSteering != null)
|
||||||
|
{
|
||||||
|
shuttleSteering.SetDestinationLevelStart();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Door door in shuttleDoors)
|
foreach (Door door in shuttleDoors)
|
||||||
{
|
{
|
||||||
@@ -284,7 +290,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (!CoroutineManager.IsCoroutineRunning("forcepos"))
|
if (!CoroutineManager.IsCoroutineRunning("forcepos"))
|
||||||
{
|
{
|
||||||
if (shuttleSteering.SteeringPath != null && shuttleSteering.SteeringPath.Finished
|
if ((shuttleSteering?.SteeringPath != null && shuttleSteering.SteeringPath.Finished)
|
||||||
|| (respawnShuttle.WorldPosition.Y + respawnShuttle.Borders.Y > Level.Loaded.StartPosition.Y - Level.ShaftHeight &&
|
|| (respawnShuttle.WorldPosition.Y + respawnShuttle.Borders.Y > Level.Loaded.StartPosition.Y - Level.ShaftHeight &&
|
||||||
Math.Abs(Level.Loaded.StartPosition.X - respawnShuttle.WorldPosition.X) < 1000.0f))
|
Math.Abs(Level.Loaded.StartPosition.X - respawnShuttle.WorldPosition.X) < 1000.0f))
|
||||||
{
|
{
|
||||||
@@ -323,7 +329,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
ResetShuttle();
|
ResetShuttle();
|
||||||
|
|
||||||
shuttleSteering.TargetVelocity = Vector2.Zero;
|
if (shuttleSteering != null)
|
||||||
|
{
|
||||||
|
shuttleSteering.TargetVelocity = Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
GameServer.Log("Dispatching the respawn shuttle.", ServerLog.MessageType.Spawning);
|
GameServer.Log("Dispatching the respawn shuttle.", ServerLog.MessageType.Spawning);
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string fileName = serverName + "_" + DateTime.Now.ToShortDateString() + "_" + DateTime.Now.ToShortTimeString() + ".txt";
|
string fileName = serverName + "_" + DateTime.Now.ToString("yyyy-MM-dd_HH:mm") + ".txt";
|
||||||
|
|
||||||
var invalidChars = Path.GetInvalidFileNameChars();
|
var invalidChars = Path.GetInvalidFileNameChars();
|
||||||
foreach (char invalidChar in invalidChars)
|
foreach (char invalidChar in invalidChars)
|
||||||
|
|||||||
@@ -111,11 +111,11 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case VoteType.EndRound:
|
case VoteType.EndRound:
|
||||||
if (sender.Character == null) return;
|
if (!sender.HasSpawned) return;
|
||||||
sender.SetVote(voteType, inc.ReadBoolean());
|
sender.SetVote(voteType, inc.ReadBoolean());
|
||||||
|
|
||||||
GameMain.NetworkMember.EndVoteCount = GameMain.Server.ConnectedClients.Count(c => c.Character != null && c.GetVote<bool>(VoteType.EndRound));
|
GameMain.NetworkMember.EndVoteCount = GameMain.Server.ConnectedClients.Count(c => c.HasSpawned && c.GetVote<bool>(VoteType.EndRound));
|
||||||
GameMain.NetworkMember.EndVoteMax = GameMain.Server.ConnectedClients.Count(c => c.Character != null);
|
GameMain.NetworkMember.EndVoteMax = GameMain.Server.ConnectedClients.Count(c => c.HasSpawned);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case VoteType.Kick:
|
case VoteType.Kick:
|
||||||
|
|||||||
@@ -1,3 +1,64 @@
|
|||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.8.1.5
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Added the option to automatically send crash reports and anonymous usage statistics to the developers.
|
||||||
|
The usage statistics include information such as the selected game mode, selected submarine, causes of
|
||||||
|
death and mission outcomes. When the game is started for the first time, a message box prompts you to
|
||||||
|
select whether you want to send the information or not.
|
||||||
|
- Fixed a bug that caused clients to get desynced when purchasing items in the multiplayer campaign.
|
||||||
|
- Added a signal component that adds the received signals together.
|
||||||
|
- Devices outside the submarine can be rewired in-game (not just in the sub editor).
|
||||||
|
- Fixed a crash caused by vision obstruction logic.
|
||||||
|
- Fixed clients being unable to give non-permanent or range bans.
|
||||||
|
- Clients are allowed to vote to end the round if they have spawned at some point during the round,
|
||||||
|
even if the character they controlled doesn't exist anymore.
|
||||||
|
- Dedicated servers can give clients the permission to use console commands that aren't available in
|
||||||
|
for dedicated server (e.g. los, lights, control)
|
||||||
|
- Banip, banid & kickid commands can be used by clients now (if they have the permission to do so).
|
||||||
|
- Spawnitem [item] inventory, ragdoll and kill commands target the character of the client using
|
||||||
|
the command instead of the host's character.
|
||||||
|
- Spawnitem can be used to spawn items in the inventory of a specific character.
|
||||||
|
- Fixed explosions with an EMP value only damaging reactors (when they should only ignore reactors).
|
||||||
|
- Fire can only explode oxygen tanks that are >25% full (otherwise the condition of the tank just drops
|
||||||
|
to 0). Prevents infinite explosions when an oxygen generator is on fire with oxygen tanks inside.
|
||||||
|
- Fixed projectiles with a damage range of 0 not applying their structuredamage value to structures.
|
||||||
|
- Items with a physics body can be used as pumps, so now it's possible to make portable items that remove
|
||||||
|
water from inside the sub.
|
||||||
|
- Fixed traitor ratio setting being ignored and the minimum number of traitors being 2.
|
||||||
|
- Fixed crashes caused by custom characters with no AI configuration.
|
||||||
|
- Character head and gender settings are saved.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.8.1.4
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Fixed clients getting assigned random jobs regardless of job preferences.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.8.1.3
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Fixed server-side crashes during job assignment if a client hasn't sent any job preferences.
|
||||||
|
- Fixed crashing if the selected respawn shuttle doesn't have a navigation terminal or any other item
|
||||||
|
with a Steering component.
|
||||||
|
- Fixed InWater status effects triggering when an item is fabricated, causing issues such as
|
||||||
|
water-sensitive items to breaking/exploding immediately after being fabricated.
|
||||||
|
- Fixed motion sensors sending out signals even if the output is set to nothing.
|
||||||
|
- Fixed crashing when a round starts if the sub has been saved while a fabricator was running.
|
||||||
|
- Fixed explosives not detonating inside railgun shells.
|
||||||
|
- Fixed characters spawning inside the respawn shuttle if no suitable spawnpoint is found inside the
|
||||||
|
main submarine.
|
||||||
|
- Fixed a timing bug in the dedicated server which prevented clients from ever timing out, AI characters
|
||||||
|
from fixing leaks and reactor usage from being logged.
|
||||||
|
- Changed the format of the server log filenames to make them more easily sortable.
|
||||||
|
- Increased assistant's skill levels.
|
||||||
|
- Added oxygenite tanks.
|
||||||
|
- Added a rearward facing variant of railgun controller.
|
||||||
|
- Added railgun loader variants with 1 shell capacity.
|
||||||
|
- Added railgun shell rack.
|
||||||
|
- Decreased the skill level requirements for fixing docking ports.
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.8.1.2
|
v0.8.1.2
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user