Пример #1
0
        public Hull(MapEntityPrefab prefab, Rectangle rectangle, Submarine submarine)
            : base(prefab, submarine)
        {
            rect = rectangle;

            OxygenPercentage = 100.0f;

            FireSources = new List <FireSource>();

            properties = SerializableProperty.GetProperties(this);

            int arraySize = (int)Math.Ceiling((float)rectangle.Width / WaveWidth + 1);

            waveY   = new float[arraySize];
            waveVel = new float[arraySize];

            leftDelta  = new float[arraySize];
            rightDelta = new float[arraySize];

            surface = rect.Y - rect.Height;

            aiTarget = new AITarget(this);

            hullList.Add(this);

            if (submarine == null || !submarine.Loading)
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            WaterVolume = 0.0f;

            InsertToList();
        }
Пример #2
0
        public static Gap Load(XElement element, Submarine submarine)
        {
            Rectangle rect = Rectangle.Empty;

            if (element.Attribute("rect") != null)
            {
                rect = element.GetAttributeRect("rect", Rectangle.Empty);
            }
            else
            {
                //backwards compatibility
                rect = new Rectangle(
                    int.Parse(element.Attribute("x").Value),
                    int.Parse(element.Attribute("y").Value),
                    int.Parse(element.Attribute("width").Value),
                    int.Parse(element.Attribute("height").Value));
            }

            bool isHorizontal = rect.Height > rect.Width;

            var horizontalAttribute = element.Attribute("horizontal");

            if (horizontalAttribute != null)
            {
                isHorizontal = horizontalAttribute.Value.ToString() == "true";
            }

            Gap g = new Gap(rect, isHorizontal, submarine);

            g.ID         = (ushort)int.Parse(element.Attribute("ID").Value);
            g.linkedToID = new List <ushort>();
            return(g);
        }
Пример #3
0
        public override void Remove()
        {
            base.Remove();
            hullList.Remove(this);

            if (Submarine != null && !Submarine.Loading && !Submarine.Unloading)
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            List <FireSource> fireSourcesToRemove = new List <FireSource>(FireSources);

            foreach (FireSource fireSource in fireSourcesToRemove)
            {
                fireSource.Remove();
            }
            FireSources.Clear();

            if (EntityGrids != null)
            {
                foreach (EntityGrid entityGrid in EntityGrids)
                {
                    entityGrid.RemoveEntity(this);
                }
            }
        }
Пример #4
0
        public static void MapLoaded(List <MapEntity> entities, bool updateHulls)
        {
            InitializeLoadedLinks(entities);

            List <LinkedSubmarine> linkedSubs = new List <LinkedSubmarine>();

            for (int i = 0; i < entities.Count; i++)
            {
                if (entities[i].mapLoadedCalled || entities[i].Removed)
                {
                    continue;
                }
                if (entities[i] is LinkedSubmarine)
                {
                    linkedSubs.Add((LinkedSubmarine)entities[i]);
                    continue;
                }

                entities[i].OnMapLoaded();
            }

            if (updateHulls)
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            entities.ForEach(e => e.mapLoadedCalled = true);

            foreach (LinkedSubmarine linkedSub in linkedSubs)
            {
                linkedSub.OnMapLoaded();
            }
        }
Пример #5
0
        public override void Remove()
        {
            base.Remove();
            hullList.Remove(this);

            if (Submarine == null || (!Submarine.Loading && !Submarine.Unloading))
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            List <FireSource> fireSourcesToRemove = new List <FireSource>(fireSources);

            foreach (FireSource fireSource in fireSourcesToRemove)
            {
                fireSource.Remove();
            }
            fireSources.Clear();

#if CLIENT
            if (soundIndex > -1)
            {
                Sounds.SoundManager.Stop(soundIndex);
                soundIndex = -1;
            }
#endif

            if (entityGrids != null)
            {
                foreach (EntityGrid entityGrid in entityGrids)
                {
                    entityGrid.RemoveEntity(this);
                }
            }
        }
