public override void DrawRectBounds( FastColour colour, float lineWidth, int x, int y, int width, int height )
 {
     using( Pen pen = new Pen( colour, lineWidth ) ) {
         pen.Alignment = PenAlignment.Inset;
         g.DrawRectangle( pen, x, y, width, height );
     }
 }
 public override void Clear( FastColour colour, int x, int y, int width, int height )
 {
     g.SmoothingMode = SmoothingMode.None;
     Brush brush = GetOrCreateBrush( colour );
     g.FillRectangle( brush, x, y, width, height );
     g.SmoothingMode = SmoothingMode.HighQuality;
 }
 public override void DrawRectBounds( FastColour colour, float lineWidth, int x, int y, int width, int height )
 {
     RectF rec = new RectF( x, y, x + width, y + height );
     Paint brush = GetOrCreateBrush( colour );
     brush.SetStyle( Paint.Style.Stroke );
     c.DrawRect( rec, brush );
     brush.SetStyle( Paint.Style.FillAndStroke );
 }
 public override void Clear( FastColour colour, int x, int y, int width, int height )
 {
     RectF rec = new RectF( x, y, x + width, y + height );
     Paint brush = GetOrCreateBrush( colour );
     brush.AntiAlias = false;
     c.DrawRect( rec, brush );
     brush.AntiAlias = true;
 }
 public static void ResetToDefault()
 {
     BackgroundCol = new FastColour( 153, 127, 172 );
     ButtonBorderCol = new FastColour( 97, 81, 110 );
     ButtonForeActiveCol = new FastColour( 189, 168, 206 );
     ButtonForeCol = new FastColour( 141, 114, 165 );
     ButtonHighlightCol = new FastColour( 162, 131, 186 );
 }
示例#6
0
 void MakeRGBTriplet( FastColour defCol, bool force, int y )
 {
     MakeInput( GetCol( defCol.R, force ), 55,
               Anchor.Centre, Anchor.Centre, false, 30, y, 3, null );
     MakeInput( GetCol( defCol.G, force ), 55,
               Anchor.Centre, Anchor.Centre, false, 95, y, 3, null );
     MakeInput( GetCol( defCol.B, force ), 55,
               Anchor.Centre, Anchor.Centre, false, 160, y, 3, null );
 }
        static void Get( string key, ref FastColour col )
        {
            FastColour defaultCol = col;
            string value = Options.Get( key );
            if( String.IsNullOrEmpty( value ) ) return;

            if( !FastColour.TryParse( value, out col ) )
                col = defaultCol;
        }
        static IsometricBlockDrawer()
        {
            colNormal = FastColour.White;
            FastColour.GetShaded( colNormal, ref colXSide, ref colZSide, ref colYBottom );

            cosX = (float)Math.Cos( 26.565f * Utils.Deg2Rad );
            sinX = (float)Math.Sin( 26.565f * Utils.Deg2Rad );
            cosY = (float)Math.Cos( -45f * Utils.Deg2Rad );
            sinY = (float)Math.Sin( -45f * Utils.Deg2Rad );
        }
示例#9
0
        void WriteColourCompound( string name, FastColour col )
        {
            WriteTag( NbtTagType.Compound ); WriteString( name );

            WriteTag( NbtTagType.Int16 );
            WriteString( "R" ); WriteInt16( col.R );
            WriteTag( NbtTagType.Int16 );
            WriteString( "G" ); WriteInt16( col.G );
            WriteTag( NbtTagType.Int16 );
            WriteString( "B" ); WriteInt16( col.B );

            WriteTag( NbtTagType.End );
        }
示例#10
0
        void DrawPart(FastBitmap dst, Font font, ref int x, int y, TextPart part)
        {
            string     text    = part.Text;
            FastColour textCol = part.TextColour;
            float      point   = font.Size;
            int        xMul    = font.Style == FontStyle.Italic ? 1 : 0;

            foreach (char c in text)
            {
                int coords = ConvertToCP437(c);
                int srcX   = (coords & 0x0F) * boxSize;
                int srcY   = (coords >> 4) * boxSize;

                int srcWidth = widths[coords], dstWidth = PtToPx(point, srcWidth);
                int srcHeight = boxSize, dstHeight = PtToPx(point, srcHeight);
                for (int yy = 0; yy < dstHeight; yy++)
                {
                    int  fontY   = srcY + yy * srcHeight / dstHeight;
                    int *fontRow = fontPixels.GetRowPtr(fontY);
                    int  dstY    = y + yy;
                    if (dstY >= dst.Height)
                    {
                        continue;
                    }

                    int *dstRow  = dst.GetRowPtr(dstY);
                    int  xOffset = xMul * ((dstHeight - 1 - yy) / italicSize);
                    for (int xx = 0; xx < dstWidth; xx++)
                    {
                        int fontX = srcX + xx * srcWidth / dstWidth;
                        int pixel = fontRow[fontX];
                        if ((byte)(pixel >> 24) == 0)
                        {
                            continue;
                        }
                        int dstX = x + xx + xOffset;
                        if (dstX >= dst.Width)
                        {
                            continue;
                        }

                        int col = pixel & ~0xFFFFFF;
                        col         |= ((pixel & 0xFF) * textCol.B / 255);
                        col         |= (((pixel >> 8) & 0xFF) * textCol.G / 255) << 8;
                        col         |= (((pixel >> 16) & 0xFF) * textCol.R / 255) << 16;
                        dstRow[dstX] = col;
                    }
                }
                x += PtToPx(point, srcWidth + 1);
            }
        }
        static IsometricBlockDrawer()
        {
            FastColour.GetShaded(FastColour.White, out colXSide, out colZSide, out colYBottom);
            Matrix4 rotY, rotX;

            Matrix4.RotateY(out rotY, 45 * Utils.Deg2Rad);
            Matrix4.RotateX(out rotX, -30f * Utils.Deg2Rad);
            Matrix4.Mult(out transform, ref rotY, ref rotX);

            cosX = (float)Math.Cos(30f * Utils.Deg2Rad);
            sinX = (float)Math.Sin(30f * Utils.Deg2Rad);
            cosY = (float)Math.Cos(-45f * Utils.Deg2Rad);
            sinY = (float)Math.Sin(-45f * Utils.Deg2Rad);
        }
