Example #1
0
        private bool CanStartEventSet(EventSet eventSet)
        {
            ISpatialEntity refEntity     = GetRefEntity();
            float          distFromStart = Vector2.Distance(refEntity.WorldPosition, level.StartPosition);
            float          distFromEnd   = Vector2.Distance(refEntity.WorldPosition, level.EndPosition);

            //don't create new events if within 50 meters of the start/end of the level
            if (!eventSet.AllowAtStart)
            {
                if (distanceTraveled <= 0.0f ||
                    distFromStart * Physics.DisplayToRealWorldRatio < 50.0f ||
                    distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f)
                {
                    return(false);
                }
            }

            if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) &&
                roundDuration < eventSet.MinMissionTime)
            {
                return(false);
            }

            if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity)
            {
                return(false);
            }

            return(true);
        }
Example #2
0
        private void LoadMonster(CharacterPrefab monsterPrefab, XElement element, Submarine submarine)
        {
            string[]       moduleFlags    = element.GetAttributeStringArray("moduleflags", null);
            string[]       spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null);
            ISpatialEntity spawnPos       = SpawnAction.GetSpawnPos(SpawnAction.SpawnLocationType.Outpost, SpawnType.Enemy, moduleFlags, spawnPointTags, element.GetAttributeBool("asfaraspossible", false));

            if (spawnPos == null)
            {
                spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom();
            }
            Character spawnedCharacter = Character.Create(monsterPrefab.Identifier, spawnPos.WorldPosition, ToolBox.RandomSeed(8), createNetworkEvent: false);

            characters.Add(spawnedCharacter);
            if (element.GetAttributeBool("requirekill", false))
            {
                requireKill.Add(spawnedCharacter);
            }
            if (spawnedCharacter.Inventory != null)
            {
                characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true));
            }
            if (submarine != null && spawnedCharacter.AIController is EnemyAIController enemyAi)
            {
                enemyAi.UnattackableSubmarines.Add(submarine);
                enemyAi.UnattackableSubmarines.Add(Submarine.MainSub);
                foreach (Submarine sub in Submarine.MainSub.DockedTo)
                {
                    enemyAi.UnattackableSubmarines.Add(sub);
                }
            }
        }
        private IEnumerable <object> DoEndCampaignCameraTransition()
        {
            Character controlled = Character.Controlled;

            if (controlled != null)
            {
                controlled.AIController.Enabled = false;
            }

            GUI.DisableHUD = true;
            ISpatialEntity endObject  = Level.Loaded.LevelObjectManager.GetAllObjects().FirstOrDefault(obj => obj.Prefab.SpawnPos == LevelObjectPrefab.SpawnPosType.LevelEnd);
            var            transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
                                                             null, Alignment.Center,
                                                             fadeOut: true,
                                                             duration: 10,
                                                             startZoom: null, endZoom: 0.2f);

            while (transition.Running)
            {
                yield return(CoroutineStatus.Running);
            }
            GameMain.CampaignEndScreen.Select();
            GUI.DisableHUD = false;

            yield return(CoroutineStatus.Success);
        }
Example #4
0
 bool TrySpawnCell(out Character cell, ISpatialEntity targetEntity = null)
 {
     cell = null;
     if (protectiveCells.Count >= MaxCellCount)
     {
         return(false);
     }
     if (targetEntity == null)
     {
         targetEntity =
             wayPoints.GetRandom(wp => wp.CurrentHull != null && populatedHulls.Count(h => h == wp.CurrentHull) < MaxCellsPerRoom && wp.CurrentHull.WaterPercentage >= MinWaterLevel) ??
             hulls.GetRandom(h => populatedHulls.Count(h2 => h2 == h) < MaxCellsPerRoom && h.WaterPercentage >= MinWaterLevel) as ISpatialEntity;
     }
     if (targetEntity == null)
     {
         return(false);
     }
     if (targetEntity is Hull h)
     {
         populatedHulls.Add(h);
     }
     else if (targetEntity is WayPoint wp && wp.CurrentHull != null)
     {
         populatedHulls.Add(wp.CurrentHull);
     }
     // Don't add items in the list, because we want to be able to ignore the restrictions for spawner organs.
     cell = Character.Create(Config.DefensiveAgent, targetEntity.WorldPosition, ToolBox.RandomSeed(8), hasAi: true, createNetworkEvent: true);
     protectiveCells.Add(cell);
     cell.OnDeath  += OnCellDeath;
     cellSpawnTimer = GetSpawnTime();
     return(true);
 }
 public AIObjectiveGetItem(Character character, Item targetItem, AIObjectiveManager objectiveManager, bool equip = true, float priorityModifier = 1)
     : base(character, objectiveManager, priorityModifier)
 {
     currSearchIndex = -1;
     this.equip      = equip;
     this.targetItem = targetItem;
     moveToTarget    = targetItem?.GetRootInventoryOwner();
 }
Example #6
0
 public OrderChatMessage(Order order, string orderOption, string text, ISpatialEntity targetEntity, Character targetCharacter, Character sender)
     : base(sender?.Name, text, ChatMessageType.Order, sender, GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == sender))
 {
     Order           = order;
     OrderOption     = orderOption;
     TargetCharacter = targetCharacter;
     TargetEntity    = targetEntity;
 }
Example #7
0
 public AIObjectiveGoTo(ISpatialEntity target, Character character, AIObjectiveManager objectiveManager, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1)
     : base(character, objectiveManager, priorityModifier)
 {
     this.Target = target;
     this.repeat = repeat;
     waitUntilPathUnreachable   = 3.0f;
     this.getDivingGearIfNeeded = getDivingGearIfNeeded;
     CalculateCloseEnough();
 }
Example #8
0
        public static ISpatialEntity FromWKT(string wkt, int srid)
        {
            SqlGeometry geometry = SqlGeometry.STGeomFromText(new SqlChars(wkt), srid);

            geometry = geometry.MakeValid();
            ISpatialEntity retval = (ISpatialEntity)ToSharpMapGeometry(geometry);

            return(retval);
        }
 public override void Reset()
 {
     base.Reset();
     RemoveSubObjective(ref goToObjective);
     targetItem      = null;
     moveToTarget    = null;
     isDoneSeeking   = false;
     currSearchIndex = 0;
 }
Example #10
0
 public void Attach(ISpatialEntity source, Item target)
 {
     System.Diagnostics.Debug.Assert(source != null);
     System.Diagnostics.Debug.Assert(target != null);
     this.source = source;
     this.target = target;
     ApplyStatusEffects(ActionType.OnUse, 1.0f, worldPosition: item.WorldPosition);
     IsActive = true;
 }
Example #11
0
        protected override void StartMissionSpecific(Level level)
        {
            items.Clear();
#if SERVER
            spawnedItems.Clear();
#endif
            if (!string.IsNullOrEmpty(itemTag))
            {
                var itemsToDestroy = Item.ItemList.FindAll(it => it.Submarine?.Info.Type != SubmarineType.Player && it.HasTag(itemTag));
                if (!itemsToDestroy.Any())
                {
                    DebugConsole.ThrowError($"Error in mission \"{Prefab.Identifier}\". Could not find an item with the tag \"{itemTag}\".");
                }
                else
                {
                    items.AddRange(itemsToDestroy);
                }
            }
            if (itemConfig != null && !IsClient)
            {
                foreach (XElement element in itemConfig.Elements())
                {
                    string itemIdentifier = element.GetAttributeString("identifier", "");
                    if (!(MapEntityPrefab.Find(null, itemIdentifier) is ItemPrefab itemPrefab))
                    {
                        DebugConsole.ThrowError("Couldn't spawn item for outpost destroy mission: item prefab \"" + itemIdentifier + "\" not found");
                        continue;
                    }

                    string[]       moduleFlags    = element.GetAttributeStringArray("moduleflags", null);
                    string[]       spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null);
                    ISpatialEntity spawnPoint     = SpawnAction.GetSpawnPos(
                        SpawnAction.SpawnLocationType.Outpost, SpawnType.Human | SpawnType.Enemy,
                        moduleFlags, spawnPointTags, element.GetAttributeBool("asfaraspossible", false));
                    if (spawnPoint == null)
                    {
                        var submarine = Submarine.Loaded.Find(s => s.Info.Type == SubmarineType.Outpost) ?? Submarine.MainSub;
                        spawnPoint = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom();
                    }
                    Vector2 spawnPos = spawnPoint.WorldPosition;
                    if (spawnPoint is WayPoint wp && wp.CurrentHull != null)
                    {
                        spawnPos = new Vector2(
                            MathHelper.Clamp(wp.WorldPosition.X + Rand.Range(-200, 200), wp.CurrentHull.WorldRect.X, wp.CurrentHull.WorldRect.Right),
                            wp.CurrentHull.WorldRect.Y - wp.CurrentHull.Rect.Height + 16.0f);
                    }
                    var item = new Item(itemPrefab, spawnPos, null);
                    items.Add(item);
#if SERVER
                    spawnedItems.Add(item);
#endif
                }
            }

            base.StartMissionSpecific(level);
        }
Example #12
0
 public AIObjectiveGoTo(ISpatialEntity target, Character character, AIObjectiveManager objectiveManager, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1, float closeEnough = 0)
     : base(character, objectiveManager, priorityModifier)
 {
     this.Target = target;
     this.repeat = repeat;
     waitUntilPathUnreachable   = 3.0f;
     this.getDivingGearIfNeeded = getDivingGearIfNeeded;
     CloseEnough = closeEnough;
     if (Target is Item i)
     {
         CloseEnough = Math.Max(CloseEnough, i.InteractDistance + Math.Max(i.Rect.Width, i.Rect.Height) / 2);
     }
 }
        private bool CheckInventory()
        {
            if (identifiersOrTags == null)
            {
                return(false);
            }
            var item = character.Inventory.FindItem(i => CheckItem(i), recursive: true);

            if (item != null)
            {
                targetItem   = item;
                moveToTarget = item.GetRootInventoryOwner();
            }
            return(item != null);
        }
