//mxd
        private void UpdateGldefsLight()
        {
            DynamicLightData light = General.Map.Data.GldefsEntries[thing.Type];

            GZGeneral.LightData ld = light.Type;

            //apply settings
            lightColor = new Color4((float)ld.LightRenderStyle / 100.0f, light.Color.Red, light.Color.Green, light.Color.Blue);
            Vector2D o = new Vector2D(light.Offset.X, light.Offset.Y).GetRotated(thing.Angle - Angle2D.PIHALF);

            lightOffset = new Vector3(o.x, o.y, light.Offset.Z);
            lightType   = light.Type;

            if (ld.LightModifier == GZGeneral.LightModifier.SECTOR)
            {
                lightPrimaryRadius = light.Interval * thing.Sector.Brightness / 5.0f;
            }
            else
            {
                lightPrimaryRadius   = light.PrimaryRadius;
                lightSecondaryRadius = light.SecondaryRadius;
            }

            lightInterval = light.Interval;
            UpdateLightRadius(lightInterval);
        }
        //mxd
        protected void CheckLightState()
        {
            //mxd. Check if thing is light
            if (thing.DynamicLightType != null)
            {
                isGldefsLight = false;
                lightInterval = -1;
                UpdateLight();
            }
            //check if we have light from GLDEFS
            else if (General.Map.Data.GldefsEntries.ContainsKey(thing.Type))
            {
                isGldefsLight = true;
                UpdateGldefsLight();
                UpdateBoundingBox(lightRadius, lightRadius * 2);
            }
            else
            {
                UpdateBoundingBox((int)thing.Size, thingheight);

                lightType            = null;
                lightRadius          = -1;
                lightSpotRadius1     = lightSpotRadius2 = -1;
                lightPrimaryRadius   = -1;
                lightSecondaryRadius = -1;
                lightInterval        = -1;
                isGldefsLight        = false;
            }
        }
Beispiel #3
0
        // This updates the settings from configuration
        public void UpdateConfiguration()
        {
            // Lookup settings
            ThingTypeInfo ti = General.Map.Data.GetThingInfo(type);

            // Apply size
            dynamiclighttype = GZGeneral.GetGZLightTypeByClass(ti.Actor);
            if (dynamiclighttype == null)
            {
                dynamiclighttype = ti.DynamicLightType;
            }
            //General.ErrorLogger.Add(ErrorType.Warning, string.Format("thing dynamiclighttype is {0}; class is {1}", dynamiclighttype, ti.Actor.ClassName));
            size        = ti.Radius;
            rendersize  = ti.RenderRadius;
            height      = ti.Height;        //mxd
            fixedsize   = ti.FixedSize;
            spritescale = ti.SpriteScale;   //mxd

            //mxd. Apply radius and height overrides?
            for (int i = 0; i < ti.Args.Length; i++)
            {
                if (ti.Args[i] == null)
                {
                    continue;
                }
                if (ti.Args[i].Type == (int)UniversalType.ThingRadius && args[i] > 0)
                {
                    size = args[i];
                }
                else if (ti.Args[i].Type == (int)UniversalType.ThingHeight && args[i] > 0)
                {
                    height = args[i];
                }
            }

            // Color valid?
            if ((ti.Color >= 0) && (ti.Color < ColorCollection.NUM_THING_COLORS))
            {
                // Apply color
                color = General.Colors.Colors[ti.Color + ColorCollection.THING_COLORS_OFFSET];
            }
            else
            {
                // Unknown thing color
                color = General.Colors.Colors[ColorCollection.THING_COLORS_OFFSET];
            }

            directional = ti.Arrow;      //mxd
            rendermode  = ti.RenderMode; //mxd
            rollsprite  = ti.RollSprite; //mxd
            UpdateCache();               //mxd
        }