示例#12
0
        SolidBrush GetOrCreateBrush(FastColour col)
        {
            int        key = col.ToArgb();
            SolidBrush brush;

            if (brushCache.TryGetValue(key, out brush))
            {
                return(brush);
            }

            brush           = new SolidBrush(col);
            brushCache[key] = brush;
            return(brush);
        }
        public override void Init()
        {
            base.Init();

            widgets = new Widget[] {
                Make(-140, -150, "Clouds colour", OnWidgetClick,
                     g => g.Map.CloudsCol.ToRGBHexString(),
                     (g, v) => g.Map.SetCloudsColour(FastColour.Parse(v))),

                Make(-140, -100, "Sky colour", OnWidgetClick,
                     g => g.Map.SkyCol.ToRGBHexString(),
                     (g, v) => g.Map.SetSkyColour(FastColour.Parse(v))),

                Make(-140, -50, "Fog colour", OnWidgetClick,
                     g => g.Map.FogCol.ToRGBHexString(),
                     (g, v) => g.Map.SetFogColour(FastColour.Parse(v))),

                Make(-140, 0, "Clouds speed", OnWidgetClick,
                     g => g.Map.CloudsSpeed.ToString(),
                     (g, v) => g.Map.SetCloudsSpeed(Single.Parse(v))),

                Make(-140, 50, "Clouds height", OnWidgetClick,
                     g => g.Map.CloudHeight.ToString(),
                     (g, v) => g.Map.SetCloudsLevel(Int32.Parse(v))),

                Make(140, -100, "Sunlight colour", OnWidgetClick,
                     g => g.Map.Sunlight.ToRGBHexString(),
                     (g, v) => g.Map.SetSunlight(FastColour.Parse(v))),

                Make(140, -50, "Shadow colour", OnWidgetClick,
                     g => g.Map.Shadowlight.ToRGBHexString(),
                     (g, v) => g.Map.SetShadowlight(FastColour.Parse(v))),

                Make(140, 0, "Weather", OnWidgetClick,
                     g => g.Map.Weather.ToString(),
                     (g, v) => g.Map.SetWeather((Weather)Enum.Parse(typeof(Weather), v))),

                Make(140, 50, "Water level", OnWidgetClick,
                     g => g.Map.EdgeHeight.ToString(),
                     (g, v) => g.Map.SetEdgeLevel(Int32.Parse(v))),

                MakeBack(false, titleFont,
                         (g, w) => g.SetNewScreen(new OptionsGroupScreen(g))),
                null, null, null,
            };
            widgets[7].Metadata = typeof(Weather);
            MakeDefaultValues();
            MakeValidators();
        }
        static void YQuad(byte block, float y, int side)
        {
            int        texId = info.GetTextureLoc(block, side);
            TextureRec rec   = atlas.GetTexRec(texId);
            FastColour col   = colNormal;

            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X - scale, pos.Y - y,
                                                                pos.Z - scale, rec.U2, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X - scale, pos.Y - y,
                                                                pos.Z + scale, rec.U1, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + scale, pos.Y - y,
                                                                pos.Z + scale, rec.U1, rec.V1, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + scale, pos.Y - y,
                                                                pos.Z - scale, rec.U2, rec.V1, col);
        }
        void DrawTopFace(int count)
        {
            int   texId   = BlockInfo.textures[curBlock * Side.Sides + Side.Top];
            int   i       = texId / elementsPerAtlas1D;
            float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
            int   offset  = (lightFlags >> Side.Top) & 1;

            float    u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f / 16f;
            float    v1   = vOrigin + minBB.Z * invVerElementSize;
            float    v2   = vOrigin + maxBB.Z * invVerElementSize * 15.99f / 16f;
            DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];

            int F      = bitFlags[cIndex];
            int aX0_Z0 = ((F >> xM1_yP1_zM1) & 1) + ((F >> xM1_yP1_zCC) & 1) + ((F >> xCC_yP1_zM1) & 1) + ((F >> xCC_yP1_zCC) & 1);
            int aX1_Z0 = ((F >> xP1_yP1_zM1) & 1) + ((F >> xP1_yP1_zCC) & 1) + ((F >> xCC_yP1_zM1) & 1) + ((F >> xCC_yP1_zCC) & 1);
            int aX0_Z1 = ((F >> xM1_yP1_zP1) & 1) + ((F >> xM1_yP1_zCC) & 1) + ((F >> xCC_yP1_zP1) & 1) + ((F >> xCC_yP1_zCC) & 1);
            int aX1_Z1 = ((F >> xP1_yP1_zP1) & 1) + ((F >> xP1_yP1_zCC) & 1) + ((F >> xCC_yP1_zP1) & 1) + ((F >> xCC_yP1_zCC) & 1);

            int col0_0 = fullBright ? FastColour.WhitePacked : lerp[aX0_Z0], col1_0 = fullBright ? FastColour.WhitePacked : lerp[aX1_Z0];
            int col1_1 = fullBright ? FastColour.WhitePacked : lerp[aX1_Z1], col0_1 = fullBright ? FastColour.WhitePacked : lerp[aX0_Z1];

            if (tinted)
            {
                FastColour tint = BlockInfo.FogColour[curBlock];
                col0_0 = Utils.Tint(col0_0, tint);
                col1_0 = Utils.Tint(col1_0, tint);
                col1_1 = Utils.Tint(col1_1, tint);
                col0_1 = Utils.Tint(col0_1, tint);
            }

            int index = part.vIndex[Side.Top];

            if (aX0_Z0 + aX1_Z1 > aX0_Z1 + aX1_Z0)
            {
                part.vertices[index]     = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_0);
                part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_0);
                part.vertices[index + 2] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col0_1);
                part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col1_1);
            }
            else
            {
                part.vertices[index]     = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_0);
                part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col0_1);
                part.vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col1_1);
                part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_0);
            }
            part.vIndex[Side.Top] += 4;
        }
        void MakeRainForSquare(int x, float y, float height, int z, FastColour col, ref int index)
        {
            float worldV = vOffset + (z & 1) / 2f - (x & 0x0F) / 16f;
            float v1     = y / 6f + worldV;
            float v2     = (y + height) / 6f + worldV;

            vertices[index++] = new VertexPos3fTex2fCol4b(x, y, z, 0, v2, col);
            vertices[index++] = new VertexPos3fTex2fCol4b(x, y + height, z, 0, v1, col);
            vertices[index++] = new VertexPos3fTex2fCol4b(x + 1, y + height, z + 1, 2, v1, col);
            vertices[index++] = new VertexPos3fTex2fCol4b(x + 1, y, z + 1, 2, v2, col);

            vertices[index++] = new VertexPos3fTex2fCol4b(x + 1, y, z, 2, v2, col);
            vertices[index++] = new VertexPos3fTex2fCol4b(x + 1, y + height, z, 2, v1, col);
            vertices[index++] = new VertexPos3fTex2fCol4b(x, y + height, z + 1, 0, v1, col);
            vertices[index++] = new VertexPos3fTex2fCol4b(x, y, z + 1, 0, v2, col);
        }
        void DrawTopFace(int count)
        {
            int   texId   = info.textures[tile * TileSide.Sides + TileSide.Top];
            int   i       = texId / elementsPerAtlas1D;
            float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;

            float      u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f / 16f;
            float      v1   = vOrigin + minBB.Z * invVerElementSize;
            float      v2   = vOrigin + maxBB.Z * invVerElementSize * 15.99f / 16f;
            DrawInfo   part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
            FastColour col  = fullBright ? FastColour.White : (Y > map.heightmap[(Z * width) + X] ? map.Sunlight : map.Shadowlight);

            part.vertices[part.vIndex.top++] = new VertexPos3fTex2fCol4b(x2 + (count - 1), y2, z1, u2, v1, col);
            part.vertices[part.vIndex.top++] = new VertexPos3fTex2fCol4b(x1, y2, z1, u1, v1, col);
            part.vertices[part.vIndex.top++] = new VertexPos3fTex2fCol4b(x1, y2, z2, u1, v2, col);
            part.vertices[part.vIndex.top++] = new VertexPos3fTex2fCol4b(x2 + (count - 1), y2, z2, u2, v2, col);
        }
示例#18
0
        void DrawTitles(IDrawer2D drawer, Font font)
        {
            int          x    = 0;
            DrawTextArgs args = new DrawTextArgs(null, font, false);

            for (int i = 0; i < elements.Length; i++)
            {
                args.Text = elements[i].Title;
                FastColour col = i == selectedIndex ? new FastColour(30, 30, 30, 200) :
                                 new FastColour(60, 60, 60, 200);
                Size size = elements[i].TitleSize;

                drawer.Clear(col, x, 0, size.Width, size.Height);
                drawer.DrawChatText(ref args, x + titleSpacing / 2, 0);
                x += size.Width;
            }
        }
示例#19
0
        static void SpriteXQuad(byte block, int side, bool firstPart)
        {
            int        texLoc = info.GetTextureLoc(block, side);
            TextureRec rec    = atlas.GetTexRec(texLoc, 1, out texIndex);

            FlushIfNotSame();

            FastColour col = colNormal;
            float      z1 = firstPart ? -0.1f : 0.5f, z2 = firstPart ? 0.5f : 1.1f;

            rec.U1 = firstPart ? 0.0f : 0.5f; rec.U2 = (firstPart ? 0.5f : 1.0f) * (15.99f / 16f);

            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(0.5f), Make(0.0f), Make(z1), rec.U1, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(0.5f), Make(1.1f), Make(z1), rec.U1, rec.V1, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(0.5f), Make(1.1f), Make(z2), rec.U2, rec.V1, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(0.5f), Make(0.0f), Make(z2), rec.U2, rec.V2, col);
        }
示例#20
0
        FastColour GetColour(string key, FastColour def)
        {
            NbtTag tag;

            if (!curCpeExt.TryGetValue(key, out tag))
            {
                return(def);
            }

            Dictionary <string, NbtTag> compound = (Dictionary <string, NbtTag>)tag.Value;
            short r       = (short)compound["R"].Value;
            short g       = (short)compound["G"].Value;
            short b       = (short)compound["B"].Value;
            bool  invalid = r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255;

            return(invalid ? def : new FastColour(r, g, b));
        }
示例#21
0
        SolidBrush GetOrCreateBrush(FastColour col)
        {
            int argb = col.ToArgb();

            for (int i = 0; i < brushes.Count; i++)
            {
                if (brushes[i].ARGB == argb)
                {
                    return(brushes[i].Brush);
                }
            }

            CachedBrush b; b.ARGB = argb; b.Brush = new SolidBrush(col);

            brushes.Add(b);
            return(b.Brush);
        }
示例#22
0
        public void InitColours()
        {
            for (int i = 0; i < Colours.Length; i++)
            {
                Colours[i] = default(FastColour);
            }

            for (int i = 0; i <= 9; i++)
            {
                Colours['0' + i] = FastColour.GetHexEncodedCol(i, 191, 64);
            }
            for (int i = 10; i <= 15; i++)
            {
                Colours['a' + i - 10] = FastColour.GetHexEncodedCol(i, 191, 64);
                Colours['A' + i - 10] = Colours['a' + i - 10];
            }
        }
