Exemple #1
0
        public List <T> BoxCrossing <T>(int x1, int y1, int x2, int y2)
        {
            Dictionary <object, bool> r = new Dictionary <object, bool>();
            List <T>      result        = new List <T>();
            List <object> res           = tx.Find(x1, x2, (o) =>
            {
                IntLine l = o as IntLine;
                if (l.y1 < y1 && l.y2 < y1)
                {
                    return(false);
                }
                if (l.y1 > y2 && l.y2 > y2)
                {
                    return(false);
                }
                if (r.ContainsKey(l.obj))
                {
                    return(false);
                }
                if (!LineVisible(l.x1, l.y1, l.x2, l.y2, x1, y1, x2, y2))
                {
                    return(false);
                }
                r[l.obj] = true;

                if (l.obj is T)
                {
                    result.Add((T)l.obj);
                }
                return(true);
            });

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Returns parameter on l1
        /// </summary>
        /// <param name="l1"></param>
        /// <param name="l2"></param>
        /// <returns></returns>
        double SegmentSegment(IntLine l1, IntLine l2)
        {
            double denom = l1.x1 * (l2.y2 - l2.y1) + l1.x2 * (l2.y1 - l2.y2) + l2.x2 * (l1.y2 - l1.y1) + l2.x1 * (l1.y1 - l1.y2);

            if (denom != 0.0)
            {
                return((l1.x1 * (l2.y2 - l2.y1) + l2.x1 * (l1.y1 - l2.y2) + l2.x2 * (l2.y1 - l1.y1)) / denom);
            }

            //handle parallel lines
            double dist1 = MathUtil.Hypot(l1.x1 - l2.x1, l1.y1 - l2.y1);
            double dist2 = MathUtil.Hypot(l1.x1 - l2.x2, l1.y1 - l2.y2);
            double l     = MathUtil.Hypot(l1.x1 - l1.x2, l1.y1 - l1.y2);

            if (l < 1e-3)
            {
                return(0.0);
            }
            if (dist1 < dist2)
            {
                return(dist1 / l);
            }
            else
            {
                return(dist1 / l);
            }
        }
Exemple #3
0
        public List <T> BoxWindow <T>(int x1, int y1, int x2, int y2)
        {
            Dictionary <object, int> r = new Dictionary <object, int>();
            List <T>      result       = new List <T>();
            List <object> res          = tx.Find(x1, x2, (o) =>
            {
                IntLine l = o as IntLine;
                if (l.x1 < x1 || l.x1 > x2 || l.x2 < x1 || l.x2 > x2 || l.y1 < y1 || l.y1 > y2 || l.y2 < y1 || l.y2 > y2)
                {
                    return(false);
                }
                if (!r.ContainsKey(l.obj))
                {
                    r[l.obj] = 0;
                }
                r[l.obj] += 1;
                if (r[l.obj] == objects[l.obj] && l.obj is T)
                {
                    result.Add((T)l.obj);
                }
                return(true);
            });

            return(result);
        }
Exemple #4
0
        public static IEnumerator LineSurface(Emplacement place, OptionEffect options)
        {
            Vector3i    shape         = options.OptionShape.shape; /// (avancée, hauteur, largeur)
            Vector3i    above         = Vectors.Up;
            Vector3i    pos           = place.ipos;
            Vector3i    offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0);
            bool        reverse       = options.OptionShape.reverse != "";
            float       pace          = options.OptionShape.pace;
            bool        collapse_once = options.OptionShape.reverse == "once";
            Block       air           = Block.GetBlockByName("air", false);
            Block       blk           = options.OptionBlock.block;
            BlockSetter setter        = new BlockSetter(options.OptionBlock);

            /// IntLine traj = new IntLine(place.ipos, Vectors.Float.UnitX);
            IntLine traj = new IntLine(place.ipos, Emplacement.Truncate(place.direction, true, true));

            for (int avance = 0; avance < shape.x; avance++)
            {
                Vector3i where = traj.Get(avance);
                Debug.Log("LineSurface " + avance.ToString());
                IntLine orth = new IntLine(Vectors.ToFloat(where), Vectors.Float.UnitZ);
                foreach (int ligne in LR(shape.z))
                {
                    Vector3i at = orth.Get(ligne);
                    //Debug.Log("Line Surface inner " + p.ToString());
                    at = Geo3D.Surface(at); // I don't need surface before orthogonal ... surface made after
                    setter.Apply(at + above + offsetSurface);
                }
                setter.Push();
                yield return(new WaitForEndOfFrame());
            }
        }