Пример #6
0
        public static void MapLoaded(List <MapEntity> entities, bool updateHulls)
        {
            foreach (MapEntity e in entities)
            {
                if (e.mapLoadedCalled)
                {
                    continue;
                }
                if (e.linkedToID == null)
                {
                    continue;
                }
                if (e.linkedToID.Count == 0)
                {
                    continue;
                }

                e.linkedTo.Clear();

                foreach (ushort i in e.linkedToID)
                {
                    if (FindEntityByID(i) is MapEntity linked)
                    {
                        e.linkedTo.Add(linked);
                    }
                }
            }

            List <LinkedSubmarine> linkedSubs = new List <LinkedSubmarine>();

            for (int i = 0; i < entities.Count; i++)
            {
                if (entities[i].mapLoadedCalled)
                {
                    continue;
                }
                if (entities[i] is LinkedSubmarine)
                {
                    linkedSubs.Add((LinkedSubmarine)entities[i]);
                    continue;
                }

                entities[i].OnMapLoaded();
            }

            if (updateHulls)
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            entities.ForEach(e => e.mapLoadedCalled = true);

            foreach (LinkedSubmarine linkedSub in linkedSubs)
            {
                linkedSub.OnMapLoaded();
            }
        }
Пример #7
0
        /// <summary>
        /// Update the linkedTo-lists of the entities based on the linkedToID-lists
        /// Has to be done after all the entities have been loaded (an entity can't
        /// be linked to some other entity that hasn't been loaded yet)
        /// </summary>
        public static void MapLoaded(Submarine sub)
        {
            foreach (MapEntity e in mapEntityList)
            {
                if (e.Submarine != sub)
                {
                    continue;
                }
                if (e.linkedToID == null)
                {
                    continue;
                }
                if (e.linkedToID.Count == 0)
                {
                    continue;
                }

                e.linkedTo.Clear();

                foreach (ushort i in e.linkedToID)
                {
                    if (FindEntityByID(i) is MapEntity linked)
                    {
                        e.linkedTo.Add(linked);
                    }
                }
            }

            List <LinkedSubmarine> linkedSubs = new List <LinkedSubmarine>();

            for (int i = 0; i < mapEntityList.Count; i++)
            {
                if (mapEntityList[i].Submarine != sub)
                {
                    continue;
                }

                if (mapEntityList[i] is LinkedSubmarine)
                {
                    linkedSubs.Add((LinkedSubmarine)mapEntityList[i]);
                    continue;
                }

                mapEntityList[i].OnMapLoaded();
            }

            if (sub != null)
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            foreach (LinkedSubmarine linkedSub in linkedSubs)
            {
                linkedSub.OnMapLoaded();
            }
        }
Пример #8
0
        private bool CheckCharacterCollision(Contact contact, Character character)
        {
            //characters that can't enter the sub always collide regardless of gaps
            if (!character.AnimController.CanEnterSubmarine)
            {
                return(true);
            }
            if (character.Submarine != null)
            {
                return(false);
            }

            contact.GetWorldManifold(out Vector2 contactNormal, out FixedArray2 <Vector2> points);

            Vector2 normalizedVel = character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
                                    Vector2.Zero : Vector2.Normalize(character.AnimController.Collider.LinearVelocity);

            //try to find the hull right next to the contact point
            Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - contactNormal * 0.1f);
            Hull    newHull   = Hull.FindHull(targetPos, null);

            //not found, try searching a bit further
            if (newHull == null)
            {
                targetPos = ConvertUnits.ToDisplayUnits(points[0] - contactNormal);
                newHull   = Hull.FindHull(targetPos, null);
            }
            //still not found, try searching in the direction the character is heading to
            if (newHull == null)
            {
                targetPos = ConvertUnits.ToDisplayUnits(points[0] + normalizedVel);
                newHull   = Hull.FindHull(targetPos, null);
            }

            var gaps = newHull?.ConnectedGaps ?? Gap.GapList.Where(g => g.Submarine == submarine);

            targetPos = character.WorldPosition;
            Gap adjacentGap = Gap.FindAdjacent(gaps, targetPos, 500.0f);

            if (adjacentGap == null)
            {
                return(true);
            }

            if (newHull != null)
            {
                CoroutineManager.Invoke(() =>
                                        character.AnimController.FindHull(newHull.WorldPosition, true));
            }

            return(false);
        }
Пример #9
0
        public override void Move(Vector2 amount)
        {
            rect.X += (int)amount.X;
            rect.Y += (int)amount.Y;

            if (Submarine == null || !Submarine.Loading)
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            surface  = rect.Y - rect.Height + WaterVolume / rect.Width;
            Pressure = surface;
        }