Example #14
0
 public Feature(ISpatialEntity entity)
 {
     switch (entity.Geography.GeometryType)
     {
         case "MultiPolygon":
             Geometry = new MultiPolygon(entity.Geography as IMultiPolygon);
             break;
         case "Polygon":
             Geometry = new Polygon(entity.Geography as IPolygon);
             break;
         case "Point":
             Geometry = new Point(entity.Geography as IPoint);
             break;
         default:
             break;
     }
     Properties = entity.Properties as Dictionary<string, string>;
 }
Example #15
0
        public CameraTransition(ISpatialEntity targetEntity, Camera cam, Alignment?cameraStartPos, Alignment?cameraEndPos, bool fadeOut = true, float duration = 10.0f, float?startZoom = null, float?endZoom = null)
        {
            Duration            = duration;
            FadeOut             = fadeOut;
            this.cameraStartPos = cameraStartPos;
            this.cameraEndPos   = cameraEndPos;
            this.startZoom      = startZoom;
            this.endZoom        = endZoom;
            AssignedCamera      = cam;

            if (targetEntity == null)
            {
                return;
            }

            Running = true;
            CoroutineManager.StopCoroutines("CameraTransition");
            updateCoroutine = CoroutineManager.StartCoroutine(Update(targetEntity, cam), "CameraTransition");
        }
Example #16
0
        private void LoadHuman(HumanPrefab humanPrefab, XElement element, Submarine submarine)
        {
            string[]       moduleFlags    = element.GetAttributeStringArray("moduleflags", null);
            string[]       spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null);
            ISpatialEntity spawnPos       = SpawnAction.GetSpawnPos(
                SpawnAction.SpawnLocationType.Outpost, SpawnType.Human,
                moduleFlags ?? humanPrefab.GetModuleFlags(),
                spawnPointTags ?? humanPrefab.GetSpawnPointTags(),
                element.GetAttributeBool("asfaraspossible", false));

            if (spawnPos == null)
            {
                spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom();
            }

            var       characterInfo    = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: humanPrefab.GetJobPrefab(Rand.RandSync.Server), randSync: Rand.RandSync.Server);
            Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, spawnPos.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);

            if (element.GetAttributeBool("requirerescue", false))
            {
                requireRescue.Add(spawnedCharacter);
                spawnedCharacter.TeamID = CharacterTeamType.FriendlyNPC;
#if CLIENT
                GameMain.GameSession.CrewManager.AddCharacterToCrewList(spawnedCharacter);
#endif
            }
            else
            {
                spawnedCharacter.TeamID = CharacterTeamType.None;
            }
            humanPrefab.InitializeCharacter(spawnedCharacter, spawnPos);
            humanPrefab.GiveItems(spawnedCharacter, Submarine.MainSub, Rand.RandSync.Server, createNetworkEvents: false);
            if (spawnPos is WayPoint wp)
            {
                spawnedCharacter.GiveIdCardTags(wp);
            }
            if (element.GetAttributeBool("requirekill", false))
            {
                requireKill.Add(spawnedCharacter);
            }
            characters.Add(spawnedCharacter);
            characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true));
        }
Example #17
0
        private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f)
        {
            if (order?.SymbolSprite == null)
            {
                return;
            }

            if (order.TargetAllCharacters)
            {
                if (order.OrderGiver != character && !order.HasAppropriateJob(character))
                {
                    return;
                }
            }

            ISpatialEntity target = order.ConnectedController != null ? order.ConnectedController.Item : order.TargetSpatialEntity;

            if (target == null)
            {
                return;
            }

            //don't show the indicator if far away and not inside the same sub
            //prevents exploiting the indicators in locating the sub
            if (character.Submarine != target.Submarine &&
                Vector2.DistanceSquared(character.WorldPosition, target.WorldPosition) > 1000.0f * 1000.0f)
            {
                return;
            }

            if (!orderIndicatorCount.ContainsKey(target))
            {
                orderIndicatorCount.Add(target, 0);
            }

            Vector2 drawPos = target is Entity ? (target as Entity).DrawPosition :
                              target.Submarine == null ? target.Position : target.Position + target.Submarine.DrawPosition;

            drawPos += Vector2.UnitX * order.SymbolSprite.size.X * 1.5f * orderIndicatorCount[target];
            GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha);

            orderIndicatorCount[target] = orderIndicatorCount[target] + 1;
        }
Example #18
0
        private void SpawnInitialCells()
        {
            int brainRoomCells = Rand.Range(MinCellsPerBrainRoom, MaxCellsPerRoom);

            if (brain.CurrentHull?.WaterPercentage >= MinWaterLevel)
            {
                for (int i = 0; i < brainRoomCells; i++)
                {
                    if (!TrySpawnCell(out _, brain.CurrentHull))
                    {
                        break;
                    }
                }
            }
            int cellsInside = Rand.Range(MinCellsInside, MaxCellsInside);

            for (int i = 0; i < cellsInside; i++)
            {
                if (!TrySpawnCell(out _))
                {
                    break;
                }
            }
            int cellsOutside = Rand.Range(MinCellsOutside, MaxCellsOutside);

            // If we failed to spawn some of the cells in the brainroom/inside, spawn some extra cells outside.
            cellsOutside = Math.Clamp(cellsOutside + brainRoomCells + cellsInside - protectiveCells.Count, cellsOutside, MaxCellsOutside);
            for (int i = 0; i < cellsOutside; i++)
            {
                ISpatialEntity targetEntity = wayPoints.GetRandom(wp => wp.CurrentHull == null);
                if (targetEntity == null)
                {
                    break;
                }
                if (!TrySpawnCell(out _, targetEntity))
                {
                    break;
                }
            }
            initialCellsSpawned = true;
        }
Example #19
0
        /// <summary>
        /// Get the entity that should be used in determining how far the player has progressed in the level.
        /// = The submarine or player character that has progressed the furthest.
        /// </summary>
        private ISpatialEntity GetRefEntity()
        {
            ISpatialEntity refEntity = Submarine.MainSub;

#if CLIENT
            if (Character.Controlled != null)
            {
                if (Character.Controlled.Submarine != null &&
                    Character.Controlled.Submarine.Info.Type == SubmarineInfo.SubmarineType.Player)
                {
                    refEntity = Character.Controlled.Submarine;
                }
                else
                {
                    refEntity = Character.Controlled;
                }
            }
#else
            foreach (Barotrauma.Networking.Client client in GameMain.Server.ConnectedClients)
            {
                if (client.Character == null)
                {
                    continue;
                }
                //only take the players inside a player sub into account.
                //Otherwise the system could be abused by for example making a respawned player wait
                //close to the destination outpost
                if (client.Character.Submarine != null &&
                    client.Character.Submarine.Info.Type == SubmarineInfo.SubmarineType.Player)
                {
                    if (client.Character.Submarine.WorldPosition.X > refEntity.WorldPosition.X)
                    {
                        refEntity = client.Character.Submarine;
                    }
                }
            }
#endif
            return(refEntity);
        }
Example #20
0
        private bool CanStartEventSet(EventSet eventSet)
        {
            ISpatialEntity refEntity     = GetRefEntity();
            float          distFromStart = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.StartExitPosition.ToPoint(), level.StartPosition.ToPoint(), refEntity.WorldPosition.ToPoint()));
            float          distFromEnd   = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.EndExitPosition.ToPoint(), level.EndPosition.ToPoint(), refEntity.WorldPosition.ToPoint()));

            //don't create new events if within 50 meters of the start/end of the level
            if (!eventSet.AllowAtStart)
            {
                if (distanceTraveled <= 0.0f ||
                    distFromStart * Physics.DisplayToRealWorldRatio < 50.0f ||
                    distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f)
                {
                    return(false);
                }
            }

            if (eventSet.DelayWhenCrewAway)
            {
                if ((isCrewAway && crewAwayDuration < settings.FreezeDurationWhenCrewAway) || crewAwayResetTimer > 0.0f)
                {
                    return(false);
                }
            }

            if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) &&
                roundDuration < eventSet.MinMissionTime)
            {
                return(false);
            }

            if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity)
            {
                return(false);
            }

            return(true);
        }
        private void LoadHuman(HumanPrefab humanPrefab, XElement element, Submarine submarine)
        {
            string[]       moduleFlags    = element.GetAttributeStringArray("moduleflags", null);
            string[]       spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null);
            ISpatialEntity spawnPos       = SpawnAction.GetSpawnPos(
                SpawnAction.SpawnLocationType.Outpost, SpawnType.Human,
                moduleFlags ?? humanPrefab.GetModuleFlags(),
                spawnPointTags ?? humanPrefab.GetSpawnPointTags(),
                element.GetAttributeBool("asfaraspossible", false));

            if (spawnPos == null)
            {
                spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom();
            }

            bool requiresRescue = element.GetAttributeBool("requirerescue", false);

            Character spawnedCharacter = CreateHuman(humanPrefab, characters, characterItems, submarine, requiresRescue ? CharacterTeamType.FriendlyNPC : CharacterTeamType.None, spawnPos, giveTags: true);

            if (spawnPos is WayPoint wp)
            {
                spawnedCharacter.GiveIdCardTags(wp);
            }

            if (requiresRescue)
            {
                requireRescue.Add(spawnedCharacter);
#if CLIENT
                GameMain.GameSession.CrewManager.AddCharacterToCrewList(spawnedCharacter);
#endif
            }

            if (element.GetAttributeBool("requirekill", false))
            {
                requireKill.Add(spawnedCharacter);
            }
        }