示例#23
0
        /// <summary> Resets all of the properties to their defaults and raises the 'OnNewMap' event. </summary>
        public void Reset()
        {
            EdgeHeight  = -1;
            CloudHeight = -1;
            Width       = Height = Length = 0;
            Uuid        = Guid.NewGuid();
            EdgeBlock   = Block.StillWater;
            SidesBlock  = Block.Bedrock;
            CloudsSpeed = 1;

            ResetLight();
            SkyCol    = DefaultSkyColour;
            FogCol    = DefaultFogColour;
            CloudsCol = DefaultCloudsColour;
            Weather   = Weather.Sunny;
            game.MapEvents.RaiseOnNewMap();
        }
        void DrawFrontFace(int count)
        {
            int   texId   = info.textures[curBlock * Side.Sides + Side.Front];
            int   i       = texId / elementsPerAtlas1D;
            float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
            int   offset  = (lightFlags >> Side.Front) & 1;

            float    u1 = (count - minBB.X), u2 = (1 - maxBB.X) * 15.99f / 16f;
            float    v1   = vOrigin + maxBB.Y * invVerElementSize;
            float    v2   = vOrigin + minBB.Y * invVerElementSize * 15.99f / 16f;
            DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];

            int F      = bitFlags[cIndex];
            int aX0_Y0 = ((F >> xM1_yM1_zM1) & 1) + ((F >> xM1_yCC_zM1) & 1) + ((F >> xCC_yM1_zM1) & 1) + ((F >> xCC_yCC_zM1) & 1);
            int aX0_Y1 = ((F >> xM1_yP1_zM1) & 1) + ((F >> xM1_yCC_zM1) & 1) + ((F >> xCC_yP1_zM1) & 1) + ((F >> xCC_yCC_zM1) & 1);
            int aX1_Y0 = ((F >> xP1_yM1_zM1) & 1) + ((F >> xP1_yCC_zM1) & 1) + ((F >> xCC_yM1_zM1) & 1) + ((F >> xCC_yCC_zM1) & 1);
            int aX1_Y1 = ((F >> xP1_yP1_zM1) & 1) + ((F >> xP1_yCC_zM1) & 1) + ((F >> xCC_yP1_zM1) & 1) + ((F >> xCC_yCC_zM1) & 1);

            int col0_0 = fullBright ? FastColour.WhitePacked : lerpZ[aX0_Y0], col1_0 = fullBright ? FastColour.WhitePacked : lerpZ[aX1_Y0];
            int col1_1 = fullBright ? FastColour.WhitePacked : lerpZ[aX1_Y1], col0_1 = fullBright ? FastColour.WhitePacked : lerpZ[aX0_Y1];

            if (tinted)
            {
                FastColour tint = info.FogColour[curBlock];
                col0_0 = Utils.Tint(col0_0, tint);
                col1_0 = Utils.Tint(col1_0, tint);
                col1_1 = Utils.Tint(col1_1, tint);
                col0_1 = Utils.Tint(col0_1, tint);
            }

            if (aX1_Y1 + aX0_Y0 > aX0_Y1 + aX1_Y0)
            {
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v2, col1_0);
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_1);
            }
            else
            {
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_1);
                part.vertices[part.vIndex[Side.Front]++] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v2, col1_0);
            }
        }
示例#25
0
        void ParseWomConfig(string page)
        {
            using (StringReader reader = new StringReader(page)) {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    Utils.LogDebug(line);
                    string[] parts = line.Split(new [] { '=' }, 2);
                    if (parts.Length < 2)
                    {
                        continue;
                    }
                    string key   = parts[0].TrimEnd();
                    string value = parts[1].TrimStart();

                    if (key == "environment.cloud")
                    {
                        FastColour col = ParseWomColour(value, Map.DefaultCloudsColour);
                        game.Map.SetCloudsColour(col);
                    }
                    else if (key == "environment.sky")
                    {
                        FastColour col = ParseWomColour(value, Map.DefaultSkyColour);
                        game.Map.SetSkyColour(col);
                    }
                    else if (key == "environment.fog")
                    {
                        FastColour col = ParseWomColour(value, Map.DefaultFogColour);
                        game.Map.SetFogColour(col);
                    }
                    else if (key == "environment.level")
                    {
                        int waterLevel = 0;
                        if (Int32.TryParse(value, out waterLevel))
                        {
                            game.Map.SetEdgeLevel(waterLevel);
                        }
                    }
                    else if (key == "user.detail" && !useMessageTypes)
                    {
                        game.Chat.Add(value, CpeMessage.Status2);
                    }
                }
            }
        }
        void HandleSetTextColor()
        {
            FastColour col = new FastColour(reader.ReadUInt8(), reader.ReadUInt8(),
                                            reader.ReadUInt8(), reader.ReadUInt8());
            byte code = reader.ReadUInt8();

            if (code <= ' ' || code > '~')
            {
                return;                                         // Control chars, space, extended chars cannot be used
            }
            if ((code >= '0' && code <= '9') || (code >= 'a' && code <= 'f') ||
                (code >= 'A' && code <= 'F'))
            {
                return;                                              // Standard chars cannot be used.
            }
            game.Drawer2D.Colours[code] = col;
            game.Events.RaiseColourCodesChanged();
        }
示例#27
0
        void DrawTopFace(int count)
        {
            int   texId   = info.textures[curBlock * Side.Sides + Side.Top];
            int   i       = texId / elementsPerAtlas1D;
            float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
            int   offset  = (lightFlags >> Side.Top) & 1;

            float      u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f / 16f;
            float      v1   = vOrigin + minBB.Z * invVerElementSize;
            float      v2   = vOrigin + maxBB.Z * invVerElementSize * 15.99f / 16f;
            DrawInfo   part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
            FastColour col  = fullBright ? FastColour.White : ((Y - offset) >= map.heightmap[(Z * width) + X] ? env.Sunlight : env.Shadowlight);

            part.vertices[part.vIndex.top++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col);
            part.vertices[part.vIndex.top++] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col);
            part.vertices[part.vIndex.top++] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col);
            part.vertices[part.vIndex.top++] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col);
        }
        void RebuildEdges(int waterLevel, int axisSize)
        {
            edgesVertices = 0;
            foreach (Rectangle rec in rects)
            {
                edgesVertices += Utils.CountVertices(rec.Width, rec.Height, axisSize);                   // YPlanes outside
            }
            VertexPos3fTex2fCol4b *vertices = stackalloc VertexPos3fTex2fCol4b[edgesVertices];
            IntPtr ptr = (IntPtr)vertices;

            fullColEdge = game.BlockInfo.FullBright[(byte)game.Map.EdgeBlock];
            FastColour col = fullColEdge ? FastColour.White : map.Sunlight;

            foreach (Rectangle rec in rects)
            {
                DrawY(rec.X, rec.Y, rec.X + rec.Width, rec.Y + rec.Height, waterLevel, axisSize, col, ref vertices);
            }
            edgesVb = graphics.CreateVb(ptr, VertexFormat.Pos3fTex2fCol4b, edgesVertices);
        }
        void DrawLeftFace(int count)
        {
            int   texId   = info.textures[tile * TileSide.Sides + TileSide.Left];
            int   i       = texId / elementsPerAtlas1D;
            float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
            int   offset  = (lightFlags >> TileSide.Left) & 1;

            float      u1 = minBB.Z, u2 = (count - 1) + maxBB.Z * 15.99f / 16f;
            float      v1   = vOrigin + maxBB.Y * invVerElementSize;
            float      v2   = vOrigin + minBB.Y * invVerElementSize * 15.99f / 16f;
            DrawInfo   part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
            FastColour col  = fullBright ? FastColour.White :
                              X >= offset ? (Y > map.heightmap[(Z * width) + (X - offset)] ? map.SunlightXSide : map.ShadowlightXSide) : map.SunlightXSide;

            part.vertices[part.vIndex.left++] = new VertexPos3fTex2fCol4b(x1, y2, z2 + (count - 1), u2, v1, col);
            part.vertices[part.vIndex.left++] = new VertexPos3fTex2fCol4b(x1, y2, z1, u1, v1, col);
            part.vertices[part.vIndex.left++] = new VertexPos3fTex2fCol4b(x1, y1, z1, u1, v2, col);
            part.vertices[part.vIndex.left++] = new VertexPos3fTex2fCol4b(x1, y1, z2 + (count - 1), u2, v2, col);
        }