Beispiel #4
0
        // Constructor
        internal ThingTypeInfo(int index, ThingTypeInfo other)
        {
            // Initialize
            this.index     = index;
            this.category  = other.category;
            this.title     = other.title;
            this.actor     = other.actor;
            this.classname = other.classname;             //mxd
            this.isknown   = true;
            this.args      = new ArgumentInfo[Linedef.NUM_ARGS];
            for (int i = 0; i < Linedef.NUM_ARGS; i++)
            {
                this.args[i] = other.args[i];
            }

            // Copy properties
            this.sprite      = other.sprite;
            this.spriteframe = new SpriteFrameInfo[other.spriteframe.Length]; //mxd
            other.spriteframe.CopyTo(this.spriteframe, 0);                    //mxd
            this.color           = other.color;
            this.alpha           = other.alpha;                               //mxd
            this.alphabyte       = other.alphabyte;                           //mxd
            this.renderstyle     = other.renderstyle;                         //mxd
            this.bright          = other.bright;                              //mxd
            this.arrow           = other.arrow;
            this.radius          = other.radius;
            this.height          = other.height;
            this.distancechecksq = other.distancechecksq;             //mxd
            this.hangs           = other.hangs;
            this.blocking        = other.blocking;
            this.errorcheck      = other.errorcheck;
            this.fixedsize       = other.fixedsize;
            this.fixedrotation   = other.fixedrotation;                                                                     //mxd
            this.absolutez       = other.absolutez;
            this.xybillboard     = other.xybillboard;                                                                       //mxd
            this.spritescale     = new SizeF(other.spritescale.Width, other.spritescale.Height);
            this.flagsrename     = new Dictionary <string, Dictionary <string, string> >(StringComparer.OrdinalIgnoreCase); //mxd

            //mxd. Copy GZDoom rendering properties
            this.rendermode = other.rendermode;
            this.rollsprite = other.rollsprite;
            this.rollcenter = other.rollcenter;

            //
            this.dynamiclighttype = other.dynamiclighttype;

            //
            this.optional = other.optional;

            // We have no destructor
            GC.SuppressFinalize(this);
        }
        // Constructor
        protected VisualThing(Thing t)
        {
            // Initialize
            this.thing      = t;
            this.renderpass = RenderPass.Mask;
            this.position   = Matrix.Identity;

            //mxd
            lightType            = null;
            lightPrimaryRadius   = -1;
            lightSecondaryRadius = -1;
            lightInterval        = -1;
            lightColor           = new Color4();
            boundingBox          = new Vector3D[9];

            // Register as resource
            General.Map.Graphics.RegisterResource(this);
        }
        public static List <Line3D> GetDynamicLightShapes(IEnumerable <Thing> things, bool highlight)
        {
            List <Line3D> circles = new List <Line3D>();

            if (General.Map.DOOM)
            {
                return(circles);
            }

            const int linealpha = 128;

            foreach (Thing t in things)
            {
                GZGeneral.LightData ld = t.DynamicLightType;
                if (ld == null)
                {
                    continue;
                }

                if (ld.LightType != GZGeneral.LightType.SPOT)
                {
                    List <Line3D> lshape = GetPointLightShape(t, highlight, ld, linealpha);
                    if (lshape != null)
                    {
                        circles.AddRange(lshape);
                    }
                }
                else
                {
                    List <Line3D> lshape = GetSpotLightShape(t, highlight, ld, linealpha);
                    if (lshape != null)
                    {
                        circles.AddRange(lshape);
                    }
                }
            }

            // Done
            return(circles);
        }
        //mxd. Update light info
        public void UpdateLight()
        {
            lightType = thing.DynamicLightType;
            if (lightType == null)
            {
                return;
            }
            GZGeneral.LightData ld = lightType;
            if (ld.LightDef != GZGeneral.LightDef.VAVOOM_GENERIC &&
                ld.LightDef != GZGeneral.LightDef.VAVOOM_COLORED) //if it's gzdoom light
            {
                if (ld.LightType == GZGeneral.LightType.POINT)
                {
                    if (ld.LightDef != GZGeneral.LightDef.POINT_SUBTRACTIVE) // normal, additive, attenuated
                    {
                        //lightColor.Alpha used in shader to perform some calculations based on light type
                        lightColor = new Color4((float)ld.LightRenderStyle / 100.0f,
                                                thing.Args[0] / DYNLIGHT_INTENSITY_SCALER,
                                                thing.Args[1] / DYNLIGHT_INTENSITY_SCALER,
                                                thing.Args[2] / DYNLIGHT_INTENSITY_SCALER);
                    }
                    else // negative
                    {
                        lightColor = new Color4((float)ld.LightRenderStyle / 100.0f,
                                                thing.Args[0] / SUBLIGHT_INTENSITY_SCALER,
                                                thing.Args[1] / SUBLIGHT_INTENSITY_SCALER,
                                                thing.Args[2] / SUBLIGHT_INTENSITY_SCALER);
                    }
                }
                else
                {
                    int c1, c2, c3;
                    if (thing.Fields.ContainsKey("arg0str"))
                    {
                        PixelColor pc;
                        ZDoom.ZDTextParser.GetColorFromString(thing.Fields["arg0str"].Value.ToString(), out pc);
                        c1 = pc.r;
                        c2 = pc.g;
                        c3 = pc.b;
                    }
                    else
                    {
                        c1 = (thing.Args[0] & 0xFF0000) >> 16;
                        c2 = (thing.Args[0] & 0x00FF00) >> 8;
                        c3 = (thing.Args[0] & 0x0000FF);
                    }

                    if (ld.LightDef != GZGeneral.LightDef.SPOT_SUBTRACTIVE)
                    {
                        lightColor = new Color4((float)ld.LightRenderStyle / 100.0f,
                                                c1 / DYNLIGHT_INTENSITY_SCALER,
                                                c2 / DYNLIGHT_INTENSITY_SCALER,
                                                c3 / DYNLIGHT_INTENSITY_SCALER);
                    }
                    else
                    {
                        lightColor = new Color4((float)ld.LightRenderStyle / 100.0f,
                                                c1 / SUBLIGHT_INTENSITY_SCALER,
                                                c2 / SUBLIGHT_INTENSITY_SCALER,
                                                c3 / SUBLIGHT_INTENSITY_SCALER);
                    }
                }

                if (lightType.LightModifier == GZGeneral.LightModifier.SECTOR)
                {
                    int scaler = 1;
                    if (thing.Sector != null)
                    {
                        scaler = thing.Sector.Brightness / 4;
                    }
                    lightPrimaryRadius = (thing.Args[3] * scaler);
                }
                else
                {
                    lightPrimaryRadius = (thing.Args[3] * 2);                     //works... that.. way in GZDoom
                    if (lightType.LightAnimated)
                    {
                        lightSecondaryRadius = (thing.Args[4] * 2);
                    }
                }

                if (lightType.LightType == GZGeneral.LightType.SPOT)
                {
                    lightSpotRadius1 = (thing.Args[1]);
                    lightSpotRadius2 = (thing.Args[2]);
                }
            }
            else             //it's one of vavoom lights
            {
                if (lightType.LightDef == GZGeneral.LightDef.VAVOOM_COLORED)
                {
                    lightColor = new Color4((float)ld.LightRenderStyle / 100.0f,
                                            thing.Args[1] / DYNLIGHT_INTENSITY_SCALER,
                                            thing.Args[2] / DYNLIGHT_INTENSITY_SCALER,
                                            thing.Args[3] / DYNLIGHT_INTENSITY_SCALER);
                }
                else
                {
                    lightColor = new Color4((float)ld.LightRenderStyle / 100.0f, 0.5f, 0.5f, 0.5f);
                }

                lightPrimaryRadius = (thing.Args[0] * 8);
            }

            UpdateLightRadius();
            UpdateBoundingBox(lightRadius, lightRadius * 2);
        }
