Merge branch 'master' of https://github.com/Regalis11/Barotrauma
Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs
This commit is contained in:
@@ -15,6 +15,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
protected float soundTimer;
|
protected float soundTimer;
|
||||||
protected float soundInterval;
|
protected float soundInterval;
|
||||||
|
protected float nameTimer;
|
||||||
|
protected bool nameVisible;
|
||||||
|
|
||||||
private List<CharacterSound> sounds;
|
private List<CharacterSound> sounds;
|
||||||
|
|
||||||
@@ -202,6 +204,34 @@ namespace Barotrauma
|
|||||||
if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null;
|
if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||||
|
{
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
nameTimer -= deltaTime;
|
||||||
|
if (nameTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
if (controlled == null)
|
||||||
|
{
|
||||||
|
nameVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the character is not in the camera view, the name can't be visible and we can avoid the expensive visibility checks
|
||||||
|
else if (WorldPosition.X < cam.WorldView.X || WorldPosition.X > cam.WorldView.Right ||
|
||||||
|
WorldPosition.Y > cam.WorldView.Y || WorldPosition.Y < cam.WorldView.Y - cam.WorldView.Height)
|
||||||
|
{
|
||||||
|
nameVisible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Ideally it shouldn't send the character entirely if we can't see them but /shrug, this isn't the most hacker-proof game atm
|
||||||
|
nameVisible = controlled.CanSeeCharacter(this);
|
||||||
|
}
|
||||||
|
nameTimer = Rand.Range(0.5f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void AddAllToGUIUpdateList()
|
public static void AddAllToGUIUpdateList()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < CharacterList.Count; i++)
|
for (int i = 0; i < CharacterList.Count; i++)
|
||||||
@@ -240,48 +270,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (aiTarget != null) aiTarget.Draw(spriteBatch);
|
if (aiTarget != null) aiTarget.Draw(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (memPos != null && memPos.Count > 0 && controlled == this)
|
|
||||||
{
|
|
||||||
PosInfo serverPos = memPos.Last();
|
|
||||||
Vector2 remoteVec = ConvertUnits.ToDisplayUnits(serverPos.Position);
|
|
||||||
if (Submarine != null)
|
|
||||||
{
|
|
||||||
remoteVec += Submarine.DrawPosition;
|
|
||||||
}
|
|
||||||
remoteVec.Y = -remoteVec.Y;
|
|
||||||
|
|
||||||
PosInfo localPos = memLocalPos.Find(m => m.ID == serverPos.ID);
|
|
||||||
int mpind = memLocalPos.FindIndex(lp => lp.ID == localPos.ID);
|
|
||||||
PosInfo localPos1 = mpind > 0 ? memLocalPos[mpind - 1] : null;
|
|
||||||
PosInfo localPos2 = mpind < memLocalPos.Count-1 ? memLocalPos[mpind + 1] : null;
|
|
||||||
|
|
||||||
Vector2 localVec = ConvertUnits.ToDisplayUnits(localPos.Position);
|
|
||||||
Vector2 localVec1 = localPos1 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos1).Position) : Vector2.Zero;
|
|
||||||
Vector2 localVec2 = localPos2 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos2).Position) : Vector2.Zero;
|
|
||||||
if (Submarine != null)
|
|
||||||
{
|
|
||||||
localVec += Submarine.DrawPosition;
|
|
||||||
localVec1 += Submarine.DrawPosition;
|
|
||||||
localVec2 += Submarine.DrawPosition;
|
|
||||||
}
|
|
||||||
localVec.Y = -localVec.Y;
|
|
||||||
localVec1.Y = -localVec1.Y;
|
|
||||||
localVec2.Y = -localVec2.Y;
|
|
||||||
|
|
||||||
//GUI.DrawLine(spriteBatch, remoteVec, localVec, Color.Yellow, 0, 10);
|
|
||||||
if (localPos1 != null) GUI.DrawLine(spriteBatch, remoteVec, localVec1, Color.Lime, 0, 2);
|
|
||||||
if (localPos2 != null) GUI.DrawLine(spriteBatch, remoteVec + Vector2.One, localVec2 + Vector2.One, Color.Red, 0, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 mouseDrawPos = CursorWorldPosition;
|
|
||||||
mouseDrawPos.Y = -mouseDrawPos.Y;
|
|
||||||
GUI.DrawLine(spriteBatch, mouseDrawPos - new Vector2(0, 5), mouseDrawPos + new Vector2(0, 5), Color.Red, 0, 10);
|
|
||||||
|
|
||||||
Vector2 closestItemPos = closestItem != null ? closestItem.DrawPosition : Vector2.Zero;
|
|
||||||
closestItemPos.Y = -closestItemPos.Y;
|
|
||||||
GUI.DrawLine(spriteBatch, closestItemPos - new Vector2(0, 5), closestItemPos + new Vector2(0, 5), Color.Lime, 0, 10);*/
|
|
||||||
|
|
||||||
if (this == controlled || GUI.DisableHUD) return;
|
if (this == controlled || GUI.DisableHUD) return;
|
||||||
|
|
||||||
Vector2 pos = DrawPosition;
|
Vector2 pos = DrawPosition;
|
||||||
@@ -291,30 +280,33 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 100.0f,
|
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 100.0f,
|
||||||
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
|
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
|
||||||
Math.Min((float)speechBubbleTimer, 1.0f));
|
Math.Min(speechBubbleTimer, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this == controlled) return;
|
if (this == controlled) return;
|
||||||
|
|
||||||
if (info != null)
|
if (nameVisible && info != null)
|
||||||
{
|
{
|
||||||
|
string name = Info.DisplayName;
|
||||||
|
if (controlled == null && name != Info.Name) name += " (Disguised)";
|
||||||
|
|
||||||
Vector2 namePos = new Vector2(pos.X, pos.Y - 110.0f - (5.0f / cam.Zoom)) - GUI.Font.MeasureString(Info.Name) * 0.5f / cam.Zoom;
|
Vector2 namePos = new Vector2(pos.X, pos.Y - 110.0f - (5.0f / cam.Zoom)) - GUI.Font.MeasureString(Info.Name) * 0.5f / cam.Zoom;
|
||||||
Vector2 screenSize = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
Vector2 screenSize = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||||
Vector2 viewportSize = new Vector2(cam.WorldView.Width, cam.WorldView.Height);
|
Vector2 viewportSize = new Vector2(cam.WorldView.Width, cam.WorldView.Height);
|
||||||
namePos.X -= cam.WorldView.X; namePos.Y += cam.WorldView.Y;
|
namePos.X -= cam.WorldView.X; namePos.Y += cam.WorldView.Y;
|
||||||
namePos *= screenSize / viewportSize;
|
namePos *= screenSize / viewportSize;
|
||||||
namePos.X = (float)Math.Floor(namePos.X); namePos.Y = (float)Math.Floor(namePos.Y);
|
namePos.X = (float)Math.Floor(namePos.X); namePos.Y = (float)Math.Floor(namePos.Y);
|
||||||
namePos *= viewportSize / screenSize;
|
namePos *= viewportSize / screenSize;
|
||||||
namePos.X += cam.WorldView.X; namePos.Y -= cam.WorldView.Y;
|
namePos.X += cam.WorldView.X; namePos.Y -= cam.WorldView.Y;
|
||||||
|
|
||||||
Color nameColor = Color.White;
|
Color nameColor = Color.White;
|
||||||
|
|
||||||
if (Character.Controlled != null && TeamID != Character.Controlled.TeamID)
|
if (Controlled != null && TeamID != Controlled.TeamID)
|
||||||
{
|
{
|
||||||
nameColor = Color.Red;
|
nameColor = Color.Red;
|
||||||
}
|
}
|
||||||
GUI.Font.DrawString(spriteBatch, Info.Name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
|
GUI.Font.DrawString(spriteBatch, name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
|
||||||
GUI.Font.DrawString(spriteBatch, Info.Name, namePos, nameColor, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
|
GUI.Font.DrawString(spriteBatch, name, namePos, nameColor, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
|
||||||
|
|
||||||
if (GameMain.DebugDraw)
|
if (GameMain.DebugDraw)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ namespace Barotrauma
|
|||||||
private static Sprite noiseOverlay, damageOverlay;
|
private static Sprite noiseOverlay, damageOverlay;
|
||||||
|
|
||||||
private static GUIButton cprButton;
|
private static GUIButton cprButton;
|
||||||
|
|
||||||
|
private static GUIButton grabHoldButton;
|
||||||
|
|
||||||
private static GUIButton suicideButton;
|
private static GUIButton suicideButton;
|
||||||
|
|
||||||
@@ -41,6 +43,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (cprButton != null && cprButton.Visible) cprButton.AddToGUIUpdateList();
|
if (cprButton != null && cprButton.Visible) cprButton.AddToGUIUpdateList();
|
||||||
|
|
||||||
|
if (grabHoldButton != null && cprButton.Visible) grabHoldButton.AddToGUIUpdateList();
|
||||||
|
|
||||||
if (suicideButton != null && suicideButton.Visible) suicideButton.AddToGUIUpdateList();
|
if (suicideButton != null && suicideButton.Visible) suicideButton.AddToGUIUpdateList();
|
||||||
|
|
||||||
if (!character.IsUnconscious && character.Stun <= 0.0f)
|
if (!character.IsUnconscious && character.Stun <= 0.0f)
|
||||||
@@ -89,6 +93,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (cprButton != null && cprButton.Visible) cprButton.Update(deltaTime);
|
if (cprButton != null && cprButton.Visible) cprButton.Update(deltaTime);
|
||||||
|
|
||||||
|
if (grabHoldButton != null && grabHoldButton.Visible) grabHoldButton.Update(deltaTime);
|
||||||
|
|
||||||
if (suicideButton != null && suicideButton.Visible) suicideButton.Update(deltaTime);
|
if (suicideButton != null && suicideButton.Visible) suicideButton.Update(deltaTime);
|
||||||
|
|
||||||
if (damageOverlayTimer > 0.0f) damageOverlayTimer -= deltaTime;
|
if (damageOverlayTimer > 0.0f) damageOverlayTimer -= deltaTime;
|
||||||
@@ -195,9 +201,37 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (grabHoldButton == null)
|
||||||
|
{
|
||||||
|
grabHoldButton = new GUIButton(
|
||||||
|
new Rectangle(character.SelectedCharacter.Inventory.SlotPositions[0].ToPoint() + new Point(320, -60), new Point(130, 20)),
|
||||||
|
"Grabbing: " + (character.AnimController.GrabLimb == LimbType.Torso ? "Torso" : "Hands"), "");
|
||||||
|
|
||||||
|
grabHoldButton.OnClicked = (button, userData) =>
|
||||||
|
{
|
||||||
|
if (Character.Controlled == null || Character.Controlled.SelectedCharacter == null) return false;
|
||||||
|
|
||||||
|
Character.Controlled.AnimController.GrabLimb = Character.Controlled.AnimController.GrabLimb == LimbType.None ? LimbType.Torso : LimbType.None;
|
||||||
|
|
||||||
|
foreach (Limb limb in Character.Controlled.SelectedCharacter.AnimController.Limbs)
|
||||||
|
{
|
||||||
|
limb.pullJoint.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameMain.Client != null)
|
||||||
|
{
|
||||||
|
GameMain.Client.CreateEntityEvent(Character.Controlled, new object[] { NetEntityEvent.Type.Control });
|
||||||
|
}
|
||||||
|
|
||||||
|
grabHoldButton.Text = "Grabbing: " + (Character.Controlled.AnimController.GrabLimb == LimbType.Torso ? "Torso" : "Hands");
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//cprButton.Visible = character.GetSkillLevel("Medical") > 20.0f;
|
//cprButton.Visible = character.GetSkillLevel("Medical") > 20.0f;
|
||||||
|
|
||||||
if (cprButton.Visible) cprButton.Draw(spriteBatch);
|
if (cprButton.Visible) cprButton.Draw(spriteBatch);
|
||||||
|
if (grabHoldButton.Visible) grabHoldButton.Draw(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected)
|
if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected)
|
||||||
@@ -208,7 +242,7 @@ namespace Barotrauma
|
|||||||
string focusName = character.FocusedCharacter.SpeciesName;
|
string focusName = character.FocusedCharacter.SpeciesName;
|
||||||
if (character.FocusedCharacter.Info != null)
|
if (character.FocusedCharacter.Info != null)
|
||||||
{
|
{
|
||||||
focusName = character.FocusedCharacter.Info.Name;
|
focusName = character.FocusedCharacter.Info.DisplayName;
|
||||||
}
|
}
|
||||||
Vector2 textPos = startPos;
|
Vector2 textPos = startPos;
|
||||||
textPos -= new Vector2(GUI.Font.MeasureString(focusName).X / 2, 20);
|
textPos -= new Vector2(GUI.Font.MeasureString(focusName).X / 2, 20);
|
||||||
|
|||||||
@@ -17,15 +17,19 @@ namespace Barotrauma
|
|||||||
switch ((NetEntityEvent.Type)extraData[0])
|
switch ((NetEntityEvent.Type)extraData[0])
|
||||||
{
|
{
|
||||||
case NetEntityEvent.Type.InventoryState:
|
case NetEntityEvent.Type.InventoryState:
|
||||||
msg.WriteRangedInteger(0, 2, 0);
|
msg.WriteRangedInteger(0, 3, 0);
|
||||||
inventory.ClientWrite(msg, extraData);
|
inventory.ClientWrite(msg, extraData);
|
||||||
break;
|
break;
|
||||||
case NetEntityEvent.Type.Repair:
|
case NetEntityEvent.Type.Repair:
|
||||||
msg.WriteRangedInteger(0, 2, 1);
|
msg.WriteRangedInteger(0, 3, 1);
|
||||||
msg.Write(AnimController.Anim == AnimController.Animation.CPR);
|
msg.Write(AnimController.Anim == AnimController.Animation.CPR);
|
||||||
break;
|
break;
|
||||||
case NetEntityEvent.Type.Status:
|
case NetEntityEvent.Type.Status:
|
||||||
msg.WriteRangedInteger(0, 2, 2);
|
msg.WriteRangedInteger(0, 3, 2);
|
||||||
|
break;
|
||||||
|
case NetEntityEvent.Type.Control:
|
||||||
|
msg.WriteRangedInteger(0, 3, 3);
|
||||||
|
msg.Write((UInt16)AnimController.GrabLimb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,6 +95,7 @@ namespace Barotrauma
|
|||||||
bool crouching = msg.ReadBoolean();
|
bool crouching = msg.ReadBoolean();
|
||||||
keys[(int)InputType.Crouch].Held = crouching;
|
keys[(int)InputType.Crouch].Held = crouching;
|
||||||
keys[(int)InputType.Crouch].SetState(false, crouching);
|
keys[(int)InputType.Crouch].SetState(false, crouching);
|
||||||
|
AnimController.GrabLimb = (LimbType)msg.ReadUInt16();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAttackLimb = msg.ReadBoolean();
|
bool hasAttackLimb = msg.ReadBoolean();
|
||||||
@@ -367,6 +372,9 @@ namespace Barotrauma
|
|||||||
SetStun(0.0f, true, true);
|
SetStun(0.0f, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ragdolled = msg.ReadBoolean();
|
||||||
|
IsRagdolled = ragdolled;
|
||||||
|
|
||||||
bool huskInfected = msg.ReadBoolean();
|
bool huskInfected = msg.ReadBoolean();
|
||||||
if (huskInfected)
|
if (huskInfected)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static Queue<ColoredText> queuedMessages = new Queue<ColoredText>();
|
private static Queue<ColoredText> queuedMessages = new Queue<ColoredText>();
|
||||||
|
|
||||||
|
private static GUITextBlock activeQuestionText;
|
||||||
|
|
||||||
public static bool IsOpen
|
public static bool IsOpen
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -69,6 +71,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (activeQuestionText != null &&
|
||||||
|
(listBox.children.Count == 0 || listBox.children[listBox.children.Count - 1] != activeQuestionText))
|
||||||
|
{
|
||||||
|
listBox.children.Remove(activeQuestionText);
|
||||||
|
listBox.children.Add(activeQuestionText);
|
||||||
|
}
|
||||||
|
|
||||||
if (PlayerInput.KeyHit(Keys.F3))
|
if (PlayerInput.KeyHit(Keys.F3))
|
||||||
{
|
{
|
||||||
isOpen = !isOpen;
|
isOpen = !isOpen;
|
||||||
@@ -105,7 +114,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (PlayerInput.KeyHit(Keys.Enter))
|
if (PlayerInput.KeyHit(Keys.Enter))
|
||||||
{
|
{
|
||||||
ExecuteCommand(textBox.Text, game);
|
ExecuteCommand(textBox.Text);
|
||||||
textBox.Text = "";
|
textBox.Text = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,7 +143,7 @@ namespace Barotrauma
|
|||||||
case "entitylist":
|
case "entitylist":
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return client.HasConsoleCommandPermission(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,13 +186,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectedIndex = Messages.Count;
|
selectedIndex = Messages.Count;
|
||||||
|
|
||||||
if (activeQuestionText != null)
|
|
||||||
{
|
|
||||||
//make sure the active question stays at the bottom of the list
|
|
||||||
listBox.children.Remove(activeQuestionText);
|
|
||||||
listBox.children.Add(activeQuestionText);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitProjectSpecific()
|
private static void InitProjectSpecific()
|
||||||
|
|||||||
@@ -549,6 +549,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Displays a message at the center of the screen, automatically preventing overlapping with other centered messages
|
||||||
|
/// </summary>
|
||||||
public static void AddMessage(string message, Color color, float lifeTime = 3.0f, bool playSound = true)
|
public static void AddMessage(string message, Color color, float lifeTime = 3.0f, bool playSound = true)
|
||||||
{
|
{
|
||||||
if (messages.Count > 0 && messages[messages.Count - 1].Text == message)
|
if (messages.Count > 0 && messages[messages.Count - 1].Text == message)
|
||||||
@@ -558,12 +561,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector2 pos = new Vector2(GameMain.GraphicsWidth / 2.0f, GameMain.GraphicsHeight * 0.7f);
|
Vector2 pos = new Vector2(GameMain.GraphicsWidth / 2.0f, GameMain.GraphicsHeight * 0.7f);
|
||||||
pos.Y += messages.FindAll(m => m.Centered).Count * 30;
|
pos.Y += messages.FindAll(m => m.AutoCenter).Count * 30;
|
||||||
|
|
||||||
messages.Add(new GUIMessage(message, color, pos, lifeTime, Alignment.Center, true));
|
messages.Add(new GUIMessage(message, color, pos, lifeTime, Alignment.Center, true));
|
||||||
if (playSound) PlayUISound(GUISoundType.Message);
|
if (playSound) PlayUISound(GUISoundType.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display and automatically fade out a piece of text at an arbitrary position on the screen
|
||||||
|
/// </summary>
|
||||||
public static void AddMessage(string message, Vector2 position, Alignment alignment, Color color, float lifeTime = 3.0f, bool playSound = true)
|
public static void AddMessage(string message, Vector2 position, Alignment alignment, Color color, float lifeTime = 3.0f, bool playSound = true)
|
||||||
{
|
{
|
||||||
if (messages.Count > 0 && messages[messages.Count - 1].Text == message)
|
if (messages.Count > 0 && messages[messages.Count - 1].Text == message)
|
||||||
@@ -602,7 +608,7 @@ namespace Barotrauma
|
|||||||
alpha -= 1.0f - msg.LifeTime;
|
alpha -= 1.0f - msg.LifeTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.Centered)
|
if (msg.AutoCenter)
|
||||||
{
|
{
|
||||||
msg.Pos = MathUtils.SmoothStep(msg.Pos, currPos, deltaTime * 20.0f);
|
msg.Pos = MathUtils.SmoothStep(msg.Pos, currPos, deltaTime * 20.0f);
|
||||||
currPos.Y += 30.0f;
|
currPos.Y += 30.0f;
|
||||||
|
|||||||
@@ -115,10 +115,11 @@ namespace Barotrauma
|
|||||||
listBox.AddChild(child);
|
listBox.AddChild(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddItem(string text, object userData = null)
|
public void AddItem(string text, object userData = null, string toolTip = "")
|
||||||
{
|
{
|
||||||
GUITextBlock textBlock = new GUITextBlock(new Rectangle(0,0,0,20), text, "ListBoxElement", Alignment.TopLeft, Alignment.CenterLeft, listBox);
|
GUITextBlock textBlock = new GUITextBlock(new Rectangle(0,0,0,20), text, "ListBoxElement", Alignment.TopLeft, Alignment.CenterLeft, listBox);
|
||||||
textBlock.UserData = userData;
|
textBlock.UserData = userData;
|
||||||
|
textBlock.ToolTip = toolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ClearChildren()
|
public override void ClearChildren()
|
||||||
|
|||||||
@@ -171,12 +171,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < children.Count; i++)
|
for (int i = 0; i < children.Count; i++)
|
||||||
{
|
{
|
||||||
if (!children[i].UserData.Equals(userData)) continue;
|
if ((children[i].UserData != null && children[i].UserData.Equals(userData)) ||
|
||||||
|
(children[i].UserData == null && userData == null))
|
||||||
Select(i, force);
|
{
|
||||||
|
Select(i, force);
|
||||||
//if (OnSelected != null) OnSelected(Selected, Selected.UserData);
|
if (!SelectMultiple) return;
|
||||||
if (!SelectMultiple) return;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,14 +46,21 @@ namespace Barotrauma
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Centered;
|
|
||||||
|
|
||||||
public GUIMessage(string text, Color color, Vector2 position, float lifeTime, Alignment textAlignment, bool centered)
|
/// <summary>
|
||||||
|
/// Autocentered messages are automatically placed at the center of the screen and prevented from overlapping with each other
|
||||||
|
/// </summary>
|
||||||
|
public bool AutoCenter;
|
||||||
|
|
||||||
|
public GUIMessage(string text, Color color, Vector2 position, float lifeTime, Alignment textAlignment, bool autoCenter)
|
||||||
{
|
{
|
||||||
coloredText = new ColoredText(text, color, false);
|
coloredText = new ColoredText(text, color, false);
|
||||||
pos = position;
|
pos = position;
|
||||||
this.lifeTime = lifeTime;
|
this.lifeTime = lifeTime;
|
||||||
this.Alignment = textAlignment;
|
this.Alignment = textAlignment;
|
||||||
|
this.AutoCenter = autoCenter;
|
||||||
|
|
||||||
|
size = GUI.Font.MeasureString(text);
|
||||||
|
|
||||||
if (textAlignment.HasFlag(Alignment.Left))
|
if (textAlignment.HasFlag(Alignment.Left))
|
||||||
Origin.X += size.X * 0.5f;
|
Origin.X += size.X * 0.5f;
|
||||||
@@ -67,14 +74,10 @@ namespace Barotrauma
|
|||||||
if (textAlignment.HasFlag(Alignment.Bottom))
|
if (textAlignment.HasFlag(Alignment.Bottom))
|
||||||
Origin.Y -= size.Y * 0.5f;
|
Origin.Y -= size.Y * 0.5f;
|
||||||
|
|
||||||
if (centered)
|
if (autoCenter)
|
||||||
{
|
{
|
||||||
Origin = new Vector2((int)(0.5f * size.X), (int)(0.5f * size.Y));
|
Origin = new Vector2((int)(0.5f * size.X), (int)(0.5f * size.Y));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
size = GUI.Font.MeasureString(text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
|
public static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
|
||||||
|
|
||||||
const int DefaultWidth=400, DefaultHeight=250;
|
public const int DefaultWidth = 400, DefaultHeight = 250;
|
||||||
|
|
||||||
//public delegate bool OnClickedHandler(GUIButton button, object obj);
|
|
||||||
//public OnClickedHandler OnClicked;
|
|
||||||
|
|
||||||
//GUIFrame frame;
|
|
||||||
public GUIButton[] Buttons;
|
public GUIButton[] Buttons;
|
||||||
|
|
||||||
public static GUIComponent VisibleBox
|
public static GUIComponent VisibleBox
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
base.Rect = value;
|
base.Rect = value;
|
||||||
|
|
||||||
box.Rect = new Rectangle(value.X,value.Y,box.Rect.Width,box.Rect.Height);
|
if (box != null) box.Rect = new Rectangle(value.X,value.Y,box.Rect.Width,box.Rect.Height);
|
||||||
text.Rect = new Rectangle(box.Rect.Right, box.Rect.Y + 2, 20, box.Rect.Height);
|
if (text != null) text.Rect = new Rectangle(box.Rect.Right, box.Rect.Y + 2, 20, box.Rect.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Barotrauma
|
|||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
SlotPositions[i] = new Vector2(
|
SlotPositions[i] = new Vector2(
|
||||||
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 2),
|
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 1),
|
||||||
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
|
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
|
||||||
|
|
||||||
useOnSelfButton[i - 3] = new GUIButton(
|
useOnSelfButton[i - 3] = new GUIButton(
|
||||||
@@ -52,16 +52,24 @@ namespace Barotrauma
|
|||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
//face
|
||||||
case 5:
|
case 5:
|
||||||
SlotPositions[i] = new Vector2(
|
SlotPositions[i] = new Vector2(
|
||||||
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 5),
|
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 5),
|
||||||
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
|
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//id card
|
||||||
|
case 6:
|
||||||
|
SlotPositions[i] = new Vector2(
|
||||||
|
spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 5),
|
||||||
|
GameMain.GraphicsHeight - (spacing + rectHeight) * 3);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SlotPositions[i] = new Vector2(
|
SlotPositions[i] = new Vector2(
|
||||||
spacing * 2 + rectWidth + (spacing + rectWidth) * ((i - 6) % 5),
|
spacing * 2 + rectWidth + (spacing + rectWidth) * ((i - 7) % 5),
|
||||||
GameMain.GraphicsHeight - (spacing + rectHeight) * ((i > 10) ? 2 : 1));
|
GameMain.GraphicsHeight - (spacing + rectHeight) * ((i > 11) ? 2 : 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,6 +255,13 @@ namespace Barotrauma
|
|||||||
new Vector2(15.0f, 16.0f), Vector2.One,
|
new Vector2(15.0f, 16.0f), Vector2.One,
|
||||||
SpriteEffects.None, 0.1f);
|
SpriteEffects.None, 0.1f);
|
||||||
}
|
}
|
||||||
|
else if (i == 6)
|
||||||
|
{
|
||||||
|
spriteBatch.Draw(icons, new Vector2(slotRect.Center.X, slotRect.Center.Y),
|
||||||
|
new Rectangle(62, 36, 22, 18), Color.White * 0.7f, 0.0f,
|
||||||
|
new Vector2(11.0f, 9.0f), Vector2.One,
|
||||||
|
SpriteEffects.None, 0.1f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Draw(spriteBatch);
|
base.Draw(spriteBatch);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System;
|
|||||||
|
|
||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
{
|
{
|
||||||
partial class Door : ItemComponent, IDrawableComponent, IServerSerializable
|
partial class Door : Pickable, IDrawableComponent, IServerSerializable
|
||||||
{
|
{
|
||||||
private ConvexHull convexHull;
|
private ConvexHull convexHull;
|
||||||
private ConvexHull convexHull2;
|
private ConvexHull convexHull2;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
GameServer.Log(Character.Controlled + (IsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(Character.Controlled.LogName + (IsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (GameMain.Client != null)
|
else if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
@@ -39,7 +39,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
GameServer.Log(Character.Controlled + " set the pumping speed of " + item.Name + " to " + (int)(flowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(Character.Controlled.LogName + " set the pumping speed of " + item.Name + " to " + (int)(flowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (GameMain.Client != null)
|
else if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
@@ -58,7 +58,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
GameServer.Log(Character.Controlled + " set the pumping speed of " + item.Name + " to " + (int)(flowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(Character.Controlled.LogName + " set the pumping speed of " + item.Name + " to " + (int)(flowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (GameMain.Client != null)
|
else if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
GameServer.Log(Character.Controlled + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(Character.Controlled.LogName + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (GameMain.Client != null)
|
else if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
@@ -38,7 +38,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
GameServer.Log(Character.Controlled + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(Character.Controlled.LogName + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (GameMain.Client != null)
|
else if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -174,12 +174,12 @@ namespace Barotrauma.Items.Components
|
|||||||
var otherConnection = draggingConnected.OtherConnection(this);
|
var otherConnection = draggingConnected.OtherConnection(this);
|
||||||
if (otherConnection == null)
|
if (otherConnection == null)
|
||||||
{
|
{
|
||||||
GameServer.Log(Character.Controlled + " connected a wire to " +
|
GameServer.Log(Character.Controlled.LogName + " connected a wire to " +
|
||||||
Item.Name + " (" + Name + ")", ServerLog.MessageType.ItemInteraction);
|
Item.Name + " (" + Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameServer.Log(Character.Controlled + " connected a wire from " +
|
GameServer.Log(Character.Controlled.LogName + " connected a wire from " +
|
||||||
Item.Name + " (" + Name + ") to " + otherConnection.item.Name + " (" + otherConnection.Name + ")", ServerLog.MessageType.ItemInteraction);
|
Item.Name + " (" + Name + ") to " + otherConnection.item.Name + " (" + otherConnection.Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -296,9 +296,26 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
toolTip = string.IsNullOrEmpty(Items[i].Description) ?
|
string description = Items[i].Description;
|
||||||
|
if (Items[i].Prefab.NameMatches("ID Card"))
|
||||||
|
{
|
||||||
|
string[] readTags = Items[i].Tags.Split(',');
|
||||||
|
string idName = null;
|
||||||
|
string idJob = null;
|
||||||
|
foreach (string tag in readTags)
|
||||||
|
{
|
||||||
|
string[] s = tag.Split(':');
|
||||||
|
if (s[0] == "name")
|
||||||
|
idName = s[1];
|
||||||
|
if (s[0] == "job")
|
||||||
|
idJob = s[1];
|
||||||
|
}
|
||||||
|
if (idName != null)
|
||||||
|
description = "This belongs to " + idName + (idJob != null ? ", the " + idJob + ".\n" : ".\n") + description;
|
||||||
|
}
|
||||||
|
toolTip = string.IsNullOrEmpty(description) ?
|
||||||
Items[i].Name :
|
Items[i].Name :
|
||||||
Items[i].Name + '\n' + Items[i].Description;
|
Items[i].Name + '\n' + description;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawToolTip(spriteBatch, toolTip, slots[i].Rect);
|
DrawToolTip(spriteBatch, toolTip, slots[i].Rect);
|
||||||
|
|||||||
@@ -106,6 +106,16 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool EnterIDCardDesc(GUITextBox textBox, string text)
|
||||||
|
{
|
||||||
|
IdCardDesc = text;
|
||||||
|
textBox.Text = text;
|
||||||
|
textBox.Color = Color.Green;
|
||||||
|
|
||||||
|
textBox.Deselect();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
private bool EnterIDCardTags(GUITextBox textBox, string text)
|
private bool EnterIDCardTags(GUITextBox textBox, string text)
|
||||||
{
|
{
|
||||||
IdCardTags = text.Split(',');
|
IdCardTags = text.Split(',');
|
||||||
@@ -143,7 +153,7 @@ namespace Barotrauma
|
|||||||
private GUIComponent CreateEditingHUD(bool inGame = false)
|
private GUIComponent CreateEditingHUD(bool inGame = false)
|
||||||
{
|
{
|
||||||
int width = 500;
|
int width = 500;
|
||||||
int height = spawnType == SpawnType.Path ? 100 : 140;
|
int height = spawnType == SpawnType.Path ? 100 : 200;
|
||||||
int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10;
|
int x = GameMain.GraphicsWidth / 2 - width / 2, y = 10;
|
||||||
|
|
||||||
editingHUD = new GUIFrame(new Rectangle(x, y, width, height), Color.Black * 0.5f);
|
editingHUD = new GUIFrame(new Rectangle(x, y, width, height), Color.Black * 0.5f);
|
||||||
@@ -172,8 +182,19 @@ namespace Barotrauma
|
|||||||
|
|
||||||
y = 40 + 20;
|
y = 40 + 20;
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, y, 100, 20), "ID Card desc:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
|
||||||
|
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 350, 20), "", editingHUD);
|
||||||
|
propertyBox.MaxTextLength = 150;
|
||||||
|
propertyBox.Text = idCardDesc;
|
||||||
|
propertyBox.OnEnterPressed = EnterIDCardDesc;
|
||||||
|
propertyBox.OnTextChanged = TextBoxChanged;
|
||||||
|
propertyBox.ToolTip = "Characters spawning at this spawnpoint will have the specified description added to their ID card. This can be used to describe additional access levels their card has on the sub.";
|
||||||
|
|
||||||
|
y = y + 30;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "ID Card tags:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
|
new GUITextBlock(new Rectangle(0, y, 100, 20), "ID Card tags:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
|
||||||
GUITextBox propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), "", editingHUD);
|
propertyBox = new GUITextBox(new Rectangle(100, y, 350, 20), "", editingHUD);
|
||||||
|
propertyBox.MaxTextLength = 60;
|
||||||
propertyBox.Text = string.Join(", ", idCardTags);
|
propertyBox.Text = string.Join(", ", idCardTags);
|
||||||
propertyBox.OnEnterPressed = EnterIDCardTags;
|
propertyBox.OnEnterPressed = EnterIDCardTags;
|
||||||
propertyBox.OnTextChanged = TextBoxChanged;
|
propertyBox.OnTextChanged = TextBoxChanged;
|
||||||
@@ -182,7 +203,8 @@ namespace Barotrauma
|
|||||||
y = y + 30;
|
y = y + 30;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, y, 100, 20), "Assigned job:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
|
new GUITextBlock(new Rectangle(0, y, 100, 20), "Assigned job:", Color.Transparent, Color.White, Alignment.TopLeft, null, editingHUD);
|
||||||
propertyBox = new GUITextBox(new Rectangle(100, y, 200, 20), "", editingHUD);
|
propertyBox = new GUITextBox(new Rectangle(100, y, 350, 20), "", editingHUD);
|
||||||
|
propertyBox.MaxTextLength = 60;
|
||||||
propertyBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
|
propertyBox.Text = (assignedJob == null) ? "None" : assignedJob.Name;
|
||||||
propertyBox.OnEnterPressed = EnterAssignedJob;
|
propertyBox.OnEnterPressed = EnterAssignedJob;
|
||||||
propertyBox.OnTextChanged = TextBoxChanged;
|
propertyBox.OnTextChanged = TextBoxChanged;
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Barotrauma.Networking
|
namespace Barotrauma.Networking
|
||||||
{
|
{
|
||||||
@@ -40,6 +36,10 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
new GUIMessageBox("", txt);
|
new GUIMessageBox("", txt);
|
||||||
}
|
}
|
||||||
|
else if (type == ChatMessageType.Console)
|
||||||
|
{
|
||||||
|
DebugConsole.NewMessage(txt, MessageColor[(int)ChatMessageType.Console]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter);
|
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace Barotrauma.Networking
|
|||||||
private GUITickBox endVoteTickBox;
|
private GUITickBox endVoteTickBox;
|
||||||
|
|
||||||
private ClientPermissions permissions = ClientPermissions.None;
|
private ClientPermissions permissions = ClientPermissions.None;
|
||||||
|
private List<string> permittedConsoleCommands = new List<string>();
|
||||||
|
|
||||||
private bool connected;
|
private bool connected;
|
||||||
|
|
||||||
@@ -598,16 +599,28 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private void ReadPermissions(NetIncomingMessage inc)
|
private void ReadPermissions(NetIncomingMessage inc)
|
||||||
{
|
{
|
||||||
|
List<string> permittedConsoleCommands = new List<string>();
|
||||||
ClientPermissions newPermissions = (ClientPermissions)inc.ReadByte();
|
ClientPermissions newPermissions = (ClientPermissions)inc.ReadByte();
|
||||||
if (newPermissions != permissions)
|
if (newPermissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||||
{
|
{
|
||||||
SetPermissions(newPermissions);
|
UInt16 consoleCommandCount = inc.ReadUInt16();
|
||||||
}
|
for (int i = 0; i < consoleCommandCount; i++)
|
||||||
|
{
|
||||||
|
permittedConsoleCommands.Add(inc.ReadString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPermissions(newPermissions, permittedConsoleCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPermissions(ClientPermissions newPermissions)
|
private void SetPermissions(ClientPermissions newPermissions, List<string> permittedConsoleCommands)
|
||||||
{
|
{
|
||||||
if (newPermissions == permissions) return;
|
if (!(this.permittedConsoleCommands.Any(c => !permittedConsoleCommands.Contains(c)) ||
|
||||||
|
permittedConsoleCommands.Any(c => !this.permittedConsoleCommands.Contains(c))))
|
||||||
|
{
|
||||||
|
if (newPermissions == permissions) return;
|
||||||
|
}
|
||||||
|
|
||||||
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "permissions");
|
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "permissions");
|
||||||
|
|
||||||
string msg = "";
|
string msg = "";
|
||||||
@@ -626,8 +639,22 @@ namespace Barotrauma.Networking
|
|||||||
msg += " - " + attributes[0].Description + "\n";
|
msg += " - " + attributes[0].Description + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
permissions = newPermissions;
|
permissions = newPermissions;
|
||||||
new GUIMessageBox("Permissions changed", msg).UserData = "permissions";
|
this.permittedConsoleCommands = new List<string>(permittedConsoleCommands);
|
||||||
|
GUIMessageBox msgBox = new GUIMessageBox("Permissions changed", msg, GUIMessageBox.DefaultWidth, 0);
|
||||||
|
msgBox.UserData = "permissions";
|
||||||
|
|
||||||
|
if (newPermissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||||
|
{
|
||||||
|
int listBoxWidth = (int)(msgBox.InnerFrame.Rect.Width - msgBox.InnerFrame.Padding.X - msgBox.InnerFrame.Padding.Z) / 2 - 30;
|
||||||
|
new GUITextBlock(new Rectangle(0, 0, listBoxWidth, 15), "Permitted console commands:", "", Alignment.TopRight, Alignment.TopLeft, msgBox.InnerFrame, true, GUI.SmallFont);
|
||||||
|
var commandList = new GUIListBox(new Rectangle(0, 20, listBoxWidth, 0), "", Alignment.BottomRight, msgBox.InnerFrame);
|
||||||
|
foreach (string permittedCommand in permittedConsoleCommands)
|
||||||
|
{
|
||||||
|
new GUITextBlock(new Rectangle(0, 0, 0, 15), permittedCommand, "", commandList, GUI.SmallFont).CanBeFocused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GameMain.NetLobbyScreen.SubList.Enabled = Voting.AllowSubVoting || HasPermission(ClientPermissions.SelectSub);
|
GameMain.NetLobbyScreen.SubList.Enabled = Voting.AllowSubVoting || HasPermission(ClientPermissions.SelectSub);
|
||||||
GameMain.NetLobbyScreen.ModeList.Enabled = Voting.AllowModeVoting || HasPermission(ClientPermissions.SelectMode);
|
GameMain.NetLobbyScreen.ModeList.Enabled = Voting.AllowModeVoting || HasPermission(ClientPermissions.SelectMode);
|
||||||
@@ -805,7 +832,7 @@ namespace Barotrauma.Networking
|
|||||||
gameStarted = inc.ReadBoolean();
|
gameStarted = inc.ReadBoolean();
|
||||||
bool allowSpectating = inc.ReadBoolean();
|
bool allowSpectating = inc.ReadBoolean();
|
||||||
|
|
||||||
SetPermissions((ClientPermissions)inc.ReadByte());
|
ReadPermissions(inc);
|
||||||
|
|
||||||
if (gameStarted)
|
if (gameStarted)
|
||||||
{
|
{
|
||||||
@@ -1169,6 +1196,14 @@ namespace Barotrauma.Networking
|
|||||||
return permissions.HasFlag(permission);
|
return permissions.HasFlag(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasConsoleCommandPermission(string command)
|
||||||
|
{
|
||||||
|
if (!permissions.HasFlag(ClientPermissions.ConsoleCommands)) return false;
|
||||||
|
|
||||||
|
command = command.ToLowerInvariant();
|
||||||
|
return permittedConsoleCommands.Any(c => c.ToLowerInvariant() == command);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
base.Draw(spriteBatch);
|
base.Draw(spriteBatch);
|
||||||
@@ -1359,6 +1394,25 @@ namespace Barotrauma.Networking
|
|||||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendConsoleCommand(string command)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(command))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Cannot send an empty console command to the server!\n" + Environment.StackTrace);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetOutgoingMessage msg = client.CreateMessage();
|
||||||
|
msg.Write((byte)ClientPacketHeader.SERVER_COMMAND);
|
||||||
|
msg.Write((byte)ClientPermissions.ConsoleCommands);
|
||||||
|
msg.Write(command);
|
||||||
|
Vector2 cursorWorldPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||||
|
msg.Write(cursorWorldPos.X);
|
||||||
|
msg.Write(cursorWorldPos.Y);
|
||||||
|
|
||||||
|
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tell the server to select a submarine (permission required)
|
/// Tell the server to select a submarine (permission required)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ namespace Barotrauma.Networking
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
y += 40;
|
y += 20;
|
||||||
|
|
||||||
var voteKickBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow vote kicking", Alignment.Left, settingsTabs[1]);
|
var voteKickBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow vote kicking", Alignment.Left, settingsTabs[1]);
|
||||||
voteKickBox.Selected = Voting.AllowVoteKick;
|
voteKickBox.Selected = Voting.AllowVoteKick;
|
||||||
@@ -357,7 +357,7 @@ namespace Barotrauma.Networking
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
y += 40;
|
y += 20;
|
||||||
|
|
||||||
var randomizeLevelBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Randomize level seed between rounds", Alignment.Left, settingsTabs[1]);
|
var randomizeLevelBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Randomize level seed between rounds", Alignment.Left, settingsTabs[1]);
|
||||||
randomizeLevelBox.Selected = RandomizeSeed;
|
randomizeLevelBox.Selected = RandomizeSeed;
|
||||||
@@ -367,7 +367,7 @@ namespace Barotrauma.Networking
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
y += 40;
|
y += 20;
|
||||||
|
|
||||||
var saveLogsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Save server logs", Alignment.Left, settingsTabs[1]);
|
var saveLogsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Save server logs", Alignment.Left, settingsTabs[1]);
|
||||||
saveLogsBox.Selected = SaveServerLogs;
|
saveLogsBox.Selected = SaveServerLogs;
|
||||||
@@ -378,6 +378,83 @@ namespace Barotrauma.Networking
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
y += 20;
|
||||||
|
|
||||||
|
var ragdollButtonBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow ragdoll button", Alignment.Left, settingsTabs[1]);
|
||||||
|
ragdollButtonBox.Selected = AllowRagdollButton;
|
||||||
|
ragdollButtonBox.OnSelected = (GUITickBox) =>
|
||||||
|
{
|
||||||
|
AllowRagdollButton = GUITickBox.Selected;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
y += 20;
|
||||||
|
|
||||||
|
var traitorRatioBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Use % of players for max traitors", Alignment.Left, settingsTabs[1]);
|
||||||
|
var traitorRatioText = new GUITextBlock(new Rectangle(20, y + 20, 20, 20), "Traitor ratio: 20 %", "", settingsTabs[1], GUI.SmallFont);
|
||||||
|
var traitorRatioSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[1]);
|
||||||
|
//Prepare the slider before the tick box
|
||||||
|
if (TraitorUseRatio)
|
||||||
|
{
|
||||||
|
traitorRatioSlider.UserData = traitorRatioText;
|
||||||
|
traitorRatioSlider.Step = 0.01f; //Lots of fine-tuning
|
||||||
|
traitorRatioSlider.BarScroll = (TraitorRatio - 0.1f) / 0.9f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traitorRatioSlider.UserData = traitorRatioText;
|
||||||
|
traitorRatioSlider.Step = 1f / (maxPlayers-1);
|
||||||
|
traitorRatioSlider.BarScroll = MathUtils.Round(TraitorRatio, 1f);
|
||||||
|
}
|
||||||
|
//Slider END
|
||||||
|
|
||||||
|
traitorRatioBox.Selected = TraitorUseRatio;
|
||||||
|
traitorRatioBox.OnSelected = (GUITickBox) =>
|
||||||
|
{
|
||||||
|
TraitorUseRatio = GUITickBox.Selected;
|
||||||
|
//Affect the slider graphics
|
||||||
|
if (TraitorUseRatio)
|
||||||
|
{
|
||||||
|
traitorRatioSlider.UserData = traitorRatioText;
|
||||||
|
traitorRatioSlider.Step = 0.01f; //Lots of fine-tuning
|
||||||
|
traitorRatioSlider.BarScroll = 0.2f; //default values
|
||||||
|
traitorRatioSlider.OnMoved(traitorRatioSlider, traitorRatioSlider.BarScroll); //Update the scroll bar
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traitorRatioSlider.UserData = traitorRatioText;
|
||||||
|
traitorRatioSlider.Step = 1f / (maxPlayers-1);
|
||||||
|
traitorRatioSlider.BarScroll = 1; //default values
|
||||||
|
traitorRatioSlider.OnMoved(traitorRatioSlider, traitorRatioSlider.BarScroll); //Update the scroll bar
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
traitorRatioSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||||
|
{
|
||||||
|
GUITextBlock traitorText = scrollBar.UserData as GUITextBlock;
|
||||||
|
if (TraitorUseRatio)
|
||||||
|
{
|
||||||
|
TraitorRatio = barScroll * 0.9f + 0.1f;
|
||||||
|
traitorText.Text = "Traitor ratio: " + (int)MathUtils.Round(TraitorRatio * 100.0f, 1.0f) + " %";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TraitorRatio = MathUtils.Round(barScroll * (maxPlayers-1), 1f) + 1;
|
||||||
|
traitorText.Text = "Traitor count: " + TraitorRatio;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
traitorRatioSlider.OnMoved(traitorRatioSlider, traitorRatioSlider.BarScroll);
|
||||||
|
|
||||||
|
y += 45;
|
||||||
|
|
||||||
|
var karmaButtonBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Use Karma", Alignment.Left, settingsTabs[1]);
|
||||||
|
karmaButtonBox.Selected = KarmaEnabled;
|
||||||
|
karmaButtonBox.OnSelected = (GUITickBox) =>
|
||||||
|
{
|
||||||
|
KarmaEnabled = GUITickBox.Selected;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
// banlist
|
// banlist
|
||||||
|
|||||||
@@ -882,24 +882,54 @@ namespace Barotrauma
|
|||||||
|
|
||||||
playerFrame = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Black * 0.6f);
|
playerFrame = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Black * 0.6f);
|
||||||
|
|
||||||
var playerFrameInner = new GUIFrame(new Rectangle(0, 0, 300, 280), null, Alignment.Center, "", playerFrame);
|
var playerFrameInner = new GUIFrame(GameMain.Server != null ? new Rectangle(0, 0, 450, 370) : new Rectangle(0, 0, 450, 150), null, Alignment.Center, "", playerFrame);
|
||||||
playerFrameInner.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
playerFrameInner.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 200, 20), component.UserData.ToString(),
|
new GUITextBlock(new Rectangle(0, 0, 200, 20), obj.ToString(),
|
||||||
"", Alignment.TopLeft, Alignment.TopLeft,
|
"", Alignment.TopLeft, Alignment.TopLeft,
|
||||||
playerFrameInner, false, GUI.LargeFont);
|
playerFrameInner, false, GUI.LargeFont);
|
||||||
|
|
||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
var selectedClient = GameMain.Server.ConnectedClients.Find(c => c.Name == component.UserData.ToString());
|
var selectedClient = GameMain.Server.ConnectedClients.Find(c => c.Name == obj.ToString());
|
||||||
|
playerFrame.UserData = selectedClient;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 25, 150, 15), selectedClient.Connection.RemoteEndPoint.Address.ToString(), "", playerFrameInner);
|
new GUITextBlock(new Rectangle(0, 25, 150, 15), selectedClient.Connection.RemoteEndPoint.Address.ToString(), "", playerFrameInner);
|
||||||
|
|
||||||
var permissionsBox = new GUIFrame(new Rectangle(0, 60, 0, 90), null, playerFrameInner);
|
new GUITextBlock(new Rectangle(0, 45, 0, 15), "Rank", "", playerFrameInner);
|
||||||
|
var rankDropDown = new GUIDropDown(new Rectangle(0, 70, 150, 20), "Rank", "", playerFrameInner);
|
||||||
|
rankDropDown.UserData = selectedClient;
|
||||||
|
foreach (PermissionPreset permissionPreset in PermissionPreset.List)
|
||||||
|
{
|
||||||
|
rankDropDown.AddItem(permissionPreset.Name, permissionPreset, permissionPreset.Description);
|
||||||
|
}
|
||||||
|
rankDropDown.AddItem("Custom", null);
|
||||||
|
|
||||||
|
PermissionPreset currentPreset = PermissionPreset.List.Find(p =>
|
||||||
|
p.Permissions == selectedClient.Permissions &&
|
||||||
|
p.PermittedCommands.Count == selectedClient.PermittedConsoleCommands.Count && !p.PermittedCommands.Except(selectedClient.PermittedConsoleCommands).Any());
|
||||||
|
rankDropDown.SelectItem(currentPreset);
|
||||||
|
|
||||||
|
rankDropDown.OnSelected += (c, userdata) =>
|
||||||
|
{
|
||||||
|
PermissionPreset selectedPreset = (PermissionPreset)userdata;
|
||||||
|
if (selectedPreset != null)
|
||||||
|
{
|
||||||
|
var client = playerFrame.UserData as Client;
|
||||||
|
client.SetPermissions(selectedPreset.Permissions, selectedPreset.PermittedCommands);
|
||||||
|
GameMain.Server.UpdateClientPermissions(client);
|
||||||
|
|
||||||
|
playerFrame = null;
|
||||||
|
SelectPlayer(null, client.Name);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var permissionsBox = new GUIFrame(new Rectangle(0, 125, (int)(playerFrameInner.Rect.Width * 0.5f), 160), null, playerFrameInner);
|
||||||
permissionsBox.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
|
permissionsBox.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
|
||||||
permissionsBox.UserData = selectedClient;
|
permissionsBox.UserData = selectedClient;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 0, 15), "Permissions:", "", permissionsBox);
|
new GUITextBlock(new Rectangle(0, 100, permissionsBox.Rect.Width, 15), "Permissions:", "", playerFrameInner);
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
||||||
{
|
{
|
||||||
@@ -910,13 +940,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
string permissionStr = attributes.Length > 0 ? attributes[0].Description : permission.ToString();
|
string permissionStr = attributes.Length > 0 ? attributes[0].Description : permission.ToString();
|
||||||
|
|
||||||
var permissionTick = new GUITickBox(new Rectangle(x, y + 25, 15, 15), permissionStr, Alignment.TopLeft, GUI.SmallFont, permissionsBox);
|
var permissionTick = new GUITickBox(new Rectangle(x, y, 15, 15), permissionStr, Alignment.TopLeft, GUI.SmallFont, permissionsBox);
|
||||||
permissionTick.UserData = permission;
|
permissionTick.UserData = permission;
|
||||||
permissionTick.Selected = selectedClient.HasPermission(permission);
|
permissionTick.Selected = selectedClient.HasPermission(permission);
|
||||||
|
|
||||||
permissionTick.OnSelected = (tickBox) =>
|
permissionTick.OnSelected = (tickBox) =>
|
||||||
{
|
{
|
||||||
var client = tickBox.Parent.UserData as Client;
|
//reset rank to custom
|
||||||
|
rankDropDown.SelectItem(null);
|
||||||
|
|
||||||
|
var client = playerFrame.UserData as Client;
|
||||||
if (client == null) return false;
|
if (client == null) return false;
|
||||||
|
|
||||||
var thisPermission = (ClientPermissions)tickBox.UserData;
|
var thisPermission = (ClientPermissions)tickBox.UserData;
|
||||||
@@ -931,19 +964,50 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
y += 20;
|
y += 20;
|
||||||
if (y >= permissionsBox.Rect.Height - 40)
|
if (y >= permissionsBox.Rect.Height - 15)
|
||||||
{
|
{
|
||||||
y = 0;
|
y = 0;
|
||||||
x += 100;
|
x += 120;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 100, (int)(playerFrameInner.Rect.Width * 0.5f), 15), "Permitted console commands:", "", Alignment.TopRight, Alignment.TopLeft, playerFrameInner, true);
|
||||||
|
var commandList = new GUIListBox(new Rectangle(0, 125, (int)(playerFrameInner.Rect.Width * 0.5f), 160), "", Alignment.TopRight, playerFrameInner);
|
||||||
|
commandList.UserData = selectedClient;
|
||||||
|
foreach (DebugConsole.Command command in DebugConsole.Commands)
|
||||||
|
{
|
||||||
|
var commandTickBox = new GUITickBox(new Rectangle(0, 0, 15, 15), command.names[0], Alignment.TopLeft, GUI.SmallFont, commandList);
|
||||||
|
commandTickBox.Selected = selectedClient.PermittedConsoleCommands.Contains(command);
|
||||||
|
commandTickBox.ToolTip = command.help;
|
||||||
|
commandTickBox.UserData = command;
|
||||||
|
commandTickBox.OnSelected += (GUITickBox tickBox) =>
|
||||||
|
{
|
||||||
|
//reset rank to custom
|
||||||
|
rankDropDown.SelectItem(null);
|
||||||
|
|
||||||
|
Client client = playerFrame.UserData as Client;
|
||||||
|
DebugConsole.Command selectedCommand = tickBox.UserData as DebugConsole.Command;
|
||||||
|
if (client == null) return false;
|
||||||
|
|
||||||
|
if (!tickBox.Selected)
|
||||||
|
{
|
||||||
|
client.PermittedConsoleCommands.Remove(selectedCommand);
|
||||||
|
}
|
||||||
|
else if (!client.PermittedConsoleCommands.Contains(selectedCommand))
|
||||||
|
{
|
||||||
|
client.PermittedConsoleCommands.Add(selectedCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMain.Server.UpdateClientPermissions(client);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.Server != null || GameMain.Client.HasPermission(ClientPermissions.Kick))
|
if (GameMain.Server != null || GameMain.Client.HasPermission(ClientPermissions.Kick))
|
||||||
{
|
{
|
||||||
var kickButton = new GUIButton(new Rectangle(0, -50, 100, 20), "Kick", Alignment.BottomLeft, "", playerFrameInner);
|
var kickButton = new GUIButton(new Rectangle(0, 0, 80, 20), "Kick", Alignment.BottomLeft, "", playerFrameInner);
|
||||||
kickButton.UserData = obj;
|
kickButton.UserData = obj;
|
||||||
kickButton.OnClicked += KickPlayer;
|
kickButton.OnClicked += KickPlayer;
|
||||||
kickButton.OnClicked += ClosePlayerFrame;
|
kickButton.OnClicked += ClosePlayerFrame;
|
||||||
@@ -951,12 +1015,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GameMain.Server != null || GameMain.Client.HasPermission(ClientPermissions.Ban))
|
if (GameMain.Server != null || GameMain.Client.HasPermission(ClientPermissions.Ban))
|
||||||
{
|
{
|
||||||
var banButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Ban", Alignment.BottomLeft, "", playerFrameInner);
|
var banButton = new GUIButton(new Rectangle(90, 0, 80, 20), "Ban", Alignment.BottomLeft, "", playerFrameInner);
|
||||||
banButton.UserData = obj;
|
banButton.UserData = obj;
|
||||||
banButton.OnClicked += BanPlayer;
|
banButton.OnClicked += BanPlayer;
|
||||||
banButton.OnClicked += ClosePlayerFrame;
|
banButton.OnClicked += ClosePlayerFrame;
|
||||||
|
|
||||||
var rangebanButton = new GUIButton(new Rectangle(0, -25, 100, 20), "Ban range", Alignment.BottomLeft, "", playerFrameInner);
|
var rangebanButton = new GUIButton(new Rectangle(180, 0, 80, 20), "Ban range", Alignment.BottomLeft, "", playerFrameInner);
|
||||||
rangebanButton.UserData = obj;
|
rangebanButton.UserData = obj;
|
||||||
rangebanButton.OnClicked += BanPlayerRange;
|
rangebanButton.OnClicked += BanPlayerRange;
|
||||||
rangebanButton.OnClicked += ClosePlayerFrame;
|
rangebanButton.OnClicked += ClosePlayerFrame;
|
||||||
|
|||||||
@@ -453,10 +453,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
damage = MathHelper.Clamp(damage+Rand.Range(-10.0f, 10.0f), 0.0f, 100.0f);
|
damage = MathHelper.Clamp(damage+Rand.Range(-10.0f, 10.0f), 0.0f, 100.0f);
|
||||||
var sounds = damageSounds.FindAll(s =>
|
var sounds = damageSounds.FindAll(s =>
|
||||||
damage >= s.damageRange.X &&
|
s.damageRange == null ||
|
||||||
damage <= s.damageRange.Y &&
|
(damage >= s.damageRange.X &&
|
||||||
|
damage <= s.damageRange.Y) &&
|
||||||
s.damageType == damageType &&
|
s.damageType == damageType &&
|
||||||
(string.IsNullOrEmpty(s.requiredTag) || (tags != null && tags.Contains(s.requiredTag))));
|
(tags == null ? string.IsNullOrEmpty(s.requiredTag) : tags.Contains(s.requiredTag)));
|
||||||
|
|
||||||
if (!sounds.Any()) return;
|
if (!sounds.Any()) return;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -16,7 +15,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
while (QueuedCommands.Count>0)
|
while (QueuedCommands.Count>0)
|
||||||
{
|
{
|
||||||
ExecuteCommand(QueuedCommands[0], GameMain.Instance);
|
ExecuteCommand(QueuedCommands[0]);
|
||||||
QueuedCommands.RemoveAt(0);
|
QueuedCommands.RemoveAt(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -744,6 +744,9 @@
|
|||||||
<Content Include="$(MSBuildThisFileDirectory)Data\ContentPackages\Vanilla 0.7.xml">
|
<Content Include="$(MSBuildThisFileDirectory)Data\ContentPackages\Vanilla 0.7.xml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="$(MSBuildThisFileDirectory)Data\permissionpresets.xml">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Icon.ico" />
|
<Content Include="$(MSBuildThisFileDirectory)Icon.ico" />
|
||||||
<Content Include="$(MSBuildThisFileDirectory)Mods\info.txt">
|
<Content Include="$(MSBuildThisFileDirectory)Mods\info.txt">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
@@ -980,6 +983,12 @@
|
|||||||
<None Include="$(MSBuildThisFileDirectory)Content\Items\Reactor\reactor.ogg">
|
<None Include="$(MSBuildThisFileDirectory)Content\Items\Reactor\reactor.ogg">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)Content\Items\Tools\bump.ogg">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)Content\Items\Tools\crowbar.ogg">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Content\Items\Tools\extinguisher.ogg">
|
<None Include="$(MSBuildThisFileDirectory)Content\Items\Tools\extinguisher.ogg">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
@@ -1489,6 +1498,7 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\BanList.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\BanList.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\ChatMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\ChatMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\Client.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\Client.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\ClientPermissions.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\EntitySpawner.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\EntitySpawner.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\FileTransfer\FileSender.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\FileTransfer\FileSender.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\GameServer.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Networking\GameServer.cs" />
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
<joint limb1="0" limb1anchor="64,-264" limb2="2" limb2anchor="0,-100" lowerlimit="180" upperlimit="210" canbesevered="true"/>
|
<joint limb1="0" limb1anchor="64,-264" limb2="2" limb2anchor="0,-100" lowerlimit="180" upperlimit="210" canbesevered="true"/>
|
||||||
|
|
||||||
<joint limb1="0" limb1anchor="-100,100" limb2="3" limb2anchor="38,0" lowerlimit="-50" upperlimit="5" canbesevered="true"/>
|
<joint limb1="0" limb1anchor="-100,100" limb2="3" limb2anchor="38,0" lowerlimit="-50" upperlimit="5" canbesevered="true"/>
|
||||||
<joint limb1="0" limb1anchor="140,268" limb2="4" limb2anchor="0,0" lowerlimit="87" upperlimit="93"/>
|
<joint limb1="0" limb1anchor="140,268" limb2="4" limb2anchor="0,0" lowerlimit="87" upperlimit="93" canbesevered="false"/>
|
||||||
|
|
||||||
</ragdoll>
|
</ragdoll>
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<Wearable limbtype="Head" slots="Any,Face">
|
<Wearable limbtype="Head" slots="Any,Face">
|
||||||
<sprite texture="DivingMask.png" limb="Head" sourcerect="1,1,37,38"/>
|
<sprite texture="DivingMask.png" limb="Head" sourcerect="1,1,37,38"/>
|
||||||
<StatusEffect type="OnWearing" target="Character" ObstructVision="true" setvalue="true" disabledeltatime="true"/>
|
<StatusEffect type="OnWearing" target="Character" HideFace="true" ObstructVision="true" setvalue="true" disabledeltatime="true"/>
|
||||||
<StatusEffect type="OnWearing" target="Contained,Character" OxygenAvailable="1000.0" Condition="-0.5">
|
<StatusEffect type="OnWearing" target="Contained,Character" OxygenAvailable="1000.0" Condition="-0.5">
|
||||||
<RequiredItem type="Contained" name="Oxygen Tank"/>
|
<RequiredItem type="Contained" name="Oxygen Tank"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
<sprite texture="DivingSuit.png" limb="RightFoot" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
|
<sprite texture="DivingSuit.png" limb="RightFoot" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
|
||||||
<sprite texture="DivingSuit.png" limb="LeftFoot" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
|
<sprite texture="DivingSuit.png" limb="LeftFoot" sourcerect="30,100,20,25" origin="0.5,0.5" depth="0.13" inheritlimbdepth="false" hidelimb="true"/>
|
||||||
|
|
||||||
<StatusEffect type="OnWearing" target="Character" ObstructVision="true" PressureProtection="100.0" SpeedMultiplier="0.6" LowPassMultiplier="0.2" setvalue="true" disabledeltatime="true"/>
|
<StatusEffect type="OnWearing" target="Character" HideFace="true" ObstructVision="true" PressureProtection="100.0" SpeedMultiplier="0.6" LowPassMultiplier="0.2" setvalue="true" disabledeltatime="true"/>
|
||||||
<StatusEffect type="OnWearing" target="Contained,Character" OxygenAvailable="1000.0" Condition="-0.5">
|
<StatusEffect type="OnWearing" target="Contained,Character" OxygenAvailable="1000.0" Condition="-0.5">
|
||||||
<RequiredItem type="Contained" name="Oxygen Tank"/>
|
<RequiredItem type="Contained" name="Oxygen Tank"/>
|
||||||
</StatusEffect>
|
</StatusEffect>
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
|
|
||||||
<Sprite texture ="door.png" sourcerect="1,0,48,208" depth="0.01" origin="0.5,0.5"/>
|
<Sprite texture ="door.png" sourcerect="1,0,48,208" depth="0.01" origin="0.5,0.5"/>
|
||||||
|
|
||||||
<Door canbeselected="true">
|
<Door canbeselected="true" selectkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
|
||||||
|
<requireditem name="Crowbar" type="Equipped"/>
|
||||||
<Sprite texture ="door.png" sourcerect="80,0,19,208" depth="0.05" origin="0.5,0.0"/>
|
<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="door.ogg" type="OnUse" range="500.0"/>
|
||||||
|
<sound file="Content/Items/Tools/Crowbar.ogg" type="OnPicked" range="2000.0"/>
|
||||||
</Door>
|
</Door>
|
||||||
|
|
||||||
<AiTarget sightrange="500.0"/>
|
<AiTarget sightrange="500.0"/>
|
||||||
@@ -35,11 +37,13 @@
|
|||||||
|
|
||||||
<Sprite texture="door.png" sourcerect="1,0,48,208" depth="0.01" origin="0.5,0.5"/>
|
<Sprite texture="door.png" sourcerect="1,0,48,208" depth="0.01" origin="0.5,0.5"/>
|
||||||
|
|
||||||
<Door window="0,-32,10,75" canbeselected="true">
|
<Door window="0,-32,10,75" canbeselected="true" selectkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
|
||||||
|
<requireditem name="Crowbar" type="Equipped"/>
|
||||||
<Sprite texture="door.png" sourcerect="56,0,19,208" depth="0.05" origin="0.5,0.0"/>
|
<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="door.ogg" type="OnUse" range="500.0"/>
|
||||||
|
<sound file="Content/Items/Tools/Crowbar.ogg" type="OnPicked" range="2000.0"/>
|
||||||
</Door>
|
</Door>
|
||||||
|
|
||||||
<AiTarget sightrange="500.0"/>
|
<AiTarget sightrange="500.0"/>
|
||||||
@@ -64,11 +68,13 @@
|
|||||||
|
|
||||||
<Sprite texture="hatch.png" sourcerect="0,0,128,46" depth="0.01" origin="0.5,0.5"/>
|
<Sprite texture="hatch.png" sourcerect="0,0,128,46" depth="0.01" origin="0.5,0.5"/>
|
||||||
|
|
||||||
<Door canbeselected="true" horizontal="true">
|
<Door canbeselected="true" horizontal="true" selectkey="Action" msg="Force Open [Crowbar]" PickingTime="10.0">
|
||||||
|
<requireditem name="Crowbar" type="Equipped"/>
|
||||||
<Sprite texture="hatch.png" sourcerect="128,0,128,19" depth="0.05" origin="0.0,0.5"/>
|
<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="door.ogg" type="OnUse" range="500.0"/>
|
||||||
|
<sound file="Content/Items/Tools/Crowbar.ogg" type="OnPicked" range="2000.0"/>
|
||||||
</Door>
|
</Door>
|
||||||
|
|
||||||
<AiTarget sightrange="500.0"/>
|
<AiTarget sightrange="500.0"/>
|
||||||
|
|||||||
@@ -14,13 +14,16 @@
|
|||||||
<RequiredItems name="Battery Cell" type="Contained"/>
|
<RequiredItems name="Battery Cell" type="Contained"/>
|
||||||
</WifiComponent>
|
</WifiComponent>
|
||||||
|
|
||||||
<ItemContainer capacity="1" hideitems="true">
|
<ItemContainer capacity="1" hideitems="true">
|
||||||
<Containable name="Battery Cell"/>
|
<Containable name="Battery Cell">
|
||||||
<Containable name="Fulgurium Battery Cell"/>
|
<StatusEffect type="OnContaining" target="Contained" Condition="-0.05"/>
|
||||||
</ItemContainer>
|
</Containable>
|
||||||
|
<Containable name="Fulgurium Battery Cell">
|
||||||
|
<StatusEffect type="OnContaining" target="Contained" Condition="-0.05"/>
|
||||||
|
</Containable>
|
||||||
|
</ItemContainer>
|
||||||
|
|
||||||
<Wearable limbtype="Head" slots="Any,Face">
|
<Wearable limbtype="Head" slots="Any,Face">
|
||||||
<StatusEffect type="OnWearing" target="Contained" Condition="-0.1"/>
|
|
||||||
<sprite texture="headset.png" limb="Head" origin="0.5,0.5"/>
|
<sprite texture="headset.png" limb="Head" origin="0.5,0.5"/>
|
||||||
</Wearable>
|
</Wearable>
|
||||||
</Item>
|
</Item>
|
||||||
@@ -38,6 +41,7 @@
|
|||||||
|
|
||||||
<Wearable limbtype="Head" slots="Any,Face">
|
<Wearable limbtype="Head" slots="Any,Face">
|
||||||
<sprite texture="clownmask.png" limb="Head" origin="0.5,0.5"/>
|
<sprite texture="clownmask.png" limb="Head" origin="0.5,0.5"/>
|
||||||
|
<StatusEffect type="OnWearing" target="Character" HideFace="true"/>
|
||||||
</Wearable>
|
</Wearable>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
|
|
||||||
<Body radius="6" height="22" density="5"/>
|
<Body radius="6" height="22" density="5"/>
|
||||||
|
|
||||||
<Holdable handle1="0,0" slots="RightHand,Any"/>
|
<Holdable handle1="0,0" slots="Any,RightHand,LeftHand"/>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
<Item
|
<Item
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
<Body radius="6" height="22" density="5"/>
|
<Body radius="6" height="22" density="5"/>
|
||||||
|
|
||||||
<Holdable handle1="0,0" slots="RightHand,Any"/>
|
<Holdable handle1="0,0" slots="Any,RightHand,LeftHand"/>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 9.7 KiB |
@@ -116,7 +116,7 @@
|
|||||||
|
|
||||||
<Body width="12" height="33" density="5"/>
|
<Body width="12" height="33" density="5"/>
|
||||||
|
|
||||||
<Holdable slots="RightHand,Any" holdpos="30,-15" handle1="0,5" handle2="0,-5">
|
<Holdable slots="Any,RightHand,LeftHand" holdpos="30,-15" handle1="0,5" handle2="0,-5">
|
||||||
<StatusEffect type="OnFire" target="This" Condition="-100.0" disabledeltatime="true">
|
<StatusEffect type="OnFire" target="This" Condition="-100.0" disabledeltatime="true">
|
||||||
<sound file="Content/Items/Reactor/explosion.ogg"/>
|
<sound file="Content/Items/Reactor/explosion.ogg"/>
|
||||||
<Explosion range="250.0" structuredamage="15" damage="25" stun="5" force="3.0"/>
|
<Explosion range="250.0" structuredamage="15" damage="25" stun="5" force="3.0"/>
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
|
|
||||||
price="10">
|
price="10">
|
||||||
|
|
||||||
<Sprite texture ="tools.png" sourcerect="0,50,26,7" depth="0.55"/>
|
<Sprite texture ="tools.png" sourcerect="0,50,26,7" depth="0.55"/>
|
||||||
|
|
||||||
<Body width="30" height="7" density="50"/>
|
<Body width="30" height="7" density="50"/>
|
||||||
|
|
||||||
@@ -185,6 +185,23 @@
|
|||||||
</MeleeWeapon>
|
</MeleeWeapon>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
<Item
|
||||||
|
name="Crowbar"
|
||||||
|
category="Equipment"
|
||||||
|
Tags="smallitem"
|
||||||
|
|
||||||
|
price="15">
|
||||||
|
|
||||||
|
<Sprite texture ="tools.png" sourcerect="0,65,64,12" depth="0.55"/>
|
||||||
|
|
||||||
|
<Body width="60" height="10" density="50"/>
|
||||||
|
|
||||||
|
<MeleeWeapon slots="RightHand+LeftHand,Any"
|
||||||
|
controlpose="true" aimpos="50,0" handle1="-5,0" handle2="-3,5" holdangle="30" reload="1.7">
|
||||||
|
<Attack damage="20" stun="0.6" damagetype="Blunt" sound="Content/Items/Weapons/smack.ogg"/>
|
||||||
|
</MeleeWeapon>
|
||||||
|
</Item>
|
||||||
|
|
||||||
<Item
|
<Item
|
||||||
name="Handheld Sonar"
|
name="Handheld Sonar"
|
||||||
category="Equipment"
|
category="Equipment"
|
||||||
@@ -218,8 +235,7 @@
|
|||||||
<Item
|
<Item
|
||||||
name="Flashlight"
|
name="Flashlight"
|
||||||
category="Equipment"
|
category="Equipment"
|
||||||
Tags="smallitem"
|
Tags="smallitem"
|
||||||
|
|
||||||
price="10">
|
price="10">
|
||||||
|
|
||||||
<Deconstruct time="15">
|
<Deconstruct time="15">
|
||||||
@@ -231,12 +247,11 @@
|
|||||||
|
|
||||||
<Body width="27" height="10" density="15"/>
|
<Body width="27" height="10" density="15"/>
|
||||||
|
|
||||||
<Holdable slots="Any,RightHand,LeftHand" aimpos="100,0" handle1="0,0">
|
<Holdable slots="Any,RightHand,LeftHand,Face" holdpos="30,-15" aimpos="100,0" handle1="-13,0" handle2="-13,0">
|
||||||
<StatusEffect type="OnActive" target="Contained" Condition="-0.2"/>
|
<StatusEffect type="OnActive" target="Contained" Condition="-0.2"/>
|
||||||
</Holdable>
|
</Holdable>
|
||||||
|
|
||||||
<LightComponent LightColor="1.0,1.0,1.0,1.0" Flicker="0.1" range="800" powerconsumption="10" IsOn="true">
|
<LightComponent LightColor="1.0,1.0,1.0,1.0" Flicker="0.1" range="800" powerconsumption="10" IsOn="true">
|
||||||
|
|
||||||
<LightTexture texture="Content/Lights/lightcone.png" origin="0.0, 0.5" size="2.0,1.0"/>
|
<LightTexture texture="Content/Lights/lightcone.png" origin="0.0, 0.5" size="2.0,1.0"/>
|
||||||
</LightComponent>
|
</LightComponent>
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
name="Revolver"
|
name="Revolver"
|
||||||
category="Equipment"
|
category="Equipment"
|
||||||
price="700"
|
price="700"
|
||||||
tags="weapon">
|
tags="smallitem,weapon">
|
||||||
|
|
||||||
<Deconstruct time="10">
|
<Deconstruct time="10">
|
||||||
<Item name="Steel Bar"/>
|
<Item name="Steel Bar"/>
|
||||||
|
|||||||
@@ -10,8 +10,5 @@
|
|||||||
|
|
||||||
<Body width="16" height="16" density="20"/>
|
<Body width="16" height="16" density="20"/>
|
||||||
|
|
||||||
<Pickable/>
|
<Pickable slots="Card,Any"/>
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<Skill name="Medical" level="10,30"/>
|
<Skill name="Medical" level="10,30"/>
|
||||||
</Skills>
|
</Skills>
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="ID Card"/>
|
<Item name="ID Card" equip="true"/>
|
||||||
<Item name="Captain's Cap" equip="true"/>
|
<Item name="Captain's Cap" equip="true"/>
|
||||||
<Item name="Captain's Jacket" equip="true"/>
|
<Item name="Captain's Jacket" equip="true"/>
|
||||||
<Item name="Captain's Trousers" equip="true"/>
|
<Item name="Captain's Trousers" equip="true"/>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<Skill name="Medical" level="10,20"/>
|
<Skill name="Medical" level="10,20"/>
|
||||||
</Skills>
|
</Skills>
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="ID Card"/>
|
<Item name="ID Card" equip="true"/>
|
||||||
<Item name="Wrench"/>
|
<Item name="Wrench"/>
|
||||||
<Item name="Screwdriver"/>
|
<Item name="Screwdriver"/>
|
||||||
<Item name="Orange Jumpsuit" equip="true"/>
|
<Item name="Orange Jumpsuit" equip="true"/>
|
||||||
@@ -48,7 +48,8 @@
|
|||||||
<Skill name="Medical" level="10,20"/>
|
<Skill name="Medical" level="10,20"/>
|
||||||
</Skills>
|
</Skills>
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="ID Card"/>
|
<Item name="ID Card" equip="true"/>
|
||||||
|
<Item name="Crowbar"/>
|
||||||
<Item name="Wrench"/>
|
<Item name="Wrench"/>
|
||||||
<Item name="Screwdriver"/>
|
<Item name="Screwdriver"/>
|
||||||
<Item name="Blue Jumpsuit" equip="true"/>
|
<Item name="Blue Jumpsuit" equip="true"/>
|
||||||
@@ -66,7 +67,7 @@
|
|||||||
<Skill name="Electrical Engineering" level="10,20"/>
|
<Skill name="Electrical Engineering" level="10,20"/>
|
||||||
</Skills>
|
</Skills>
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="ID Card"/>
|
<Item name="ID Card" equip="true"/>
|
||||||
<Item name="Stun Baton"/>
|
<Item name="Stun Baton"/>
|
||||||
<Item name="Battery Cell"/>
|
<Item name="Battery Cell"/>
|
||||||
<Item name="Handcuffs"/>
|
<Item name="Handcuffs"/>
|
||||||
@@ -86,7 +87,7 @@
|
|||||||
<Skill name="Medical" level="60,70"/>
|
<Skill name="Medical" level="60,70"/>
|
||||||
</Skills>
|
</Skills>
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="ID Card"/>
|
<Item name="ID Card" equip="true"/>
|
||||||
<Item name="Doctor's Coat" equip="true"/>
|
<Item name="Doctor's Coat" equip="true"/>
|
||||||
<Item name="Doctor's Trousers" equip="true"/>
|
<Item name="Doctor's Trousers" equip="true"/>
|
||||||
<Item name="Health Scanner HUD"/>
|
<Item name="Health Scanner HUD"/>
|
||||||
@@ -105,7 +106,7 @@
|
|||||||
<Skill name="Medical" level="10,20"/>
|
<Skill name="Medical" level="10,20"/>
|
||||||
</Skills>
|
</Skills>
|
||||||
<Items>
|
<Items>
|
||||||
<Item name="ID Card"/>
|
<Item name="ID Card" equip="true"/>
|
||||||
<Item name="Wrench"/>
|
<Item name="Wrench"/>
|
||||||
<Item name="Screwdriver"/>
|
<Item name="Screwdriver"/>
|
||||||
<Item name="Headset" equip="true">
|
<Item name="Headset" equip="true">
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
<damagesound file="Content/Sounds/Damage/GlassImpact3.ogg" damagerange="10.0,20.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
<damagesound file="Content/Sounds/Damage/GlassImpact3.ogg" damagerange="10.0,20.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
||||||
|
|
||||||
<damagesound file="Content/Sounds/Damage/GlassBreak1.ogg" damagerange="20.0,50.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
<damagesound file="Content/Sounds/Damage/GlassBreak1.ogg" damagerange="20.0,50.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
||||||
<damagesound file="Content/Sounds/Damage/GlassBreak1.ogg" damagerange="25.0,80.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
<damagesound file="Content/Sounds/Damage/GlassBreak2.ogg" damagerange="25.0,80.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
||||||
<damagesound file="Content/Sounds/Damage/GlassBreak1.ogg" damagerange="50.0,100.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
<damagesound file="Content/Sounds/Damage/GlassBreak3.ogg" damagerange="50.0,100.0" damagesoundtype="StructureBlunt" requiredtag="glass"/>
|
||||||
|
|
||||||
<damagesound file="Content/Sounds/Damage/StructureCrunch1.ogg" damagerange="0.0,40.0" damagesoundtype="StructureSlash"/>
|
<damagesound file="Content/Sounds/Damage/StructureCrunch1.ogg" damagerange="0.0,40.0" damagesoundtype="StructureSlash"/>
|
||||||
<damagesound file="Content/Sounds/Damage/StructureCrunch2.ogg" damagerange="5.0,70.0" damagesoundtype="StructureSlash"/>
|
<damagesound file="Content/Sounds/Damage/StructureCrunch2.ogg" damagerange="5.0,70.0" damagesoundtype="StructureSlash"/>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<PermissionPresets>
|
||||||
|
<Preset
|
||||||
|
name="None"
|
||||||
|
description="No special privileges."
|
||||||
|
permissions="None"/>
|
||||||
|
|
||||||
|
<Preset
|
||||||
|
name="Moderator"
|
||||||
|
description="Allowed to manage round settings and kick players."
|
||||||
|
permissions="EndRound,Kick,SelectSub,SelectMode,ManageCampaign,ConsoleCommands">
|
||||||
|
<Command name="clientlist"/>
|
||||||
|
<Command name="autorestart"/>
|
||||||
|
<Command name="autorestartinterval"/>
|
||||||
|
<Command name="autorestarttimer"/>
|
||||||
|
<Command name="kick"/>
|
||||||
|
<Command name="kickid"/>
|
||||||
|
<Command name="campaigninfo"/>
|
||||||
|
<Command name="campaigndestination"/>
|
||||||
|
</Preset>
|
||||||
|
|
||||||
|
<Preset
|
||||||
|
name="Admin"
|
||||||
|
description="Allowed to ban and kick players, manage round settings and use nearly all console commands."
|
||||||
|
permissions="EndRound,Kick,Ban,SelectSub,SelectMode,ManageCampaign,ConsoleCommands">
|
||||||
|
<Command name="clientlist"/>
|
||||||
|
<Command name="autorestart"/>
|
||||||
|
<Command name="autorestartinterval"/>
|
||||||
|
<Command name="autorestarttimer"/>
|
||||||
|
<Command name="kick"/>
|
||||||
|
<Command name="kickid"/>
|
||||||
|
<Command name="campaigninfo"/>
|
||||||
|
<Command name="campaigndestination"/>
|
||||||
|
<Command name="spawn"/>
|
||||||
|
<Command name="spawnitem"/>
|
||||||
|
<Command name="disablecrewai"/>
|
||||||
|
<Command name="enablecrewai"/>
|
||||||
|
<Command name="ban"/>
|
||||||
|
<Command name="banid"/>
|
||||||
|
<Command name="banip"/>
|
||||||
|
<Command name="teleportcharacter"/>
|
||||||
|
<Command name="godmode"/>
|
||||||
|
<Command name="lockx"/>
|
||||||
|
<Command name="locky"/>
|
||||||
|
<Command name="heal"/>
|
||||||
|
<Command name="revive"/>
|
||||||
|
<Command name="freeze"/>
|
||||||
|
<Command name="freecam"/>
|
||||||
|
<Command name="explosion"/>
|
||||||
|
<Command name="fixitems"/>
|
||||||
|
<Command name="fixhulls"/>
|
||||||
|
<Command name="power"/>
|
||||||
|
<Command name="oxygen"/>
|
||||||
|
<Command name="setclientcharacter"/>
|
||||||
|
</Preset>
|
||||||
|
</PermissionPresets>
|
||||||
@@ -9,6 +9,8 @@ namespace Barotrauma
|
|||||||
public enum Animation { None, Climbing, UsingConstruction, Struggle, CPR };
|
public enum Animation { None, Climbing, UsingConstruction, Struggle, CPR };
|
||||||
public Animation Anim;
|
public Animation Anim;
|
||||||
|
|
||||||
|
public LimbType GrabLimb;
|
||||||
|
|
||||||
protected Character character;
|
protected Character character;
|
||||||
|
|
||||||
protected float walkSpeed, swimSpeed;
|
protected float walkSpeed, swimSpeed;
|
||||||
|
|||||||
+165
-34
@@ -20,6 +20,7 @@ namespace Barotrauma
|
|||||||
private float thighTorque;
|
private float thighTorque;
|
||||||
|
|
||||||
private float cprAnimState;
|
private float cprAnimState;
|
||||||
|
private float cprPump;
|
||||||
|
|
||||||
private float inWaterTimer;
|
private float inWaterTimer;
|
||||||
private bool swimming;
|
private bool swimming;
|
||||||
@@ -872,7 +873,34 @@ namespace Barotrauma
|
|||||||
character.SelectedConstruction = null;
|
character.SelectedConstruction = null;
|
||||||
IgnorePlatforms = false;
|
IgnorePlatforms = false;
|
||||||
}
|
}
|
||||||
|
else if (character.SelectedCharacter != null && !character.SelectedCharacter.AllowInput)
|
||||||
|
{
|
||||||
|
Limb targetLeftHand = character.SelectedCharacter.AnimController.GetLimb(LimbType.LeftHand);
|
||||||
|
Limb targetRightHand = character.SelectedCharacter.AnimController.GetLimb(LimbType.RightHand);
|
||||||
|
Limb targetTorso = character.SelectedCharacter.AnimController.GetLimb(LimbType.Torso);
|
||||||
|
|
||||||
|
if (character.SelectedCharacter.AnimController.Dir != Dir)
|
||||||
|
character.SelectedCharacter.AnimController.Flip();
|
||||||
|
|
||||||
|
targetTorso.pullJoint.Enabled = true;
|
||||||
|
targetTorso.pullJoint.WorldAnchorB = torso.SimPosition + (Vector2.UnitX * -Dir) * 0.2f;
|
||||||
|
targetTorso.pullJoint.MaxForce = 5000.0f;
|
||||||
|
|
||||||
|
if (!targetLeftHand.IsSevered)
|
||||||
|
{
|
||||||
|
targetLeftHand.pullJoint.Enabled = true;
|
||||||
|
targetLeftHand.pullJoint.WorldAnchorB = torso.SimPosition + (new Vector2(1 * Dir, 1)) * 0.2f;
|
||||||
|
targetLeftHand.pullJoint.MaxForce = 5000.0f;
|
||||||
|
}
|
||||||
|
if (!targetRightHand.IsSevered)
|
||||||
|
{
|
||||||
|
targetRightHand.pullJoint.Enabled = true;
|
||||||
|
targetRightHand.pullJoint.WorldAnchorB = torso.SimPosition + (new Vector2(1 * Dir, 1)) * 0.2f;
|
||||||
|
targetRightHand.pullJoint.MaxForce = 5000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
character.SelectedCharacter.AnimController.IgnorePlatforms = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateCPR(float deltaTime)
|
private void UpdateCPR(float deltaTime)
|
||||||
@@ -883,11 +911,16 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Character target = character.SelectedCharacter;
|
||||||
|
|
||||||
Crouching = true;
|
Crouching = true;
|
||||||
|
|
||||||
Vector2 diff = character.SelectedCharacter.SimPosition - character.SimPosition;
|
Vector2 diff = target.SimPosition - character.SimPosition;
|
||||||
var targetHead = character.SelectedCharacter.AnimController.GetLimb(LimbType.Head);
|
Limb targetHead = target.AnimController.GetLimb(LimbType.Head);
|
||||||
|
Limb targetTorso = target.AnimController.GetLimb(LimbType.Torso);
|
||||||
|
Limb head = GetLimb(LimbType.Head);
|
||||||
|
Limb torso = GetLimb(LimbType.Torso);
|
||||||
|
|
||||||
Vector2 headDiff = targetHead == null ? diff : targetHead.SimPosition - character.SimPosition;
|
Vector2 headDiff = targetHead == null ? diff : targetHead.SimPosition - character.SimPosition;
|
||||||
|
|
||||||
targetMovement = new Vector2(diff.X, 0.0f);
|
targetMovement = new Vector2(diff.X, 0.0f);
|
||||||
@@ -895,21 +928,98 @@ namespace Barotrauma
|
|||||||
|
|
||||||
UpdateStanding();
|
UpdateStanding();
|
||||||
|
|
||||||
Vector2 handPos = character.SelectedCharacter.AnimController.GetLimb(LimbType.Torso).SimPosition + Vector2.UnitY * 0.2f;
|
Vector2 handPos = targetTorso.SimPosition + Vector2.UnitY * 0.2f;
|
||||||
|
|
||||||
Grab(handPos, handPos);
|
Grab(handPos, handPos);
|
||||||
|
|
||||||
float yPos = (float)Math.Sin(cprAnimState) * 0.1f;
|
Vector2 colliderPos = GetColliderBottom();
|
||||||
cprAnimState += deltaTime * 8.0f;
|
|
||||||
|
|
||||||
var head = GetLimb(LimbType.Head);
|
if (GameMain.Client == null) //Serverside code
|
||||||
head.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.6f + yPos);
|
{
|
||||||
head.pullJoint.Enabled = true;
|
if (target.Bleeding <= 0.5f && target.Oxygen <= 0.0f) //If they're bleeding too hard CPR will hurt them
|
||||||
|
{
|
||||||
|
target.Oxygen += deltaTime * 0.5f; //Stabilize them
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int skill = character.GetSkillLevel("Medical");
|
||||||
|
if (cprAnimState % 17 > 15.0f)
|
||||||
|
{
|
||||||
|
float yPos = (float)Math.Sin(cprAnimState) * 0.2f;
|
||||||
|
head.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.3f + yPos);
|
||||||
|
head.pullJoint.Enabled = true;
|
||||||
|
torso.pullJoint.WorldAnchorB = new Vector2(torso.SimPosition.X, colliderPos.Y + (TorsoPosition - 0.2f));
|
||||||
|
torso.pullJoint.Enabled = true;
|
||||||
|
|
||||||
|
if (GameMain.Client == null) //Serverside code
|
||||||
|
{
|
||||||
|
float cpr = skill / 2.0f; //Max possible oxygen addition is 20 per second
|
||||||
|
character.Oxygen -= (30.0f - cpr) * deltaTime; //Worse skill = more oxygen required
|
||||||
|
if (character.Oxygen > 0.0f) //we didn't suffocate yet did we
|
||||||
|
target.Oxygen += cpr * deltaTime;
|
||||||
|
|
||||||
|
//DebugConsole.NewMessage("CPR Us: " + character.Oxygen + " Them: " + target.Oxygen + " How good we are: restore " + cpr + " use " + (30.0f - cpr), Color.Aqua);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
head.pullJoint.WorldAnchorB = new Vector2(targetHead.SimPosition.X, targetHead.SimPosition.Y + 0.8f);
|
||||||
|
head.pullJoint.Enabled = true;
|
||||||
|
torso.pullJoint.WorldAnchorB = new Vector2(torso.SimPosition.X, colliderPos.Y + (TorsoPosition - 0.1f));
|
||||||
|
torso.pullJoint.Enabled = true;
|
||||||
|
if (cprPump >= 1)
|
||||||
|
{
|
||||||
|
torso.body.ApplyForce(new Vector2(0, -1000f));
|
||||||
|
targetTorso.body.ApplyForce(new Vector2(0, -1000f));
|
||||||
|
cprPump = 0;
|
||||||
|
|
||||||
|
if (target.Bleeding <= 0.5f && target.Health <= 0.0f && !target.IsDead) //Have a chance to revive them to 2 HP if they were damaged.
|
||||||
|
{
|
||||||
|
if (GameMain.Client == null) //Serverside code
|
||||||
|
{
|
||||||
|
float reviveChance = (cprAnimState % 17) * (skill / 50.0f); //~5% max chance for 10 skill, ~50% max chance for 100 skill
|
||||||
|
float rng = Rand.Int(100, Rand.RandSync.Server);
|
||||||
|
|
||||||
|
//DebugConsole.NewMessage("CPR Pump cprAnimState: " + (cprAnimState % 17) + " revive chance: " + reviveChance + " rng: " + rng, Color.Aqua);
|
||||||
|
if (rng <= reviveChance) //HOLY CRAP YOU SAVED HIM!!!
|
||||||
|
{
|
||||||
|
target.Oxygen = Math.Max(target.Oxygen, 10.0f);
|
||||||
|
target.Health = 2.0f;
|
||||||
|
Anim = Animation.None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (target.Bleeding > 0.5f || skill < 50) //We will hurt them if they're bleeding or we suck
|
||||||
|
{
|
||||||
|
//If not bleeding: 10% skill causes 0.8 damage per pump, 40% skill causes only 0.2
|
||||||
|
if (target.Bleeding <= 0.5f)
|
||||||
|
target.AddDamage(CauseOfDeath.Damage, (50 - skill) * 0.02f, character);
|
||||||
|
else //If bleeding: 2 HP damage per pump. Basically speeds up their death. Don't pump bleeding people!
|
||||||
|
{
|
||||||
|
target.AddDamage(CauseOfDeath.Bloodloss, 1.0f, character);
|
||||||
|
#if CLIENT
|
||||||
|
SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, 25.0f, targetTorso.body);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
var blood = GameMain.ParticleManager.CreateParticle(inWater ? "waterblood" : "blood", targetTorso.WorldPosition, Rand.Vector(10.0f), 0.0f, target.AnimController.CurrentHull);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cprPump += deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
cprAnimState += deltaTime;
|
||||||
}
|
}
|
||||||
public override void DragCharacter(Character target)
|
public override void DragCharacter(Character target)
|
||||||
{
|
{
|
||||||
if (target == null) return;
|
if (target == null) return;
|
||||||
|
|
||||||
|
Limb torso = GetLimb(LimbType.Torso);
|
||||||
Limb leftHand = GetLimb(LimbType.LeftHand);
|
Limb leftHand = GetLimb(LimbType.LeftHand);
|
||||||
Limb rightHand = GetLimb(LimbType.RightHand);
|
Limb rightHand = GetLimb(LimbType.RightHand);
|
||||||
|
|
||||||
@@ -922,31 +1032,34 @@ namespace Barotrauma
|
|||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Limb targetLimb = target.AnimController.GetLimb(LimbType.Torso);
|
Limb targetLimb = target.AnimController.GetLimb(GrabLimb);
|
||||||
|
|
||||||
if (i == 0)
|
if (targetLimb == null || targetLimb.IsSevered)
|
||||||
{
|
{
|
||||||
if (!targetLeftHand.IsSevered)
|
targetLimb = target.AnimController.GetLimb(LimbType.Torso);
|
||||||
|
if (i == 0)
|
||||||
{
|
{
|
||||||
targetLimb = targetLeftHand;
|
if (!targetLeftHand.IsSevered)
|
||||||
|
{
|
||||||
|
targetLimb = targetLeftHand;
|
||||||
|
}
|
||||||
|
else if (!targetRightHand.IsSevered)
|
||||||
|
{
|
||||||
|
targetLimb = targetRightHand;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!targetRightHand.IsSevered)
|
else
|
||||||
{
|
{
|
||||||
targetLimb = targetRightHand;
|
if (!targetRightHand.IsSevered)
|
||||||
|
{
|
||||||
|
targetLimb = targetRightHand;
|
||||||
|
}
|
||||||
|
else if (!targetLeftHand.IsSevered)
|
||||||
|
{
|
||||||
|
targetLimb = targetLeftHand;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!targetRightHand.IsSevered)
|
|
||||||
{
|
|
||||||
targetLimb = targetRightHand;
|
|
||||||
}
|
|
||||||
else if (!targetLeftHand.IsSevered)
|
|
||||||
{
|
|
||||||
targetLimb = targetLeftHand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Limb pullLimb = i == 0 ? leftHand : rightHand;
|
Limb pullLimb = i == 0 ? leftHand : rightHand;
|
||||||
|
|
||||||
if (i == 1 && inWater)
|
if (i == 1 && inWater)
|
||||||
@@ -958,12 +1071,32 @@ namespace Barotrauma
|
|||||||
Vector2 diff = ConvertUnits.ToSimUnits(targetLimb.WorldPosition - pullLimb.WorldPosition);
|
Vector2 diff = ConvertUnits.ToSimUnits(targetLimb.WorldPosition - pullLimb.WorldPosition);
|
||||||
|
|
||||||
pullLimb.pullJoint.Enabled = true;
|
pullLimb.pullJoint.Enabled = true;
|
||||||
pullLimb.pullJoint.WorldAnchorB = pullLimb.SimPosition + diff;
|
if (targetLimb.type == LimbType.Torso)
|
||||||
pullLimb.pullJoint.MaxForce = 10000.0f;
|
{
|
||||||
|
pullLimb.pullJoint.WorldAnchorB = targetLimb.SimPosition;
|
||||||
|
pullLimb.pullJoint.MaxForce = 5000.0f;
|
||||||
|
targetMovement *= 0.7f; //Carrying people like that takes a lot of effort.
|
||||||
|
|
||||||
|
if (target.AnimController.Dir != Dir)
|
||||||
|
target.AnimController.Flip();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pullLimb.pullJoint.WorldAnchorB = pullLimb.SimPosition + diff;
|
||||||
|
pullLimb.pullJoint.MaxForce = 5000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
targetLimb.pullJoint.Enabled = true;
|
targetLimb.pullJoint.Enabled = true;
|
||||||
targetLimb.pullJoint.WorldAnchorB = targetLimb.SimPosition - diff;
|
if (targetLimb.type == LimbType.Torso)
|
||||||
targetLimb.pullJoint.MaxForce = 10000.0f;
|
{
|
||||||
|
targetLimb.pullJoint.WorldAnchorB = torso.SimPosition + (Vector2.UnitX * Dir) * 0.6f;
|
||||||
|
targetLimb.pullJoint.MaxForce = 300.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetLimb.pullJoint.WorldAnchorB = targetLimb.SimPosition - diff;
|
||||||
|
targetLimb.pullJoint.MaxForce = 5000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
target.AnimController.movement = -diff;
|
target.AnimController.movement = -diff;
|
||||||
}
|
}
|
||||||
@@ -1011,8 +1144,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle)
|
public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle)
|
||||||
{
|
{
|
||||||
Holdable holdable = item.GetComponent<Holdable>();
|
|
||||||
|
|
||||||
if (character.IsUnconscious || character.Stun > 0.0f) aim = false;
|
if (character.IsUnconscious || character.Stun > 0.0f) aim = false;
|
||||||
|
|
||||||
//calculate the handle positions
|
//calculate the handle positions
|
||||||
@@ -1030,7 +1161,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
bool usingController = character.SelectedConstruction != null && character.SelectedConstruction.GetComponent<Controller>() != null;
|
bool usingController = character.SelectedConstruction != null && character.SelectedConstruction.GetComponent<Controller>() != null;
|
||||||
|
|
||||||
|
|
||||||
float itemAngle;
|
float itemAngle;
|
||||||
if (Anim != Animation.Climbing && !usingController && character.Stun <= 0.0f && aim && itemPos != Vector2.Zero)
|
if (Anim != Animation.Climbing && !usingController && character.Stun <= 0.0f && aim && itemPos != Vector2.Zero)
|
||||||
{
|
{
|
||||||
@@ -1042,6 +1172,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
itemAngle = (torso.body.Rotation + holdAngle * Dir);
|
itemAngle = (torso.body.Rotation + holdAngle * Dir);
|
||||||
|
|
||||||
|
Holdable holdable = item.GetComponent<Holdable>();
|
||||||
if (holdable.ControlPose)
|
if (holdable.ControlPose)
|
||||||
{
|
{
|
||||||
head.body.SmoothRotate(itemAngle);
|
head.body.SmoothRotate(itemAngle);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
|
using FarseerPhysics.Dynamics;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -138,6 +139,27 @@ namespace Barotrauma
|
|||||||
return info != null && !string.IsNullOrWhiteSpace(info.Name) ? info.Name : SpeciesName;
|
return info != null && !string.IsNullOrWhiteSpace(info.Name) ? info.Name : SpeciesName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Only used by server logs to determine "true identity" of the player for cases when they're disguised
|
||||||
|
public string LogName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return info != null && !string.IsNullOrWhiteSpace(info.Name) ? info.Name + (info.DisplayName != info.Name ? " (as " + info.DisplayName + ")" : "") : SpeciesName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float hideFaceTimer;
|
||||||
|
public bool HideFace
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return hideFaceTimer > 0.0f;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
hideFaceTimer = MathHelper.Clamp(hideFaceTimer + (value ? 1.0f : -0.5f), 0.0f, 10.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string ConfigPath
|
public string ConfigPath
|
||||||
{
|
{
|
||||||
@@ -591,7 +613,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
AnimController = new HumanoidAnimController(this, doc.Root.Element("ragdoll"));
|
AnimController = new HumanoidAnimController(this, doc.Root.Element("ragdoll"));
|
||||||
AnimController.TargetDir = Direction.Right;
|
AnimController.TargetDir = Direction.Right;
|
||||||
inventory = new CharacterInventory(16, this);
|
inventory = new CharacterInventory(17, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -961,6 +983,56 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CanSeeCharacter(Character character)
|
||||||
|
{
|
||||||
|
Limb selfLimb = AnimController.GetLimb(LimbType.Head);
|
||||||
|
if (selfLimb == null) selfLimb = AnimController.GetLimb(LimbType.Torso);
|
||||||
|
if (selfLimb == null) selfLimb = AnimController.Limbs[0];
|
||||||
|
|
||||||
|
Limb targetLimb = character.AnimController.GetLimb(LimbType.Head);
|
||||||
|
if (targetLimb == null) targetLimb = character.AnimController.GetLimb(LimbType.Torso);
|
||||||
|
if (targetLimb == null) targetLimb = character.AnimController.Limbs[0];
|
||||||
|
|
||||||
|
if (selfLimb != null && targetLimb != null)
|
||||||
|
{
|
||||||
|
Vector2 diff = ConvertUnits.ToSimUnits(targetLimb.WorldPosition - selfLimb.WorldPosition);
|
||||||
|
|
||||||
|
Body closestBody = null;
|
||||||
|
//both inside the same sub (or both outside)
|
||||||
|
//OR the we're inside, the other character outside
|
||||||
|
if (character.Submarine == Submarine || character.Submarine == null)
|
||||||
|
{
|
||||||
|
closestBody = Submarine.CheckVisibility(selfLimb.SimPosition, selfLimb.SimPosition + diff);
|
||||||
|
if (closestBody == null) return true;
|
||||||
|
}
|
||||||
|
//we're outside, the other character inside
|
||||||
|
else if (Submarine == null)
|
||||||
|
{
|
||||||
|
closestBody = Submarine.CheckVisibility(targetLimb.SimPosition, targetLimb.SimPosition - diff);
|
||||||
|
if (closestBody == null) return true;
|
||||||
|
}
|
||||||
|
//both inside different subs
|
||||||
|
else
|
||||||
|
{
|
||||||
|
closestBody = Submarine.CheckVisibility(selfLimb.SimPosition, selfLimb.SimPosition + diff);
|
||||||
|
if (closestBody != null && closestBody.UserData is Structure)
|
||||||
|
{
|
||||||
|
if (((Structure)closestBody.UserData).CastShadow) return false;
|
||||||
|
}
|
||||||
|
closestBody = Submarine.CheckVisibility(targetLimb.SimPosition, targetLimb.SimPosition - diff);
|
||||||
|
if (closestBody == null) return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Structure wall = closestBody.UserData as Structure;
|
||||||
|
return wall == null || !wall.CastShadow;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasEquippedItem(Item item)
|
public bool HasEquippedItem(Item item)
|
||||||
{
|
{
|
||||||
@@ -1311,7 +1383,7 @@ namespace Barotrauma
|
|||||||
findFocusedTimer -= deltaTime;
|
findFocusedTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SelectedCharacter != null && IsKeyHit(InputType.Select))
|
if (SelectedCharacter != null && focusedItem == null && IsKeyHit(InputType.Select)) //Let people use ladders and buttons and stuff when dragging chars
|
||||||
{
|
{
|
||||||
DeselectCharacter();
|
DeselectCharacter();
|
||||||
}
|
}
|
||||||
@@ -1379,6 +1451,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public virtual void Update(float deltaTime, Camera cam)
|
public virtual void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
|
UpdateProjSpecific(deltaTime, cam);
|
||||||
|
|
||||||
if (GameMain.Client != null && this == Controlled && !isSynced) return;
|
if (GameMain.Client != null && this == Controlled && !isSynced) return;
|
||||||
|
|
||||||
if (!Enabled) return;
|
if (!Enabled) return;
|
||||||
@@ -1409,6 +1483,8 @@ namespace Barotrauma
|
|||||||
item.Submarine = Submarine;
|
item.Submarine = Submarine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HideFace = false;
|
||||||
|
|
||||||
if (isDead) return;
|
if (isDead) return;
|
||||||
|
|
||||||
@@ -1465,26 +1541,42 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Skip health effects as critical health handles it differently
|
||||||
if (IsUnconscious)
|
if (IsUnconscious)
|
||||||
{
|
{
|
||||||
UpdateUnconscious(deltaTime);
|
UpdateUnconscious(deltaTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Do ragdoll shenanigans before Stun because it's still technically a stun, innit? Less network updates for us!
|
||||||
if (IsForceRagdolled)
|
if (IsForceRagdolled)
|
||||||
IsRagdolled = IsForceRagdolled;
|
IsRagdolled = IsForceRagdolled;
|
||||||
else if (!IsRagdolled || AnimController.Collider.LinearVelocity.Length() < 1f) //Keep us ragdolled if we were forced or we're too speedy to unragdoll
|
else if ((GameMain.Server == null || GameMain.Server.AllowRagdollButton) && (!IsRagdolled || AnimController.Collider.LinearVelocity.Length() < 1f)) //Keep us ragdolled if we were forced or we're too speedy to unragdoll
|
||||||
IsRagdolled = IsKeyDown(InputType.Ragdoll); //Handle this here instead of Control because we can stop being ragdolled ourselves
|
IsRagdolled = IsKeyDown(InputType.Ragdoll); //Handle this here instead of Control because we can stop being ragdolled ourselves
|
||||||
|
|
||||||
|
//Health effects
|
||||||
|
if (needsAir) UpdateOxygen(deltaTime);
|
||||||
|
|
||||||
|
Health -= bleeding * deltaTime;
|
||||||
|
Bleeding -= BleedingDecreaseSpeed * deltaTime;
|
||||||
|
|
||||||
|
if (health <= minHealth) Kill(CauseOfDeath.Bloodloss);
|
||||||
|
|
||||||
|
if (!IsDead) LockHands = false;
|
||||||
|
|
||||||
|
//ragdoll button
|
||||||
if (IsRagdolled)
|
if (IsRagdolled)
|
||||||
{
|
{
|
||||||
if (AnimController is HumanoidAnimController) ((HumanoidAnimController)AnimController).Crouching = false;
|
if (AnimController is HumanoidAnimController) ((HumanoidAnimController)AnimController).Crouching = false;
|
||||||
|
if(GameMain.Server != null)
|
||||||
|
GameMain.Server.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.Status });
|
||||||
AnimController.ResetPullJoints();
|
AnimController.ResetPullJoints();
|
||||||
selectedConstruction = null;
|
selectedConstruction = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AI and control stuff
|
||||||
|
|
||||||
Control(deltaTime, cam);
|
Control(deltaTime, cam);
|
||||||
if (controlled != this && (!(this is AICharacter) || IsRemotePlayer))
|
if (controlled != this && (!(this is AICharacter) || IsRemotePlayer))
|
||||||
{
|
{
|
||||||
@@ -1497,28 +1589,18 @@ namespace Barotrauma
|
|||||||
selectedConstruction = null;
|
selectedConstruction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SelectedCharacter != null && AnimController.Anim == AnimController.Animation.CPR)
|
|
||||||
{
|
|
||||||
if (GameMain.Client == null) SelectedCharacter.Oxygen += (GetSkillLevel("Medical") / 10.0f) * deltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSightRange();
|
UpdateSightRange();
|
||||||
if (aiTarget != null) aiTarget.SoundRange = 0.0f;
|
if (aiTarget != null) aiTarget.SoundRange = 0.0f;
|
||||||
|
|
||||||
lowPassMultiplier = MathHelper.Lerp(lowPassMultiplier, 1.0f, 0.1f);
|
lowPassMultiplier = MathHelper.Lerp(lowPassMultiplier, 1.0f, 0.1f);
|
||||||
|
|
||||||
if (needsAir) UpdateOxygen(deltaTime);
|
//CPR stuff is handled in the UpdateCPR function in HumanoidAnimController
|
||||||
|
|
||||||
Health -= bleeding * deltaTime;
|
|
||||||
Bleeding -= BleedingDecreaseSpeed * deltaTime;
|
|
||||||
|
|
||||||
if (health <= minHealth) Kill(CauseOfDeath.Bloodloss);
|
|
||||||
|
|
||||||
if (!IsDead) LockHands = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateControlled(float deltaTime, Camera cam);
|
partial void UpdateControlled(float deltaTime, Camera cam);
|
||||||
|
|
||||||
|
partial void UpdateProjSpecific(float deltaTime, Camera cam);
|
||||||
|
|
||||||
private void UpdateOxygen(float deltaTime)
|
private void UpdateOxygen(float deltaTime)
|
||||||
{
|
{
|
||||||
float prevOxygen = oxygen;
|
float prevOxygen = oxygen;
|
||||||
@@ -1552,12 +1634,17 @@ namespace Barotrauma
|
|||||||
AnimController.ResetPullJoints();
|
AnimController.ResetPullJoints();
|
||||||
selectedConstruction = null;
|
selectedConstruction = null;
|
||||||
|
|
||||||
if (oxygen <= 0.0f) Oxygen -= deltaTime * 0.5f;
|
Oxygen -= deltaTime * 0.5f; //We're critical - our heart stopped!
|
||||||
|
|
||||||
if (health <= 0.0f)
|
if (health <= 0.0f) //Critical health - use current state for crit time
|
||||||
{
|
{
|
||||||
AddDamage(bleeding > 0.5f ? CauseOfDeath.Bloodloss : CauseOfDeath.Damage, Math.Max(bleeding, 1.0f) * deltaTime, null);
|
AddDamage(bleeding > 0.5f ? CauseOfDeath.Bloodloss : CauseOfDeath.Damage, Math.Max(bleeding, 1.0f) * deltaTime, null);
|
||||||
}
|
}
|
||||||
|
else //Keep on bleedin'
|
||||||
|
{
|
||||||
|
Health -= bleeding * deltaTime;
|
||||||
|
Bleeding -= BleedingDecreaseSpeed * deltaTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSightRange()
|
private void UpdateSightRange()
|
||||||
@@ -1634,7 +1721,7 @@ namespace Barotrauma
|
|||||||
var attackingCharacter = attacker as Character;
|
var attackingCharacter = attacker as Character;
|
||||||
if (attackingCharacter != null && attackingCharacter.AIController == null)
|
if (attackingCharacter != null && attackingCharacter.AIController == null)
|
||||||
{
|
{
|
||||||
GameServer.Log(Name + " attacked by " + attackingCharacter.Name+". Damage: "+attackResult.Damage+" Bleeding damage: "+attackResult.Bleeding, ServerLog.MessageType.Attack);
|
GameServer.Log(LogName + " attacked by " + attackingCharacter.LogName +". Damage: "+attackResult.Damage+" Bleeding damage: "+attackResult.Bleeding, ServerLog.MessageType.Attack);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.Client == null &&
|
if (GameMain.Client == null &&
|
||||||
@@ -1799,7 +1886,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
AnimController.Frozen = false;
|
AnimController.Frozen = false;
|
||||||
|
|
||||||
GameServer.Log(Name+" has died (Cause of death: "+causeOfDeath+")", ServerLog.MessageType.Attack);
|
GameServer.Log(LogName+" has died (Cause of death: "+causeOfDeath+")", ServerLog.MessageType.Attack);
|
||||||
|
|
||||||
if (OnDeath != null) OnDeath(this, causeOfDeath);
|
if (OnDeath != null) OnDeath(this, causeOfDeath);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,38 @@ namespace Barotrauma
|
|||||||
partial class CharacterInfo
|
partial class CharacterInfo
|
||||||
{
|
{
|
||||||
public string Name;
|
public string Name;
|
||||||
|
public string DisplayName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string disguiseName = "?";
|
||||||
|
if (Character == null || !Character.HideFace)
|
||||||
|
{
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Character.Inventory != null)
|
||||||
|
{
|
||||||
|
int cardSlotIndex = Character.Inventory.FindLimbSlot(InvSlotType.Card);
|
||||||
|
if (cardSlotIndex < 0) return disguiseName;
|
||||||
|
|
||||||
|
var idCard = Character.Inventory.Items[cardSlotIndex];
|
||||||
|
if (idCard == null) return disguiseName;
|
||||||
|
|
||||||
|
//Disguise as the ID card name if it's equipped
|
||||||
|
string[] readTags = idCard.Tags.Split(',');
|
||||||
|
foreach (string tag in readTags)
|
||||||
|
{
|
||||||
|
string[] s = tag.Split(':');
|
||||||
|
if (s[0] == "name")
|
||||||
|
{
|
||||||
|
return s[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return disguiseName;
|
||||||
|
}
|
||||||
|
}
|
||||||
public Character Character;
|
public Character Character;
|
||||||
|
|
||||||
public readonly string File;
|
public readonly string File;
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ClientNetObject.ENTITY_STATE:
|
case ClientNetObject.ENTITY_STATE:
|
||||||
int eventType = msg.ReadRangedInteger(0,2);
|
int eventType = msg.ReadRangedInteger(0,3);
|
||||||
switch (eventType)
|
switch (eventType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -357,6 +357,9 @@ namespace Barotrauma
|
|||||||
Kill(lastAttackCauseOfDeath);
|
Kill(lastAttackCauseOfDeath);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
AnimController.GrabLimb = (LimbType)msg.ReadUInt16();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -436,6 +439,7 @@ namespace Barotrauma
|
|||||||
if (AnimController is HumanoidAnimController)
|
if (AnimController is HumanoidAnimController)
|
||||||
{
|
{
|
||||||
tempBuffer.Write(((HumanoidAnimController)AnimController).Crouching);
|
tempBuffer.Write(((HumanoidAnimController)AnimController).Crouching);
|
||||||
|
tempBuffer.Write((UInt16)AnimController.GrabLimb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAttackLimb = AnimController.Limbs.Any(l => l != null && l.attack != null);
|
bool hasAttackLimb = AnimController.Limbs.Any(l => l != null && l.attack != null);
|
||||||
@@ -534,6 +538,8 @@ namespace Barotrauma
|
|||||||
msg.WriteRangedSingle(MathHelper.Clamp(Stun, 0.0f, MaxStun), 0.0f, MaxStun, 8);
|
msg.WriteRangedSingle(MathHelper.Clamp(Stun, 0.0f, MaxStun), 0.0f, MaxStun, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msg.Write(IsRagdolled);
|
||||||
|
|
||||||
msg.Write(HuskInfectionState > 0.0f);
|
msg.Write(HuskInfectionState > 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
item.AddTag(s);
|
item.AddTag(s);
|
||||||
}
|
}
|
||||||
|
item.AddTag("name:" + character.Name);
|
||||||
|
item.AddTag("job:" + Name);
|
||||||
|
if (!string.IsNullOrWhiteSpace(spawnPoint.IdCardDesc))
|
||||||
|
item.Description = spawnPoint.IdCardDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentItem != null) parentItem.Combine(item);
|
if (parentItem != null) parentItem.Combine(item);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ namespace Barotrauma
|
|||||||
[Flags]
|
[Flags]
|
||||||
public enum InvSlotType
|
public enum InvSlotType
|
||||||
{
|
{
|
||||||
None = 0, Any = 1, RightHand = 2, LeftHand = 4, Head = 8, Torso = 16, Legs = 32, Face=64
|
None = 0, Any = 1, RightHand = 2, LeftHand = 4, Head = 8, Torso = 16, Legs = 32, Face=64, Card=128
|
||||||
};
|
};
|
||||||
|
|
||||||
partial class CharacterInventory : Inventory
|
partial class CharacterInventory : Inventory
|
||||||
@@ -18,7 +18,7 @@ namespace Barotrauma
|
|||||||
private Character character;
|
private Character character;
|
||||||
|
|
||||||
public static InvSlotType[] limbSlots = new InvSlotType[] {
|
public static InvSlotType[] limbSlots = new InvSlotType[] {
|
||||||
InvSlotType.Head, InvSlotType.Torso, InvSlotType.Legs, InvSlotType.LeftHand, InvSlotType.RightHand, InvSlotType.Face,
|
InvSlotType.Head, InvSlotType.Torso, InvSlotType.Legs, InvSlotType.LeftHand, InvSlotType.RightHand, InvSlotType.Face, InvSlotType.Card,
|
||||||
InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any,
|
InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any,
|
||||||
InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any};
|
InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any, InvSlotType.Any};
|
||||||
|
|
||||||
|
|||||||
@@ -699,12 +699,12 @@ namespace Barotrauma.Items.Components
|
|||||||
if (docked)
|
if (docked)
|
||||||
{
|
{
|
||||||
if (item.Submarine != null && dockingTarget?.item?.Submarine != null)
|
if (item.Submarine != null && dockingTarget?.item?.Submarine != null)
|
||||||
GameServer.Log(sender.Name + " docked " + item.Submarine.Name + " to " + dockingTarget.item.Submarine.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(sender.LogName + " docked " + item.Submarine.Name + " to " + dockingTarget.item.Submarine.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (item.Submarine != null && prevDockingTarget?.item?.Submarine != null)
|
if (item.Submarine != null && prevDockingTarget?.item?.Submarine != null)
|
||||||
GameServer.Log(sender.Name + " undocked " + item.Submarine.Name + " from " + prevDockingTarget.item.Submarine.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(sender.LogName + " undocked " + item.Submarine.Name + " from " + prevDockingTarget.item.Submarine.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using Barotrauma.Lights;
|
|||||||
|
|
||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
{
|
{
|
||||||
partial class Door : ItemComponent, IDrawableComponent, IServerSerializable
|
partial class Door : Pickable, IDrawableComponent, IServerSerializable
|
||||||
{
|
{
|
||||||
private Gap linkedGap;
|
private Gap linkedGap;
|
||||||
|
|
||||||
@@ -203,12 +203,13 @@ namespace Barotrauma.Items.Components
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool OnPicked(Character picker)
|
||||||
public override bool Pick(Character picker)
|
|
||||||
{
|
{
|
||||||
isOpen = !isOpen;
|
SetState(predictedState == null ? !isOpen : !predictedState.Value, false, true); //crowbar function
|
||||||
|
#if CLIENT
|
||||||
return true;
|
PlaySound(ActionType.OnPicked, item.WorldPosition);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Select(Character character)
|
public override bool Select(Character character)
|
||||||
@@ -419,7 +420,7 @@ namespace Barotrauma.Items.Components
|
|||||||
bool newState = predictedState == null ? isOpen : predictedState.Value;
|
bool newState = predictedState == null ? isOpen : predictedState.Value;
|
||||||
if (sender != null && wasOpen != newState)
|
if (sender != null && wasOpen != newState)
|
||||||
{
|
{
|
||||||
GameServer.Log(sender.Name + (newState ? " opened " : " closed ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(sender.LogName + (newState ? " opened " : " closed ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,13 +184,13 @@ namespace Barotrauma.Items.Components
|
|||||||
item.SetTransform(rightHand.SimPosition, 0.0f);
|
item.SetTransform(rightHand.SimPosition, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alreadySelected = character.HasSelectedItem(item);
|
bool alreadySelected = character.HasEquippedItem(item);
|
||||||
if (picker.TrySelectItem(item))
|
if (picker.TrySelectItem(item) || picker.HasEquippedItem(item))
|
||||||
{
|
{
|
||||||
item.body.Enabled = true;
|
item.body.Enabled = true;
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
|
|
||||||
if (!alreadySelected) GameServer.Log(character.Name + " equipped " + item.Name, ServerLog.MessageType.ItemInteraction);
|
if (!alreadySelected) GameServer.Log(character.LogName + " equipped " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
picker.DeselectItem(item);
|
picker.DeselectItem(item);
|
||||||
|
|
||||||
GameServer.Log(character.Name + " unequipped " + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(character.LogName + " unequipped " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
|
|
||||||
item.body.Enabled = false;
|
item.body.Enabled = false;
|
||||||
IsActive = false;
|
IsActive = false;
|
||||||
@@ -224,7 +224,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnPicked(Character picker)
|
public override bool OnPicked(Character picker)
|
||||||
{
|
{
|
||||||
if (base.OnPicked(picker))
|
if (base.OnPicked(picker))
|
||||||
{
|
{
|
||||||
@@ -235,7 +235,7 @@ namespace Barotrauma.Items.Components
|
|||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
if (picker != null)
|
if (picker != null)
|
||||||
{
|
{
|
||||||
Networking.GameServer.Log(picker.Name + " detached " + item.Name + " from a wall", ServerLog.MessageType.ItemInteraction);
|
Networking.GameServer.Log(picker.LogName + " detached " + item.Name + " from a wall", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -290,7 +290,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
GameServer.Log(character.Name + " attached " + item.Name+" to a wall", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(character.LogName + " attached " + item.Name+" to a wall", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
item.Drop();
|
item.Drop();
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ namespace Barotrauma.Items.Components
|
|||||||
public override void Update(float deltaTime, Camera cam)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
if (item.body == null || !item.body.Enabled) return;
|
if (item.body == null || !item.body.Enabled) return;
|
||||||
if (picker == null || !picker.HasSelectedItem(item))
|
if (picker == null || !picker.HasEquippedItem(item))
|
||||||
{
|
{
|
||||||
IsActive = false;
|
IsActive = false;
|
||||||
return;
|
return;
|
||||||
@@ -320,7 +320,37 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
item.Submarine = picker.Submarine;
|
item.Submarine = picker.Submarine;
|
||||||
|
|
||||||
picker.AnimController.HoldItem(deltaTime, item, handlePos, holdPos, aimPos, picker.IsKeyDown(InputType.Aim), holdAngle);
|
if (picker.HasSelectedItem(item))
|
||||||
|
{
|
||||||
|
picker.AnimController.HoldItem(deltaTime, item, handlePos, holdPos, aimPos, picker.IsKeyDown(InputType.Aim), holdAngle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Limb equipLimb = null;
|
||||||
|
if (picker.Inventory.IsInLimbSlot(item, InvSlotType.Face) || picker.Inventory.IsInLimbSlot(item, InvSlotType.Head))
|
||||||
|
{
|
||||||
|
equipLimb = picker.AnimController.GetLimb(LimbType.Head);
|
||||||
|
}
|
||||||
|
else if (picker.Inventory.IsInLimbSlot(item, InvSlotType.Torso))
|
||||||
|
{
|
||||||
|
equipLimb = picker.AnimController.GetLimb(LimbType.Torso);
|
||||||
|
}
|
||||||
|
else if (picker.Inventory.IsInLimbSlot(item, InvSlotType.Legs))
|
||||||
|
{
|
||||||
|
equipLimb = picker.AnimController.GetLimb(LimbType.Waist);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (equipLimb != null)
|
||||||
|
{
|
||||||
|
float itemAngle = (equipLimb.Rotation + holdAngle * picker.AnimController.Dir);
|
||||||
|
|
||||||
|
Matrix itemTransfrom = Matrix.CreateRotationZ(equipLimb.Rotation);
|
||||||
|
Vector2 transformedHandlePos = Vector2.Transform(handlePos[0], itemTransfrom);
|
||||||
|
|
||||||
|
item.body.ResetDynamics();
|
||||||
|
item.SetTransform(equipLimb.SimPosition - transformedHandlePos, itemAngle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Flip(Item item)
|
protected void Flip(Item item)
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ac.HoldItem(deltaTime, item, handlePos, new Vector2(hitPos, 0.0f), aimPos, false, holdAngle);
|
ac.HoldItem(deltaTime, item, handlePos, holdPos, aimPos, false, holdAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -255,12 +255,12 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
GameMain.Server.CreateEntityEvent(item, new object[] { Networking.NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnUse, targetCharacter.ID });
|
GameMain.Server.CreateEntityEvent(item, new object[] { Networking.NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnUse, targetCharacter.ID });
|
||||||
|
|
||||||
string logStr = picker?.Name + " used " + item.Name;
|
string logStr = picker?.LogName + " used " + item.Name;
|
||||||
if (item.ContainedItems != null && item.ContainedItems.Length > 0)
|
if (item.ContainedItems != null && item.ContainedItems.Length > 0)
|
||||||
{
|
{
|
||||||
logStr += "(" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")";
|
logStr += "(" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")";
|
||||||
}
|
}
|
||||||
logStr += " on " + targetCharacter + ".";
|
logStr += " on " + targetCharacter.LogName + ".";
|
||||||
Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack);
|
Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool OnPicked(Character picker)
|
public virtual bool OnPicked(Character picker)
|
||||||
{
|
{
|
||||||
if (picker.Inventory.TryPutItem(item, picker, allowedSlots))
|
if (picker.Inventory.TryPutItem(item, picker, allowedSlots))
|
||||||
{
|
{
|
||||||
@@ -89,6 +89,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (!GameMain.Instance.LoadingScreenOpen && picker == Character.Controlled) GUI.PlayUISound(GUISoundType.PickItem);
|
if (!GameMain.Instance.LoadingScreenOpen && picker == Character.Controlled) GUI.PlayUISound(GUISoundType.PickItem);
|
||||||
|
PlaySound(ActionType.OnPicked, item.WorldPosition);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 throwVector = picker.CursorWorldPosition - picker.WorldPosition;
|
Vector2 throwVector = picker.CursorWorldPosition - picker.WorldPosition;
|
||||||
throwVector = Vector2.Normalize(throwVector);
|
throwVector = Vector2.Normalize(throwVector);
|
||||||
|
|
||||||
GameServer.Log(picker.Name + " threw " + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(picker.LogName + " threw " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
|
|
||||||
item.Drop();
|
item.Drop();
|
||||||
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
|
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(user.Name + (IsActive ? " activated " : " deactivated ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(user.LogName + (IsActive ? " activated " : " deactivated ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(user.Name + " started fabricating " + selectedItem.TargetItem.Name + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(user.LogName + " started fabricating " + selectedItem.TargetItem.Name + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
@@ -184,7 +184,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (fabricatedItem != null && user != null)
|
if (fabricatedItem != null && user != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(user.Name + " cancelled the fabrication of " + fabricatedItem.TargetItem.Name + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(user.LogName + " cancelled the fabrication of " + fabricatedItem.TargetItem.Name + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsActive = false;
|
IsActive = false;
|
||||||
|
|||||||
@@ -157,11 +157,11 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (newFlowPercentage != FlowPercentage)
|
if (newFlowPercentage != FlowPercentage)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character + " set the pumping speed of " + item.Name + " to " + (int)(newFlowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(c.Character.LogName + " set the pumping speed of " + item.Name + " to " + (int)(newFlowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
if (newIsActive != IsActive)
|
if (newIsActive != IsActive)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character + (newIsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(c.Character.LogName + (newIsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlowPercentage = newFlowPercentage;
|
FlowPercentage = newFlowPercentage;
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (Timing.TotalTime >= (float)nextServerLogWriteTime)
|
if (Timing.TotalTime >= (float)nextServerLogWriteTime)
|
||||||
{
|
{
|
||||||
GameServer.Log(lastUser + " adjusted reactor settings: " +
|
GameServer.Log(lastUser.LogName + " adjusted reactor settings: " +
|
||||||
"Temperature: " + (int)temperature +
|
"Temperature: " + (int)temperature +
|
||||||
", Fission rate: " + (int)fissionRate +
|
", Fission rate: " + (int)fissionRate +
|
||||||
", Cooling rate: " + (int)coolingRate +
|
", Cooling rate: " + (int)coolingRate +
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (item.CanClientAccess(c))
|
if (item.CanClientAccess(c))
|
||||||
{
|
{
|
||||||
RechargeSpeed = newRechargeSpeed;
|
RechargeSpeed = newRechargeSpeed;
|
||||||
GameServer.Log(c.Character + " set the recharge speed of "+item.Name+" to "+ (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(c.Character.LogName + " set the recharge speed of "+item.Name+" to "+ (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ namespace Barotrauma.Items.Components
|
|||||||
if (existingWire.Locked)
|
if (existingWire.Locked)
|
||||||
{
|
{
|
||||||
//this should not be possible unless the client is running a modified version of the game
|
//this should not be possible unless the client is running a modified version of the game
|
||||||
GameServer.Log(c.Character.Name + " attempted to disconnect a locked wire from " +
|
GameServer.Log(c.Character.LogName + " attempted to disconnect a locked wire from " +
|
||||||
Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Error);
|
Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Error);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -224,12 +224,12 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (existingWire.Connections[0] == null && existingWire.Connections[1] == null)
|
if (existingWire.Connections[0] == null && existingWire.Connections[1] == null)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character.Name + " disconnected a wire from " +
|
GameServer.Log(c.Character.LogName + " disconnected a wire from " +
|
||||||
Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.ItemInteraction);
|
Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (existingWire.Connections[0] != null)
|
else if (existingWire.Connections[0] != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character.Name + " disconnected a wire from " +
|
GameServer.Log(c.Character.LogName + " disconnected a wire from " +
|
||||||
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[0].Item.Name + " (" + existingWire.Connections[0].Name + ")", ServerLog.MessageType.ItemInteraction);
|
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[0].Item.Name + " (" + existingWire.Connections[0].Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
|
|
||||||
//wires that are not in anyone's inventory (i.e. not currently being rewired)
|
//wires that are not in anyone's inventory (i.e. not currently being rewired)
|
||||||
@@ -244,7 +244,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
else if (existingWire.Connections[1] != null)
|
else if (existingWire.Connections[1] != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character.Name + " disconnected a wire from " +
|
GameServer.Log(c.Character.LogName + " disconnected a wire from " +
|
||||||
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[1].Item.Name + " (" + existingWire.Connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
|
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[1].Item.Name + " (" + existingWire.Connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
|
|
||||||
if (existingWire.Item.ParentInventory == null)
|
if (existingWire.Item.ParentInventory == null)
|
||||||
@@ -276,13 +276,13 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (otherConnection == null)
|
if (otherConnection == null)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character.Name + " connected a wire to " +
|
GameServer.Log(c.Character.LogName + " connected a wire to " +
|
||||||
Connections[i].Item.Name + " (" + Connections[i].Name + ")",
|
Connections[i].Item.Name + " (" + Connections[i].Name + ")",
|
||||||
ServerLog.MessageType.ItemInteraction);
|
ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character.Name + " connected a wire from " +
|
GameServer.Log(c.Character.LogName + " connected a wire from " +
|
||||||
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " +
|
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " +
|
||||||
(otherConnection == null ? "none" : otherConnection.Item.Name + " (" + (otherConnection.Name) + ")"),
|
(otherConnection == null ? "none" : otherConnection.Item.Name + " (" + (otherConnection.Name) + ")"),
|
||||||
ServerLog.MessageType.ItemInteraction);
|
ServerLog.MessageType.ItemInteraction);
|
||||||
|
|||||||
@@ -308,18 +308,18 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (connections[0] != null && connections[1] != null)
|
if (connections[0] != null && connections[1] != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(user.Name + " disconnected a wire from " +
|
GameServer.Log(user.LogName + " disconnected a wire from " +
|
||||||
connections[0].Item.Name + " (" + connections[0].Name + ") to "+
|
connections[0].Item.Name + " (" + connections[0].Name + ") to "+
|
||||||
connections[1].Item.Name + " (" + connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
|
connections[1].Item.Name + " (" + connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (connections[0] != null)
|
else if (connections[0] != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(user.Name + " disconnected a wire from " +
|
GameServer.Log(user.LogName + " disconnected a wire from " +
|
||||||
connections[0].Item.Name + " (" + connections[0].Name + ")", ServerLog.MessageType.ItemInteraction);
|
connections[0].Item.Name + " (" + connections[0].Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else if (connections[1] != null)
|
else if (connections[1] != null)
|
||||||
{
|
{
|
||||||
GameServer.Log(user.Name + " disconnected a wire from " +
|
GameServer.Log(user.LogName + " disconnected a wire from " +
|
||||||
connections[1].Item.Name + " (" + connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
|
connections[1].Item.Name + " (" + connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (character != null)
|
if (character != null)
|
||||||
{
|
{
|
||||||
string msg = character.Name + " launched " + item.Name + " (projectile: " + projectiles[0].Item.Name;
|
string msg = character.LogName + " launched " + item.Name + " (projectile: " + projectiles[0].Item.Name;
|
||||||
if (projectiles[0].Item.ContainedItems == null || projectiles[0].Item.ContainedItems.All(i => i == null))
|
if (projectiles[0].Item.ContainedItems == null || projectiles[0].Item.ContainedItems.All(i => i == null))
|
||||||
{
|
{
|
||||||
msg += ")";
|
msg += ")";
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (itemName == null) return null;
|
if (itemName == null) return null;
|
||||||
|
|
||||||
return Items.FirstOrDefault(i => i != null && (i.Name == itemName || i.HasTag(itemName)));
|
return Items.FirstOrDefault(i => i != null && (i.Prefab.NameMatches(itemName) || i.HasTag(itemName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RemoveItem(Item item)
|
public virtual void RemoveItem(Item item)
|
||||||
@@ -212,11 +212,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Owner == c.Character)
|
if (Owner == c.Character)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character + " picked up " + item.Name, ServerLog.MessageType.Inventory);
|
GameServer.Log(c.Character.LogName+ " picked up " + item.Name, ServerLog.MessageType.Inventory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character + " placed " + item.Name + " in " + Owner, ServerLog.MessageType.Inventory);
|
GameServer.Log(c.Character.LogName + " placed " + item.Name + " in " + Owner, ServerLog.MessageType.Inventory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,11 +227,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Owner == c.Character)
|
if (Owner == c.Character)
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character + " dropped " + item.Name, ServerLog.MessageType.Inventory);
|
GameServer.Log(c.Character.LogName + " dropped " + item.Name, ServerLog.MessageType.Inventory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character + " removed " + item.Name + " from " + Owner, ServerLog.MessageType.Inventory);
|
GameServer.Log(c.Character.LogName + " removed " + item.Name + " from " + Owner, ServerLog.MessageType.Inventory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,9 +119,12 @@ namespace Barotrauma
|
|||||||
get { return prefab.Name; }
|
get { return prefab.Name; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string description;
|
||||||
|
[Editable, Serialize("", true)]
|
||||||
public string Description
|
public string Description
|
||||||
{
|
{
|
||||||
get { return prefab.Description; }
|
get { return description == null ? prefab.Description : description; }
|
||||||
|
set { description = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public float ImpactTolerance
|
public float ImpactTolerance
|
||||||
@@ -1359,12 +1362,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (ContainedItems == null || ContainedItems.All(i => i == null))
|
if (ContainedItems == null || ContainedItems.All(i => i == null))
|
||||||
{
|
{
|
||||||
GameServer.Log(c.Character.Name + " used item " + Name, ServerLog.MessageType.ItemInteraction);
|
GameServer.Log(c.Character.LogName + " used item " + Name, ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameServer.Log(
|
GameServer.Log(
|
||||||
c.Character.Name + " used item " + Name + " (contained items: " + string.Join(", ", Array.FindAll(ContainedItems, i => i != null).Select(i => i.Name)) + ")",
|
c.Character.LogName + " used item " + Name + " (contained items: " + string.Join(", ", Array.FindAll(ContainedItems, i => i != null).Select(i => i.Name)) + ")",
|
||||||
ServerLog.MessageType.ItemInteraction);
|
ServerLog.MessageType.ItemInteraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1458,6 +1461,7 @@ namespace Barotrauma
|
|||||||
if (GameMain.Server == null) return;
|
if (GameMain.Server == null) return;
|
||||||
|
|
||||||
msg.Write(Prefab.Name);
|
msg.Write(Prefab.Name);
|
||||||
|
msg.Write(Description);
|
||||||
msg.Write(ID);
|
msg.Write(ID);
|
||||||
|
|
||||||
if (ParentInventory == null || ParentInventory.Owner == null)
|
if (ParentInventory == null || ParentInventory.Owner == null)
|
||||||
@@ -1476,7 +1480,8 @@ namespace Barotrauma
|
|||||||
msg.Write(index < 0 ? (byte)255 : (byte)index);
|
msg.Write(index < 0 ? (byte)255 : (byte)index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Name == "ID Card") msg.Write(Tags);
|
//TODO: See if tags are different from their prefab before sending 'em
|
||||||
|
msg.Write(Tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Item ReadSpawnData(NetBuffer msg, bool spawn = true)
|
public static Item ReadSpawnData(NetBuffer msg, bool spawn = true)
|
||||||
@@ -1484,6 +1489,7 @@ namespace Barotrauma
|
|||||||
if (GameMain.Server != null) return null;
|
if (GameMain.Server != null) return null;
|
||||||
|
|
||||||
string itemName = msg.ReadString();
|
string itemName = msg.ReadString();
|
||||||
|
string itemDesc = msg.ReadString();
|
||||||
ushort itemId = msg.ReadUInt16();
|
ushort itemId = msg.ReadUInt16();
|
||||||
|
|
||||||
ushort inventoryId = msg.ReadUInt16();
|
ushort inventoryId = msg.ReadUInt16();
|
||||||
@@ -1507,11 +1513,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string tags = "";
|
string tags = msg.ReadString();
|
||||||
if (itemName == "ID Card")
|
|
||||||
{
|
|
||||||
tags = msg.ReadString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spawn) return null;
|
if (!spawn) return null;
|
||||||
|
|
||||||
@@ -1541,6 +1543,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var item = new Item(itemPrefab, pos, sub);
|
var item = new Item(itemPrefab, pos, sub);
|
||||||
|
|
||||||
|
item.Description = itemDesc;
|
||||||
item.ID = itemId;
|
item.ID = itemId;
|
||||||
if (sub != null)
|
if (sub != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -506,15 +506,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
float impact = Vector2.Dot(f2.Body.LinearVelocity, -normal)*f2.Body.Mass*0.1f;
|
float impact = Vector2.Dot(f2.Body.LinearVelocity, -normal)*f2.Body.Mass*0.1f;
|
||||||
|
|
||||||
if (impact < 10.0f) return true;
|
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact,
|
SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact,
|
||||||
new Vector2(
|
new Vector2(
|
||||||
sections[section].rect.X + sections[section].rect.Width / 2,
|
sections[section].rect.X + sections[section].rect.Width / 2,
|
||||||
sections[section].rect.Y - sections[section].rect.Height / 2));
|
sections[section].rect.Y - sections[section].rect.Height / 2), tags: Tags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (impact < 10.0f) return true;
|
||||||
|
|
||||||
AddDamage(section, impact);
|
AddDamage(section, impact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -566,7 +566,7 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
float particleAmount = Math.Min(Health - section.damage, damage) * Rand.Range(0.01f, 1.0f);
|
float particleAmount = Math.Min(Health - section.damage, damage) * Rand.Range(0.01f, 1.0f);
|
||||||
|
|
||||||
particleAmount = Math.Min(particleAmount + Rand.Range(-5,1), 100);
|
particleAmount = Math.Min(particleAmount + Rand.Range(-5,1), 20);
|
||||||
for (int i = 0; i < particleAmount; i++)
|
for (int i = 0; i < particleAmount; i++)
|
||||||
{
|
{
|
||||||
Vector2 particlePos = new Vector2(
|
Vector2 particlePos = new Vector2(
|
||||||
@@ -661,10 +661,10 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
|
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
|
||||||
|
|
||||||
if (playSound && !SectionBodyDisabled(i))
|
if (playSound)// && !SectionBodyDisabled(i))
|
||||||
{
|
{
|
||||||
DamageSoundType damageSoundType = (attack.DamageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
|
DamageSoundType damageSoundType = (attack.DamageType == DamageType.Blunt) ? DamageSoundType.StructureBlunt : DamageSoundType.StructureSlash;
|
||||||
SoundPlayer.PlayDamageSound(damageSoundType, damageAmount, worldPosition);
|
SoundPlayer.PlayDamageSound(damageSoundType, damageAmount, worldPosition, tags: Tags);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -678,14 +678,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!MathUtils.IsValid(damage)) return;
|
if (!MathUtils.IsValid(damage)) return;
|
||||||
|
|
||||||
float damageDiff = damage - sections[sectionIndex].damage;
|
|
||||||
|
|
||||||
if (GameMain.Server != null && damage != sections[sectionIndex].damage)
|
if (GameMain.Server != null && damage != sections[sectionIndex].damage)
|
||||||
{
|
{
|
||||||
GameMain.Server.CreateEntityEvent(this);
|
GameMain.Server.CreateEntityEvent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdjustKarma(attacker, damageDiff);
|
|
||||||
if (damage < prefab.Health*0.5f)
|
if (damage < prefab.Health*0.5f)
|
||||||
{
|
{
|
||||||
if (sections[sectionIndex].gap != null)
|
if (sections[sectionIndex].gap != null)
|
||||||
@@ -717,10 +716,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
sections[sectionIndex].gap.Open = (damage / prefab.Health - 0.5f) * 2.0f;
|
sections[sectionIndex].gap.Open = (damage / prefab.Health - 0.5f) * 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float damageDiff = damage - sections[sectionIndex].damage;
|
||||||
bool hadHole = SectionBodyDisabled(sectionIndex);
|
bool hadHole = SectionBodyDisabled(sectionIndex);
|
||||||
sections[sectionIndex].damage = MathHelper.Clamp(damage, 0.0f, prefab.Health);
|
sections[sectionIndex].damage = MathHelper.Clamp(damage, 0.0f, prefab.Health);
|
||||||
|
|
||||||
|
if (sections[sectionIndex].damage < prefab.Health) //otherwise it's possible to infinitely gain karma by welding fixed things
|
||||||
|
AdjustKarma(attacker, damageDiff);
|
||||||
|
|
||||||
bool hasHole = SectionBodyDisabled(sectionIndex);
|
bool hasHole = SectionBodyDisabled(sectionIndex);
|
||||||
|
|
||||||
if (hadHole == hasHole) return;
|
if (hadHole == hasHole) return;
|
||||||
|
|||||||
@@ -373,118 +373,53 @@ namespace Barotrauma
|
|||||||
Limb limb = f2.Body.UserData as Limb;
|
Limb limb = f2.Body.UserData as Limb;
|
||||||
if (limb != null)
|
if (limb != null)
|
||||||
{
|
{
|
||||||
|
bool collision = CheckLimbCollision(contact, limb);
|
||||||
bool collision = HandleLimbCollision(contact, limb);
|
if (collision) HandleLimbCollision(contact, limb);
|
||||||
|
|
||||||
if (collision && limb.Mass > 100.0f)
|
|
||||||
{
|
|
||||||
Vector2 normal = Vector2.Normalize(Body.SimPosition - limb.SimPosition);
|
|
||||||
|
|
||||||
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f * Math.Min(limb.Mass / 200.0f, 1);
|
|
||||||
|
|
||||||
ApplyImpact(impact, -normal, contact);
|
|
||||||
foreach (Submarine dockedSub in submarine.DockedTo)
|
|
||||||
{
|
|
||||||
dockedSub.SubBody.ApplyImpact(impact, -normal, contact);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return collision;
|
return collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
|
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
|
||||||
if (cell != null)
|
if (cell != null)
|
||||||
{
|
{
|
||||||
var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center);
|
HandleLevelCollision(contact, cell);
|
||||||
|
|
||||||
float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
|
|
||||||
|
|
||||||
ApplyImpact(wallImpact, -collisionNormal, contact);
|
|
||||||
foreach (Submarine dockedSub in submarine.DockedTo)
|
|
||||||
{
|
|
||||||
dockedSub.SubBody.ApplyImpact(wallImpact, -collisionNormal, contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 n;
|
|
||||||
FixedArray2<Vector2> particlePos;
|
|
||||||
contact.GetWorldManifold(out n, out particlePos);
|
|
||||||
|
|
||||||
#if CLIENT
|
|
||||||
int particleAmount = (int)(wallImpact * 10.0f);
|
|
||||||
for (int i = 0; i < particleAmount; i++)
|
|
||||||
{
|
|
||||||
GameMain.ParticleManager.CreateParticle("iceshards",
|
|
||||||
ConvertUnits.ToDisplayUnits(particlePos[0]) + Rand.Vector(Rand.Range(1.0f, 50.0f)),
|
|
||||||
Rand.Vector(Rand.Range(50.0f, 500.0f)) + Velocity);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Submarine otherSub = f2.Body.UserData as Submarine;
|
Submarine otherSub = f2.Body.UserData as Submarine;
|
||||||
if (otherSub != null)
|
if (otherSub != null)
|
||||||
{
|
{
|
||||||
Debug.Assert(otherSub != submarine);
|
HandleSubCollision(contact, otherSub);
|
||||||
|
|
||||||
Vector2 normal;
|
|
||||||
FixedArray2<Vector2> points;
|
|
||||||
contact.GetWorldManifold(out normal, out points);
|
|
||||||
if (contact.FixtureA.Body == otherSub.SubBody.Body.FarseerBody)
|
|
||||||
{
|
|
||||||
normal = -normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
float thisMass = Body.Mass + submarine.DockedTo.Sum(s => s.PhysicsBody.Mass);
|
|
||||||
float otherMass = otherSub.PhysicsBody.Mass + otherSub.DockedTo.Sum(s => s.PhysicsBody.Mass);
|
|
||||||
|
|
||||||
float massRatio = otherMass / (thisMass + otherMass);
|
|
||||||
|
|
||||||
float impact = (Vector2.Dot(Velocity - otherSub.Velocity, normal) / 2.0f) * massRatio;
|
|
||||||
|
|
||||||
ApplyImpact(impact, normal, contact);
|
|
||||||
foreach (Submarine dockedSub in submarine.DockedTo)
|
|
||||||
{
|
|
||||||
dockedSub.SubBody.ApplyImpact(impact, normal, contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandleLimbCollision(Contact contact, Limb limb)
|
private bool CheckLimbCollision(Contact contact, Limb limb)
|
||||||
{
|
{
|
||||||
if (limb.character.Submarine != null) return false;
|
if (limb.character.Submarine != null) return false;
|
||||||
|
|
||||||
Vector2 normal2;
|
Vector2 contactNormal;
|
||||||
FixedArray2<Vector2> points;
|
FixedArray2<Vector2> points;
|
||||||
contact.GetWorldManifold(out normal2, out points);
|
contact.GetWorldManifold(out contactNormal, out points);
|
||||||
|
|
||||||
Vector2 normalizedVel = limb.character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
|
Vector2 normalizedVel = limb.character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
|
||||||
Vector2.Zero : Vector2.Normalize(limb.character.AnimController.Collider.LinearVelocity);
|
Vector2.Zero : Vector2.Normalize(limb.character.AnimController.Collider.LinearVelocity);
|
||||||
|
|
||||||
Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - normal2);
|
Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - contactNormal);
|
||||||
|
|
||||||
Hull newHull = Hull.FindHull(targetPos, null);
|
Hull newHull = Hull.FindHull(targetPos, null);
|
||||||
|
|
||||||
if (newHull == null)
|
if (newHull == null)
|
||||||
{
|
{
|
||||||
targetPos = ConvertUnits.ToDisplayUnits(points[0] + normalizedVel);
|
targetPos = ConvertUnits.ToDisplayUnits(points[0] + normalizedVel);
|
||||||
|
|
||||||
newHull = Hull.FindHull(targetPos, null);
|
newHull = Hull.FindHull(targetPos, null);
|
||||||
|
|
||||||
if (newHull == null) return true;
|
if (newHull == null) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var gaps = newHull.ConnectedGaps;
|
var gaps = newHull.ConnectedGaps;
|
||||||
|
|
||||||
targetPos = limb.character.WorldPosition;
|
targetPos = limb.character.WorldPosition;
|
||||||
|
|
||||||
Gap adjacentGap = Gap.FindAdjacent(gaps, targetPos, 200.0f);
|
Gap adjacentGap = Gap.FindAdjacent(gaps, targetPos, 200.0f);
|
||||||
|
if (adjacentGap == null) return true;
|
||||||
if (adjacentGap==null) return true;
|
|
||||||
|
|
||||||
var ragdoll = limb.character.AnimController;
|
var ragdoll = limb.character.AnimController;
|
||||||
ragdoll.FindHull(newHull.WorldPosition, true);
|
ragdoll.FindHull(newHull.WorldPosition, true);
|
||||||
@@ -492,13 +427,190 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleLimbCollision(Contact contact, Limb limb)
|
||||||
|
{
|
||||||
|
if (limb.Mass > 100.0f)
|
||||||
|
{
|
||||||
|
Vector2 normal = Vector2.Normalize(Body.SimPosition - limb.SimPosition);
|
||||||
|
|
||||||
|
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f * Math.Min(limb.Mass / 200.0f, 1);
|
||||||
|
|
||||||
|
ApplyImpact(impact, -normal, contact);
|
||||||
|
foreach (Submarine dockedSub in submarine.DockedTo)
|
||||||
|
{
|
||||||
|
dockedSub.SubBody.ApplyImpact(impact, -normal, contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//find all contacts between the limb and level walls
|
||||||
|
List<Contact> levelContacts = new List<Contact>();
|
||||||
|
ContactEdge contactEdge = limb.body.FarseerBody.ContactList;
|
||||||
|
while (contactEdge.Next != null)
|
||||||
|
{
|
||||||
|
if (contactEdge.Contact.Enabled &&
|
||||||
|
contactEdge.Other.UserData is VoronoiCell &&
|
||||||
|
contactEdge.Contact.IsTouching)
|
||||||
|
{
|
||||||
|
levelContacts.Add(contactEdge.Contact);
|
||||||
|
}
|
||||||
|
contactEdge = contactEdge.Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levelContacts.Count == 0) return;
|
||||||
|
|
||||||
|
//if the limb is in contact with the level, apply an artifical impact to prevent the sub from bouncing on top of it
|
||||||
|
//not a very realistic way to handle the collisions (makes it seem as if the characters were made of reinforced concrete),
|
||||||
|
//but more realistic than bouncing and prevents using characters as "bumpers" that prevent all collision damage
|
||||||
|
|
||||||
|
//TODO: apply impact damage and/or gib the character that got crushed between the sub and the level?
|
||||||
|
Vector2 avgContactNormal = Vector2.Zero;
|
||||||
|
foreach (Contact levelContact in levelContacts)
|
||||||
|
{
|
||||||
|
Vector2 contactNormal;
|
||||||
|
FixedArray2<Vector2> temp;
|
||||||
|
levelContact.GetWorldManifold(out contactNormal, out temp);
|
||||||
|
|
||||||
|
//if the contact normal is pointing from the limb towards the level cell it's touching, flip the normal
|
||||||
|
VoronoiCell cell = levelContact.FixtureB.Body.UserData is VoronoiCell ?
|
||||||
|
((VoronoiCell)levelContact.FixtureB.Body.UserData) : ((VoronoiCell)levelContact.FixtureA.Body.UserData);
|
||||||
|
|
||||||
|
var cellDiff = ConvertUnits.ToDisplayUnits(limb.body.SimPosition) - cell.Center;
|
||||||
|
if (Vector2.Dot(contactNormal, cellDiff) < 0)
|
||||||
|
{
|
||||||
|
contactNormal = -contactNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
avgContactNormal += contactNormal;
|
||||||
|
|
||||||
|
//apply impacts at the positions where this sub is touching the limb
|
||||||
|
ApplyImpact((Vector2.Dot(-Velocity, contactNormal) / 2.0f) / levelContacts.Count, contactNormal, levelContact);
|
||||||
|
}
|
||||||
|
avgContactNormal /= levelContacts.Count;
|
||||||
|
|
||||||
|
float contactDot = Vector2.Dot(Body.LinearVelocity, -avgContactNormal);
|
||||||
|
if (contactDot > 0.0f)
|
||||||
|
{
|
||||||
|
Body.LinearVelocity -= Vector2.Normalize(Body.LinearVelocity) * contactDot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleLevelCollision(Contact contact, VoronoiCell cell)
|
||||||
|
{
|
||||||
|
var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center);
|
||||||
|
|
||||||
|
float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
|
||||||
|
|
||||||
|
ApplyImpact(wallImpact, -collisionNormal, contact);
|
||||||
|
foreach (Submarine dockedSub in submarine.DockedTo)
|
||||||
|
{
|
||||||
|
dockedSub.SubBody.ApplyImpact(wallImpact, -collisionNormal, contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 n;
|
||||||
|
FixedArray2<Vector2> particlePos;
|
||||||
|
contact.GetWorldManifold(out n, out particlePos);
|
||||||
|
|
||||||
|
#if CLIENT
|
||||||
|
int particleAmount = (int)Math.Min(wallImpact * 10.0f, 50);
|
||||||
|
for (int i = 0; i < particleAmount; i++)
|
||||||
|
{
|
||||||
|
GameMain.ParticleManager.CreateParticle("iceshards",
|
||||||
|
ConvertUnits.ToDisplayUnits(particlePos[0]) + Rand.Vector(Rand.Range(1.0f, 50.0f)),
|
||||||
|
Rand.Vector(Rand.Range(50.0f, 500.0f)) + Velocity);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleSubCollision(Contact contact, Submarine otherSub)
|
||||||
|
{
|
||||||
|
Debug.Assert(otherSub != submarine);
|
||||||
|
|
||||||
|
Vector2 normal;
|
||||||
|
FixedArray2<Vector2> points;
|
||||||
|
contact.GetWorldManifold(out normal, out points);
|
||||||
|
if (contact.FixtureA.Body == otherSub.SubBody.Body.FarseerBody)
|
||||||
|
{
|
||||||
|
normal = -normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
float thisMass = Body.Mass + submarine.DockedTo.Sum(s => s.PhysicsBody.Mass);
|
||||||
|
float otherMass = otherSub.PhysicsBody.Mass + otherSub.DockedTo.Sum(s => s.PhysicsBody.Mass);
|
||||||
|
float massRatio = otherMass / (thisMass + otherMass);
|
||||||
|
|
||||||
|
float impact = (Vector2.Dot(Velocity - otherSub.Velocity, normal) / 2.0f) * massRatio;
|
||||||
|
|
||||||
|
//apply impact to this sub (the other sub takes care of this in its own collision callback)
|
||||||
|
ApplyImpact(impact, normal, contact);
|
||||||
|
foreach (Submarine dockedSub in submarine.DockedTo)
|
||||||
|
{
|
||||||
|
dockedSub.SubBody.ApplyImpact(impact, normal, contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
//find all contacts between this sub and level walls
|
||||||
|
List<Contact> levelContacts = new List<Contact>();
|
||||||
|
ContactEdge contactEdge = Body.FarseerBody.ContactList;
|
||||||
|
while (contactEdge.Next != null)
|
||||||
|
{
|
||||||
|
if (contactEdge.Contact.Enabled &&
|
||||||
|
contactEdge.Other.UserData is VoronoiCell &&
|
||||||
|
contactEdge.Contact.IsTouching)
|
||||||
|
{
|
||||||
|
levelContacts.Add(contactEdge.Contact);
|
||||||
|
}
|
||||||
|
|
||||||
|
contactEdge = contactEdge.Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (levelContacts.Count == 0) return;
|
||||||
|
|
||||||
|
//if this sub is in contact with the level, apply artifical impacts
|
||||||
|
//to both subs to prevent the other sub from bouncing on top of this one
|
||||||
|
//and to fake the other sub "crushing" this one against a wall
|
||||||
|
Vector2 avgContactNormal = Vector2.Zero;
|
||||||
|
foreach (Contact levelContact in levelContacts)
|
||||||
|
{
|
||||||
|
Vector2 contactNormal;
|
||||||
|
FixedArray2<Vector2> temp;
|
||||||
|
levelContact.GetWorldManifold(out contactNormal, out temp);
|
||||||
|
|
||||||
|
//if the contact normal is pointing from the sub towards the level cell we collided with, flip the normal
|
||||||
|
VoronoiCell cell = levelContact.FixtureB.Body.UserData is VoronoiCell ?
|
||||||
|
((VoronoiCell)levelContact.FixtureB.Body.UserData) : ((VoronoiCell)levelContact.FixtureA.Body.UserData);
|
||||||
|
|
||||||
|
var cellDiff = ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center;
|
||||||
|
if (Vector2.Dot(contactNormal, cellDiff) < 0)
|
||||||
|
{
|
||||||
|
contactNormal = -contactNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
avgContactNormal += contactNormal;
|
||||||
|
|
||||||
|
//apply impacts at the positions where this sub is touching the level
|
||||||
|
ApplyImpact((Vector2.Dot(Velocity - otherSub.Velocity, contactNormal) / 2.0f) * massRatio / levelContacts.Count, contactNormal, levelContact);
|
||||||
|
}
|
||||||
|
avgContactNormal /= levelContacts.Count;
|
||||||
|
|
||||||
|
//apply an impact to the other sub
|
||||||
|
float contactDot = Vector2.Dot(otherSub.PhysicsBody.LinearVelocity, -avgContactNormal);
|
||||||
|
if (contactDot > 0.0f)
|
||||||
|
{
|
||||||
|
otherSub.PhysicsBody.LinearVelocity -= Vector2.Normalize(otherSub.PhysicsBody.LinearVelocity) * contactDot;
|
||||||
|
|
||||||
|
impact = Vector2.Dot(otherSub.Velocity, normal);
|
||||||
|
otherSub.SubBody.ApplyImpact(impact, normal, contact);
|
||||||
|
foreach (Submarine dockedSub in otherSub.DockedTo)
|
||||||
|
{
|
||||||
|
dockedSub.SubBody.ApplyImpact(impact, normal, contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ApplyImpact(float impact, Vector2 direction, Contact contact)
|
private void ApplyImpact(float impact, Vector2 direction, Contact contact)
|
||||||
{
|
{
|
||||||
if (impact < 3.0f) return;
|
if (impact < 3.0f) return;
|
||||||
|
|
||||||
Vector2 tempNormal;
|
Vector2 tempNormal;
|
||||||
|
FixedArray2<Vector2> worldPoints;
|
||||||
FarseerPhysics.Common.FixedArray2<Vector2> worldPoints;
|
|
||||||
contact.GetWorldManifold(out tempNormal, out worldPoints);
|
contact.GetWorldManifold(out tempNormal, out worldPoints);
|
||||||
|
|
||||||
Vector2 lastContactPoint = worldPoints[0];
|
Vector2 lastContactPoint = worldPoints[0];
|
||||||
@@ -537,6 +649,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var damagedStructures = Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits(lastContactPoint), impact * 50.0f, impact * DamageMultiplier);
|
var damagedStructures = Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits(lastContactPoint), impact * 50.0f, impact * DamageMultiplier);
|
||||||
|
|
||||||
|
#if CLIENT
|
||||||
//play a damage sound for the structure that took the most damage
|
//play a damage sound for the structure that took the most damage
|
||||||
float maxDamage = 0.0f;
|
float maxDamage = 0.0f;
|
||||||
Structure maxDamageStructure = null;
|
Structure maxDamageStructure = null;
|
||||||
@@ -549,7 +662,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CLIENT
|
|
||||||
if (maxDamageStructure != null)
|
if (maxDamageStructure != null)
|
||||||
{
|
{
|
||||||
SoundPlayer.PlayDamageSound(
|
SoundPlayer.PlayDamageSound(
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace Barotrauma
|
|||||||
protected SpawnType spawnType;
|
protected SpawnType spawnType;
|
||||||
|
|
||||||
//characters spawning at the waypoint will be given an ID card with these tags
|
//characters spawning at the waypoint will be given an ID card with these tags
|
||||||
|
private string idCardDesc;
|
||||||
private string[] idCardTags;
|
private string[] idCardTags;
|
||||||
|
|
||||||
//only characters with this job will be spawned at the waypoint
|
//only characters with this job will be spawned at the waypoint
|
||||||
@@ -57,6 +58,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string IdCardDesc
|
||||||
|
{
|
||||||
|
get { return idCardDesc; }
|
||||||
|
private set { idCardDesc = value; }
|
||||||
|
}
|
||||||
public string[] IdCardTags
|
public string[] IdCardTags
|
||||||
{
|
{
|
||||||
get { return idCardTags; }
|
get { return idCardTags; }
|
||||||
@@ -113,6 +119,7 @@ namespace Barotrauma
|
|||||||
public override MapEntity Clone()
|
public override MapEntity Clone()
|
||||||
{
|
{
|
||||||
var clone = new WayPoint(rect, Submarine);
|
var clone = new WayPoint(rect, Submarine);
|
||||||
|
clone.idCardDesc = idCardDesc;
|
||||||
clone.idCardTags = idCardTags;
|
clone.idCardTags = idCardTags;
|
||||||
clone.spawnType = spawnType;
|
clone.spawnType = spawnType;
|
||||||
clone.assignedJob = assignedJob;
|
clone.assignedJob = assignedJob;
|
||||||
@@ -570,6 +577,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Enum.TryParse<SpawnType>(element.GetAttributeString("spawn", "Path"), out w.spawnType);
|
Enum.TryParse<SpawnType>(element.GetAttributeString("spawn", "Path"), out w.spawnType);
|
||||||
|
|
||||||
|
string idCardDescString = element.GetAttributeString("idcarddesc", "");
|
||||||
|
if (!string.IsNullOrWhiteSpace(idCardDescString))
|
||||||
|
{
|
||||||
|
w.IdCardDesc = idCardDescString;
|
||||||
|
}
|
||||||
string idCardTagString = element.GetAttributeString("idcardtags", "");
|
string idCardTagString = element.GetAttributeString("idcardtags", "");
|
||||||
if (!string.IsNullOrWhiteSpace(idCardTagString))
|
if (!string.IsNullOrWhiteSpace(idCardTagString))
|
||||||
{
|
{
|
||||||
@@ -604,6 +616,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("y", (int)(rect.Y - Submarine.HiddenSubPosition.Y)),
|
new XAttribute("y", (int)(rect.Y - Submarine.HiddenSubPosition.Y)),
|
||||||
new XAttribute("spawn", spawnType));
|
new XAttribute("spawn", spawnType));
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(idCardDesc)) element.Add(new XAttribute("idcarddesc", idCardDesc));
|
||||||
if (idCardTags.Length > 0)
|
if (idCardTags.Length > 0)
|
||||||
{
|
{
|
||||||
element.Add(new XAttribute("idcardtags", string.Join(",", idCardTags)));
|
element.Add(new XAttribute("idcardtags", string.Join(",", idCardTags)));
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
enum ChatMessageType
|
enum ChatMessageType
|
||||||
{
|
{
|
||||||
Default, Error, Dead, Server, Radio, Private, MessageBox
|
Default, Error, Dead, Server, Radio, Private, Console, MessageBox
|
||||||
}
|
}
|
||||||
|
|
||||||
partial class ChatMessage
|
partial class ChatMessage
|
||||||
@@ -25,7 +25,8 @@ namespace Barotrauma.Networking
|
|||||||
new Color(63, 72, 204), //dead
|
new Color(63, 72, 204), //dead
|
||||||
new Color(157, 225, 160), //server
|
new Color(157, 225, 160), //server
|
||||||
new Color(238, 208, 0), //radio
|
new Color(238, 208, 0), //radio
|
||||||
new Color(64, 240, 89) //private
|
new Color(64, 240, 89), //private
|
||||||
|
new Color(255, 255, 255) //console
|
||||||
};
|
};
|
||||||
|
|
||||||
public readonly string Text;
|
public readonly string Text;
|
||||||
@@ -105,18 +106,18 @@ namespace Barotrauma.Networking
|
|||||||
return ApplyDistanceEffect(listener, Sender, Text, SpeakRange);
|
return ApplyDistanceEffect(listener, Sender, Text, SpeakRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ApplyDistanceEffect(Entity listener, Entity Sender, string text, float range)
|
public static string ApplyDistanceEffect(Entity listener, Entity Sender, string text, float range, float obstructionmult = 2.0f)
|
||||||
{
|
{
|
||||||
if (listener.WorldPosition == Sender.WorldPosition) return text;
|
if (listener.WorldPosition == Sender.WorldPosition) return text;
|
||||||
|
|
||||||
float dist = Vector2.Distance(listener.WorldPosition, Sender.WorldPosition);
|
float dist = Vector2.Distance(listener.WorldPosition, Sender.WorldPosition);
|
||||||
if (dist > range) return "";
|
if (dist > range) return "";
|
||||||
|
|
||||||
if (Submarine.CheckVisibility(listener.SimPosition, Sender.SimPosition) != null) dist *= 2.0f;
|
if (Submarine.CheckVisibility(listener.SimPosition, Sender.SimPosition) != null) dist = (dist + 100f) * obstructionmult;
|
||||||
if (dist > range) return "";
|
if (dist > range) return "";
|
||||||
|
|
||||||
float garbleAmount = dist / range;
|
float garbleAmount = dist / range;
|
||||||
if (garbleAmount < 0.5f) return text;
|
if (garbleAmount < 0.3f) return text;
|
||||||
|
|
||||||
int startIndex = Math.Max(text.IndexOf(':') + 1, 1);
|
int startIndex = Math.Max(text.IndexOf(':') + 1, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,10 @@
|
|||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Barotrauma.Networking
|
namespace Barotrauma.Networking
|
||||||
{
|
{
|
||||||
[Flags]
|
|
||||||
enum ClientPermissions
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
[Description("End round")]
|
|
||||||
EndRound = 1,
|
|
||||||
[Description("Kick")]
|
|
||||||
Kick = 2,
|
|
||||||
[Description("Ban")]
|
|
||||||
Ban = 4,
|
|
||||||
[Description("Select submarine")]
|
|
||||||
SelectSub = 8,
|
|
||||||
[Description("Select game mode")]
|
|
||||||
SelectMode = 16,
|
|
||||||
[Description("Manage campaign")]
|
|
||||||
ManageCampaign = 32
|
|
||||||
}
|
|
||||||
|
|
||||||
class Client
|
class Client
|
||||||
{
|
{
|
||||||
public string Name;
|
public string Name;
|
||||||
@@ -96,6 +77,11 @@ namespace Barotrauma.Networking
|
|||||||
public float DeleteDisconnectedTimer;
|
public float DeleteDisconnectedTimer;
|
||||||
|
|
||||||
public ClientPermissions Permissions = ClientPermissions.None;
|
public ClientPermissions Permissions = ClientPermissions.None;
|
||||||
|
public List<DebugConsole.Command> PermittedConsoleCommands
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
public bool SpectateOnly;
|
public bool SpectateOnly;
|
||||||
|
|
||||||
@@ -130,6 +116,7 @@ namespace Barotrauma.Networking
|
|||||||
this.Name = name;
|
this.Name = name;
|
||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
|
|
||||||
|
PermittedConsoleCommands = new List<DebugConsole.Command>();
|
||||||
kickVoters = new List<Client>();
|
kickVoters = new List<Client>();
|
||||||
|
|
||||||
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
|
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
|
||||||
@@ -171,9 +158,10 @@ namespace Barotrauma.Networking
|
|||||||
return rName;
|
return rName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPermissions(ClientPermissions permissions)
|
public void SetPermissions(ClientPermissions permissions, List<DebugConsole.Command> permittedConsoleCommands)
|
||||||
{
|
{
|
||||||
this.Permissions = permissions;
|
this.Permissions = permissions;
|
||||||
|
this.PermittedConsoleCommands = new List<DebugConsole.Command>(permittedConsoleCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GivePermission(ClientPermissions permission)
|
public void GivePermission(ClientPermissions permission)
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Networking
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
enum ClientPermissions
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
[Description("End round")]
|
||||||
|
EndRound = 1,
|
||||||
|
[Description("Kick")]
|
||||||
|
Kick = 2,
|
||||||
|
[Description("Ban")]
|
||||||
|
Ban = 4,
|
||||||
|
[Description("Select submarine")]
|
||||||
|
SelectSub = 8,
|
||||||
|
[Description("Select game mode")]
|
||||||
|
SelectMode = 16,
|
||||||
|
[Description("Manage campaign")]
|
||||||
|
ManageCampaign = 32,
|
||||||
|
[Description("Console commands")]
|
||||||
|
ConsoleCommands = 64
|
||||||
|
}
|
||||||
|
|
||||||
|
class PermissionPreset
|
||||||
|
{
|
||||||
|
public static List<PermissionPreset> List = new List<PermissionPreset>();
|
||||||
|
|
||||||
|
public readonly string Name;
|
||||||
|
public readonly string Description;
|
||||||
|
public readonly ClientPermissions Permissions;
|
||||||
|
public readonly List<DebugConsole.Command> PermittedCommands;
|
||||||
|
|
||||||
|
public PermissionPreset(XElement element)
|
||||||
|
{
|
||||||
|
Name = element.GetAttributeString("name", "");
|
||||||
|
Description = element.GetAttributeString("description", "");
|
||||||
|
|
||||||
|
string permissionsStr = element.GetAttributeString("permissions", "");
|
||||||
|
if (!Enum.TryParse(permissionsStr, out Permissions))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in permission preset \"" + Name + "\" - " + permissionsStr + " is not a valid permission!");
|
||||||
|
}
|
||||||
|
|
||||||
|
PermittedCommands = new List<DebugConsole.Command>();
|
||||||
|
if (Permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||||
|
{
|
||||||
|
foreach (XElement subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (subElement.Name.ToString().ToLowerInvariant() != "command") continue;
|
||||||
|
string commandName = subElement.GetAttributeString("name", "");
|
||||||
|
|
||||||
|
DebugConsole.Command command = DebugConsole.FindCommand(commandName);
|
||||||
|
if (command == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in permission preset \"" + Name + "\" - " + commandName + "\" is not a valid console command.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PermittedCommands.Add(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LoadAll(string file)
|
||||||
|
{
|
||||||
|
if (!File.Exists(file)) return;
|
||||||
|
|
||||||
|
XDocument doc = XMLExtensions.TryLoadXml(file);
|
||||||
|
if (doc == null || doc.Root == null) return;
|
||||||
|
|
||||||
|
foreach (XElement element in doc.Root.Elements())
|
||||||
|
{
|
||||||
|
List.Add(new PermissionPreset(element));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -125,8 +125,9 @@ namespace Barotrauma.Networking
|
|||||||
banList = new BanList();
|
banList = new BanList();
|
||||||
|
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
|
PermissionPreset.LoadAll(PermissionPresetFile);
|
||||||
LoadClientPermissions();
|
LoadClientPermissions();
|
||||||
|
|
||||||
CoroutineManager.StartCoroutine(StartServer(isPublic));
|
CoroutineManager.StartCoroutine(StartServer(isPublic));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,6 +796,11 @@ namespace Barotrauma.Networking
|
|||||||
campaign.ServerRead(inc, sender);
|
campaign.ServerRead(inc, sender);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ClientPermissions.ConsoleCommands:
|
||||||
|
string consoleCommand = inc.ReadString();
|
||||||
|
Vector2 clientCursorPos = new Vector2(inc.ReadSingle(), inc.ReadSingle());
|
||||||
|
DebugConsole.ExecuteClientCommand(sender, clientCursorPos, consoleCommand);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
inc.ReadPadBits();
|
inc.ReadPadBits();
|
||||||
@@ -853,7 +859,7 @@ namespace Barotrauma.Networking
|
|||||||
outmsg.Write(GameStarted);
|
outmsg.Write(GameStarted);
|
||||||
outmsg.Write(AllowSpectating);
|
outmsg.Write(AllowSpectating);
|
||||||
|
|
||||||
outmsg.Write((byte)c.Permissions);
|
WritePermissions(outmsg, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClientWriteIngame(Client c)
|
private void ClientWriteIngame(Client c)
|
||||||
@@ -1636,6 +1642,18 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendChatMessage(string txt, Client recipient)
|
||||||
|
{
|
||||||
|
ChatMessage msg = ChatMessage.Create("", txt, ChatMessageType.Server, null);
|
||||||
|
SendChatMessage(msg, recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendConsoleMessage(string txt, Client recipient)
|
||||||
|
{
|
||||||
|
ChatMessage msg = ChatMessage.Create("", txt, ChatMessageType.Console, null);
|
||||||
|
SendChatMessage(msg, recipient);
|
||||||
|
}
|
||||||
|
|
||||||
public void SendChatMessage(ChatMessage msg, Client recipient)
|
public void SendChatMessage(ChatMessage msg, Client recipient)
|
||||||
{
|
{
|
||||||
msg.NetStateID = recipient.ChatMsgQueue.Count > 0 ?
|
msg.NetStateID = recipient.ChatMsgQueue.Count > 0 ?
|
||||||
@@ -1848,7 +1866,7 @@ namespace Barotrauma.Networking
|
|||||||
case ChatMessageType.Default:
|
case ChatMessageType.Default:
|
||||||
if (!receiver.IsDead)
|
if (!receiver.IsDead)
|
||||||
{
|
{
|
||||||
return ChatMessage.ApplyDistanceEffect(receiver, sender, message, ChatMessage.SpeakRange);
|
return ChatMessage.ApplyDistanceEffect(receiver, sender, message, ChatMessage.SpeakRange, 3.0f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ChatMessageType.Radio:
|
case ChatMessageType.Radio:
|
||||||
@@ -1936,16 +1954,34 @@ namespace Barotrauma.Networking
|
|||||||
clientPermissions.Add(new SavedClientPermission(
|
clientPermissions.Add(new SavedClientPermission(
|
||||||
client.Name,
|
client.Name,
|
||||||
client.Connection.RemoteEndPoint.Address.ToString(),
|
client.Connection.RemoteEndPoint.Address.ToString(),
|
||||||
client.Permissions));
|
client.Permissions,
|
||||||
|
client.PermittedConsoleCommands));
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg = server.CreateMessage();
|
var msg = server.CreateMessage();
|
||||||
msg.Write((byte)ServerPacketHeader.PERMISSIONS);
|
msg.Write((byte)ServerPacketHeader.PERMISSIONS);
|
||||||
msg.Write((byte)client.Permissions);
|
WritePermissions(msg, client);
|
||||||
|
|
||||||
server.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableUnordered);
|
server.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
|
||||||
SaveClientPermissions();
|
SaveClientPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WritePermissions(NetBuffer msg, Client client)
|
||||||
|
{
|
||||||
|
msg.Write((byte)client.Permissions);
|
||||||
|
if (client.Permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||||
|
{
|
||||||
|
msg.Write((UInt16)client.PermittedConsoleCommands.Sum(c => c.names.Length));
|
||||||
|
foreach (DebugConsole.Command command in client.PermittedConsoleCommands)
|
||||||
|
{
|
||||||
|
foreach (string commandName in command.names)
|
||||||
|
{
|
||||||
|
msg.Write(commandName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetClientCharacter(Client client, Character newCharacter)
|
public void SetClientCharacter(Client client, Character newCharacter)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -218,11 +218,11 @@ namespace Barotrauma.Networking
|
|||||||
var savedPermissions = clientPermissions.Find(cp => cp.IP == newClient.Connection.RemoteEndPoint.Address.ToString());
|
var savedPermissions = clientPermissions.Find(cp => cp.IP == newClient.Connection.RemoteEndPoint.Address.ToString());
|
||||||
if (savedPermissions != null)
|
if (savedPermissions != null)
|
||||||
{
|
{
|
||||||
newClient.SetPermissions(savedPermissions.Permissions);
|
newClient.SetPermissions(savedPermissions.Permissions, savedPermissions.PermittedCommands);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newClient.SetPermissions(ClientPermissions.None);
|
newClient.SetPermissions(ClientPermissions.None, new List<DebugConsole.Command>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,20 +25,23 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
public readonly string IP;
|
public readonly string IP;
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
public List<DebugConsole.Command> PermittedCommands;
|
||||||
|
|
||||||
public ClientPermissions Permissions;
|
public ClientPermissions Permissions;
|
||||||
|
|
||||||
public SavedClientPermission(string name, string ip, ClientPermissions permissions)
|
public SavedClientPermission(string name, string ip, ClientPermissions permissions, List<DebugConsole.Command> permittedCommands)
|
||||||
{
|
{
|
||||||
this.Name = name;
|
this.Name = name;
|
||||||
this.IP = ip;
|
this.IP = ip;
|
||||||
|
|
||||||
this.Permissions = permissions;
|
this.Permissions = permissions;
|
||||||
|
this.PermittedCommands = permittedCommands;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public const string SettingsFile = "serversettings.xml";
|
public const string SettingsFile = "serversettings.xml";
|
||||||
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.txt";
|
public static readonly string PermissionPresetFile = "Data" + Path.DirectorySeparatorChar + "permissionpresets.xml";
|
||||||
|
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.xml";
|
||||||
|
|
||||||
public Dictionary<string, SerializableProperty> SerializableProperties
|
public Dictionary<string, SerializableProperty> SerializableProperties
|
||||||
{
|
{
|
||||||
@@ -130,6 +133,13 @@ namespace Barotrauma.Networking
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize(true, true)]
|
||||||
|
public bool AllowRagdollButton
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
[Serialize(true, true)]
|
[Serialize(true, true)]
|
||||||
public bool AllowFileTransfers
|
public bool AllowFileTransfers
|
||||||
{
|
{
|
||||||
@@ -210,6 +220,20 @@ namespace Barotrauma.Networking
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize(true, true)]
|
||||||
|
public bool TraitorUseRatio
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serialize(0.2f, true)]
|
||||||
|
public float TraitorRatio
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
[Serialize(false,true)]
|
[Serialize(false,true)]
|
||||||
public bool KarmaEnabled
|
public bool KarmaEnabled
|
||||||
{
|
{
|
||||||
@@ -323,12 +347,67 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void LoadClientPermissions()
|
public void LoadClientPermissions()
|
||||||
{
|
{
|
||||||
if (!File.Exists(ClientPermissionsFile)) return;
|
clientPermissions.Clear();
|
||||||
|
|
||||||
|
if (File.Exists("Data/clientpermissions.txt") && !File.Exists(ClientPermissionsFile))
|
||||||
|
{
|
||||||
|
LoadClientPermissionsOld("Data/clientpermissions.txt");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDocument doc = XMLExtensions.TryLoadXml(ClientPermissionsFile);
|
||||||
|
foreach (XElement clientElement in doc.Root.Elements())
|
||||||
|
{
|
||||||
|
string clientName = clientElement.GetAttributeString("name", "");
|
||||||
|
string clientIP = clientElement.GetAttributeString("ip", "");
|
||||||
|
if (string.IsNullOrWhiteSpace(clientName) || string.IsNullOrWhiteSpace(clientIP))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - all clients must have a name and an IP address.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string permissionsStr = clientElement.GetAttributeString("permissions", "");
|
||||||
|
ClientPermissions permissions;
|
||||||
|
if (!Enum.TryParse(permissionsStr, out permissions))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + permissionsStr + "\" is not a valid client permission.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
|
||||||
|
if (permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||||
|
{
|
||||||
|
foreach (XElement commandElement in clientElement.Elements())
|
||||||
|
{
|
||||||
|
if (commandElement.Name.ToString().ToLowerInvariant() != "command") continue;
|
||||||
|
|
||||||
|
string commandName = commandElement.GetAttributeString("name", "");
|
||||||
|
DebugConsole.Command command = DebugConsole.FindCommand(commandName);
|
||||||
|
if (command == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + commandName + "\" is not a valid console command.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
permittedCommands.Add(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clientPermissions.Add(new SavedClientPermission(clientName, clientIP, permissions, permittedCommands));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method for loading old .txt client permission files to provide backwards compatibility
|
||||||
|
/// </summary>
|
||||||
|
private void LoadClientPermissionsOld(string file)
|
||||||
|
{
|
||||||
|
if (!File.Exists(file)) return;
|
||||||
|
|
||||||
string[] lines;
|
string[] lines;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lines = File.ReadAllLines(ClientPermissionsFile);
|
lines = File.ReadAllLines(file);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -337,36 +416,63 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
clientPermissions.Clear();
|
clientPermissions.Clear();
|
||||||
|
|
||||||
foreach (string line in lines)
|
foreach (string line in lines)
|
||||||
{
|
{
|
||||||
string[] separatedLine = line.Split('|');
|
string[] separatedLine = line.Split('|');
|
||||||
if (separatedLine.Length < 3) continue;
|
if (separatedLine.Length < 3) continue;
|
||||||
|
|
||||||
string name = String.Join("|", separatedLine.Take(separatedLine.Length - 2));
|
string name = string.Join("|", separatedLine.Take(separatedLine.Length - 2));
|
||||||
string ip = separatedLine[separatedLine.Length - 2];
|
string ip = separatedLine[separatedLine.Length - 2];
|
||||||
|
|
||||||
ClientPermissions permissions = ClientPermissions.None;
|
ClientPermissions permissions = ClientPermissions.None;
|
||||||
if (Enum.TryParse<ClientPermissions>(separatedLine.Last(), out permissions))
|
if (Enum.TryParse(separatedLine.Last(), out permissions))
|
||||||
{
|
{
|
||||||
clientPermissions.Add(new SavedClientPermission(name, ip, permissions));
|
clientPermissions.Add(new SavedClientPermission(name, ip, permissions, new List<DebugConsole.Command>()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveClientPermissions()
|
public void SaveClientPermissions()
|
||||||
{
|
{
|
||||||
GameServer.Log("Saving client permissions", ServerLog.MessageType.ServerMessage);
|
//delete old client permission file
|
||||||
|
if (File.Exists("Data/clientpermissions.txt"))
|
||||||
|
{
|
||||||
|
File.Delete("Data/clientpermissions.txt");
|
||||||
|
}
|
||||||
|
|
||||||
List<string> lines = new List<string>();
|
Log("Saving client permissions", ServerLog.MessageType.ServerMessage);
|
||||||
|
|
||||||
|
XDocument doc = new XDocument(new XElement("ClientPermissions"));
|
||||||
|
|
||||||
foreach (SavedClientPermission clientPermission in clientPermissions)
|
foreach (SavedClientPermission clientPermission in clientPermissions)
|
||||||
{
|
{
|
||||||
lines.Add(clientPermission.Name + "|" + clientPermission.IP+"|"+clientPermission.Permissions.ToString());
|
XElement clientElement = new XElement("Client",
|
||||||
|
new XAttribute("name", clientPermission.Name),
|
||||||
|
new XAttribute("ip", clientPermission.IP),
|
||||||
|
new XAttribute("permissions", clientPermission.Permissions.ToString()));
|
||||||
|
|
||||||
|
if (clientPermission.Permissions.HasFlag(ClientPermissions.ConsoleCommands))
|
||||||
|
{
|
||||||
|
foreach (DebugConsole.Command command in clientPermission.PermittedCommands)
|
||||||
|
{
|
||||||
|
clientElement.Add(new XElement("command", new XAttribute("name", command.names[0])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.Root.Add(clientElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.WriteAllLines(ClientPermissionsFile, lines);
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
|
settings.Indent = true;
|
||||||
|
settings.NewLineOnAttributes = true;
|
||||||
|
|
||||||
|
using (var writer = XmlWriter.Create(ClientPermissionsFile, settings))
|
||||||
|
{
|
||||||
|
doc.Save(writer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -533,7 +533,9 @@ namespace Barotrauma.Networking
|
|||||||
foreach (string s in shuttleSpawnPoints[i].IdCardTags)
|
foreach (string s in shuttleSpawnPoints[i].IdCardTags)
|
||||||
{
|
{
|
||||||
item.AddTag(s);
|
item.AddTag(s);
|
||||||
}
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(shuttleSpawnPoints[i].IdCardDesc))
|
||||||
|
item.Description = shuttleSpawnPoints[i].IdCardDesc;
|
||||||
}
|
}
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
GameMain.GameSession.CrewManager.AddCharacter(character);
|
GameMain.GameSession.CrewManager.AddCharacter(character);
|
||||||
|
|||||||
@@ -28,18 +28,20 @@ namespace Barotrauma.Networking
|
|||||||
Attack,
|
Attack,
|
||||||
Spawning,
|
Spawning,
|
||||||
ServerMessage,
|
ServerMessage,
|
||||||
|
ConsoleUsage,
|
||||||
Error
|
Error
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Color[] messageColor =
|
private readonly Color[] messageColor =
|
||||||
{
|
{
|
||||||
Color.LightBlue,
|
Color.LightBlue, //Chat
|
||||||
new Color(255, 142, 0),
|
new Color(255, 142, 0), //ItemInteraction
|
||||||
new Color(238, 208, 0),
|
new Color(238, 208, 0), //Inventory
|
||||||
new Color(204, 74, 78),
|
new Color(204, 74, 78), //Attack
|
||||||
new Color(163, 73, 164),
|
new Color(163, 73, 164), //Spawning
|
||||||
new Color(157, 225, 160),
|
new Color(157, 225, 160), //ServerMessage
|
||||||
Color.Red
|
new Color(0, 162, 232), //ConsoleUsage
|
||||||
|
Color.Red //Error
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly string[] messageTypeName =
|
private readonly string[] messageTypeName =
|
||||||
@@ -50,6 +52,7 @@ namespace Barotrauma.Networking
|
|||||||
"Attack & death",
|
"Attack & death",
|
||||||
"Spawning",
|
"Spawning",
|
||||||
"Server message",
|
"Server message",
|
||||||
|
"Console usage",
|
||||||
"Error"
|
"Error"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,15 @@
|
|||||||
allowspectating="True"
|
allowspectating="True"
|
||||||
endroundatlevelend="True"
|
endroundatlevelend="True"
|
||||||
saveserverlogs="True"
|
saveserverlogs="True"
|
||||||
|
allowragdollbutton="True"
|
||||||
allowfiletransfers="True"
|
allowfiletransfers="True"
|
||||||
allowrespawn="True"
|
allowrespawn="True"
|
||||||
allowvotekick="True"
|
allowvotekick="True"
|
||||||
endvoterequiredratio="0.6"
|
endvoterequiredratio="0.6"
|
||||||
kickvoterequiredratio="0.6"
|
kickvoterequiredratio="0.6"
|
||||||
|
traitoruseratio="True"
|
||||||
|
traitorratio="0.2"
|
||||||
|
karmaenabled="False"
|
||||||
SubSelection="Manual"
|
SubSelection="Manual"
|
||||||
ModeSelection="Manual"
|
ModeSelection="Manual"
|
||||||
TraitorsEnabled="No"
|
TraitorsEnabled="No"
|
||||||
|
|||||||
Reference in New Issue
Block a user