Example #22
0
        public void ThalamusOperate(WreckAI ai, float deltaTime, bool targetHumans, bool targetOtherCreatures, bool targetSubmarines, bool ignoreDelay)
        {
            if (ai == null)
            {
                return;
            }

            IsActive = true;

            if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
            {
                return;
            }

            if (updatePending)
            {
                if (updateTimer < 0.0f)
                {
#if SERVER
                    item.CreateServerEvent(this);
#endif
                    prevTargetRotation = targetRotation;
                    updateTimer        = 0.25f;
                }
                updateTimer -= deltaTime;
            }

            if (!ignoreDelay && waitTimer > 0)
            {
                waitTimer -= deltaTime;
                return;
            }
            Submarine      closestSub    = null;
            float          maxDistance   = 10000.0f;
            float          shootDistance = AIRange;
            ISpatialEntity target        = null;
            float          closestDist   = shootDistance * shootDistance;
            if (targetHumans || targetOtherCreatures)
            {
                foreach (var character in Character.CharacterList)
                {
                    if (character == null || character.Removed || character.IsDead)
                    {
                        continue;
                    }
                    if (character.Params.Group.Equals(ai.Config.Entity, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }
                    bool isHuman = character.IsHuman || character.Params.Group.Equals(CharacterPrefab.HumanSpeciesName, StringComparison.OrdinalIgnoreCase);
                    if (isHuman)
                    {
                        if (!targetHumans)
                        {
                            // Don't target humans if not defined to.
                            continue;
                        }
                    }
                    else if (!targetOtherCreatures)
                    {
                        // Don't target other creatures if not defined to.
                        continue;
                    }
                    float dist = Vector2.DistanceSquared(character.WorldPosition, item.WorldPosition);
                    if (dist > closestDist)
                    {
                        continue;
                    }
                    target      = character;
                    closestDist = dist;
                }
            }
            if (targetSubmarines)
            {
                if (target == null || target.Submarine != null)
                {
                    closestDist = maxDistance * maxDistance;
                    foreach (Submarine sub in Submarine.Loaded)
                    {
                        if (sub.Info.Type != SubmarineInfo.SubmarineType.Player)
                        {
                            continue;
                        }
                        float dist = Vector2.DistanceSquared(sub.WorldPosition, item.WorldPosition);
                        if (dist > closestDist)
                        {
                            continue;
                        }
                        closestSub  = sub;
                        closestDist = dist;
                    }
                    closestDist = shootDistance * shootDistance;
                    if (closestSub != null)
                    {
                        foreach (var hull in Hull.hullList)
                        {
                            if (!closestSub.IsEntityFoundOnThisSub(hull, true))
                            {
                                continue;
                            }
                            float dist = Vector2.DistanceSquared(hull.WorldPosition, item.WorldPosition);
                            if (dist > closestDist)
                            {
                                continue;
                            }
                            target      = hull;
                            closestDist = dist;
                        }
                    }
                }
            }
            if (!ignoreDelay)
            {
                if (target == null)
                {
                    // Random movement
                    waitTimer      = Rand.Value(Rand.RandSync.Unsynced) < 0.98f ? 0f : Rand.Range(5f, 20f);
                    targetRotation = Rand.Range(minRotation, maxRotation);
                    updatePending  = true;
                    return;
                }
                if (disorderTimer < 0)
                {
                    // Random disorder
                    disorderTimer  = Rand.Range(0f, 3f);
                    waitTimer      = Rand.Range(0.25f, 1f);
                    targetRotation = MathUtils.WrapAngleTwoPi(targetRotation += Rand.Range(-1f, 1f));
                    updatePending  = true;
                    return;
                }
                else
                {
                    disorderTimer -= deltaTime;
                }
            }
            if (target == null)
            {
                return;
            }

            float angle = -MathUtils.VectorToAngle(target.WorldPosition - item.WorldPosition);
            targetRotation = MathUtils.WrapAngleTwoPi(angle);

            if (Math.Abs(targetRotation - prevTargetRotation) > 0.1f)
            {
                updatePending = true;
            }

            if (target is Hull targetHull)
            {
                Vector2 barrelDir = new Vector2((float)Math.Cos(rotation), -(float)Math.Sin(rotation));
                if (!MathUtils.GetLineRectangleIntersection(item.WorldPosition, item.WorldPosition + barrelDir * AIRange, targetHull.WorldRect, out _))
                {
                    return;
                }
            }
            else
            {
                float midRotation = (minRotation + maxRotation) / 2.0f;
                while (midRotation - angle < -MathHelper.Pi)
                {
                    angle -= MathHelper.TwoPi;
                }
                while (midRotation - angle > MathHelper.Pi)
                {
                    angle += MathHelper.TwoPi;
                }
                if (angle < minRotation || angle > maxRotation)
                {
                    return;
                }
                float enemyAngle  = MathUtils.VectorToAngle(target.WorldPosition - item.WorldPosition);
                float turretAngle = -rotation;
                if (Math.Abs(MathUtils.GetShortestAngle(enemyAngle, turretAngle)) > 0.15f)
                {
                    return;
                }
            }

            Vector2 start = ConvertUnits.ToSimUnits(item.WorldPosition);
            Vector2 end   = ConvertUnits.ToSimUnits(target.WorldPosition);
            if (target.Submarine != null)
            {
                start -= target.Submarine.SimPosition;
                end   -= target.Submarine.SimPosition;
            }
            var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel;
            var pickedBody          = Submarine.PickBody(start, end, null, collisionCategories, allowInsideFixture: true,
                                                         customPredicate: (Fixture f) => { return(!item.StaticFixtures.Contains(f)); });
            if (pickedBody == null)
            {
                return;
            }
            Character targetCharacter = null;
            if (pickedBody.UserData is Character c)
            {
                targetCharacter = c;
            }
            else if (pickedBody.UserData is Limb limb)
            {
                targetCharacter = limb.character;
            }
            if (targetCharacter != null)
            {
                if (targetCharacter.Params.Group.Equals(ai.Config.Entity, StringComparison.OrdinalIgnoreCase))
                {
                    // Don't shoot friendly characters
                    return;
                }
            }
            else
            {
                if (pickedBody.UserData is ISpatialEntity e)
                {
                    Submarine sub = e.Submarine;
                    if (sub == null)
                    {
                        return;
                    }
                    if (!targetSubmarines)
                    {
                        return;
                    }
                    if (sub == Item.Submarine)
                    {
                        return;
                    }
                    // Don't shoot non-player submarines, i.e. wrecks or outposts.
                    if (!sub.Info.IsPlayer)
                    {
                        return;
                    }
                }
                else
                {
                    // Hit something else, probably a level wall
                    return;
                }
            }
            TryLaunch(deltaTime, ignorePower: true);
        }
        private void FindTargetItem()
        {
            if (identifiersOrTags == null)
            {
                if (targetItem == null)
                {
#if DEBUG
                    DebugConsole.NewMessage($"{character.Name}: Cannot find an item, because neither identifiers nor item was defined.", Color.Red);
#endif
                    Abandon = true;
                }
                return;
            }

            float priority            = Math.Clamp(objectiveManager.GetCurrentPriority(), 10, 100);
            bool  checkPath           = priority >= AIObjectiveManager.LowestOrderPriority && (objectiveManager.IsCurrentOrder <AIObjectiveFixLeaks>() || objectiveManager.CurrentOrder is AIObjectiveGoTo gotoOrder && gotoOrder.isFollowOrderObjective);
            bool  hasCalledPathFinder = false;
            int   itemsPerFrame       = (int)priority;
            for (int i = 0; i < itemsPerFrame && currSearchIndex < Item.ItemList.Count - 1; i++)
            {
                currSearchIndex++;
                var       item    = Item.ItemList[currSearchIndex];
                Submarine itemSub = item.Submarine ?? item.ParentInventory?.Owner?.Submarine;
                if (itemSub == null)
                {
                    continue;
                }
                Submarine mySub = character.Submarine;
                if (mySub == null)
                {
                    continue;
                }
                if (!AllowStealing)
                {
                    if (character.TeamID == CharacterTeamType.FriendlyNPC != item.SpawnedInOutpost)
                    {
                        continue;
                    }
                }
                if (!CheckItem(item))
                {
                    continue;
                }
                if (item.Container != null)
                {
                    if (item.Container.HasTag("donttakeitems"))
                    {
                        continue;
                    }
                    if (ignoredContainerIdentifiers != null)
                    {
                        if (ignoredContainerIdentifiers.Contains(item.ContainerIdentifier))
                        {
                            continue;
                        }
                    }
                }
                // Don't allow going into another sub, unless it's connected and of the same team and type.
                if (!character.Submarine.IsEntityFoundOnThisSub(item, includingConnectedSubs: true))
                {
                    continue;
                }
                if (character.IsItemTakenBySomeoneElse(item))
                {
                    continue;
                }
                if (item.ParentInventory is ItemInventory itemInventory)
                {
                    if (!itemInventory.Container.HasRequiredItems(character, addMessage: false))
                    {
                        continue;
                    }
                }
                float itemPriority = 1;
                if (GetItemPriority != null)
                {
                    itemPriority = GetItemPriority(item);
                }
                Entity rootInventoryOwner = item.GetRootInventoryOwner();
                if (rootInventoryOwner is Item ownerItem)
                {
                    if (!ownerItem.IsInteractable(character))
                    {
                        continue;
                    }
                    if (!(ownerItem.GetComponent <ItemContainer>()?.HasRequiredItems(character, addMessage: false) ?? true))
                    {
                        continue;
                    }
                }
                Vector2 itemPos = (rootInventoryOwner ?? item).WorldPosition;
                float   yDist   = Math.Abs(character.WorldPosition.Y - itemPos.Y);
                yDist = yDist > 100 ? yDist * 5 : 0;
                float dist           = Math.Abs(character.WorldPosition.X - itemPos.X) + yDist;
                float distanceFactor = MathHelper.Lerp(1, 0, MathUtils.InverseLerp(0, 10000, dist));
                itemPriority *= distanceFactor;
                itemPriority *= item.Condition / item.MaxCondition;
                // Ignore if the item has a lower priority than the currently selected one
                if (itemPriority < currItemPriority)
                {
                    continue;
                }
                if (!hasCalledPathFinder && PathSteering != null && checkPath)
                {
                    // While following the player, let's ensure that there's a valid path to the target before accepting it.
                    // Otherwise it will take some time for us to find a valid item when there are multiple items that we can't reach and some that we can.
                    // This is relatively expensive, so let's do this only when it significantly improves the behavior.
                    // Only allow one path find call per frame.
                    hasCalledPathFinder = true;
                    var path = PathSteering.PathFinder.FindPath(character.SimPosition, item.SimPosition, character.Submarine, errorMsgStr: $"AIObjectiveGetItem {character.DisplayName}", nodeFilter: node => node.Waypoint.CurrentHull != null);
                    if (path.Unreachable)
                    {
                        continue;
                    }
                }
                currItemPriority = itemPriority;
                targetItem       = item;
                moveToTarget     = rootInventoryOwner ?? item;
            }
            if (currSearchIndex >= Item.ItemList.Count - 1)
            {
                isDoneSeeking = true;
                if (targetItem == null)
                {
                    if (spawnItemIfNotFound)
                    {
                        if (!(MapEntityPrefab.List.FirstOrDefault(me => me is ItemPrefab ip && identifiersOrTags.Any(id => id == ip.Identifier || ip.Tags.Contains(id))) is ItemPrefab prefab))
                        {
#if DEBUG
                            DebugConsole.NewMessage($"{character.Name}: Cannot find an item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}, tried to spawn the item but no matching item prefabs were found.", Color.Yellow);
#endif
                            Abandon = true;
                        }
                        else
                        {
                            Entity.Spawner.AddToSpawnQueue(prefab, character.Inventory, onSpawned: (Item spawnedItem) =>
                            {
                                targetItem = spawnedItem;
                                if (character.TeamID == CharacterTeamType.FriendlyNPC && (character.Submarine?.Info.IsOutpost ?? false))
                                {
                                    spawnedItem.SpawnedInOutpost = true;
                                }
                            });
                        }
                    }
                    else
                    {
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Cannot find an item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}", Color.Yellow);
#endif
                        SpeakCannotFind();
                        Abandon = true;
                    }
                }
            }
        protected override void Act(float deltaTime)
        {
            if (character.LockHands)
            {
                Abandon = true;
                return;
            }
            if (character.Submarine == null)
            {
                Abandon = true;
                return;
            }
            if (identifiersOrTags != null && !isDoneSeeking)
            {
                if (checkInventory)
                {
                    if (CheckInventory())
                    {
                        isDoneSeeking = true;
                    }
                }
                if (!isDoneSeeking)
                {
                    if (!AllowDangerousPressure)
                    {
                        bool dangerousPressure = character.CurrentHull == null || character.CurrentHull.LethalPressure > 0 && character.PressureProtection <= 0;
                        if (dangerousPressure)
                        {
#if DEBUG
                            string itemName = targetItem != null ? targetItem.Name : identifiersOrTags.FirstOrDefault();
                            DebugConsole.NewMessage($"{character.Name}: Seeking item ({itemName}) aborted, because the pressure is dangerous.", Color.Yellow);
#endif
                            Abandon = true;
                            return;
                        }
                    }
                    FindTargetItem();
                    if (!objectiveManager.IsCurrentOrder <AIObjectiveGoTo>())
                    {
                        objectiveManager.GetObjective <AIObjectiveIdle>().Wander(deltaTime);
                    }
                    return;
                }
            }
            if (targetItem == null || targetItem.Removed)
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Target null or removed. Aborting.", Color.Red);
#endif
                Abandon = true;
                return;
            }
            else if (isDoneSeeking && moveToTarget == null)
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Move target null. Aborting.", Color.Red);
#endif
                Abandon = true;
                return;
            }
            if (character.IsItemTakenBySomeoneElse(targetItem))
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Found an item, but it's already equipped by someone else.", Color.Yellow);
#endif
                if (originalTarget == null)
                {
                    // Try again
                    ignoredItems.Add(targetItem);
                    ResetInternal();
                }
                else
                {
                    Abandon = true;
                }
                return;
            }
            bool canInteract = false;
            if (moveToTarget is Character c)
            {
                if (character == c)
                {
                    canInteract  = true;
                    moveToTarget = null;
                }
                else
                {
                    character.SelectCharacter(c);
                    canInteract = character.CanInteractWith(c, maxDist: DefaultReach);
                    character.DeselectCharacter();
                }
            }
            else if (moveToTarget is Item parentItem)
            {
                canInteract = character.CanInteractWith(parentItem, checkLinked: false);
            }
            if (canInteract)
            {
                var pickable = targetItem.GetComponent <Pickable>();
                if (pickable == null)
                {
#if DEBUG
                    DebugConsole.NewMessage($"{character.Name}: Target not pickable. Aborting.", Color.Yellow);
#endif
                    Abandon = true;
                    return;
                }

                Inventory itemInventory = targetItem.ParentInventory;
                var       slots         = itemInventory?.FindIndices(targetItem);
                if (HumanAIController.TakeItem(targetItem, character.Inventory, Equip, Wear, storeUnequipped: true))
                {
                    if (TakeWholeStack && slots != null)
                    {
                        foreach (int slot in slots)
                        {
                            foreach (Item item in itemInventory.GetItemsAt(slot).ToList())
                            {
                                HumanAIController.TakeItem(item, character.Inventory, equip: false, storeUnequipped: true);
                            }
                        }
                    }
                    IsCompleted = true;
                }
                else
                {
#if DEBUG
                    DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red);
#endif
                    Abandon = true;
                }
            }
            else if (moveToTarget != null)
            {
                TryAddSubObjective(ref goToObjective,
                                   constructor: () =>
                {
                    return(new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach)
                    {
                        // If the root container changes, the item is no longer where it was (taken by someone -> need to find another item)
                        AbortCondition = obj => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget,
                        SpeakIfFails = false
                    });
                },
                                   onAbandon: () =>
                {
                    if (originalTarget == null)
                    {
                        // Try again
                        ignoredItems.Add(targetItem);
                        ResetInternal();
                    }
                    else
                    {
                        Abandon = true;
                    }
                },
                                   onCompleted: () => RemoveSubObjective(ref goToObjective));
            }
        }