Exemple #5
0
 bool Intersect(IntLine l, List <object> lines)
 {
     foreach (IntLine l2 in lines)
     {
         if (Intersect(l.x1, l.y1, l.x2, l.y2, l2.x1, l2.y1, l2.x2, l2.y2))
         {
             return(true);
         }
     }
     return(false);
 }
Exemple #6
0
        public static IEnumerator TrapLine(Entity player, Emplacement place, OptionEffect options)
        {
            /// TODO: recoder ca avec rift
            Vector3i offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0);

            Vector3i pos = place.ipos;
            // size = E/W=largeur, hauteur, N/S profondeur (portee)
            Vector3i size           = options.OptionShape.shape;
            Vector3  base_direction = Emplacement.Truncate(place.direction, true, true);

            float pace = 0.1f;                               // TODO pace in option
            Block air  = Block.GetBlockByName("air", false); // The air instance could prolly be shared ...
            // Block blk = options.OptionBlock.block;

            int portee = 100;

            BlockSetter setter    = new BlockSetter(options.OptionBlock);
            BlockSetter setterAir = new BlockSetter(options.OptionBlock.Copy());

            setterAir.options.block = air;

            Vector3 posf = Vectors.ToFloat(pos + offsetSurface);
            // string[] random_blocks = new string[]{"trapSpikesWoodDmg0", "trapSpikesWoodDmg1", "trapSpikesWoodDmg2"};
            // Block[] random_blocks = options.OptionBlock.blocks;
            Vector3i start = Geo3D.Surface(place.ipos);

            for (int k = 0; k < 10; k++)
            {
                Vector3 direction = base_direction + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.1f);
                direction.y = 0;
                direction   = direction.normalized;
                // IntLine traj = new IntLine(start, direction); //east
                IEnumerable <Vector3i> segment = IntLine.Segment(Vectors.ToFloat(start), direction, 1, 10); // skip 0 intersecting with the previous
                foreach (Vector3i where in segment)
                {
                    Vector3i Swhere = Geo3D.Surface(where);
                    // randomisation : "trapSpikesWoodDmg0-2"
                    // string rdm = random_blocks[(int) Math.Floor(GameManager.Instance.World.GetGameRandom().RandomFloat*3)];
                    // setter.options.block = Block.GetBlockByName(rdm, false);
                    // Block rdm =

                    setter.Apply(Swhere + Vectors.Up);
                    setter.Push();
                    start = Swhere;
                    yield return(new WaitForEndOfFrame());
                }
                yield return(new WaitForSeconds(0.5f));
            }
        }
Exemple #7
0
        /*
         *
         * Options:
         * - ground (water, traps)
         * - recursion
         * - size / depth (puis avant)
         * - other content : Z, animal, torch, lights ...
         *
         */


        public static IEnumerator Rift(EntityPlayer player, Emplacement place, OptionEffect options)
        {
            /*
             * Laisse des blocks tomber au dessus ? just changed  erase="yes"
             * (longueur 1, hauteur (profonfeur), replicats)
             */
            EntityPlayerLocal epl = player as EntityPlayerLocal;

            epl.cameraTransform.SendMessage("ShakeBig");
            yield return(new WaitForSeconds(1f));

            BlockSetter setter    = new BlockSetter(options.OptionBlock);
            Vector3     direction = Vectors.Copy(place.direction);

            direction.y = 0;
            direction   = direction.normalized;

            Vector3i start = Geo3D.Surface(place.ipos);

            for (int k = 0; k < options.OptionShape.shape.z; k++)
            {
                Vector3 kdirection = direction + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.2f);
                // IntLine traj = new IntLine(start, direction); //east
                IEnumerable <Vector3i> segment = IntLine.Segment(Vectors.ToFloat(start), kdirection, 0, options.OptionShape.shape.x);
                Vector3i prev    = new Vector3i();
                bool     hasprev = false;
                foreach (Vector3i where in segment)
                {
                    Vector3i Swhere = Geo3D.Surface(where);
                    setter.Apply(Swhere);
                    if (hasprev)
                    {
                        for (int creuse = 1; creuse < options.OptionShape.shape.y; creuse++)
                        {
                            setter.Apply(prev + creuse * Vectors.Down);
                        }
                    }
                    setter.Push();
                    start = Swhere;
                    yield return(new WaitForEndOfFrame());

                    hasprev = true; prev = Swhere;
                }
                yield return(new WaitForSeconds(1f));
            }
        }