Beispiel #8
0
        }                                                                                                          //mxd

        internal void ModifyByDecorateActor(ActorStructure actor, bool replacetitle)
        {
            // Keep reference to actor
            this.actor     = actor;
            this.classname = actor.ClassName;             //mxd

            // Set the title
            if (actor.HasPropertyWithValue("$title"))
            {
                title = actor.GetPropertyAllValues("$title");
            }
            else if (actor.HasPropertyWithValue("tag"))
            {
                string tag = actor.GetPropertyAllValues("tag");
                if (!tag.StartsWith("\"$"))
                {
                    title = tag;                                        //mxd. Don't use LANGUAGE keywords.
                }
            }

            if (string.IsNullOrEmpty(title) || replacetitle)
            {
                title = actor.ClassName;
            }

            //mxd. Color override?
            if (actor.HasPropertyWithValue("$color"))
            {
                int ci = actor.GetPropertyValueInt("$color", 0);
                color = (ci == 0 || ci > 19 ? 18 : ci);
            }

            //mxd. Custom argument titles?
            for (int i = 0; i < args.Length; i++)
            {
                ArgumentInfo arg = actor.GetArgumentInfo(i);
                if (arg != null)
                {
                    args[i] = arg;
                }
            }

            //mxd. Some SLADE compatibility
            if (actor.HasProperty("$angled"))
            {
                this.arrow = true;
            }
            else if (actor.HasProperty("$notangled"))
            {
                this.arrow = false;
            }

            //mxd. Marked as obsolete?
            if (actor.HasPropertyWithValue("$obsolete"))
            {
                obsoletemessage = actor.GetPropertyValueString("$obsolete", 0, true);
                obsolete        = true;
                color           = 4;       //red
            }

            // Remove doublequotes from title
            title = ZDTextParser.StripQuotes(title);             //mxd

            // Set sprite
            StateStructure.FrameInfo info = actor.FindSuitableSprite(); //mxd
            if (!locksprite && info != null)                            //mxd. Added locksprite property
            {
                sprite = info.Sprite;
            }
            else if (string.IsNullOrEmpty(sprite))           //mxd
            {
                sprite = DataManager.INTERNAL_PREFIX + "unknownthing";
            }

            //mxd. Store dynamic light name
            lightname = (info != null ? info.LightName : string.Empty);

            //mxd. Create sprite frame
            this.spriteframe = new[] { new SpriteFrameInfo {
                                           Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true)
                                       } };

            // Set sprite scale (mxd. Scale is translated to xscale and yscale in ActorStructure)
            if (actor.HasPropertyWithValue("xscale"))
            {
                this.spritescale.Width = actor.GetPropertyValueFloat("xscale", 0);
            }

            if (actor.HasPropertyWithValue("yscale"))
            {
                this.spritescale.Height = actor.GetPropertyValueFloat("yscale", 0);
            }

            // Size
            if (actor.HasPropertyWithValue("radius"))
            {
                radius = actor.GetPropertyValueInt("radius", 0);
            }
            if (actor.HasPropertyWithValue("height"))
            {
                height = actor.GetPropertyValueInt("height", 0);
            }

            //mxd. DistanceCheck. The value is CVAR. Also we'll need squared value
            if (actor.HasPropertyWithValue("distancecheck"))
            {
                string cvarname = actor.GetPropertyValueString("distancecheck", 0);
                if (!General.Map.Data.CVars.Integers.ContainsKey(cvarname))
                {
                    General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". DistanceCheck property references undefined cvar \"" + cvarname + "\"");
                    distancechecksq = int.MaxValue;
                }
                else
                {
                    distancechecksq = (int)Math.Pow(General.Map.Data.CVars.Integers[cvarname], 2);
                }
            }

            //mxd. Renderstyle
            if (actor.HasPropertyWithValue("renderstyle") && !actor.HasProperty("$ignorerenderstyle"))
            {
                renderstyle = actor.GetPropertyValueString("renderstyle", 0, true).ToLower();
            }

            //mxd. Alpha
            if (actor.HasPropertyWithValue("alpha"))
            {
                this.alpha     = General.Clamp(actor.GetPropertyValueFloat("alpha", 0), 0f, 1f);
                this.alphabyte = (byte)(this.alpha * 255);
            }
            else if (actor.HasProperty("defaultalpha"))
            {
                this.alpha     = (General.Map.Config.BaseGame == GameType.HERETIC ? 0.4f : 0.6f);
                this.alphabyte = (byte)(this.alpha * 255);
            }

            //mxd. BRIGHT
            this.bright = (info != null && info.Bright) || actor.GetFlagValue("bright", false);

            // Safety
            if (this.radius < 4f || this.fixedsize)
            {
                this.radius = THING_FIXED_SIZE;
            }
            if (this.spritescale.Width == 0.0f)
            {
                this.spritescale.Width = 1.0f;
            }
            if (this.spritescale.Height == 0.0f)
            {
                this.spritescale.Height = 1.0f;
            }

            // Options
            hangs = actor.GetFlagValue("spawnceiling", hangs);
            int blockvalue = (blocking > 0) ? blocking : 2;

            blocking    = actor.GetFlagValue("solid", (blocking != 0)) ? blockvalue : 0;
            xybillboard = actor.GetFlagValue("forcexybillboard", false);             //mxd

            //mxd. GZDoom rendering flags
            if (actor.GetFlagValue("wallsprite", false))
            {
                rendermode = ThingRenderMode.WALLSPRITE;
            }
            if (actor.GetFlagValue("flatsprite", false))
            {
                // WALLSPRITE + FLATSPRITE = HORRIBLE GLITCHES in GZDoom
                if (rendermode == ThingRenderMode.WALLSPRITE)
                {
                    General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". WALLSPRITE and FLATSPRITE flags can not be combined");
                }
                else
                {
                    rendermode = ThingRenderMode.FLATSPRITE;
                }
            }
            //mxd. WALLSPRITE and FLATSPRITE support rolling without the ROLLSPRITE flag
            rollsprite = actor.GetFlagValue("rollsprite", (rendermode == ThingRenderMode.WALLSPRITE || rendermode == ThingRenderMode.FLATSPRITE));
            if (rollsprite)
            {
                rollcenter = actor.GetFlagValue("rollcenter", false);
            }

            //mxd
            if (blocking > THING_BLOCKING_NONE)
            {
                errorcheck = THING_ERROR_INSIDE_STUCK;
            }

            // [ZZ]
            dynamiclighttype = GZGeneral.GetGZLightTypeByClass(actor);
        }