Example #25
0
        protected override void Act(float deltaTime)
        {
            if (character.LockHands)
            {
                Abandon = true;
                return;
            }
            if (itemIdentifiers != null && !isDoneSeeking)
            {
                if (checkInventory)
                {
                    if (CheckInventory())
                    {
                        isDoneSeeking = true;
                    }
                }
                if (!isDoneSeeking)
                {
                    bool dangerousPressure = character.CurrentHull == null || character.CurrentHull.LethalPressure > 0;
                    if (dangerousPressure)
                    {
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Seeking item aborted, because the pressure is dangerous.", Color.Yellow);
#endif
                        Abandon = true;
                        return;
                    }
                    FindTargetItem();
                    objectiveManager.GetObjective <AIObjectiveIdle>().Wander(deltaTime);
                    return;
                }
            }
            if (targetItem == null || targetItem.Removed)
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Target null or removed. Aborting.", Color.Red);
#endif
                Abandon = true;
                return;
            }
            if (character.IsItemTakenBySomeoneElse(targetItem))
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Found an item, but it's already equipped by someone else.", Color.Yellow);
#endif
                // Try again
                Reset();
                return;
            }
            bool canInteract = false;
            if (moveToTarget is Character c)
            {
                if (character == c)
                {
                    canInteract  = true;
                    moveToTarget = null;
                }
                else
                {
                    character.SelectCharacter(c);
                    canInteract = character.CanInteractWith(c, maxDist: DefaultReach);
                    character.DeselectCharacter();
                }
            }
            else if (moveToTarget is Item parentItem)
            {
                canInteract = character.CanInteractWith(parentItem, out _, checkLinked: false);
            }
            if (canInteract)
            {
                var pickable = targetItem.GetComponent <Pickable>();
                if (pickable == null)
                {
#if DEBUG
                    DebugConsole.NewMessage($"{character.Name}: Target not pickable. Aborting.", Color.Yellow);
#endif
                    Abandon = true;
                    return;
                }

                if (equip)
                {
                    int targetSlot = -1;
                    //check if all the slots required by the item are free
                    foreach (InvSlotType slots in pickable.AllowedSlots)
                    {
                        if (slots.HasFlag(InvSlotType.Any))
                        {
                            continue;
                        }
                        for (int i = 0; i < character.Inventory.Items.Length; i++)
                        {
                            //slot not needed by the item, continue
                            if (!slots.HasFlag(character.Inventory.SlotTypes[i]))
                            {
                                continue;
                            }
                            targetSlot = i;
                            //slot free, continue
                            var otherItem = character.Inventory.Items[i];
                            if (otherItem == null)
                            {
                                continue;
                            }
                            //try to move the existing item to LimbSlot.Any and continue if successful
                            if (otherItem.AllowedSlots.Contains(InvSlotType.Any) &&
                                character.Inventory.TryPutItem(otherItem, character, new List <InvSlotType>()
                            {
                                InvSlotType.Any
                            }))
                            {
                                continue;
                            }
                            //if everything else fails, simply drop the existing item
                            otherItem.Drop(character);
                        }
                    }
                    if (character.Inventory.TryPutItem(targetItem, targetSlot, false, false, character))
                    {
                        targetItem.Equip(character);
                        IsCompleted = true;
                    }
                    else
                    {
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red);
#endif
                        Abandon = true;
                    }
                }
                else
                {
                    if (character.Inventory.TryPutItem(targetItem, null, new List <InvSlotType>()
                    {
                        InvSlotType.Any
                    }))
                    {
                        IsCompleted = true;
                    }
                    else
                    {
                        Abandon = true;
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red);
#endif
                    }
                }
            }
            else if (moveToTarget != null)
            {
                TryAddSubObjective(ref goToObjective,
                                   constructor: () =>
                {
                    return(new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach)
                    {
                        // If the root container changes, the item is no longer where it was (taken by someone -> need to find another item)
                        abortCondition = () => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget,
                        DialogueIdentifier = "dialogcannotreachtarget",
                        TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString()
                    });
                },
                                   onAbandon: () =>
                {
                    ignoredItems.Add(targetItem);
                    Reset();
                },
                                   onCompleted: () => RemoveSubObjective(ref goToObjective));
            }
        }