示例#30
0
        static void YQuad(byte block, float y, int side)
        {
            int        texLoc = info.GetTextureLoc(block, side);
            TextureRec rec    = atlas.GetTexRec(texLoc, 1, out texIndex);

            FlushIfNotSame();
            FastColour col = colNormal;

            float vOrigin = (texLoc % atlas.elementsPerAtlas1D) * atlas.invElementSize;

            rec.U1 = minBB.X; rec.U2 = maxBB.X;
            rec.V1 = vOrigin + minBB.Z * atlas.invElementSize;
            rec.V2 = vOrigin + maxBB.Z * atlas.invElementSize * (15.99f / 16f);

            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(minBB.X), y, Make(minBB.Z), rec.U1, rec.V1, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(maxBB.X), y, Make(minBB.Z), rec.U2, rec.V1, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(maxBB.X), y, Make(maxBB.Z), rec.U2, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(Make(minBB.X), y, Make(maxBB.Z), rec.U1, rec.V2, col);
        }
        void DrawBackFace(int count)
        {
            int   texId   = info.textures[tile * TileSide.Sides + TileSide.Back];
            int   i       = texId / elementsPerAtlas1D;
            float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
            int   offset  = (lightFlags >> TileSide.Back) & 1;

            float      u1 = minBB.X, u2 = (count - 1) + maxBB.X * 15.99f / 16f;
            float      v1   = vOrigin + maxBB.Y * invVerElementSize;
            float      v2   = vOrigin + minBB.Y * invVerElementSize * 15.99f / 16f;
            DrawInfo   part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
            FastColour col  = fullBright ? FastColour.White :
                              Z <= (maxZ - offset) ? (Y > map.heightmap[((Z + offset) * width) + X] ? map.SunlightZSide : map.ShadowlightZSide) : map.SunlightZSide;

            part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b(x2 + (count - 1), y2, z2, u2, v1, col);
            part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b(x1, y2, z2, u1, v1, col);
            part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b(x1, y1, z2, u1, v2, col);
            part.vertices[part.vIndex.back++] = new VertexPos3fTex2fCol4b(x2 + (count - 1), y1, z2, u2, v2, col);
        }
示例#32
0
        void DrawRightFace(int count)
        {
            int   texId   = info.textures[curBlock * Side.Sides + Side.Right];
            int   i       = texId / elementsPerAtlas1D;
            float vOrigin = (texId % elementsPerAtlas1D) * invVerElementSize;
            int   offset  = (lightFlags >> Side.Right) & 1;

            float      u1 = minBB.Z, u2 = (count - 1) + maxBB.Z * 15.99f / 16f;
            float      v1   = vOrigin + maxBB.Y * invVerElementSize;
            float      v2   = vOrigin + minBB.Y * invVerElementSize * 15.99f / 16f;
            DrawInfo   part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
            FastColour col  = fullBright ? FastColour.White :
                              X <= (maxX - offset) ? (Y > map.heightmap[(Z * width) + (X + offset)] ? env.SunlightXSide : env.ShadowlightXSide) : env.SunlightXSide;

            part.vertices[part.vIndex.right++] = new VertexP3fT2fC4b(x2, y2, z1, u2, v1, col);
            part.vertices[part.vIndex.right++] = new VertexP3fT2fC4b(x2, y2, z2 + (count - 1), u1, v1, col);
            part.vertices[part.vIndex.right++] = new VertexP3fT2fC4b(x2, y1, z2 + (count - 1), u1, v2, col);
            part.vertices[part.vIndex.right++] = new VertexP3fT2fC4b(x2, y1, z1, u2, v2, col);
        }
示例#33
0
        FastColour GetBlockColorXSide(int X, int Y, int Z, out bool blocksLight)
        {
            blocksLight = false;
            if (map.IsValidPos(X, Y, Z))
            {
                BlockID thisBlock = map.GetBlock(X, Y, Z);
                if (isOccluder[thisBlock])
                {
                    blocksLight = true;
                }

                FastColour col = blocksLight ? darkX : FastColour.Unpack(light.LightCol_XSide_Fast(X, Y, Z));
                if (BlockInfo.FullBright[thisBlock])
                {
                    col = sun;
                }
                return(col);
            }
            return(sunX);
        }
        protected void DrawName()
        {
            IGraphicsApi api = game.Graphics;

            api.BindTexture(nameTex.ID);
            Vector3 pos = Position; pos.Y += Model.NameYOffset;

            Vector3    p111, p121, p212, p222;
            FastColour col  = FastColour.White;
            Vector2    size = new Vector2(nameTex.Width / 70f, nameTex.Height / 70f);

            Utils.CalcBillboardPoints(size, pos, ref game.View, out p111, out p121, out p212, out p222);
            api.texVerts[0] = new VertexPos3fTex2fCol4b(p111, nameTex.U1, nameTex.V2, col);
            api.texVerts[1] = new VertexPos3fTex2fCol4b(p121, nameTex.U1, nameTex.V1, col);
            api.texVerts[2] = new VertexPos3fTex2fCol4b(p222, nameTex.U2, nameTex.V1, col);
            api.texVerts[3] = new VertexPos3fTex2fCol4b(p212, nameTex.U2, nameTex.V2, col);

            api.SetBatchFormat(VertexFormat.Pos3fTex2fCol4b);
            api.UpdateDynamicIndexedVb(DrawMode.Triangles, api.texVb, api.texVerts, 4, 6);
        }
        public override void DrawRoundedRect( FastColour colour, float radius, float x, float y, float width, float height )
        {
            GraphicsPath path = new GraphicsPath();
            float x1 = x, y1 = y, x2 = x + width, y2 = y + height;

            float r = radius, dia = radius * 2;
            path.AddArc( x1, y1, dia, dia, 180, 90 );
            path.AddLine( x1 + r, y1, x2 - r, y1 );
            path.AddArc( x2 - dia, y1, dia, dia, 270, 90 );
            path.AddLine( x2, y1 + r, x2, y2 - r );
            path.AddArc( x2 - dia, y2 - dia, dia, dia, 0, 90 );
            path.AddLine( x1 + r, y2, x2 - r, y2 );
            path.AddArc( x1, y2 - dia, dia, dia, 90, 90 );
            path.AddLine( x1, y1 + r, x1, y2 - r );
            path.CloseAllFigures();

            using( Brush brush = new SolidBrush( colour ) )
                g.FillPath( brush, path );
            path.Dispose();
        }
        static void ZQuad(byte block, float z, int side)
        {
            int        texId = info.GetTextureLoc(block, side);
            TextureRec rec   = atlas.GetTexRec(texId);
            FastColour col   = colZSide;

            float vOrigin = rec.V1;

            rec.V1 = vOrigin + minBB.Y * TerrainAtlas2D.invElementSize;
            rec.V2 = vOrigin + maxBB.Y * TerrainAtlas2D.invElementSize;

            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X - scale, pos.Y + Y(minBB.Y),
                                                                pos.Z - z, rec.U1, rec.V1, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X - scale, pos.Y + Y(maxBB.Y),
                                                                pos.Z - z, rec.U1, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + scale, pos.Y + Y(maxBB.Y),
                                                                pos.Z - z, rec.U2, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + scale, pos.Y + Y(minBB.Y),
                                                                pos.Z - z, rec.U2, rec.V1, col);
        }
        void DrawUnderline(FastBitmap fastBmp, FastColour textCol, int startX, int endX,
                           int yOffset, ref DrawTextArgs args)
        {
            int height = PtToPx(args.Font.Size, boxSize);
            int offset = ShadowOffset(args.Font.Size);
            int col    = textCol.ToArgb();

            if (args.UseShadow)
            {
                height += offset;
            }

            for (int yy = height - offset; yy < height; yy++)
            {
                int *dstRow = fastBmp.GetRowPtr(yy + yOffset);
                for (int xx = startX; xx < endX; xx++)
                {
                    dstRow[xx] = col;
                }
            }
        }
        public override void DrawRoundedRect(FastColour colour, float radius, float x, float y, float width, float height)
        {
            GraphicsPath path = new GraphicsPath();
            float        x1 = x, y1 = y, x2 = x + width, y2 = y + height;

            float r = radius, dia = radius * 2;

            path.AddArc(x1, y1, dia, dia, 180, 90);
            path.AddLine(x1 + r, y1, x2 - r, y1);
            path.AddArc(x2 - dia, y1, dia, dia, 270, 90);
            path.AddLine(x2, y1 + r, x2, y2 - r);
            path.AddArc(x2 - dia, y2 - dia, dia, dia, 0, 90);
            path.AddLine(x1 + r, y2, x2 - r, y2);
            path.AddArc(x1, y2 - dia, dia, dia, 90, 90);
            path.AddLine(x1, y1 + r, x1, y2 - r);
            path.CloseAllFigures();

            using (Brush brush = new SolidBrush(colour))
                g.FillPath(brush, path);
            path.Dispose();
        }
        static void YQuad(byte block, float y, int side)
        {
            int        texId = info.GetTextureLoc(block, side);
            TextureRec rec = atlas.GetTexRec(texId);
            FastColour col = colNormal;
            float      uOrigin = rec.U1, vOrigin = rec.V1;

            rec.U1 = uOrigin + minBB.Z * invElemSize;
            rec.U2 = uOrigin + maxBB.Z * invElemSize * 15.99f / 16f;
            rec.V1 = vOrigin + minBB.X * invElemSize;
            rec.V2 = vOrigin + maxBB.X * invElemSize * 15.99f / 16f;

            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + Make(minBB.X), pos.Y + y,
                                                                pos.Z + Make(minBB.Z), rec.U2, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + Make(minBB.X), pos.Y + y,
                                                                pos.Z + Make(maxBB.Z), rec.U1, rec.V2, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + Make(maxBB.X), pos.Y + y,
                                                                pos.Z + Make(maxBB.Z), rec.U1, rec.V1, col);
            cache.vertices[index++] = new VertexPos3fTex2fCol4b(pos.X + Make(maxBB.X), pos.Y + y,
                                                                pos.Z + Make(minBB.Z), rec.U2, rec.V1, col);
        }
