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(); }
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); }
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); } } }
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(); } }
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); } } }
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(); } }
/// <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(); } }
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); }
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; }
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); }
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 + ")"); }
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; //} }
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); }
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); }
private bool CanFitThroughGap(Gap gap, float minWidth) => gap.IsHorizontal ? gap.RectHeight > minWidth : gap.RectWidth > minWidth;
public AIObjectiveFixLeak(Gap leak, Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1, bool ignoreSeverityAndDistance = false) : base(character, objectiveManager, priorityModifier) { Leak = leak; IgnoreSeverityAndDistance = ignoreSeverityAndDistance; }
public AIObjectiveFixLeak(Gap leak, Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier) { Leak = leak; }
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; }
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(); }
public AIObjectiveFixLeak(Gap leak, Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1, bool isPriority = false) : base(character, objectiveManager, priorityModifier) { Leak = leak; this.isPriority = isPriority; }
public AIObjectiveFixLeak(Gap leak, Character character) : base(character, "") { this.leak = leak; }