Example #26
0
        protected override void Act(float deltaTime)
        {
            if (followControlledCharacter)
            {
                if (Character.Controlled == null)
                {
                    Abandon = true;
                    return;
                }
                Target = Character.Controlled;
            }
            if (Target == character)
            {
                // Wait
                character.AIController.SteeringManager.Reset();
                return;
            }
            waitUntilPathUnreachable -= deltaTime;
            if (!character.IsClimbing)
            {
                character.SelectedConstruction = null;
            }
            if (Target is Entity e)
            {
                if (e.Removed)
                {
                    Abandon = true;
                }
                else
                {
                    character.AIController.SelectTarget(e.AiTarget);
                }
            }
            var targetHull = Target is Hull h ? h : Target is Item i ? i.CurrentHull : Target is Character c ? c.CurrentHull : character.CurrentHull;

            if (!followControlledCharacter)
            {
                // Abandon if going through unsafe paths. Note ignores unsafe nodes when following an order or when the objective is set to ignore unsafe hulls.
                bool containsUnsafeNodes = HumanAIController.CurrentOrder == null && !HumanAIController.ObjectiveManager.CurrentObjective.IgnoreUnsafeHulls &&
                                           PathSteering != null && PathSteering.CurrentPath != null &&
                                           PathSteering.CurrentPath.Nodes.Any(n => HumanAIController.UnsafeHulls.Contains(n.CurrentHull));
                if (containsUnsafeNodes || HumanAIController.UnreachableHulls.Contains(targetHull))
                {
                    Abandon = true;
                    SteeringManager.Reset();
                    return;
                }
            }
            bool insideSteering  = SteeringManager == PathSteering && PathSteering.CurrentPath != null && !PathSteering.IsPathDirty;
            bool isInside        = character.CurrentHull != null;
            bool targetIsOutside = (Target != null && targetHull == null) || (insideSteering && PathSteering.CurrentPath.HasOutdoorsNodes);

            if (isInside && targetIsOutside && !AllowGoingOutside)
            {
                Abandon = true;
            }
            else if (waitUntilPathUnreachable < 0)
            {
                if (SteeringManager == PathSteering && PathSteering.CurrentPath != null && PathSteering.CurrentPath.Unreachable && !PathSteering.IsPathDirty)
                {
                    if (repeat)
                    {
                        SteeringManager.Reset();
                    }
                    else
                    {
                        Abandon = true;
                    }
                }
            }
            if (Abandon)
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {Target.ToString()}", Color.Yellow);
#endif
                if (objectiveManager.CurrentOrder != null && objectiveManager.CurrentOrder.ReportFailures)
                {
                    character.Speak(TextManager.Get("DialogCannotReach"), identifier: "cannotreach", minDurationBetweenSimilar: 10.0f);
                }
                SteeringManager.Reset();
            }
            else
            {
                if (getDivingGearIfNeeded && !character.LockHands)
                {
                    Character followTarget    = Target as Character;
                    bool      needsDivingSuit = targetIsOutside;
                    bool      needsDivingGear = needsDivingSuit || HumanAIController.NeedsDivingGear(character, targetHull, out needsDivingSuit);
                    if (!needsDivingGear && mimic)
                    {
                        if (HumanAIController.HasDivingSuit(followTarget))
                        {
                            needsDivingGear = true;
                            needsDivingSuit = true;
                        }
                        else if (HumanAIController.HasDivingMask(followTarget))
                        {
                            needsDivingGear = true;
                        }
                    }
                    bool needsEquipment = false;
                    if (needsDivingSuit)
                    {
                        needsEquipment = !HumanAIController.HasDivingSuit(character, AIObjectiveFindDivingGear.lowOxygenThreshold);
                    }
                    else if (needsDivingGear)
                    {
                        needsEquipment = !HumanAIController.HasDivingGear(character, AIObjectiveFindDivingGear.lowOxygenThreshold);
                    }
                    if (needsEquipment)
                    {
                        TryAddSubObjective(ref findDivingGear, () => new AIObjectiveFindDivingGear(character, needsDivingSuit, objectiveManager),
                                           onAbandon: () => Abandon = true,
                                           onCompleted: () => RemoveSubObjective(ref findDivingGear));
                        return;
                    }
                }
                if (repeat && IsCloseEnough)
                {
                    OnCompleted();
                    return;
                }
                if (SteeringManager == PathSteering)
                {
                    Func <PathNode, bool> nodeFilter = null;
                    if (isInside && !AllowGoingOutside)
                    {
                        nodeFilter = node => node.Waypoint.CurrentHull != null;
                    }
                    PathSteering.SteeringSeek(character.GetRelativeSimPosition(Target), 1, startNodeFilter, endNodeFilter, nodeFilter);
                }
                else
                {
                    SteeringManager.SteeringSeek(character.GetRelativeSimPosition(Target), 10);
                }
                if (!insideSteering)
                {
                    SteeringManager.SteeringAvoid(deltaTime, lookAheadDistance: 5, weight: 1);
                }
            }
        }