Exemple #8
0
 bool Outside(IntLine l, int x1, int y1, int x2, int y2)
 {
     if (l.x1 < x1 && l.x2 < x1)
     {
         return(true);
     }
     if (l.y1 < y1 && l.y2 < y1)
     {
         return(true);
     }
     if (l.x1 > x2 && l.x2 > x2)
     {
         return(true);
     }
     if (l.y1 > y2 && l.y2 > y2)
     {
         return(true);
     }
     return(false);
 }
Exemple #9
0
        public static IEnumerator Rift(EntityPlayer player, Emplacement place, OptionEffect options)
        {
            /*
             * Laisse des blocks tomber au dessus ? just changed  erase="yes"
             */
            Vector3i offsetSurface = new Vector3i(0, options.OptionShape.offsetSurface, 0);

            EntityPlayerLocal epl = player as EntityPlayerLocal;

            epl.cameraTransform.SendMessage("ShakeBig");
            yield return(new WaitForSeconds(1f));

            // Vector3i shape = options.OptionShape.shape; /// (longueur, hauteur, largeur)
            BlockSetter setter = new BlockSetter(options.OptionBlock);
            Vector3i    start  = Geo3D.Surface(place.ipos);

            for (int k = 0; k < 3; k++)
            {
                // Vector3 direction = Vectors.Float.UnitX + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.1f);
                Vector3 direction = place.direction + Vectors.Float.Randomize(GameManager.Instance.World.GetGameRandom(), 0.1f);
                direction.y = 0;
                direction   = direction.normalized;
                // IntLine traj = new IntLine(start, direction); //east
                IEnumerable <Vector3i> segment = IntLine.Segment(Vectors.ToFloat(start), direction, 1, 5); // skip 0 intersecting with the previous
                foreach (Vector3i where in segment)
                {
                    Vector3i Swhere = Geo3D.Surface(where) + offsetSurface;
                    setter.Apply(Swhere);
                    setter.Apply(Swhere + Vectors.Up);
                    setter.Apply(Swhere + 2 * Vectors.Up);
                    setter.Push();
                    start = Swhere;
                    yield return(new WaitForEndOfFrame());
                }
                yield return(new WaitForSeconds(1f));
            }
        }
Exemple #10
0
        public static IEnumerator Cave(EntityPlayer player, Emplacement place, OptionEffect options)
        {
            /// TODO: enumérer les colonnes et s'arreter à surface
            BlockSetter setter = new BlockSetter(options.OptionBlock);
            Vector3i    shape  = options.OptionShape.shape;
            Vector3i    start  = Geo3D.Surface(place.ipos);

            int     depth     = shape.y;
            Vector3 direction = Vectors.Float.UnitY; // cannot use negative, so positive and get(_k) !
            IntLine colonne   = new IntLine(Vectors.ToFloat(start), direction);

            // Debug.Log(String.Format("Cave: pos={0} start={1} dir={2} ground={3}", place.position, start, direction, ground));

            for (int d = 0; d < depth; d++)
            {
                // Debug.Log(String.Format("cave {0} {1}", d, setter));
                if (options.OptionShape.ground != "" && d == depth - 1)
                {
                    setter.options.block = Block.GetBlockByName(options.OptionShape.ground, false);
                }
                Vector3i where = colonne.Get(-d);
                Vector3i dxy = new Vector3i(0, 0, 0);
                foreach (int p in SdtdUtils.EffectsGround.LR(shape.x))
                {
                    foreach (int q in SdtdUtils.EffectsGround.LR(shape.z))
                    {
                        dxy.x = p; dxy.z = q;
                        Printer.Log(20, "Cave Apply (d,p) =", d, p, "where, dxy=", where, dxy);
                        setter.Apply(where + dxy);
                    }
                }
                Printer.FLog(20, "cave Push {0} {1}", d, where);
                setter.Push();
            }
            yield return(new WaitForEndOfFrame());
        }
Exemple #11
0
 bool Intersect(IntLine l1, IntLine l2)
 {
     return(Intersect(l1.x1, l1.y1, l1.x2, l1.y2, l2.x1, l2.y1, l2.x2, l2.y2));
 }
