(92a838f87) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev

This commit is contained in:
Joonas Rikkonen
2019-03-29 21:50:58 +02:00
parent 6f919a4de0
commit 0b098efbf6
7 changed files with 117 additions and 20 deletions

View File

@@ -226,8 +226,15 @@ namespace Barotrauma
if (SelectedConstruction != null && SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null && HUD.CloseHUD(ic.GuiFrame.Rect)))
{
//emulate a Select input to get the character to deselect the item server-side
keys[(int)InputType.Select].Hit = true;
if (GameMain.Client != null)
{
//emulate a Select input to get the character to deselect the item server-side
keys[(int)InputType.Select].Hit = true;
}
//reset focus to prevent us from accidentally interacting with another entity
focusedItem = null;
focusedCharacter = null;
findFocusedTimer = 0.2f;
SelectedConstruction = null;
}

View File

@@ -453,7 +453,10 @@ namespace Barotrauma.Lights
//raster pattern on top of everything
spriteBatch.Begin(blendState: BlendState.AlphaBlend, samplerState: SamplerState.LinearWrap);
spriteBatch.Draw(highlightRaster, new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), Color.White * 0.5f);
spriteBatch.Draw(highlightRaster,
new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height),
new Rectangle(0, 0, (int)(HighlightMap.Width / currLightMapScale * 0.5f), (int)(HighlightMap.Height / currLightMapScale * 0.5f)),
Color.White * 0.5f);
spriteBatch.End();
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];

View File

@@ -337,7 +337,24 @@ namespace Barotrauma
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLighting"))
{
Selected = lightingEnabled,
OnSelected = (GUITickBox obj) => { lightingEnabled = obj.Selected; return true; }
OnSelected = (GUITickBox obj) =>
{
lightingEnabled = obj.Selected;
if (lightingEnabled)
{
//turn off lights that are inside containers
foreach (Item item in Item.ItemList)
{
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
{
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
Color.Transparent :
lightComponent.LightColor;
}
}
}
return true;
}
};
tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWalls"))
{

View File

@@ -115,9 +115,13 @@ namespace Barotrauma
SonarLabel = element.GetAttributeString("sonarlabel", "");
}
public AITarget(Entity e, float sightRange = 3000, float soundRange = 0)
public AITarget(Entity e, float sightRange = -1, float soundRange = 0)
{
Entity = e;
if (sightRange < 0)
{
sightRange = StaticSightRange;
}
SightRange = sightRange;
SoundRange = soundRange;
List.Add(this);

View File

@@ -635,6 +635,7 @@ namespace Barotrauma
var newLimb = GetAttackLimb(attackWorldPos, previousLimb);
if (newLimb != null)
{
// Attack with the new limb
AttackingLimb = newLimb;
}
else
@@ -659,6 +660,49 @@ namespace Barotrauma
}
}
break;
case AIBehaviorAfterAttack.FallBackUntilCanAttack:
if (AttackingLimb.attack.SecondaryCoolDown <= 0)
{
// No (valid) secondary cooldown defined.
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
else
{
if (AttackingLimb.attack.SecondaryCoolDownTimer <= 0)
{
// Don't allow attacking when the attack target has just changed.
if (_previousAiTarget != null && SelectedAiTarget != _previousAiTarget)
{
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
else
{
// If the secondary cooldown is defined and expired, check if we can switch the attack
var previousLimb = AttackingLimb;
var newLimb = GetAttackLimb(attackWorldPos, previousLimb);
if (newLimb != null)
{
// Attack with the new limb
AttackingLimb = newLimb;
}
else
{
// No new limb was found.
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
}
}
else
{
// Cooldown not yet expired -> steer away from the target
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
}
break;
case AIBehaviorAfterAttack.FallBack:
default:
UpdateFallBack(attackWorldPos, deltaTime);
@@ -784,20 +828,39 @@ namespace Barotrauma
{
AttackContext currentContext = Character.GetAttackContext();
var target = wallTarget != null ? wallTarget.Structure : SelectedAiTarget.Entity;
var limbs = Character.AnimController.Limbs
.Where(l =>
l != ignoredLimb &&
l.attack != null &&
l.attack.CoolDownTimer <= 0 &&
!l.IsSevered &&
!l.IsStuck &&
l.attack.IsValidContext(currentContext) &&
l.attack.IsValidTarget(target) &&
l.attack.Conditionals.All(c => (target is ISerializableEntity se && c.Matches(se)) || !(target is ISerializableEntity) || !(target is Character)))
.OrderByDescending(l => l.attack.Priority)
.ThenBy(l => Vector2.Distance(l.WorldPosition, attackWorldPos));
// TODO: priority should probably not override the distance -> use values instead of booleans
return limbs.FirstOrDefault();
Limb selectedLimb = null;
float currentPriority = 0;
foreach (Limb limb in Character.AnimController.Limbs)
{
if (limb == ignoredLimb) { continue; }
if (limb.IsSevered || limb.IsStuck) { continue; }
var attack = limb.attack;
if (attack == null) { continue; }
if (attack.CoolDownTimer > 0) { continue; }
if (!attack.IsValidContext(currentContext)) { continue; }
if (!attack.IsValidTarget(target)) { continue; }
if (target is ISerializableEntity se && target is Character)
{
// TODO: allow conditionals of which matching any is enough instead of having to fulfill all
if (attack.Conditionals.Any(c => !c.Matches(se))) { continue; }
}
float priority = CalculatePriority(limb, attackWorldPos);
if (priority > currentPriority)
{
currentPriority = priority;
selectedLimb = limb;
}
}
return selectedLimb;
float CalculatePriority(Limb limb, Vector2 attackPos)
{
float dist = Vector2.Distance(limb.WorldPosition, attackPos);
// The limb is ignored if the target is not close. Prevents character going in reverse if very far away from it.
// We also need a max value that is more than the actual range.
float distanceFactor = MathHelper.Lerp(1, 0, MathUtils.InverseLerp(0, limb.attack.Range * 3, dist));
return (1 + limb.attack.Priority) * distanceFactor;
}
}
private void UpdateWallTarget()

View File

@@ -28,6 +28,7 @@ namespace Barotrauma
public enum AIBehaviorAfterAttack
{
FallBack,
FallBackUntilCanAttack,
PursueIfCanAttack,
Pursue
}
@@ -188,7 +189,7 @@ namespace Barotrauma
public readonly List<Affliction> Afflictions = new List<Affliction>();
/// <summary>
/// Only affects ai decision making.
/// Only affects ai decision making. All the conditionals has to be met in order to select the attack. TODO: allow to define conditionals using any (implemented in StatusEffect -> move from there to PropertyConditional?)
/// </summary>
public List<PropertyConditional> Conditionals { get; private set; } = new List<PropertyConditional>();

View File

@@ -162,6 +162,7 @@ namespace Barotrauma.Items.Components
if (contained == null) continue;
if (contained.TryInteract(character))
{
character.FocusedItem = contained;
return false;
}
}
@@ -178,6 +179,7 @@ namespace Barotrauma.Items.Components
if (contained == null) continue;
if (contained.TryInteract(picker))
{
picker.FocusedItem = contained;
return true;
}
}