Example #27
0
        private void FindTargetItem()
        {
            if (identifiersOrTags == null)
            {
                if (targetItem == null)
                {
#if DEBUG
                    DebugConsole.NewMessage($"{character.Name}: Cannot find the item, because neither identifiers nor item was defined.", Color.Red);
#endif
                    Abandon = true;
                }
                return;
            }
            for (int i = 0; i < 10 && currSearchIndex < Item.ItemList.Count - 1; i++)
            {
                currSearchIndex++;
                var       item    = Item.ItemList[currSearchIndex];
                Submarine itemSub = item.Submarine ?? item.ParentInventory?.Owner?.Submarine;
                Submarine mySub   = character.Submarine;
                if (itemSub == null)
                {
                    continue;
                }
                if (mySub == null)
                {
                    continue;
                }
                if (!CheckItem(item))
                {
                    continue;
                }
                if (ignoredContainerIdentifiers != null && item.Container != null)
                {
                    if (ignoredContainerIdentifiers.Contains(item.ContainerIdentifier))
                    {
                        continue;
                    }
                }
                // Don't allow going into another sub, unless it's connected and of the same team and type.
                if (!character.Submarine.IsEntityFoundOnThisSub(item, includingConnectedSubs: true))
                {
                    continue;
                }
                if (character.IsItemTakenBySomeoneElse(item))
                {
                    continue;
                }
                if (item.ParentInventory is ItemInventory itemInventory)
                {
                    if (!itemInventory.Container.HasRequiredItems(character, addMessage: false))
                    {
                        continue;
                    }
                }
                float itemPriority = 1;
                if (GetItemPriority != null)
                {
                    itemPriority = GetItemPriority(item);
                }
                Entity  rootInventoryOwner = item.GetRootInventoryOwner();
                Vector2 itemPos            = (rootInventoryOwner ?? item).WorldPosition;
                float   yDist = Math.Abs(character.WorldPosition.Y - itemPos.Y);
                yDist = yDist > 100 ? yDist * 5 : 0;
                float dist           = Math.Abs(character.WorldPosition.X - itemPos.X) + yDist;
                float distanceFactor = MathHelper.Lerp(1, 0, MathUtils.InverseLerp(0, 10000, dist));
                itemPriority *= distanceFactor;
                itemPriority *= item.Condition / item.MaxCondition;
                //ignore if the item has a lower priority than the currently selected one
                if (itemPriority < currItemPriority)
                {
                    continue;
                }
                currItemPriority = itemPriority;
                targetItem       = item;
                moveToTarget     = rootInventoryOwner ?? item;
            }
            if (currSearchIndex >= Item.ItemList.Count - 1)
            {
                isDoneSeeking = true;
                if (targetItem == null)
                {
                    if (spawnItemIfNotFound)
                    {
                        if (!(MapEntityPrefab.List.FirstOrDefault(me => me is ItemPrefab ip && identifiersOrTags.Any(id => id == ip.Identifier || ip.Tags.Contains(id))) is ItemPrefab prefab))
                        {
#if DEBUG
                            DebugConsole.NewMessage($"{character.Name}: Cannot find the item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}, tried to spawn the item but no matching item prefabs were found.", Color.Yellow);
#endif
                            Abandon = true;
                        }
                        else
                        {
                            Entity.Spawner.AddToSpawnQueue(prefab, character.Inventory, onSpawned: (Item spawnedItem) =>
                            {
                                targetItem = spawnedItem;
                                if (character.TeamID == Character.TeamType.FriendlyNPC && (character.Submarine?.Info.IsOutpost ?? false))
                                {
                                    spawnedItem.SpawnedInOutpost = true;
                                }
                            });
                        }
                    }
                    else
                    {
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Cannot find the item with the following identifier(s) or tag(s): {string.Join(", ", identifiersOrTags)}", Color.Yellow);
#endif
                        Abandon = true;
                    }
                }
            }
Example #28
0
        protected override void Act(float deltaTime)
        {
            if (followControlledCharacter)
            {
                if (Character.Controlled == null)
                {
                    abandon = true;
                    return;
                }
                Target = Character.Controlled;
            }
            if (Target == character)
            {
                character.AIController.SteeringManager.Reset();
                abandon = true;
                return;
            }
            waitUntilPathUnreachable -= deltaTime;
            if (!character.IsClimbing)
            {
                character.SelectedConstruction = null;
            }
            if (Target is Entity e)
            {
                if (e.Removed)
                {
                    abandon = true;
                }
                else
                {
                    character.AIController.SelectTarget(e.AiTarget);
                }
            }
            bool isInside        = character.CurrentHull != null;
            bool insideSteering  = SteeringManager == PathSteering && PathSteering.CurrentPath != null && !PathSteering.IsPathDirty;
            var  targetHull      = Target is Hull h ? h : Target is Item i ? i.CurrentHull : Target is Character c ? c.CurrentHull : character.CurrentHull;
            bool targetIsOutside = (Target != null && targetHull == null) || (insideSteering && PathSteering.CurrentPath.HasOutdoorsNodes);

            if (isInside && targetIsOutside && !AllowGoingOutside)
            {
                abandon = true;
            }
            else if (waitUntilPathUnreachable < 0)
            {
                if (SteeringManager == PathSteering && PathSteering.CurrentPath != null && PathSteering.CurrentPath.Unreachable)
                {
                    if (repeat)
                    {
                        SteeringManager.Reset();
                    }
                    else
                    {
                        abandon = true;
                    }
                }
            }
            if (abandon)
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {Target.ToString()}", Color.Yellow);
#endif
                if (objectiveManager.CurrentOrder != null)
                {
                    character.Speak(TextManager.Get("DialogCannotReach"), identifier: "cannotreach", minDurationBetweenSimilar: 10.0f);
                }
                character.AIController.SteeringManager.Reset();
            }
            else
            {
                Vector2 currTargetSimPos = Vector2.Zero;
                currTargetSimPos = Target.SimPosition;
                // Take the sub position into account in the sim pos
                if (SteeringManager != PathSteering && character.Submarine == null && Target.Submarine != null)
                {
                    currTargetSimPos += Target.Submarine.SimPosition;
                }
                else if (character.Submarine != null && Target.Submarine == null)
                {
                    currTargetSimPos -= character.Submarine.SimPosition;
                }
                else if (character.Submarine != Target.Submarine)
                {
                    if (character.Submarine != null && Target.Submarine != null)
                    {
                        Vector2 diff = character.Submarine.SimPosition - Target.Submarine.SimPosition;
                        currTargetSimPos -= diff;
                    }
                }
                character.AIController.SteeringManager.SteeringSeek(currTargetSimPos);
                if (SteeringManager != PathSteering)
                {
                    SteeringManager.SteeringAvoid(deltaTime, lookAheadDistance: 5, weight: 1, heading: VectorExtensions.Forward(character.AnimController.Collider.Rotation));
                }
                if (getDivingGearIfNeeded)
                {
                    Character followTarget    = Target as Character;
                    bool      needsDivingGear = HumanAIController.NeedsDivingGear(targetHull) || mimic && HumanAIController.HasDivingMask(followTarget);
                    bool      needsDivingSuit = needsDivingGear && (targetHull == null || targetIsOutside || targetHull.WaterPercentage > 90) || mimic && HumanAIController.HasDivingSuit(followTarget);
                    bool      needsEquipment  = false;
                    if (needsDivingSuit)
                    {
                        needsEquipment = !HumanAIController.HasDivingSuit(character);
                    }
                    else if (needsDivingGear)
                    {
                        needsEquipment = !HumanAIController.HasDivingMask(character);
                    }
                    if (needsEquipment)
                    {
                        TryAddSubObjective(ref findDivingGear, () => new AIObjectiveFindDivingGear(character, needsDivingSuit, objectiveManager));
                    }
                }
            }
        }
        protected override void Act(float deltaTime)
        {
            var extinguisherItem = character.Inventory.FindItemByTag("fireextinguisher");

            if (extinguisherItem == null || extinguisherItem.Condition <= 0.0f || !character.HasEquippedItem(extinguisherItem))
            {
                TryAddSubObjective(ref getExtinguisherObjective, () =>
                {
                    if (character.IsOnPlayerTeam && !character.HasEquippedItem("fireextinguisher", allowBroken: false))
                    {
                        character.Speak(TextManager.Get("DialogFindExtinguisher"), null, 2.0f, "findextinguisher", 30.0f);
                    }
                    var getItemObjective = new AIObjectiveGetItem(character, "fireextinguisher", objectiveManager, equip: true)
                    {
                        AllowStealing = true,
                        // If the item is inside an unsafe hull, decrease the priority
                        GetItemPriority = i => HumanAIController.UnsafeHulls.Contains(i.CurrentHull) ? 0.1f : 1
                    };
                    if (objectiveManager.HasOrder <AIObjectiveExtinguishFires>())
                    {
                        getItemObjective.Abandoned += () => character.Speak(TextManager.Get("dialogcannotfindfireextinguisher"), null, 0.0f, "dialogcannotfindfireextinguisher", 10.0f);
                    }
                    ;
                    return(getItemObjective);
                });
            }
            else
            {
                var extinguisher = extinguisherItem.GetComponent <RepairTool>();
                if (extinguisher == null)
                {
#if DEBUG
                    DebugConsole.ThrowError($"{character.Name}: AIObjectiveExtinguishFire failed - the item \"" + extinguisherItem + "\" has no RepairTool component but is tagged as an extinguisher");
#endif
                    Abandon = true;
                    return;
                }
                foreach (FireSource fs in targetHull.FireSources)
                {
                    float xDist   = Math.Abs(character.WorldPosition.X - fs.WorldPosition.X) - fs.DamageRange;
                    float yDist   = Math.Abs(character.WorldPosition.Y - fs.WorldPosition.Y);
                    bool  inRange = xDist + yDist < extinguisher.Range;
                    // Use the hull position, because the fire x pos is sometimes inside a wall -> the bot can't ever see it and continues running towards the wall.
                    ISpatialEntity lookTarget = character.CurrentHull == targetHull || character.CurrentHull.linkedTo.Contains(targetHull) ? targetHull : fs as ISpatialEntity;
                    bool           move       = !inRange || !character.CanSeeTarget(lookTarget);
                    if ((inRange && character.CanSeeTarget(lookTarget)) || useExtinquisherTimer > 0)
                    {
                        useExtinquisherTimer += deltaTime;
                        if (useExtinquisherTimer > 2.0f)
                        {
                            useExtinquisherTimer = 0.0f;
                        }
                        // Aim
                        character.CursorPosition = fs.Position;
                        Vector2 fromCharacterToFireSource = fs.WorldPosition - character.WorldPosition;
                        float   dist = fromCharacterToFireSource.Length();
                        character.CursorPosition += VectorExtensions.Forward(extinguisherItem.body.TransformedRotation + (float)Math.Sin(sinTime) / 2, dist / 2);
                        if (extinguisherItem.RequireAimToUse)
                        {
                            character.SetInput(InputType.Aim, false, true);
                            sinTime += deltaTime * 10;
                        }
                        character.SetInput(extinguisherItem.IsShootable ? InputType.Shoot : InputType.Use, false, true);
                        extinguisher.Use(deltaTime, character);
                        if (!targetHull.FireSources.Contains(fs))
                        {
                            character.Speak(TextManager.GetWithVariable("DialogPutOutFire", "[roomname]", targetHull.DisplayName, true), null, 0, "putoutfire", 10.0f);
                        }
                    }
                    if (move)
                    {
                        //go to the first firesource
                        if (TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(fs, character, objectiveManager, closeEnough: Math.Max(fs.DamageRange, extinguisher.Range * 0.7f))
                        {
                            DialogueIdentifier = "dialogcannotreachfire",
                            TargetName = fs.Hull.DisplayName
                        },
                                               onAbandon: () => Abandon = true,
                                               onCompleted: () => RemoveSubObjective(ref gotoObjective)))
                        {
                            gotoObjective.requiredCondition = () => targetHull == null || character.CanSeeTarget(targetHull);
                        }
                    }
                    else
                    {
                        character.AIController.SteeringManager.Reset();
                    }
                    break;
                }
            }
        }
Example #30
0
        public void Resize(ISpatialEntity entity, IShape shape, MovementDelegate movementDelegate)
        {
            // TODO: Check if shape > cellsize
            if (gpuActive) gpuActiveWait.WaitOne();
            Interlocked.Increment(ref m_ActiveOperationCount);
            long objId = spatialObjIdMap[entity];
            var newEnt = entity;
            newEnt.Shape = shape;
            spatialObjIdMap.Remove(entity);
            spatialObjIdMap.Add(newEnt, objId);
            objIdSpatialMap[(int)objId].Shape = shape;
            shapeList.Remove(objIdClShapeMap[(int)objId]);
            m_MoveDelegates.Add(new Tuple<long, MovementDelegate>(objId, movementDelegate));

            clShapeObject act;
            clPoint center;
            center.x = (float)entity.Shape.Bounds.Position.X;
            center.y = (float)entity.Shape.Bounds.Position.Y;
            center.z = (float)entity.Shape.Bounds.Position.Z;
            clPoint front;
            front.x = (float)entity.Shape.Bounds.LeftBottomFront.X;
            front.y = (float)entity.Shape.Bounds.LeftBottomFront.Y;
            front.z = (float)entity.Shape.Bounds.LeftBottomFront.Z;
            clPoint rear;
            rear.x = (float)entity.Shape.Bounds.RightTopRear.X;
            rear.y = (float)entity.Shape.Bounds.RightTopRear.Y;
            rear.z = (float)entity.Shape.Bounds.RightTopRear.Z;
            act.center = center;
            act.leftBottomFront = front;
            act.rigthTopRear = rear;
            shapeList.Add(act);
            objIdClShapeMap[(int)objId] = act;
            Interlocked.Decrement(ref m_ActiveOperationCount);
        }
Example #31
0
        public void Remove(ISpatialEntity entity)
        {
            if (gpuActive) gpuActiveWait.WaitOne();

            long objId = spatialObjIdMap[entity];
            envActEnvObjs.Remove(objId);
            objIdList.Remove(objId);
            spatialObjIdMap.Remove(entity);
            objIdSpatialMap.Remove((int)objId);
            objIdClShapeMap.Remove((int)objId);
            shapeList.Remove(objIdClShapeMap[(int)objId]);
        }
Example #32
0
        public void Move(ISpatialEntity entity, Vector3 movementVector, Direction rotation, MovementDelegate movementDelegate)
        {
            if (gpuActive) gpuActiveWait.WaitOne();
            Interlocked.Increment(ref m_ActiveOperationCount);
            var objId = spatialObjIdMap[entity];
            objId &= (~(0xFFFFFFFF << 32));
            objId |= FLAG_MOVE;
            var newEnt = entity;
            var newShape = newEnt.Shape.Transform(movementVector, rotation);
            newEnt.Shape = newShape;
            spatialObjIdMap.Remove(entity);
            spatialObjIdMap.Add(newEnt, objId);
            objIdSpatialMap[(int)objId].Shape = newShape;

            //shapeList.Remove(objIdClShapeMap[objId]);

            envActEnvObjs.Remove(objId);
            // TODO Testen ob es auch mit Konstruktoren funktioniert
            clShapeObject act;
            clPoint center;
            center.x = (float)entity.Shape.Bounds.Position.X;
            center.y = (float)entity.Shape.Bounds.Position.Y;
            center.z = (float)entity.Shape.Bounds.Position.Z;
            clPoint front;
            front.x = (float)entity.Shape.Bounds.LeftBottomFront.X;
            front.y = (float)entity.Shape.Bounds.LeftBottomFront.Y;
            front.z = (float)entity.Shape.Bounds.LeftBottomFront.Z;
            clPoint rear;
            rear.x = (float)entity.Shape.Bounds.RightTopRear.X;
            rear.y = (float)entity.Shape.Bounds.RightTopRear.Y;
            rear.z = (float)entity.Shape.Bounds.RightTopRear.Z;
            act.center = center;
            act.leftBottomFront = front;
            act.rigthTopRear = rear;
            envActEnvObjs[objId] = act;
            //shapeList.Add(act);
            objIdClShapeMap[(int)objId] = act;
            Interlocked.Decrement(ref m_ActiveOperationCount);
        }