Beispiel #9
0
        // Constructor
        internal ThingTypeInfo(ThingCategory cat, int index, Configuration cfg, IDictionary <string, EnumList> enums)
        {
            string key = index.ToString(CultureInfo.InvariantCulture);

            // Initialize
            this.index           = index;
            this.category        = cat;
            this.args            = new ArgumentInfo[Linedef.NUM_ARGS];
            this.isknown         = true;
            this.actor           = null;
            this.bright          = false;        //mxd
            this.distancechecksq = int.MaxValue; //mxd

            // Read properties
            this.title         = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".title", "<" + key + ">");
            this.sprite        = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".sprite", cat.Sprite);
            this.color         = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".color", cat.Color);
            this.alpha         = General.Clamp(cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".alpha", cat.Alpha), 0f, 1f); //mxd
            this.alphabyte     = (byte)(this.alpha * 255);                                                                           //mxd
            this.renderstyle   = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".renderstyle", cat.RenderStyle).ToLower();  //mxd
            this.arrow         = (cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".arrow", cat.Arrow) != 0);
            this.radius        = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".width", cat.Radius);
            this.height        = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".height", cat.Height);
            this.hangs         = (cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".hangs", cat.Hangs) != 0);
            this.blocking      = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".blocking", cat.Blocking);
            this.errorcheck    = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".error", cat.ErrorCheck);
            this.fixedsize     = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".fixedsize", cat.FixedSize);
            this.fixedrotation = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".fixedrotation", cat.FixedRotation);             //mxd
            this.absolutez     = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".absolutez", cat.AbsoluteZ);
            float sscale = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".spritescale", cat.SpriteScale);

            this.spritescale = new SizeF(sscale, sscale);
            this.locksprite  = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".locksprite", false);            //mxd
            this.classname   = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".class", String.Empty);          //mxd
            this.thinglink   = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".thinglink", 0);

            //mxd. Read flagsrename
            this.flagsrename = new Dictionary <string, Dictionary <string, string> >(StringComparer.OrdinalIgnoreCase);
            IDictionary maindic = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".flagsrename", new Hashtable());

            foreach (DictionaryEntry de in maindic)
            {
                string ioname = de.Key.ToString().ToLowerInvariant();
                switch (ioname)
                {
                case "doommapsetio":
                case "hexenmapsetio":
                case "universalmapsetio":
                    IDictionary flagdic = de.Value as IDictionary;
                    if (flagdic == null)
                    {
                        continue;
                    }
                    flagsrename.Add(ioname, new Dictionary <string, string>());
                    foreach (DictionaryEntry fe in flagdic)
                    {
                        flagsrename[ioname].Add(fe.Key.ToString(), fe.Value.ToString());
                    }
                    break;

                default: throw new NotImplementedException("Unsupported MapSetIO");
                }
            }

            // Read the args
            for (int i = 0; i < Linedef.NUM_ARGS; i++)
            {
                this.args[i] = new ArgumentInfo(cfg, "thingtypes." + cat.Name + "." + key, i, enums);
            }

            // Safety
            if (this.radius < 4f || this.fixedsize)
            {
                this.radius = THING_FIXED_SIZE;
            }
            if (this.hangs && this.absolutez)
            {
                this.hangs = false;                                          //mxd
            }
            //mxd. Create sprite frame
            this.spriteframe = new[] { new SpriteFrameInfo {
                                           Sprite = sprite, SpriteLongName = Lump.MakeLongName(sprite, true)
                                       } };

            // [ZZ] optional thing sprite.
            this.optional = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".optional", cat.Optional);

            // [ZZ] generate internal light data
            this.dynamiclighttype = GZGeneral.GetLightDataByNum(index);

            // We have no destructor
            GC.SuppressFinalize(this);
        }
        public static List <Line3D> GetSpotLightShape(Thing t, bool highlight, GZGeneral.LightData ld, int linealpha)
        {
            PixelColor color;

            if (t.Fields.ContainsKey("arg0str"))
            {
                ZDoom.ZDTextParser.GetColorFromString(t.Fields["arg0str"].Value.ToString(), out color);
                color.a = (byte)linealpha;
            }
            else
            {
                color = new PixelColor((byte)linealpha, (byte)((t.Args[0] & 0xFF0000) >> 16), (byte)((t.Args[0] & 0x00FF00) >> 8), (byte)((t.Args[0] & 0x0000FF)));
            }

            if (highlight)
            {
                color = General.Colors.Highlight.WithAlpha((byte)linealpha);
            }

            PixelColor color_secondary = color;

            color_secondary.a /= 2;

            List <Line3D> shapes   = new List <Line3D>();
            float         _lAngle1 = Angle2D.DegToRad(t.Args[1]);
            float         _lAngle2 = Angle2D.DegToRad(t.Args[2]);
            float         lAngle1  = _lAngle1;
            float         lAngle2  = _lAngle2;

            float lRadius = t.Args[3] * 2;
            float lDirY1  = (float)Math.Sin(-lAngle1) * lRadius;
            float lDirX1  = (float)Math.Cos(-lAngle1) * lRadius;
            float lDirY2  = (float)Math.Sin(-lAngle2) * lRadius;
            float lDirX2  = (float)Math.Cos(-lAngle2) * lRadius;

            IEnumerable <Line3D> circleLines = MakeCircleLines(new Vector3D(0, 0, 0), color, (float)Math.Abs(lDirY1), CIRCLE_SIDES);

            foreach (Line3D l3d in circleLines)
            {
                shapes.Add(new Line3D(new Vector3D(lDirX1, l3d.Start.x, l3d.Start.y),
                                      new Vector3D(lDirX1, l3d.End.x, l3d.End.y),
                                      color, false));
            }

            if (lAngle2 != lAngle1)
            {
                circleLines = MakeCircleLines(new Vector3D(0, 0, 0), color_secondary, (float)Math.Abs(lDirY2), CIRCLE_SIDES);
                foreach (Line3D l3d in circleLines)
                {
                    shapes.Add(new Line3D(new Vector3D(lDirX2, l3d.Start.x, l3d.Start.y),
                                          new Vector3D(lDirX2, l3d.End.x, l3d.End.y),
                                          color_secondary, false));
                }
            }

            // draw another circle to show the front cone shape
            int   numsides  = CIRCLE_SIDES * 2;
            float anglestep = Angle2D.PI2 / numsides;

            for (int j = -1; j <= 1; j++)
            {
                if (j == 0)
                {
                    continue;
                }
                List <Line3D> tmplines = new List <Line3D>();
                PixelColor    ccol     = color;
                for (int i = 1; i < numsides + 1; i++)
                {
                    float angc = j * i * anglestep;
                    float angp = j * (i - 1) * anglestep;
                    if (i * anglestep > lAngle1 && ccol.a == color.a)
                    {
                        shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0),
                                              new Vector3D((float)Math.Cos(j * lAngle1) * lRadius, (float)Math.Sin(j * lAngle1) * lRadius, 0),
                                              ccol, false));
                        bool dobreak = false;
                        if (i * anglestep > lAngle2)
                        {
                            angc    = j * lAngle2;
                            dobreak = true;
                        }
                        shapes.Add(new Line3D(new Vector3D((float)Math.Cos(j * lAngle1) * lRadius, (float)Math.Sin(j * lAngle1) * lRadius, 0),
                                              new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0),
                                              color_secondary, false));
                        ccol = color_secondary;
                        if (dobreak)
                        {
                            break;
                        }
                    }
                    else if (i * anglestep > lAngle2)
                    {
                        angc = j * lAngle2;
                        shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0),
                                              new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0),
                                              ccol, false));
                        break;
                    }
                    else
                    {
                        shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0),
                                              new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0),
                                              ccol, false));
                    }
                }
            }

            shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX1, lDirY1, 0), color, false));
            shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX1, -lDirY1, 0), color, false));
            if (lAngle2 != lAngle1)
            {
                shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX2, lDirY2, 0), color_secondary, false));
                shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX2, -lDirY2, 0), color_secondary, false));
            }

            // do translation and rotation
            foreach (Line3D l3d in shapes)
            {
                // rotate
                l3d.Start = GetRotatedVertex(l3d.Start, t.Angle - 1.5708f, Angle2D.DegToRad(t.Pitch));
                l3d.End   = GetRotatedVertex(l3d.End, t.Angle - 1.5708f, Angle2D.DegToRad(t.Pitch));
                // translate
                l3d.Start += t.Position;
                l3d.End   += t.Position;
            }

            return(shapes);
        }
        public static List <Line3D> GetPointLightShape(Thing t, bool highlight, GZGeneral.LightData ld, int linealpha)
        {
            // TODO: this basically duplicates VisualThing.UpdateLight()...
            // Determine light radiii
            int primaryradius;
            int secondaryradius = 0;

            if (ld.LightDef != GZGeneral.LightDef.VAVOOM_GENERIC &&
                ld.LightDef != GZGeneral.LightDef.VAVOOM_COLORED) //if it's gzdoom light
            {
                if (ld.LightModifier == GZGeneral.LightModifier.SECTOR)
                {
                    if (t.Sector == null)
                    {
                        t.DetermineSector();
                    }
                    int scaler = (t.Sector != null ? t.Sector.Brightness / 4 : 2);
                    primaryradius = t.Args[3] * scaler;
                }
                else
                {
                    primaryradius = t.Args[3] * 2; //works... that.. way in GZDoom
                    if (ld.LightAnimated)
                    {
                        secondaryradius = t.Args[4] * 2;
                    }
                }
            }
            else //it's one of vavoom lights
            {
                primaryradius = t.Args[0] * 8;
            }

            // Check radii...
            if (primaryradius < 1 && secondaryradius < 1)
            {
                return(null);
            }

            // Determine light color
            PixelColor color;

            if (highlight)
            {
                color = General.Colors.Highlight.WithAlpha((byte)linealpha);
            }
            else
            {
                switch (t.DynamicLightType.LightDef)
                {
                case GZGeneral.LightDef.VAVOOM_GENERIC:     // Vavoom light
                    color = new PixelColor((byte)linealpha, 255, 255, 255);
                    break;

                case GZGeneral.LightDef.VAVOOM_COLORED:     // Vavoom colored light
                    color = new PixelColor((byte)linealpha, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]);
                    break;

                default:
                    color = new PixelColor((byte)linealpha, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]);
                    break;
                }
            }

            // Add lines if visible
            List <Line3D> circles = new List <Line3D>();

            if (primaryradius > 0)
            {
                circles.AddRange(MakeCircleLines(t.Position, color, primaryradius, CIRCLE_SIDES));
            }
            if (secondaryradius > 0)
            {
                circles.AddRange(MakeCircleLines(t.Position, color, secondaryradius, CIRCLE_SIDES));
            }
            return(circles);
        }
 public DynamicLightData(GZGeneral.LightData type)
 {
     Type   = type;
     Color  = new Color3();
     Offset = new Vector3f();
 }