예제 #1
0
        protected virtual Vector2 DoSteeringAvoid(float deltaTime, float lookAheadDistance, float weight, Vector2?heading = null)
        {
            if (steering == Vector2.Zero || host.Steering == Vector2.Zero)
            {
                return(Vector2.Zero);
            }

            float maxDistance = lookAheadDistance;

            if (Timing.TotalTime >= lastRayCastTime + RayCastInterval)
            {
                avoidRayCastHit   = false;
                AvoidLookAheadPos = host.SimPosition + Vector2.Normalize(host.Steering) * maxDistance;
                lastRayCastTime   = (float)Timing.TotalTime;
                Body closestBody = Submarine.CheckVisibility(host.SimPosition, AvoidLookAheadPos);
                if (closestBody != null)
                {
                    avoidRayCastHit         = true;
                    AvoidRayCastHitPosition = Submarine.LastPickedPosition;
                    AvoidDir = Submarine.LastPickedNormal;
                    //add a bit of randomness
                    AvoidDir = MathUtils.RotatePoint(AvoidDir, Rand.Range(-0.15f, 0.15f));
                    //wait a bit longer for the next raycast
                    lastRayCastTime += RayCastInterval;
                }
            }

            if (AvoidDir.LengthSquared() < 0.0001f)
            {
                return(Vector2.Zero);
            }

            //if raycast hit nothing, lerp avoid dir to zero
            if (!avoidRayCastHit)
            {
                AvoidDir -= Vector2.Normalize(AvoidDir) * deltaTime * 0.5f;
            }

            Vector2 diff = AvoidRayCastHitPosition - host.SimPosition;
            float   dist = diff.Length();

            //> 0 when heading in the same direction as the obstacle, < 0 when away from it
            float dot = MathHelper.Clamp(Vector2.Dot(diff / dist, host.Steering), 0.0f, 1.0f);

            if (dot < 0)
            {
                return(Vector2.Zero);
            }

            return(AvoidDir * dot * weight * MathHelper.Clamp(1.0f - dist / lookAheadDistance, 0.0f, 1.0f));
        }
예제 #2
0
        private void BakeItemComponents(
            ItemPrefab prefab,
            Rectangle rect, Color color,
            float scale, float rotation, float depth,
            out bool overrideSprite)
        {
            overrideSprite = false;

            foreach (var subElement in prefab.ConfigElement.Elements())
            {
                switch (subElement.Name.LocalName.ToLowerInvariant())
                {
                case "turret":
                    Sprite barrelSprite = null;
                    Sprite railSprite   = null;
                    foreach (XElement turretSubElem in subElement.Elements())
                    {
                        switch (turretSubElem.Name.ToString().ToLowerInvariant())
                        {
                        case "barrelsprite":
                            barrelSprite = new Sprite(turretSubElem);
                            break;

                        case "railsprite":
                            railSprite = new Sprite(turretSubElem);
                            break;
                        }
                    }

                    Vector2 barrelPos            = subElement.GetAttributeVector2("barrelpos", Vector2.Zero);
                    Vector2 relativeBarrelPos    = barrelPos * prefab.Scale - new Vector2(rect.Width / 2, rect.Height / 2);
                    var     transformedBarrelPos = MathUtils.RotatePoint(
                        relativeBarrelPos,
                        MathHelper.ToRadians(rotation));

                    float   relativeScale = scale / prefab.Scale;
                    Vector2 drawPos       = new Vector2(rect.X + rect.Width * relativeScale / 2 + transformedBarrelPos.X * relativeScale, rect.Y - rect.Height * relativeScale / 2 - transformedBarrelPos.Y * relativeScale);
                    drawPos.Y = -drawPos.Y;

                    railSprite?.Draw(spriteRecorder,
                                     drawPos,
                                     color,
                                     rotation + MathHelper.PiOver2, scale,
                                     SpriteEffects.None, depth + (railSprite.Depth - prefab.sprite.Depth));

                    barrelSprite?.Draw(spriteRecorder,
                                       drawPos,
                                       color,
                                       rotation + MathHelper.PiOver2, scale,
                                       SpriteEffects.None, depth + (barrelSprite.Depth - prefab.sprite.Depth));

                    break;

                case "door":
                    doors.Add(new Door(rect));

                    var doorSpriteElem = subElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("sprite", StringComparison.OrdinalIgnoreCase));
                    if (doorSpriteElem != null)
                    {
                        string  texturePath = doorSpriteElem.GetAttributeString("texture", "");
                        Vector2 pos         = rect.Location.ToVector2() * new Vector2(1f, -1f);
                        if (subElement.GetAttributeBool("horizontal", false))
                        {
                            pos.Y += (float)rect.Height * 0.5f;
                        }
                        else
                        {
                            pos.X += (float)rect.Width * 0.5f;
                        }
                        Sprite doorSprite = new Sprite(doorSpriteElem, texturePath.Contains("/") ? "" : Path.GetDirectoryName(prefab.FilePath));
                        spriteRecorder.Draw(doorSprite.Texture, pos,
                                            new Rectangle((int)doorSprite.SourceRect.X,
                                                          (int)doorSprite.SourceRect.Y,
                                                          (int)doorSprite.size.X, (int)doorSprite.size.Y),
                                            color, 0.0f, doorSprite.Origin, new Vector2(scale), SpriteEffects.None, doorSprite.Depth);
                    }
                    break;

                case "ladder":
                    var backgroundSprElem = subElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("backgroundsprite", StringComparison.OrdinalIgnoreCase));
                    if (backgroundSprElem != null)
                    {
                        Sprite backgroundSprite = new Sprite(backgroundSprElem);
                        backgroundSprite.DrawTiled(spriteRecorder,
                                                   new Vector2(rect.Left, -rect.Top) - backgroundSprite.Origin * scale,
                                                   new Vector2(backgroundSprite.size.X * scale, rect.Height), color: color,
                                                   textureScale: Vector2.One * scale,
                                                   depth: depth + 0.1f);
                    }
                    break;
                }
            }
        }