示例#40
0
        void HandleCpeMakeSelection()
        {
            byte   selectionId = reader.ReadUInt8();
            string label       = reader.ReadAsciiString();
            short  startX      = reader.ReadInt16();
            short  startY      = reader.ReadInt16();
            short  startZ      = reader.ReadInt16();
            short  endX        = reader.ReadInt16();
            short  endY        = reader.ReadInt16();
            short  endZ        = reader.ReadInt16();

            byte r = (byte)reader.ReadInt16();
            byte g = (byte)reader.ReadInt16();
            byte b = (byte)reader.ReadInt16();
            byte a = (byte)reader.ReadInt16();

            Vector3I   p1  = Vector3I.Min(startX, startY, startZ, endX, endY, endZ);
            Vector3I   p2  = Vector3I.Max(startX, startY, startZ, endX, endY, endZ);
            FastColour col = new FastColour(r, g, b, a);

            game.SelectionManager.AddSelection(selectionId, p1, p2, col);
        }
        public static unsafe void DrawNoise( FastBitmap dst, Rectangle dstRect, FastColour col, int variation )
        {
            int dstX, dstY, dstWidth, dstHeight;
            if( !CheckCoords( dst, dstRect, out dstX, out dstY, out dstWidth, out dstHeight ) )
                return;
            const int alpha = 255 << 24;
            for( int yy = 0; yy < dstHeight; yy++ ) {
                int* row = dst.GetRowPtr( dstY + yy );
                for( int xx = 0; xx < dstWidth; xx++ ) {
                    int n = (dstX + xx) + (dstY + yy) * 57;
                    n = (n << 13) ^ n;
                    float noise = 1f - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824f;

                    int r = col.R + (int)(noise * variation);
                    r = r < 0 ? 0 : (r > 255 ? 255 : r);
                    int g = col.G + (int)(noise * variation);
                    g = g < 0 ? 0 : (g > 255 ? 255 : g);
                    int b = col.B + (int)(noise * variation);
                    b = b < 0 ? 0 : (b > 255 ? 255 : b);
                    row[dstX + xx] = alpha | (r << 16) | (g << 8) | b;
                }
            }
        }
 bool Parse( int index, ref FastColour dst )
 {
     byte r, g, b;
     if( !Byte.TryParse( widgets[index + 0].Text, out r )
        || !Byte.TryParse( widgets[index + 1].Text, out g )
        || !Byte.TryParse( widgets[index + 2].Text, out b ) )
         return false;
     dst.R = r; dst.G = g; dst.B = b;
     return true;
 }
示例#43
0
        void MakeRainForSquare( int x, int y, int height, int z, FastColour col, ref int index )
        {
            float v1 = vOffset + (z & 0x01) * 0.5f - (x & 0x0F) * 0.0625f;
            float v2 = height / 6f + v1;

            vertices[index++] = new VertexPos3fTex2fCol4b( x, y, z, 0, v2, col );
            vertices[index++] = new VertexPos3fTex2fCol4b( x, y + height, z, 0, v1, col );
            vertices[index++] = new VertexPos3fTex2fCol4b( x + 1, y + height, z + 1, 2, v1, col );
            vertices[index++] = new VertexPos3fTex2fCol4b( x + 1, y, z + 1, 2, v2, col );

            vertices[index++] = new VertexPos3fTex2fCol4b( x + 1, y, z, 2, v2, col );
            vertices[index++] = new VertexPos3fTex2fCol4b( x + 1, y + height, z, 2, v1, col );
            vertices[index++] = new VertexPos3fTex2fCol4b( x, y + height, z + 1, 0, v1, col );
            vertices[index++] = new VertexPos3fTex2fCol4b( x, y, z + 1, 0, v2, col );
        }
示例#44
0
 public bool Equals( FastColour other )
 {
     return A == other.A && R == other.R && G == other.G && B == other.B;
 }
示例#45
0
        public static bool TryParse( string input, out FastColour value )
        {
            value = default( FastColour );
            if( input == null || input.Length < 6 ) return false;

            try {
                int i = input.Length > 6 ? 1 : 0;
                if( input.Length > 6 && (input[0] != '#' || input.Length > 7) )
                    return false;

                int r = Utils.ParseHex( input[i + 0] ) * 16 + Utils.ParseHex( input[i + 1] );
                int g = Utils.ParseHex( input[i + 2] ) * 16 + Utils.ParseHex( input[i + 3] );
                int b = Utils.ParseHex( input[i + 4] ) * 16 + Utils.ParseHex( input[i + 5] );
                value = new FastColour( r, g, b );
                return true;
            } catch( FormatException ) {
                return false;
            }
        }
示例#46
0
 public static FastColour Scale( FastColour value, float t )
 {
     FastColour result = value;
     result.R = (byte)( value.R * t );
     result.G = (byte)( value.G * t );
     result.B = (byte)( value.B * t );
     return result;
 }
		void HandleCpeEnvColours() {
			byte variable = reader.ReadUInt8();
			short red = reader.ReadInt16();
			short green = reader.ReadInt16();
			short blue = reader.ReadInt16();
			bool invalid = red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255;
			FastColour col = new FastColour( red, green, blue );

			if( variable == 0 ) { // sky colour
				game.Map.SetSkyColour( invalid ? Map.DefaultSkyColour : col );
			} else if( variable == 1 ) { // clouds colour
				game.Map.SetCloudsColour( invalid ? Map.DefaultCloudsColour : col );
			} else if( variable == 2 ) { // fog colour
				game.Map.SetFogColour( invalid ? Map.DefaultFogColour : col );
			} else if( variable == 3 ) { // ambient light (shadow light)
				game.Map.SetShadowlight( invalid ? Map.DefaultShadowlight : col );
			} else if( variable == 4 ) { // diffuse light (sun light)
				game.Map.SetSunlight( invalid ? Map.DefaultSunlight : col );
			}
		}
示例#48
0
 /// <summary> Clears the entire bound bitmap to the specified colour. </summary>
 public abstract void Clear( FastColour colour );
