Build 0.20.7.0
This commit is contained in:
@@ -276,7 +276,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
//get all walls within range
|
||||
//get all walls within range the arc could potentially hit
|
||||
List<Entity> entitiesInRange = new List<Entity>(100);
|
||||
foreach (Structure structure in Structure.WallList)
|
||||
{
|
||||
@@ -284,10 +284,10 @@ namespace Barotrauma.Items.Components
|
||||
if (structure.Submarine != null&& !submarinesInRange.Contains(structure.Submarine)) { continue; }
|
||||
|
||||
var structureWorldRect = structure.WorldRect;
|
||||
if (worldPosition.X < structureWorldRect.X - range) continue;
|
||||
if (worldPosition.X > structureWorldRect.Right + range) continue;
|
||||
if (worldPosition.Y > structureWorldRect.Y + range) continue;
|
||||
if (worldPosition.Y < structureWorldRect.Y -structureWorldRect.Height - range) continue;
|
||||
if (worldPosition.X < structureWorldRect.X - range) { continue; }
|
||||
if (worldPosition.X > structureWorldRect.Right + range) { continue; }
|
||||
if (worldPosition.Y > structureWorldRect.Y + range) { continue; }
|
||||
if (worldPosition.Y < structureWorldRect.Y - structureWorldRect.Height - range) { continue; }
|
||||
|
||||
if (structure.Submarine != null)
|
||||
{
|
||||
@@ -317,6 +317,7 @@ namespace Barotrauma.Items.Components
|
||||
nodes.Add(new Node(worldPosition, -1));
|
||||
}
|
||||
|
||||
//get all characters within range the arc could potentially hit
|
||||
float totalRange = RaycastRange + range;
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
@@ -325,11 +326,20 @@ namespace Barotrauma.Items.Components
|
||||
if (OutdoorsOnly && character.Submarine != null) { continue; }
|
||||
if (character.Submarine != null && !submarinesInRange.Contains(character.Submarine)) { continue; }
|
||||
|
||||
if (Vector2.DistanceSquared(character.WorldPosition, worldPosition) < totalRange * totalRange * RangeMultiplierInWalls ||
|
||||
(RaycastRange > 0.0f && MathUtils.LineToPointDistanceSquared(worldPosition, item.WorldPosition, character.WorldPosition) < range * range * RangeMultiplierInWalls))
|
||||
if (Vector2.DistanceSquared(character.WorldPosition, worldPosition) < totalRange * totalRange * RangeMultiplierInWalls)
|
||||
{
|
||||
entitiesInRange.Add(character);
|
||||
charactersInRange.Add((character, nodes[0]));
|
||||
}
|
||||
//if the weapon does a raycast, check distance to the ray too (not just the end of the ray)
|
||||
if (RaycastRange > 0)
|
||||
{
|
||||
float distSqr = MathUtils.LineSegmentToPointDistanceSquared(worldPosition, item.WorldPosition, character.WorldPosition);
|
||||
//if the distance from the initial raycast to the character is small (e.g. goes through the character), we know it must hit
|
||||
if (distSqr < range * range * RangeMultiplierInWalls)
|
||||
{
|
||||
if (!entitiesInRange.Contains(character)) { entitiesInRange.Add(character); }
|
||||
charactersInRange.Add((character, nodes.First()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,7 +388,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (entitiesInRange[i] is Character character)
|
||||
{
|
||||
dist = Vector2.Distance(character.WorldPosition, currPos);
|
||||
dist = MathUtils.LineSegmentToPointDistanceSquared(currPos, nodes[parentNodeIndex].WorldPosition, character.WorldPosition);
|
||||
}
|
||||
|
||||
if (dist < closestDist)
|
||||
@@ -494,17 +504,31 @@ namespace Barotrauma.Items.Components
|
||||
if (IgnoreUser && character == user) { continue; }
|
||||
if (OutdoorsOnly && character.Submarine != null) { continue; }
|
||||
|
||||
Vector2 characterMin = new Vector2(character.AnimController.Limbs.Min(l => l.WorldPosition.X), character.AnimController.Limbs.Min(l => l.WorldPosition.Y));
|
||||
Vector2 characterMax = new Vector2(character.AnimController.Limbs.Max(l => l.WorldPosition.X), character.AnimController.Limbs.Max(l => l.WorldPosition.Y));
|
||||
if (targetStructure.IsHorizontal)
|
||||
{
|
||||
if (otherEntity.WorldPosition.X < targetStructure.WorldRect.X) { continue; }
|
||||
if (otherEntity.WorldPosition.X > targetStructure.WorldRect.Right) { continue; }
|
||||
if (Math.Abs(otherEntity.WorldPosition.Y - targetStructure.WorldPosition.Y) > currentRange) { continue; }
|
||||
if (characterMax.X < targetStructure.WorldRect.X) { continue; }
|
||||
if (characterMin.X > targetStructure.WorldRect.Right) { continue; }
|
||||
if (Math.Abs(characterMin.Y - targetStructure.WorldPosition.Y) > currentRange &&
|
||||
Math.Abs(characterMax.Y - targetStructure.WorldPosition.Y) > currentRange)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (otherEntity.WorldPosition.Y < targetStructure.WorldRect.Y - targetStructure.Rect.Height) { continue; }
|
||||
if (otherEntity.WorldPosition.Y > targetStructure.WorldRect.Y) { continue; }
|
||||
if (Math.Abs(otherEntity.WorldPosition.X - targetStructure.WorldPosition.X) > currentRange) { continue; }
|
||||
if (characterMax.Y < targetStructure.WorldRect.Y - targetStructure.Rect.Height) { continue; }
|
||||
if (characterMin.Y > targetStructure.WorldRect.Y) { continue; }
|
||||
if (Math.Abs(characterMin.X - targetStructure.WorldPosition.X) > currentRange &&
|
||||
Math.Abs(characterMax.X - targetStructure.WorldPosition.X) > currentRange)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!charactersInRange.Any(c => c.character == character))
|
||||
{
|
||||
charactersInRange.Add((character, nodes[parentNodeIndex]));
|
||||
}
|
||||
float closestNodeDistSqr = float.MaxValue;
|
||||
int closestNodeIndex = -1;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
public enum UseEnvironment
|
||||
{
|
||||
Air, Water, Both
|
||||
Air, Water, Both, None
|
||||
};
|
||||
|
||||
private float useState;
|
||||
@@ -44,6 +44,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (character == null || character.Removed) { return false; }
|
||||
if (!character.IsKeyDown(InputType.Aim) || character.Stun > 0.0f) { return false; }
|
||||
if (UsableIn == UseEnvironment.None) { return false; }
|
||||
|
||||
IsActive = true;
|
||||
useState = 0.1f;
|
||||
|
||||
@@ -476,6 +476,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (Item item in Inventory.AllItemsMod)
|
||||
{
|
||||
item.ApplyStatusEffects(ActionType.OnSuccess, 1.0f, ownerCharacter);
|
||||
item.ApplyStatusEffects(ActionType.OnUse, 1.0f, ownerCharacter);
|
||||
item.GetComponent<GeneticMaterial>()?.Equip(ownerCharacter);
|
||||
autoInjectCooldown = AutoInjectInterval;
|
||||
|
||||
@@ -450,6 +450,7 @@ namespace Barotrauma.Items.Components
|
||||
public override bool Select(Character activator)
|
||||
{
|
||||
if (activator == null || activator.Removed) { return false; }
|
||||
if (Item.Condition <= 0.0f && !UpdateWhenInactive) { return false; }
|
||||
|
||||
if (UsableIn == UseEnvironment.Water && !activator.AnimController.InWater ||
|
||||
UsableIn == UseEnvironment.Air && activator.AnimController.InWater)
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
private ImmutableDictionary<uint, FabricationRecipe> fabricationRecipes; //this is not readonly because tutorials fuck this up!!!!
|
||||
|
||||
private const int MaxAmountToFabricate = 99;
|
||||
|
||||
private FabricationRecipe fabricatedItem;
|
||||
private float timeUntilReady;
|
||||
private float requiredTime;
|
||||
@@ -39,6 +41,16 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes)]
|
||||
public float SkillRequirementMultiplier { get; set; }
|
||||
|
||||
private int amountToFabricate;
|
||||
[Serialize(1, IsPropertySaveable.Yes)]
|
||||
public int AmountToFabricate
|
||||
{
|
||||
get { return amountToFabricate; }
|
||||
set { amountToFabricate = MathHelper.Clamp(value, 1, MaxAmountToFabricate); }
|
||||
}
|
||||
|
||||
private int amountRemaining;
|
||||
|
||||
private const float TinkeringSpeedIncrease = 2.5f;
|
||||
|
||||
private enum FabricatorState
|
||||
@@ -183,16 +195,20 @@ namespace Barotrauma.Items.Components
|
||||
if (selectedItem == null) { return; }
|
||||
if (!outputContainer.Inventory.CanBePut(selectedItem.TargetItem, selectedItem.OutCondition * selectedItem.TargetItem.Health)) { return; }
|
||||
|
||||
#if CLIENT
|
||||
itemList.Enabled = false;
|
||||
activateButton.Text = TextManager.Get("FabricatorCancel");
|
||||
#endif
|
||||
|
||||
IsActive = true;
|
||||
this.user = user;
|
||||
fabricatedItem = selectedItem;
|
||||
RefreshAvailableIngredients();
|
||||
|
||||
#if CLIENT
|
||||
itemList.Enabled = false;
|
||||
if (amountInput != null)
|
||||
{
|
||||
amountInput.Enabled = false;
|
||||
}
|
||||
RefreshActivateButtonText();
|
||||
#endif
|
||||
|
||||
bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient;
|
||||
if (!isClient)
|
||||
{
|
||||
@@ -249,10 +265,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
#elif CLIENT
|
||||
itemList.Enabled = true;
|
||||
if (activateButton != null)
|
||||
if (amountInput != null)
|
||||
{
|
||||
activateButton.Text = TextManager.Get(CreateButtonText);
|
||||
amountInput.Enabled = true;
|
||||
}
|
||||
RefreshActivateButtonText();
|
||||
#endif
|
||||
fabricatedItem = null;
|
||||
}
|
||||
@@ -518,20 +535,16 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
//disabled "continuous fabrication" for now
|
||||
//before we enable it, there should be some UI controls for fabricating a specific number of items
|
||||
|
||||
/*var prevFabricatedItem = fabricatedItem;
|
||||
var prevFabricatedItem = fabricatedItem;
|
||||
var prevUser = user;
|
||||
CancelFabricating();
|
||||
if (CanBeFabricated(prevFabricatedItem))
|
||||
|
||||
amountRemaining--;
|
||||
if (amountRemaining > 0 && CanBeFabricated(prevFabricatedItem, availableIngredients, prevUser))
|
||||
{
|
||||
//keep fabricating if we can fabricate more
|
||||
StartFabricating(prevFabricatedItem, prevUser, addToServerLog: false);
|
||||
}*/
|
||||
|
||||
|
||||
CancelFabricating();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -594,7 +607,15 @@ namespace Barotrauma.Items.Components
|
||||
private bool CanBeFabricated(FabricationRecipe fabricableItem, IReadOnlyDictionary<Identifier, List<Item>> availableIngredients, Character character)
|
||||
{
|
||||
if (fabricableItem == null) { return false; }
|
||||
if (fabricableItem.RequiresRecipe && (character == null || !character.HasRecipeForItem(fabricableItem.TargetItem.Identifier))) { return false; }
|
||||
if (fabricableItem.RequiresRecipe)
|
||||
{
|
||||
if (character == null) { return false; }
|
||||
if (!character.HasRecipeForItem(fabricableItem.TargetItem.Identifier) &&
|
||||
GameSession.GetSessionCrewCharacters(CharacterType.Bot).None(c => c.HasRecipeForItem(fabricableItem.TargetItem.Identifier)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fabricableItem.RequiredMoney > 0)
|
||||
{
|
||||
|
||||
@@ -151,7 +151,6 @@ namespace Barotrauma.Items.Components
|
||||
set
|
||||
{
|
||||
bool changed = currentMode != value;
|
||||
|
||||
currentMode = value;
|
||||
#if CLIENT
|
||||
if (changed) { prevPassivePingRadius = float.MaxValue; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
@@ -9,14 +10,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
public const int MaxQuality = 3;
|
||||
|
||||
public static readonly float[] QualityCommonnesses = new float[]
|
||||
{
|
||||
0.8f,
|
||||
0.15f,
|
||||
0.045f,
|
||||
0.005f,
|
||||
};
|
||||
|
||||
public enum StatType
|
||||
{
|
||||
Condition,
|
||||
@@ -81,5 +74,29 @@ namespace Barotrauma.Items.Components
|
||||
if (!statValues.ContainsKey(statType)) { return 0.0f; }
|
||||
return statValues[statType] * qualityLevel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a random quality for an item spawning in some sub, taking into account the type of the submarine and the difficulty of the current level
|
||||
/// (high-quality items become more common as difficulty increases)
|
||||
/// </summary>
|
||||
public static int GetSpawnedItemQuality(Submarine submarine, Level level, Rand.RandSync randSync = Rand.RandSync.ServerAndClient)
|
||||
{
|
||||
if (submarine?.Info == null || level == null || submarine.Info.Type == SubmarineType.Player) { return 0; }
|
||||
|
||||
float difficultyFactor = MathHelper.Clamp(level.Difficulty, 0.0f, 1.0f);
|
||||
return ToolBox.SelectWeightedRandom(Enumerable.Range(0, MaxQuality + 1), q => GetCommonness(q, difficultyFactor), randSync);
|
||||
|
||||
static float GetCommonness(int quality, float difficultyFactor)
|
||||
{
|
||||
return quality switch
|
||||
{
|
||||
0 => 1,
|
||||
1 => MathHelper.Lerp(0.0f, 1f, difficultyFactor),
|
||||
2 => MathHelper.Lerp(0.0f, 1f, Math.Max(difficultyFactor-0.15f, 0f)), //15 difficulty transition to next biome - unlock Excellent loot
|
||||
3 => MathHelper.Lerp(0.0f, 1f, Math.Max(difficultyFactor-0.35f, 0f)), //35 difficulty transition to next biome - unlock Masterwork loot
|
||||
_ => 0.0f,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user