Example #33
0
        protected Character CreateHuman(HumanPrefab humanPrefab, List <Character> characters, Dictionary <Character, List <Item> > characterItems, Submarine submarine, CharacterTeamType teamType, ISpatialEntity positionToStayIn = null, Rand.RandSync humanPrefabRandSync = Rand.RandSync.Server, bool giveTags = true)
        {
            var characterInfo = humanPrefab.GetCharacterInfo(Rand.RandSync.Server) ?? new CharacterInfo(CharacterPrefab.HumanSpeciesName, npcIdentifier: humanPrefab.Identifier, jobPrefab: humanPrefab.GetJobPrefab(humanPrefabRandSync), randSync: humanPrefabRandSync);

            characterInfo.TeamID = teamType;

            if (positionToStayIn == null)
            {
                positionToStayIn =
                    WayPoint.GetRandom(SpawnType.Human, characterInfo.Job?.Prefab, submarine) ??
                    WayPoint.GetRandom(SpawnType.Human, null, submarine);
            }

            Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, positionToStayIn.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);

            spawnedCharacter.Prefab = humanPrefab;
            humanPrefab.InitializeCharacter(spawnedCharacter, positionToStayIn);
            humanPrefab.GiveItems(spawnedCharacter, submarine, Rand.RandSync.Server, createNetworkEvents: false);

            characters.Add(spawnedCharacter);
            characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true));

            return(spawnedCharacter);
        }
Example #34
0
        private static void Main(string[] args)
        {
            if (File.Exists(Path.Combine(System.Environment.CurrentDirectory, @"..\..\log.txt")))
            {
            File.Delete(Path.Combine(System.Environment.CurrentDirectory, @"..\..\log.txt"));
            }

            if (File.Exists(Path.Combine(System.Environment.CurrentDirectory, @"..\..\sortLog.txt")))
            {
                File.Delete(Path.Combine(System.Environment.CurrentDirectory, @"..\..\sortLog.txt"));
            }
            if (File.Exists(Path.Combine(System.Environment.CurrentDirectory, @"..\..\OpenCLDebugLog.txt")))
            {
                File.Delete(Path.Combine(System.Environment.CurrentDirectory, @"..\..\OpenCLDebugLog.txt"));
            }

            numElements--;
            numElements |= numElements >> 1;
            numElements |= numElements >> 2;
            numElements |= numElements >> 4;
            numElements |= numElements >> 8;
            numElements |= numElements >> 16;
            numElements++;

            Random generator = new Random();
            Console.SetWindowSize(Console.LargestWindowWidth/2,Console.LargestWindowHeight/2);
            /*
            ISpatialEntity[] testSpatials = new ISpatialEntity[numElements];
             for (int i = 2; i < testSpatials.Length; i++)
            {
                testSpatials[i] = new TestSpatialEntity(new Vector3(1, 1, 1));
                testSpatials[i].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(generator.Next(1,100), generator.Next(1,100), generator.Next(1,100)), null);
                Console.WriteLine("GUID = "+ testSpatials[i].AgentGuid);
                Console.WriteLine(string.Format("Pos: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.Position.X, testSpatials[i].Shape.Bounds.Position.Y, testSpatials[i].Shape.Bounds.Position.Z));
                Console.WriteLine(string.Format("Min: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.LeftBottomFront.X, testSpatials[i].Shape.Bounds.LeftBottomFront.Y, testSpatials[i].Shape.Bounds.LeftBottomFront.Z, testSpatials[i].AgentGuid));
                Console.WriteLine(string.Format("Max: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.RightTopRear.X, testSpatials[i].Shape.Bounds.RightTopRear.Y, testSpatials[i].Shape.Bounds.RightTopRear.Z, testSpatials[i].AgentGuid));
                Console.WriteLine();
                // Console.Write(" " + testData[i]);#3##2#
            }
             testSpatials[0] = new TestSpatialEntity(new Vector3(1, 1, 1));
             testSpatials[0].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(3, 3, 2), null);

             testSpatials[1] = new TestSpatialEntity(new Vector3(1, 1, 1));
             testSpatials[1].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(3, 2.5, 2), null);

              testSpatials[0] = new TestSpatialEntity(new Vector3(1, 1, 1));
              testSpatials[0].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(2,2,2), null);

              testSpatials[1] = new TestSpatialEntity(new Vector3(1, 1, 1));
              testSpatials[1].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(2,2,2), null);

              testSpatials[2] = new TestSpatialEntity(new Vector3(1, 1, 1));
              testSpatials[2].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(4,4,2), null);

              testSpatials[3] = new TestSpatialEntity(new Vector3(1, 1, 1));
              testSpatials[3].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(4, 4, 2), null);#1#

               for (int i = 0; i < numElements; i++)
            {
                Console.WriteLine("GUID = " + testSpatials[i].AgentGuid);
                Console.WriteLine(string.Format("Pos: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.Position.X, testSpatials[i].Shape.Bounds.Position.Y, testSpatials[i].Shape.Bounds.Position.Z));
                Console.WriteLine(string.Format("Min: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.LeftBottomFront.X, testSpatials[i].Shape.Bounds.LeftBottomFront.Y, testSpatials[i].Shape.Bounds.LeftBottomFront.Z));
                Console.WriteLine(string.Format("Max: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.RightTopRear.X, testSpatials[i].Shape.Bounds.RightTopRear.Y, testSpatials[i].Shape.Bounds.RightTopRear.Z));
                Console.WriteLine();

            }
            #1#
               // compute the next highest power of 2 of 32-bit v

            /*

            #1#
            int[] testData = new int[numElements];
            int[] testResult = new int[numElements];
            for (int i = 0; i < testData.Length; i++)
            {
                testData[i] = generator.Next(1000000);
                // Console.Write(" " + testData[i]);#3#
            }
            Console.WriteLine();
            Program ins = new Program();
            ins.Setup();

            var radix = new GPURadixSort(cqCommandQueue, cxGPUContext, _device);

            Event eve;
            ErrorCode error;
            IMem inputBuff = Cl.CreateBuffer(cxGPUContext, MemFlags.ReadWrite, (IntPtr)(numElements * 4), testData,
                out error);
            ins.CheckErr(error, "Createbuffer");
            IMem outputBuff = Cl.CreateBuffer(cxGPUContext, MemFlags.ReadWrite, (IntPtr)(numElements * 4),
                out error);
            ins.CheckErr(error, "Createbuffer");

            error = Cl.EnqueueWriteBuffer(cqCommandQueue, inputBuff, Bool.True, IntPtr.Zero, (IntPtr)(numElements * 4),
                testData, 0, null,
                out eve);
            ins.CheckErr(error, "EnqBuffer");
            error = Cl.Finish(cqCommandQueue);
            ins.CheckErr(error, "Cl.Finish");
            */

            #region RadixSortTest

            /*            DateTime before = DateTime.Now;
            radix.sortKeysOnly(inputBuff, outputBuff, numElements);

            error = Cl.EnqueueWriteBuffer(cqCommandQueue, inputBuff, Bool.True, IntPtr.Zero, (IntPtr)(numElements * 4),
                testData, 0, null,
                out eve);
            ins.CheckErr(error, "EnqBuffer");

            radix.sortKeysOnly(inputBuff, outputBuff, numElements);*/

                //Collision Detection tests
            /*
            CollisionDetection detec = new CollisionDetection(cqCommandQueue,cxGPUContext,_device,radix,new Point3D(150,150,150),new Vector3(2,2,2) );
            IMem inp;
            IMem outp;
            detec.CreateCellIdArray(testSpatials,out inp, out outp);
            #1#

            */
            #endregion

            /*
               radix.sortKeysOnly(inputBuff, outputBuff, numElements);
            #1#

            error = Cl.EnqueueReadBuffer(cqCommandQueue, outputBuff, Bool.True, IntPtr.Zero, (IntPtr)(numElements * 4),
                testResult, 0, null, out eve);
            ins.CheckErr(error, "Cl.EnqueueReadBuffer");

            //Execute our kernel (OpenCL code)
            error = Cl.Finish(cqCommandQueue);
            ins.CheckErr(error, "Cl.Finish");
            Console.WriteLine("Execution time Gpu ="+( DateTime.Now- before ).TotalMilliseconds);
               /* for (int i = 0; i < numElements; i++)
            {
                Console.Write(" " + testResult[i]);
            }#1#
            before = DateTime.Now;
            Array.Sort(testData);
            Console.WriteLine("Execution time CPU =" + (DateTime.Now - before).TotalMilliseconds);
            int r = 0;

            */

               MovementDelegate moveDel = new MovementDelegate(dele1);
            ExploreDelegate expDel = new ExploreDelegate(dele2);
            generator = new Random();
            Console.SetWindowSize(Console.LargestWindowWidth / 2, Console.LargestWindowHeight / 2);

            ISpatialEntity[] testSpatials = new ISpatialEntity[numElements];

            GpuESC esc = new GpuESC(new Vector3(2, 2, 2), new Vector3(2000000, 8, 8));

            for (int i = 2; i < testSpatials.Length; i++)
            {
                testSpatials[i] = new TestSpatialEntity(new Vector3(0.5, 0.5, 0.5));
                Vector3 actos = new Vector3(i + 0.1, 1.5, 1.5);
                testSpatials[i].Shape = new Cuboid(new Vector3(0.5, 0.5, 0.5), actos, null);
                /*Console.WriteLine("GUID = " + testSpatials[i].AgentGuid);
                Console.WriteLine(string.Format("Pos: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.Position.X, testSpatials[i].Shape.Bounds.Position.Y, testSpatials[i].Shape.Bounds.Position.Z));
                Console.WriteLine(string.Format("Min: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.LeftBottomFront.X, testSpatials[i].Shape.Bounds.LeftBottomFront.Y, testSpatials[i].Shape.Bounds.LeftBottomFront.Z, testSpatials[i].AgentGuid));
                Console.WriteLine(string.Format("Max: x={0} , y ={1}, z={2} ", testSpatials[i].Shape.Bounds.RightTopRear.X, testSpatials[i].Shape.Bounds.RightTopRear.Y, testSpatials[i].Shape.Bounds.RightTopRear.Z, testSpatials[i].AgentGuid));
             */   // Console.WriteLine();
                // Console.Write(" " + testData[i]);#3##2#*/
                esc.Add(testSpatials[i], actos, null, moveDel);
            }
            testSpatials[0] = new TestSpatialEntity(new Vector3(1, 1, 1));
            testSpatials[0].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(3, 3, 2), null);
            esc.Add(testSpatials[0], testSpatials[0].Shape.Position, null, moveDel);

            testSpatials[1] = new TestSpatialEntity(new Vector3(1, 1, 1));
            testSpatials[1].Shape = new Cuboid(new Vector3(1, 1, 1), new Vector3(3, 3, 2), null);
            Console.WriteLine(testSpatials[0].AgentGuid);
            Console.WriteLine(testSpatials[1].AgentGuid);

            esc.Add(testSpatials[1], testSpatials[1].Shape.Position, null, moveDel);
            var before = DateTime.Now;
            for (int i = 0; i <10; i++)
            {
                esc.Commit();
            }

            Console.WriteLine("Execution time Total =" + (DateTime.Now - before).TotalMilliseconds);
            Console.WriteLine(collisionCount);
            int asdcyxcsa = 2;
        }