示例#49
0
        void ReadPacket( byte opcode )
        {
            reader.Remove( 1 ); // remove opcode
            lastOpcode = (PacketId)opcode;

            switch( (PacketId)opcode ) {
                case PacketId.Handshake:
                    {
                        byte protocolVer = reader.ReadUInt8();
                        ServerName = reader.ReadAsciiString();
                        ServerMotd = reader.ReadAsciiString();
                        game.LocalPlayer.SetUserType( reader.ReadUInt8() );
                        receivedFirstPosition = false;
                        game.LocalPlayer.ParseHackFlags( ServerName, ServerMotd );
                    } break;

                case PacketId.Ping:
                    break;

                case PacketId.LevelInitialise:
                    {
                        game.Map.Reset();
                        game.SetNewScreen( new LoadingMapScreen( game, ServerName, ServerMotd ) );
                        if( ServerMotd.Contains( "cfg=" ) ) {
                            ReadWomConfigurationAsync();
                        }
                        receivedFirstPosition = false;
                        gzipHeader = new GZipHeaderReader();
                        // Workaround because built in mono stream assumes that the end of stream
                        // has been reached the first time a read call returns 0. (MS.NET doesn't)
                        #if __MonoCS__
                        gzipStream = new DeflateStream( gzippedMap, true );
                        #else
                        gzipStream = new DeflateStream( gzippedMap, CompressionMode.Decompress );
                        if( OpenTK.Configuration.RunningOnMono ) {
                            Utils.LogWarning( "You are running on Mono, but this build does not support the Mono workaround." );
                            Utils.LogWarning( "You should either download the Mono compatible build or define '__MonoCS__' when targeting Mono. " +
                                             "(The Mono compiler already defines this by default)" );
                            Utils.LogWarning( "You will likely experience an 'Internal error (no progress possible) ReadInternal' exception when decompressing the map." );
                        }
                        #endif
                        mapSizeIndex = 0;
                        mapIndex = 0;
                        receiveStart = DateTime.UtcNow;
                    } break;

                case PacketId.LevelDataChunk:
                    {
                        int usedLength = reader.ReadInt16();
                        gzippedMap.Position = 0;
                        gzippedMap.SetLength( usedLength );

                        if( gzipHeader.done || gzipHeader.ReadHeader( gzippedMap ) ) {
                            if( mapSizeIndex < 4 ) {
                                mapSizeIndex += gzipStream.Read( mapSize, mapSizeIndex, 4 - mapSizeIndex );
                            }

                            if( mapSizeIndex == 4 ) {
                                if( map == null ) {
                                    int size = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
                                    map = new byte[size];
                                }
                                mapIndex += gzipStream.Read( map, mapIndex, map.Length - mapIndex );
                            }
                        }
                        reader.Remove( 1024 );
                        byte progress = reader.ReadUInt8();
                        game.Events.RaiseMapLoading( progress );
                    } break;

                case PacketId.LevelFinalise:
                    {
                        game.SetNewScreen( new NormalScreen( game ) );
                        int mapWidth = reader.ReadInt16();
                        int mapHeight = reader.ReadInt16();
                        int mapLength = reader.ReadInt16();

                        double loadingMs = ( DateTime.UtcNow - receiveStart ).TotalMilliseconds;
                        Utils.LogDebug( "map loading took:" + loadingMs );
                        game.Map.UseRawMap( map, mapWidth, mapHeight, mapLength );
                        game.Events.RaiseOnNewMapLoaded();
                        map = null;
                        gzipStream.Close();
                        if( sendWomId && !sentWomId ) {
                            SendChat( "/womid WoMClient-2.0.7" );
                            sentWomId = true;
                        }
                        gzipStream = null;
                        GC.Collect( 0 );
                    } break;

                case PacketId.SetBlock:
                    {
                        int x = reader.ReadInt16();
                        int y = reader.ReadInt16();
                        int z = reader.ReadInt16();
                        byte type = reader.ReadUInt8();
                        if( !game.Map.IsNotLoaded )
                            game.UpdateBlock( x, y, z, type );
                        else
                            Utils.LogWarning( "Server tried to update a block while still sending us the map!" );
                    } break;

                case PacketId.AddEntity:
                    {
                        byte entityId = reader.ReadUInt8();
                        string name = reader.ReadAsciiString();
                        AddEntity( entityId, name, name, true );
                    }  break;

                case PacketId.EntityTeleport:
                    {
                        byte entityId = reader.ReadUInt8();
                        ReadAbsoluteLocation( entityId, true );
                    } break;

                case PacketId.RelPosAndOrientationUpdate:
                    ReadRelativeLocation();
                    break;

                case PacketId.RelPosUpdate:
                    ReadRelativePosition();
                    break;

                case PacketId.OrientationUpdate:
                    ReadOrientation();
                    break;

                case PacketId.RemoveEntity:
                    {
                        byte entityId = reader.ReadUInt8();
                        Player player = game.Players[entityId];
                        if( entityId != 0xFF && player != null ) {
                            game.Events.RaiseEntityRemoved( entityId );
                            player.Despawn();
                            game.Players[entityId] = null;
                        }
                    } break;

                case PacketId.Message:
                    {
                        byte messageType = reader.ReadUInt8();
                        string text = reader.ReadChatString( ref messageType, useMessageTypes );
                        game.Chat.Add( text, (CpeMessage)messageType );
                    } break;

                case PacketId.Kick:
                    {
                        string reason = reader.ReadAsciiString();
                        game.Disconnect( "&eLost connection to the server", reason );
                        Dispose();
                    } break;

                case PacketId.SetPermission:
                    {
                        game.LocalPlayer.SetUserType( reader.ReadUInt8() );
                    } break;

                case PacketId.CpeExtInfo:
                    {
                        string appName = reader.ReadAsciiString();
                        Utils.LogDebug( "Server identified itself as: " + appName );
                        cpeServerExtensionsCount = reader.ReadInt16();
                    } break;

                case PacketId.CpeExtEntry:
                    {
                        string extName = reader.ReadAsciiString();
                        int extVersion = reader.ReadInt32();
                        Utils.LogDebug( "cpe ext: " + extName + " , " + extVersion );
                        if( extName == "HeldBlock" ) {
                            sendHeldBlock = true;
                        } else if( extName == "MessageTypes" ) {
                            useMessageTypes = true;
                        } else if( extName == "ExtPlayerList" ) {
                            UsingExtPlayerList = true;
                        } else if( extName == "PlayerClick" ) {
                            UsingPlayerClick = true;
                        } else if( extName == "EnvMapAppearance" && extVersion == 2 ) {
                            usingTexturePack = true;
                        }
                        cpeServerExtensionsCount--;

                        if( cpeServerExtensionsCount == 0 ) {
                            MakeExtInfo( Utils.AppName, clientExtensions.Length );
                            SendPacket();
                            for( int i = 0; i < clientExtensions.Length; i++ ) {
                                string name = clientExtensions[i];
                                int version = (name == "ExtPlayerList" || name == "EnvMapApperance") ? 2 : 1;
                                MakeExtEntry( name, version );
                                SendPacket();
                            }
                        }
                    } break;

                case PacketId.CpeSetClickDistance:
                    {
                        game.LocalPlayer.ReachDistance = reader.ReadInt16() / 32f;
                    } break;

                case PacketId.CpeCustomBlockSupportLevel:
                    {
                        byte supportLevel = reader.ReadUInt8();
                        MakeCustomBlockSupportLevel( 1 );
                        SendPacket();

                        if( supportLevel == 1 ) {
                            for( int i = (int)Block.CobblestoneSlab; i <= (int)Block.StoneBrick; i++ ) {
                                game.Inventory.CanPlace[i] = true;
                                game.Inventory.CanDelete[i] = true;
                            }
                            game.Events.RaiseBlockPermissionsChanged();
                        } else {
                            Utils.LogWarning( "Server's block support level is {0}, this client only supports level 1.", supportLevel );
                            Utils.LogWarning( "You won't be able to see or use blocks from levels above level 1" );
                        }
                    } break;

                case PacketId.CpeHoldThis:
                    {
                        byte blockType = reader.ReadUInt8();
                        bool canChange = reader.ReadUInt8() == 0;
                        game.Inventory.CanChangeHeldBlock = true;
                        game.Inventory.HeldBlock = (Block)blockType;
                        game.Inventory.CanChangeHeldBlock = canChange;
                    } break;

                case PacketId.CpeExtAddPlayerName:
                    {
                        short nameId = reader.ReadInt16();
                        string playerName = Utils.StripColours( reader.ReadAsciiString() );
                        string listName = reader.ReadAsciiString();
                        string groupName = reader.ReadAsciiString();
                        byte groupRank = reader.ReadUInt8();
                        if( nameId >= 0 && nameId <= 255 ) {
                            CpeListInfo oldInfo = game.CpePlayersList[nameId];
                            CpeListInfo info = new CpeListInfo( (byte)nameId, playerName, listName, groupName, groupRank );
                            game.CpePlayersList[nameId] = info;

                            if( oldInfo != null ) {
                                game.Events.RaiseCpeListInfoChanged( (byte)nameId );
                            } else {
                                game.Events.RaiseCpeListInfoAdded( (byte)nameId );
                            }
                        }
                    } break;

                case PacketId.CpeExtAddEntity:
                    {
                        byte entityId = reader.ReadUInt8();
                        string displayName = reader.ReadAsciiString();
                        string skinName = reader.ReadAsciiString();
                        AddEntity( entityId, displayName, skinName, false );
                    } break;

                case PacketId.CpeExtRemovePlayerName:
                    {
                        short nameId = reader.ReadInt16();
                        if( nameId >= 0 && nameId <= 255 ) {
                            game.Events.RaiseCpeListInfoRemoved( (byte)nameId );
                            game.CpePlayersList[nameId] = null;
                        }
                    } break;

                case PacketId.CpeMakeSelection:
                    {
                        byte selectionId = reader.ReadUInt8();
                        string label = reader.ReadAsciiString();
                        short startX = reader.ReadInt16();
                        short startY = reader.ReadInt16();
                        short startZ = reader.ReadInt16();
                        short endX = reader.ReadInt16();
                        short endY = reader.ReadInt16();
                        short endZ = reader.ReadInt16();

                        byte r = (byte)reader.ReadInt16();
                        byte g = (byte)reader.ReadInt16();
                        byte b = (byte)reader.ReadInt16();
                        byte a = (byte)reader.ReadInt16();

                        Vector3I p1 = Vector3I.Min( startX, startY, startZ, endX, endY, endZ );
                        Vector3I p2 = Vector3I.Max( startX, startY, startZ, endX, endY, endZ );
                        FastColour col = new FastColour( r, g, b, a );
                        game.SelectionManager.AddSelection( selectionId, p1, p2, col );
                    } break;

                case PacketId.CpeRemoveSelection:
                    {
                        byte selectionId = reader.ReadUInt8();
                        game.SelectionManager.RemoveSelection( selectionId );
                    } break;

                case PacketId.CpeEnvColours:
                    {
                        byte variable = reader.ReadUInt8();
                        short red = reader.ReadInt16();
                        short green = reader.ReadInt16();
                        short blue = reader.ReadInt16();
                        bool invalid = red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255;
                        FastColour col = new FastColour( red, green, blue );

                        if( variable == 0 ) { // sky colour
                            game.Map.SetSkyColour( invalid ? Map.DefaultSkyColour : col );
                        } else if( variable == 1 ) { // clouds colour
                            game.Map.SetCloudsColour( invalid ? Map.DefaultCloudsColour : col );
                        } else if( variable == 2 ) { // fog colour
                            game.Map.SetFogColour( invalid ? Map.DefaultFogColour : col );
                        } else if( variable == 3 ) { // ambient light (shadow light)
                            game.Map.SetShadowlight( invalid ? Map.DefaultShadowlight : col );
                        } else if( variable == 4 ) { // diffuse light (sun light)
                            game.Map.SetSunlight( invalid ? Map.DefaultSunlight : col );
                        }
                    } break;

                case PacketId.CpeSetBlockPermission:
                    {
                        byte blockId = reader.ReadUInt8();
                        bool canPlace = reader.ReadUInt8() != 0;
                        bool canDelete = reader.ReadUInt8() != 0;
                        Inventory inv = game.Inventory;

                        if( blockId == 0 ) {
                            for( int i = 1; i < BlockInfo.CpeBlocksCount; i++ ) {
                                inv.CanPlace.SetNotOverridable( canPlace, i );
                                inv.CanDelete.SetNotOverridable( canDelete, i );
                            }
                        } else {
                            inv.CanPlace.SetNotOverridable( canPlace, blockId );
                            inv.CanDelete.SetNotOverridable( canDelete, blockId );
                        }
                        game.Events.RaiseBlockPermissionsChanged();
                    } break;

                case PacketId.CpeChangeModel:
                    {
                        byte playerId = reader.ReadUInt8();
                        string modelName = reader.ReadAsciiString().ToLowerInvariant();
                        Player player = game.Players[playerId];
                        if( player != null ) {
                            player.SetModel( modelName );
                        }
                    } break;

                case PacketId.CpeEnvSetMapApperance:
                    {
                        string url = reader.ReadAsciiString();
                        byte sideBlock = reader.ReadUInt8();
                        byte edgeBlock = reader.ReadUInt8();
                        short waterLevel = reader.ReadInt16();
                        game.Map.SetWaterLevel( waterLevel );
                        game.Map.SetEdgeBlock( (Block)edgeBlock );
                        game.Map.SetSidesBlock( (Block)sideBlock );
                        if( url == String.Empty ) {
                            TexturePackExtractor extractor = new TexturePackExtractor();
                            extractor.Extract( game.defaultTexPack, game );
                        } else {
                            game.Animations.Dispose();
                            if( usingTexturePack )
                                game.AsyncDownloader.DownloadData( url, true, "texturePack" );
                            else
                                game.AsyncDownloader.DownloadImage( url, true, "terrain" );

                        }
                        Utils.LogDebug( "Image url: " + url );
                    } break;

                case PacketId.CpeEnvWeatherType:
                    game.Map.SetWeather( (Weather)reader.ReadUInt8() );
                    break;

                case PacketId.CpeHackControl:
                    {
                        game.LocalPlayer.CanFly = reader.ReadUInt8() != 0;
                        game.LocalPlayer.CanNoclip = reader.ReadUInt8() != 0;
                        game.LocalPlayer.CanSpeed = reader.ReadUInt8() != 0;
                        game.LocalPlayer.CanRespawn = reader.ReadUInt8() != 0;
                        game.CanUseThirdPersonCamera = reader.ReadUInt8() != 0;
                        if( !game.CanUseThirdPersonCamera ) {
                            game.SetCamera( false );
                        }
                        float jumpHeight = reader.ReadInt16() / 32f;
                        if( jumpHeight < 0 ) jumpHeight = 1.4f;
                        game.LocalPlayer.CalculateJumpVelocity( jumpHeight );
                    } break;

                case PacketId.CpeExtAddEntity2:
                    {
                        byte entityId = reader.ReadUInt8();
                        string displayName = reader.ReadAsciiString();
                        string skinName = reader.ReadAsciiString();
                        AddEntity( entityId, displayName, skinName, true );
                    } break;

                case PacketId.CpeDefineBlock:
                case PacketId.CpeDefineLiquid:
                    {
                        byte block = reader.ReadUInt8();
                        BlockInfo info = game.BlockInfo;
                        info.ResetBlockInfo( block );

                        info.Name[block] = reader.ReadAsciiString();
                        info.CollideType[block] = (BlockCollideType)reader.ReadUInt8();
                        // TODO: Liquid collide type not properly supported.
                        info.SpeedMultiplier[block] = (float)Math.Pow( 2, (reader.ReadUInt8() - 128) / 64f );
                        info.SetTop( reader.ReadUInt8(), (Block)block );
                        info.SetSide( reader.ReadUInt8(), (Block)block );
                        info.SetBottom( reader.ReadUInt8(), (Block)block );
                        reader.ReadUInt8(); // opacity hint, but we ignore this.
                        info.BlocksLight[block] = reader.ReadUInt8() == 0;
                        reader.ReadUInt8(); // walk sound, but we ignore this.
                        info.EmitsLight[block] = reader.ReadUInt8() != 0;

                        if( opcode == (byte)PacketId.CpeDefineBlock ) {
                            byte shape = reader.ReadUInt8();
                            if( shape == 1 ) info.Height[block] = 1;
                            else if( shape == 2 ) info.Height[block] = 0.5f;
                            // TODO: upside down slab not properly supported
                            else if( shape == 3 ) info.Height[block] = 0.5f;
                            else if( shape == 4 ) info.IsSprite[block] = true;

                            byte blockDraw = reader.ReadUInt8();
                            if( blockDraw == 0 ) info.IsOpaque[block] = true;
                            else if( blockDraw == 1 ) info.IsTransparent[block] = true;
                            else if( blockDraw == 2 ) info.IsTranslucent[block] = true;
                            else if( blockDraw == 3 ) info.IsTranslucent[block] = true;

                            Console.WriteLine( block + " : " + shape + "," + blockDraw );
                        } else {
                            byte fogDensity = reader.ReadUInt8();
                            info.FogDensity[block] = fogDensity == 0 ? 0 : (fogDensity + 1) / 128f;
                            info.FogColour[block] = new FastColour(
                                reader.ReadUInt8(), reader.ReadUInt8(), reader.ReadUInt8() );
                        }
                        info.SetupCullingCache();
                    } break;

                case PacketId.CpeRemoveBlockDefinition:
                    game.BlockInfo.ResetBlockInfo( reader.ReadUInt8() );
                    break;

                default:
                    throw new NotImplementedException( "Unsupported packet:" + (PacketId)opcode );
            }
        }
        public override void Init()
        {
            X = 5;

            chatInputText.WordWrap( ref parts, ref partLens, 64 );
            maxWidth = 0;
            DrawTextArgs args = new DrawTextArgs( null, font, true );
            for( int i = 0; i < lines; i++ ) {
                args.Text = parts[i];
                sizes[i] = game.Drawer2D.MeasureChatSize( ref args );
                maxWidth = Math.Max( maxWidth, sizes[i].Width );
            }

            int realIndex = caretPos;
            if( chatInputText.Empty || caretPos == -1 || caretPos >= chatInputText.Length ) {
                caretPos = -1; realIndex = 500000;
            }

            int sum = 0, indexX = -1, indexY = 0;
            for( int i = 0; i < lines; i++ ) {
                if( partLens[i] == 0 ) break;

                indexY = i;
                if( realIndex < sum + partLens[i] ) {
                    indexX = realIndex - sum;
                    break;
                }
                sum += partLens[i];
            }
            if( indexX == -1 ) indexX = partLens[indexY];

            if( indexX == 64 ) {
                caretTex.X1 = 10 + sizes[indexY].Width;
                sizes[indexY].Width += caretTex.Width;

                maxWidth = Math.Max( maxWidth, sizes[indexY].Width );
                caretTex.Y1 = sizes[0].Height * indexY;
                caretCol = nextCaretCol;
            } else {
                args.Text = parts[indexY].Substring( 0, indexX );
                Size trimmedSize = game.Drawer2D.MeasureChatSize( ref args );
                caretTex.X1 = 10 + trimmedSize.Width;

                string line = parts[indexY];
                args.Text = indexX < line.Length ? new String( line[indexX], 1 ) : " ";
                Size charSize = game.Drawer2D.MeasureChatSize( ref args );
                caretTex.Width = charSize.Width;

                caretTex.Y1 = sizes[0].Height * indexY;
                caretCol = normalCaretCol;
            }
            DrawString();
            altText.texture.Y1 = game.Height - (YOffset + Height + altText.texture.Height);
            altText.Y = altText.texture.Y1;
        }