Exemple #12
0
        public List <T> Fence <T>(List <Point2i> pnts, Func <int, int, int, int, int, int> plot = null)
        {
            Dictionary <object, bool> r = new Dictionary <object, bool>();
            List <T> result             = new List <T>();
            int      cnt = pnts.Count;

            for (int i = 0; i < cnt - 1; i++)
            {
                IntLine seg = new IntLine(pnts[i].X, pnts[i].Y, pnts[(i + 1) % cnt].X, pnts[(i + 1) % cnt].Y, null);
                if (plot != null)
                {
                    plot(seg.x1, seg.y1, seg.x2, seg.y2, 3);
                }
                int           x1  = Math.Min(seg.x1, seg.x2);
                int           y1  = Math.Min(seg.y1, seg.y2);
                int           x2  = Math.Max(seg.x1, seg.x2);
                int           y2  = Math.Max(seg.y1, seg.y2);
                List <object> res = tx.Find(seg.x1, seg.x2, (o) =>
                {
                    IntLine l = o as IntLine;
                    if (Outside(l, x1, y1, x2, y2))
                    {
                        return(false);
                    }
                    if (r.ContainsKey(l.obj))
                    {
                        return(false);
                    }
                    if (Intersect(l, seg))
                    {
                        r[l.obj] = true;
                        return(true);
                    }
                    return(false);
                });
                if (res.Count <= 0)
                {
                    continue;
                }
                else if (res.Count == 1)
                {
                    object o = ((IntLine)res[0]).obj;
                    if (o is T)
                    {
                        result.Add((T)o);
                    }
                }
                else
                {
                    // Loop res and calc proper intersections and sort then add
                    List <KeyValuePair <IntLine, double> > ints = new List <KeyValuePair <IntLine, double> >();
                    foreach (IntLine l in res)
                    {
                        double s = SegmentSegment(seg, l);
                        ints.Add(new KeyValuePair <IntLine, double>(l, s));
                    }
                    ints.Sort((a, b) => { return(a.Value.CompareTo(b.Value)); });
                    foreach (var l in ints)
                    {
                        if (l.Key.obj is T)
                        {
                            result.Add((T)(l.Key.obj));
                        }
                    }
                }
            }
            if (plot != null)
            {
                foreach (IntLine l in tx)
                {
                    plot(l.x1, l.y1, l.x2, l.y2, r.ContainsKey(l.obj)?5:1);
                }
            }
            return(result);
        }
Exemple #13
0
        public List <T> PolyWindow <T>(List <Point2i> pnts)
        {
            Dictionary <object, int> r = new Dictionary <object, int>();
            List <T> result            = new List <T>();

            // Bounding box
            int x1 = int.MaxValue;
            int y1 = int.MaxValue;
            int x2 = int.MinValue;
            int y2 = int.MinValue;

            // First create an Y-interval tree for fast inside/intersection checking
            IntervalTreeInt ins = new IntervalTreeInt();
            int             cnt = pnts.Count;

            for (int i = 0; i < cnt; i++)
            {
                IntLine l = new IntLine(pnts[i].X, pnts[i].Y, pnts[(i + 1) % cnt].X, pnts[(i + 1) % cnt].Y, null);
                ins.Add(l, Math.Min(l.y1, l.y2), Math.Max(l.y1, l.y2));
                // Calc bbox
                if (pnts[i].X < x1)
                {
                    x1 = pnts[i].X;
                }
                if (pnts[i].X > x2)
                {
                    x2 = pnts[i].X;
                }
                if (pnts[i].Y < y1)
                {
                    y1 = pnts[i].Y;
                }
                if (pnts[i].Y > y2)
                {
                    y2 = pnts[i].Y;
                }
            }

            List <object> res = tx.Find(x1, x2, (o) =>
            {
                IntLine l = o as IntLine;
                if (l.y1 < y1 && l.y2 < y1)
                {
                    return(false);
                }
                if (l.y1 > y2 && l.y2 > y2)
                {
                    return(false);
                }
                // Collect all candidates from poly
                List <object> candidates = ins.Find(l.y1, l.y2, null);
                if (Inside(l.x1, l.y1, candidates) && Inside(l.x2, l.y2, candidates) && !Intersect(l, candidates))
                {
                    if (!r.ContainsKey(l.obj))
                    {
                        r[l.obj] = 0;
                    }
                    r[l.obj] += 1;
                    if (r[l.obj] == objects[l.obj] && l.obj is T)
                    {
                        result.Add((T)l.obj);
                    }
                    return(true);
                }
                return(false);
            });

            return(result);
        }