Example #35
0
        protected override void Act(float deltaTime)
        {
            if (character.LockHands)
            {
                Abandon = true;
                return;
            }
            if (itemIdentifiers != null && !isDoneSeeking)
            {
                if (checkInventory)
                {
                    if (CheckInventory())
                    {
                        isDoneSeeking = true;
                    }
                }
                if (!isDoneSeeking)
                {
                    bool dangerousPressure = character.CurrentHull == null || character.CurrentHull.LethalPressure > 0;
                    if (dangerousPressure)
                    {
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Seeking item aborted, because the pressure is dangerous.", Color.Yellow);
#endif
                        Abandon = true;
                        return;
                    }
                    FindTargetItem();
                    objectiveManager.GetObjective <AIObjectiveIdle>().Wander(deltaTime);
                    return;
                }
            }
            if (targetItem == null || targetItem.Removed)
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Target null or removed. Aborting.", Color.Red);
#endif
                Abandon = true;
                return;
            }
            else if (isDoneSeeking && moveToTarget == null)
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Move target null. Aborting.", Color.Red);
#endif
                Abandon = true;
                return;
            }
            if (character.IsItemTakenBySomeoneElse(targetItem))
            {
#if DEBUG
                DebugConsole.NewMessage($"{character.Name}: Found an item, but it's already equipped by someone else.", Color.Yellow);
#endif
                if (originalTarget == null)
                {
                    // Try again
                    Reset();
                }
                else
                {
                    Abandon = true;
                }
                return;
            }
            bool canInteract = false;
            if (moveToTarget is Character c)
            {
                if (character == c)
                {
                    canInteract  = true;
                    moveToTarget = null;
                }
                else
                {
                    character.SelectCharacter(c);
                    canInteract = character.CanInteractWith(c, maxDist: DefaultReach);
                    character.DeselectCharacter();
                }
            }
            else if (moveToTarget is Item parentItem)
            {
                canInteract = character.CanInteractWith(parentItem, out _, checkLinked: false);
            }
            if (canInteract)
            {
                var pickable = targetItem.GetComponent <Pickable>();
                if (pickable == null)
                {
#if DEBUG
                    DebugConsole.NewMessage($"{character.Name}: Target not pickable. Aborting.", Color.Yellow);
#endif
                    Abandon = true;
                    return;
                }

                if (equip)
                {
                    if (HumanAIController.TryToMoveItem(targetItem, character.Inventory))
                    {
                        targetItem.Equip(character);
                        IsCompleted = true;
                    }
                    else
                    {
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red);
#endif
                        Abandon = true;
                    }
                }
                else
                {
                    if (character.Inventory.TryPutItem(targetItem, character, new List <InvSlotType>()
                    {
                        InvSlotType.Any
                    }))
                    {
                        IsCompleted = true;
                    }
                    else
                    {
                        Abandon = true;
#if DEBUG
                        DebugConsole.NewMessage($"{character.Name}: Failed to equip/move the item '{targetItem.Name}' into the character inventory. Aborting.", Color.Red);
#endif
                    }
                }
            }
            else if (moveToTarget != null)
            {
                TryAddSubObjective(ref goToObjective,
                                   constructor: () =>
                {
                    return(new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach)
                    {
                        // If the root container changes, the item is no longer where it was (taken by someone -> need to find another item)
                        abortCondition = () => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget,
                        DialogueIdentifier = "dialogcannotreachtarget",
                        TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString()
                    });
                },
                                   onAbandon: () =>
                {
                    ignoredItems.Add(targetItem);
                    Reset();
                },
                                   onCompleted: () => RemoveSubObjective(ref goToObjective));
            }
        }
Example #36
0
        public void AddWithRandomPosition(ISpatialEntity entity, Vector3 min, Vector3 max, bool grid, MovementDelegate movementDelegate)
        {
            //Evaluate dimesions
            var shapeTmp = new Vector3(entity.Shape.Bounds.Length / 2, entity.Shape.Bounds.Height / 2, entity.Shape.Bounds.Width / 2);
            if (!checkBoundarys(min - shapeTmp, max + shapeTmp))
            {
                movementDelegate.Invoke(new MovementResult());
                return;
            }
            if (gpuActive) gpuActiveWait.WaitOne();
            Interlocked.Increment(ref m_ActiveOperationCount);
            Vector3 freepos = GetNextFreeCell(min, max);
            if (freepos == Vector3.Null)
            {
                var rnd = new Random();
                freepos = new Vector3((double)rnd.Next((int)min.X, (int)max.X), (double)rnd.Next((int)min.Y, (int)max.Y), (double)rnd.Next((int)min.Z, (int)max.Z));
            }
            var objId = getNextObjId();
            var objData = objId | FLAG_NEW;
            m_AddDelegates.Add(new Tuple<long, MovementDelegate>(objData, movementDelegate));
            objIdList.Add(objId);
            spatialObjIdMap.Add(entity, objId);
            objIdSpatialMap.Add(objId, entity);
            entity.Shape = new Cuboid(entity.Shape.Bounds.Dimension, freepos);

            clShapeObject act;
            clPoint center;
            center.x = (float)entity.Shape.Bounds.Position.X;
            center.y = (float)entity.Shape.Bounds.Position.Y;
            center.z = (float)entity.Shape.Bounds.Position.Z;
            clPoint front;
            front.x = (float)entity.Shape.Bounds.LeftBottomFront.X;
            front.y = (float)entity.Shape.Bounds.LeftBottomFront.Y;
            front.z = (float)entity.Shape.Bounds.LeftBottomFront.Z;
            clPoint rear;
            rear.x = (float)entity.Shape.Bounds.RightTopRear.X;
            rear.y = (float)entity.Shape.Bounds.RightTopRear.Y;
            rear.z = (float)entity.Shape.Bounds.RightTopRear.Z;
            act.center = center;
            act.leftBottomFront = front;
            act.rigthTopRear = rear;

            envFreshAddedObjs.Add(objData, act);
            /*
                        shapeList.Add(act);
                        objIdClShapeMap.Add(objId, act);
                        */
            // Added Element -> Now wait until the CollisionDetection did its work at the LayerTick
            Interlocked.Decrement(ref m_ActiveOperationCount);

               // envActEnvObjs.Add(objId, act);

            // We need the list with free positions first
        }
Example #37
0
        public void Add(ISpatialEntity entity, Vector3 position, Direction rotation, MovementDelegate movementDelegate)
        {
            entity.Shape.Transform(position - entity.Shape.Position, null);
            // First check boundarys
            if (!checkBoundarys(entity.Shape.Bounds.LeftBottomFront,entity.Shape.Bounds.RightTopRear))
            {
                movementDelegate.Invoke(new MovementResult());
                return;
            }
            bool res;
            if (gpuActive) gpuActiveWait.WaitOne();
            Interlocked.Increment(ref m_ActiveOperationCount);
            int objId = getNextObjId();
            long objData = objId | FLAG_NEW;
            m_AddDelegates.Add(new Tuple<long,MovementDelegate>(objData,movementDelegate));
            objIdList.Add(objId);
            spatialObjIdMap.Add(entity, objId);
            objIdSpatialMap.Add(objId, entity);

            clShapeObject act;
            clPoint center;
            center.x = (float)entity.Shape.Bounds.Position.X;
            center.y = (float)entity.Shape.Bounds.Position.Y;
            center.z = (float)entity.Shape.Bounds.Position.Z;
            clPoint front;
            front.x = (float)entity.Shape.Bounds.LeftBottomFront.X;
            front.y = (float)entity.Shape.Bounds.LeftBottomFront.Y;
            front.z = (float)entity.Shape.Bounds.LeftBottomFront.Z;
            clPoint rear;
            rear.x = (float)entity.Shape.Bounds.RightTopRear.X;
            rear.y = (float)entity.Shape.Bounds.RightTopRear.Y;
            rear.z = (float)entity.Shape.Bounds.RightTopRear.Z;
            act.center = center;
            act.leftBottomFront = front;
            act.rigthTopRear = rear;
            objIdClShapeMap.Add(objId, act);
            envFreshAddedObjs.Add(objData, act);
            /*
                        shapeList.Add(act);
                        objIdClShapeMap.Add(objId, act);
                        */

               Interlocked.Decrement(ref m_ActiveOperationCount);
        }