示例#51
0
 /// <summary> Draws the outline of a 2D flat rectangle of the specified dimensions
 /// at the specified coordinates in the currently bound bitmap. </summary>
 public abstract void DrawRectBounds( FastColour colour, float lineWidth, int x, int y, int width, int height );
        void DrawRun( FastBitmap dst, int x, int y, int xMul, string text,
            int runCount, byte* coords, int point, FastColour col)
        {
            if( runCount == 0 ) return;
            int srcY = (coords[0] >> 4) * boxSize;
            int textHeight = AdjTextSize( point ), cellHeight = CellSize( textHeight );
            int padding = (cellHeight - textHeight) / 2;
            int startX = x;

            ushort* dstWidths = stackalloc ushort[runCount];
            for( int i = 0; i < runCount; i++ )
                dstWidths[i] = (ushort)PtToPx( point, widths[coords[i]] );

            for( int yy = 0; yy < textHeight; yy++ ) {
                int fontY = srcY + yy * boxSize / textHeight;
                int* fontRow = fontPixels.GetRowPtr( fontY );
                int dstY = y + (yy + padding);
                if( dstY >= dst.Height ) return;

                int* dstRow = dst.GetRowPtr( dstY );
                int xOffset = xMul * ((textHeight - 1 - yy) / italicSize);
                for( int i = 0; i < runCount; i++ ) {
                    int srcX = (coords[i] & 0x0F) * boxSize;
                    int srcWidth = widths[coords[i]], dstWidth = dstWidths[i];

                    for( int xx = 0; xx < dstWidth; xx++ ) {
                        int fontX = srcX + xx * srcWidth / dstWidth;
                        int src = fontRow[fontX];
                        if( (byte)(src >> 24) == 0 ) continue;
                        int dstX = x + xx + xOffset;
                        if( dstX >= dst.Width ) break;

                        int pixel = src & ~0xFFFFFF;
                        pixel |= ((src & 0xFF) * col.B / 255);
                        pixel |= (((src >> 8) & 0xFF) * col.G / 255) << 8;
                        pixel |= (((src >> 16) & 0xFF) * col.R / 255) << 16;
                        dstRow[dstX] = pixel;
                    }
                    x += PtToPx( point, srcWidth + 1 );
                }
                x = startX;
            }
        }