Пример #10
0
        private bool HandleLimbCollision(Contact contact, Limb limb)
        {
            if (limb.character.Submarine != null)
            {
                return(false);
            }

            Vector2 normal2;
            FixedArray2 <Vector2> points;

            contact.GetWorldManifold(out normal2, out points);

            Vector2 normalizedVel = limb.character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
                                    Vector2.Zero : Vector2.Normalize(limb.character.AnimController.Collider.LinearVelocity);

            Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - normal2);

            Hull newHull = Hull.FindHull(targetPos, null);

            if (newHull == null)
            {
                targetPos = ConvertUnits.ToDisplayUnits(points[0] + normalizedVel);

                newHull = Hull.FindHull(targetPos, null);

                if (newHull == null)
                {
                    return(true);
                }
            }

            var gaps = newHull.ConnectedGaps;

            targetPos = limb.character.WorldPosition;

            Gap adjacentGap = Gap.FindAdjacent(gaps, targetPos, 200.0f);

            if (adjacentGap == null)
            {
                return(true);
            }

            var ragdoll = limb.character.AnimController;

            ragdoll.FindHull(newHull.WorldPosition, true);

            return(false);
        }
Пример #11
0
        public Hull(MapEntityPrefab prefab, Rectangle rectangle, Submarine submarine)
            : base(prefab, submarine)
        {
            rect = rectangle;

            OxygenPercentage = 100.0f;

            FireSources = new List <FireSource>();

            properties = SerializableProperty.GetProperties(this);

            int arraySize = (int)Math.Ceiling((float)rectangle.Width / WaveWidth + 1);

            waveY   = new float[arraySize];
            waveVel = new float[arraySize];

            leftDelta  = new float[arraySize];
            rightDelta = new float[arraySize];

            surface = rect.Y - rect.Height;

            if (submarine?.Info != null && !submarine.Info.IsWreck)
            {
                aiTarget = new AITarget(this)
                {
                    MinSightRange = 2000,
                    MaxSightRange = 5000,
                    MaxSoundRange = 5000,
                    SoundRange    = 0
                };
            }

            hullList.Add(this);

            if (submarine == null || !submarine.Loading)
            {
                Item.UpdateHulls();
                Gap.UpdateHulls();
            }

            WaterVolume = 0.0f;

            InsertToList();

            DebugConsole.Log("Created hull (" + ID + ")");
        }
Пример #12
0
        public static void Load(XElement element, Submarine submarine)
        {
            Rectangle rect = Rectangle.Empty;

            if (element.Attribute("rect") != null)
            {
                string   rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0");
                string[] rectValues = rectString.Split(',');

                rect = new Rectangle(
                    int.Parse(rectValues[0]),
                    int.Parse(rectValues[1]),
                    int.Parse(rectValues[2]),
                    int.Parse(rectValues[3]));
            }
            else
            {
                rect = new Rectangle(
                    int.Parse(element.Attribute("x").Value),
                    int.Parse(element.Attribute("y").Value),
                    int.Parse(element.Attribute("width").Value),
                    int.Parse(element.Attribute("height").Value));
            }

            bool isHorizontal = rect.Height > rect.Width;

            var horizontalAttribute = element.Attribute("horizontal");

            if (horizontalAttribute != null)
            {
                isHorizontal = horizontalAttribute.Value.ToString() == "true";
            }

            Gap g = new Gap(rect, isHorizontal, submarine);

            g.ID = (ushort)int.Parse(element.Attribute("ID").Value);

            g.linkedToID = new List <ushort>();
            //int i = 0;
            //while (element.Attribute("linkedto" + i) != null)
            //{
            //    g.linkedToID.Add(int.Parse(element.Attribute("linkedto" + i).Value));
            //    i += 1;
            //}
        }
Пример #13
0
        private bool CheckCharacterCollision(Contact contact, Character character)
        {
            //characters that can't enter the sub always collide regardless of gaps
            if (!character.AnimController.CanEnterSubmarine)
            {
                return(true);
            }
            if (character.Submarine != null)
            {
                return(false);
            }

            contact.GetWorldManifold(out Vector2 contactNormal, out FixedArray2 <Vector2> points);

            Vector2 normalizedVel = character.AnimController.Collider.LinearVelocity == Vector2.Zero ?
                                    Vector2.Zero : Vector2.Normalize(character.AnimController.Collider.LinearVelocity);

            Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - contactNormal);
            Hull    newHull   = Hull.FindHull(targetPos, null);

            if (newHull == null)
            {
                targetPos = ConvertUnits.ToDisplayUnits(points[0] + normalizedVel);
                newHull   = Hull.FindHull(targetPos, null);
            }

            var gaps = newHull?.ConnectedGaps ?? Gap.GapList.Where(g => g.Submarine == submarine);

            targetPos = character.WorldPosition;
            Gap adjacentGap = Gap.FindAdjacent(gaps, targetPos, 200.0f);

            if (adjacentGap == null)
            {
                return(true);
            }

            if (newHull != null)
            {
                character.AnimController.FindHull(newHull.WorldPosition, true);
            }

            return(false);
        }