示例#53
0
        void Stretch( int x1, int y1, int z1 )
        {
            for( int i = 0; i < counts.Length; i++ ) {
                counts[i] = 1;
            }

            int xMax = Math.Min( width, x1 + chunkSize );
            int yMax = Math.Min( height, y1 + chunkSize );
            int zMax = Math.Min( length, z1 + chunkSize );
            #if DEBUG_OCCLUSION
            int flags = ComputeOcclusion();
            FastColour col = new FastColour( 60, 60, 60, 255 );
            if( (flags & 1) != 0 ) col.R = 255; // x
            if( (flags & 4) != 0 ) col.G = 255; // y
            if( (flags & 2) != 0 ) col.B = 255; // z
            map.Sunlight = map.Shadowlight = col;
            map.SunlightXSide = map.ShadowlightXSide = col;
            map.SunlightZSide = map.ShadowlightZSide = col;
            map.SunlightYBottom = map.ShadowlightYBottom = col;
            #endif

            for( int y = y1, yy = 0; y < yMax; y++, yy++ ) {
                for( int z = z1, zz = 0; z < zMax; z++, zz++ ) {

                    int chunkIndex = (yy + 1) * extChunkSize2 + (zz + 1) * extChunkSize + (-1 + 1);
                    for( int x = x1, xx = 0; x < xMax; x++, xx++ ) {
                        chunkIndex++;
                        byte tile = chunk[chunkIndex];
                        if( tile == 0 ) continue;
                        int countIndex = ((yy << 8) + (zz << 4) + xx) * TileSide.Sides;

                        // Sprites only use one face to indicate stretching count, so we can take a shortcut here.
                        // Note that sprites are not drawn with any of the DrawXFace, they are drawn using DrawSprite.
                        if( info.IsSprite[tile] ) {
                            countIndex += TileSide.Top;
                            if( counts[countIndex] != 0 ) {
                                X = x; Y = y; Z = z;
                                AddSpriteVertices( tile, 1 );
                                counts[countIndex] = 1;
                            }
                        } else {
                            X = x; Y = y; Z = z;
                            fullBright = info.FullBright[tile];
                            TestAndStretchZ( zz, countIndex, tile, chunkIndex, x, 0, TileSide.Left, -1 );
                            TestAndStretchZ( zz, countIndex, tile, chunkIndex, x, maxX, TileSide.Right, 1 );
                            TestAndStretchX( xx, countIndex, tile, chunkIndex, z, 0, TileSide.Front, -extChunkSize );
                            TestAndStretchX( xx, countIndex, tile, chunkIndex, z, maxZ, TileSide.Back, extChunkSize );

                            if( y > 0 )
                                TestAndStretchX( xx, countIndex, tile, chunkIndex, y, 0, TileSide.Bottom, -extChunkSize2 );
                            else
                                counts[countIndex + TileSide.Bottom] = 0;
                            TestAndStretchX( xx, countIndex, tile, chunkIndex, y, maxY + 2, TileSide.Top, extChunkSize2 );
                        }
                    }
                }
            }
        }
示例#54
0
 void DrawCrosshairs()
 {
     int curCol = 150 + (int)( 50 * Math.Abs( Math.Sin( game.accumulator ) ) );
     FastColour col = new FastColour( curCol, curCol, curCol );
     float centreX = game.Width / 2, centreY = game.Height / 2;
     graphicsApi.Draw2DQuad( centreX - crosshairExtent, centreY - crosshairWeight,
                            crosshairExtent * 2, crosshairWeight * 2, col );
     graphicsApi.Draw2DQuad( centreX - crosshairWeight, centreY - crosshairExtent,
                            crosshairWeight * 2, crosshairExtent * 2, col );
 }
示例#55
0
 /// <summary> Draws a 2D flat rectangle of the specified dimensions at the
 /// specified coordinates in the currently bound bitmap. </summary>
 public abstract void DrawRect( FastColour colour, int x, int y, int width, int height );
示例#56
0
 public void Render( IGraphicsApi graphics, FastColour colour )
 {
     graphics.BindTexture( ID );
     graphics.Draw2DTexture( ref this, colour );
 }
示例#57
0
 public TextPart( string text, FastColour col )
 {
     Text = text;
     TextColour = col;
 }
示例#58
0
        void DrawZ( int z, int x1, int x2, int y1, int y2, int axisSize, FastColour col, ref VertexPos3fTex2fCol4b* vertices )
        {
            int endX = x2, endY = y2, startY = y1;
            for( ; x1 < endX; x1 += axisSize ) {
                x2 = x1 + axisSize;
                if( x2 > endX ) x2 = endX;
                y1 = startY;
                for( ; y1 < endY; y1 += axisSize ) {
                    y2 = y1 + axisSize;
                    if( y2 > endY ) y2 = endY;

                    TextureRectangle rec = new TextureRectangle( 0, 0, x2 - x1, y2 - y1 );
                    *vertices++ = new VertexPos3fTex2fCol4b( x1, y1, z, rec.U1, rec.V1, col );
                    *vertices++ = new VertexPos3fTex2fCol4b( x1, y2, z, rec.U1, rec.V2, col );
                    *vertices++ = new VertexPos3fTex2fCol4b( x2, y2, z, rec.U2, rec.V2, col );
                    *vertices++ = new VertexPos3fTex2fCol4b( x2, y1, z, rec.U2, rec.V1, col );
                }
            }
        }
示例#59
0
 /// <summary> Clears the entire given area to the specified colour. </summary>
 public abstract void Clear( FastColour colour, int x, int y, int width, int height );
		void HandleCpeMakeSelection() {
			byte selectionId = reader.ReadUInt8();
			string label = reader.ReadAsciiString();
			short startX = reader.ReadInt16();
			short startY = reader.ReadInt16();
			short startZ = reader.ReadInt16();
			short endX = reader.ReadInt16();
			short endY = reader.ReadInt16();
			short endZ = reader.ReadInt16();
			
			byte r = (byte)reader.ReadInt16();
			byte g = (byte)reader.ReadInt16();
			byte b = (byte)reader.ReadInt16();
			byte a = (byte)reader.ReadInt16();
			
			Vector3I p1 = Vector3I.Min( startX, startY, startZ, endX, endY, endZ );
			Vector3I p2 = Vector3I.Max( startX, startY, startZ, endX, endY, endZ );
			FastColour col = new FastColour( r, g, b, a );
			game.SelectionManager.AddSelection( selectionId, p1, p2, col );
		}