Пример #14
0
        private float GetGapFixPriority(Gap gap)
        {
            if (gap == null)
            {
                return(0.0f);
            }

            //larger gap -> higher priority
            float gapPriority = (gap.IsHorizontal ? gap.Rect.Width : gap.Rect.Height) * gap.Open;

            //prioritize gaps that are close
            gapPriority /= Math.Max(Vector2.Distance(character.WorldPosition, gap.WorldPosition), 1.0f);

            //gaps to outside are much higher priority
            if (!gap.IsRoomToRoom)
            {
                gapPriority *= 10.0f;
            }

            return(gapPriority);
        }
Пример #15
0
 private bool CanFitThroughGap(Gap gap, float minWidth) => gap.IsHorizontal ? gap.RectHeight > minWidth : gap.RectWidth > minWidth;
Пример #16
0
 public AIObjectiveFixLeak(Gap leak, Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1, bool ignoreSeverityAndDistance = false) : base(character, objectiveManager, priorityModifier)
 {
     Leak = leak;
     IgnoreSeverityAndDistance = ignoreSeverityAndDistance;
 }
Пример #17
0
 public AIObjectiveFixLeak(Gap leak, Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier)
 {
     Leak = leak;
 }
Пример #18
0
 public WayPoint(Vector2 position, SpawnType spawnType, Submarine submarine, Gap gap = null)
     : this(new Rectangle((int)position.X - 3, (int)position.Y + 3, 6, 6), submarine)
 {
     this.spawnType = spawnType;
     ConnectedGap   = gap;
 }
Пример #19
0
        public void FlipX(List <Submarine> parents = null)
        {
            if (parents == null)
            {
                parents = new List <Submarine>();
            }
            parents.Add(this);

            flippedX = !flippedX;

            Item.UpdateHulls();

            List <Item> bodyItems = Item.ItemList.FindAll(it => it.Submarine == this && it.body != null);

            List <MapEntity> subEntities = MapEntity.mapEntityList.FindAll(me => me.Submarine == this);

            foreach (MapEntity e in subEntities)
            {
                if (e.MoveWithLevel || e is Item)
                {
                    continue;
                }

                if (e is LinkedSubmarine)
                {
                    Submarine sub = ((LinkedSubmarine)e).Sub;
                    if (!parents.Contains(sub))
                    {
                        Vector2 relative1 = sub.SubBody.Position - SubBody.Position;
                        relative1.X = -relative1.X;
                        sub.SetPosition(relative1 + SubBody.Position);
                        sub.FlipX(parents);
                    }
                }
                else
                {
                    e.FlipX();
                }
            }

            foreach (MapEntity mapEntity in subEntities)
            {
                mapEntity.Move(-HiddenSubPosition);
            }

            Vector2 pos = new Vector2(subBody.Position.X, subBody.Position.Y);

            subBody.Body.Remove();
            subBody = new SubmarineBody(this);
            SetPosition(pos);

            if (entityGrid != null)
            {
                Hull.EntityGrids.Remove(entityGrid);
                entityGrid = null;
            }
            entityGrid = Hull.GenerateEntityGrid(this);

            foreach (MapEntity mapEntity in subEntities)
            {
                mapEntity.Move(HiddenSubPosition);
            }

            foreach (Item item in Item.ItemList)
            {
                if (bodyItems.Contains(item))
                {
                    item.Submarine = this;
                    if (Position == Vector2.Zero)
                    {
                        item.Move(-HiddenSubPosition);
                    }
                }
                else if (item.Submarine != this)
                {
                    continue;
                }

                item.FlipX();
            }

            Item.UpdateHulls();
            Gap.UpdateHulls();
        }
Пример #20
0
 public AIObjectiveFixLeak(Gap leak, Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1, bool isPriority = false) : base(character, objectiveManager, priorityModifier)
 {
     Leak            = leak;
     this.isPriority = isPriority;
 }
Пример #21
0
 public AIObjectiveFixLeak(Gap leak, Character character)
     : base(character, "")
 {
     this.leak = leak;
 }