Example #1
0
        public void Draw(int width, int height,
            double startx, double starty,
            double scale, ref byte[] pixels,
            bool isHilight,
            int light, bool texture, bool houses, bool wires, bool fogofwar, ref Tile[,] tiles)
        {
            if (texture)
            {
                int blocksWide = (int)(width / Math.Floor(scale)) + 2; //scale=1.0 to 16.0
                int blocksHigh = (int)(height / Math.Floor(scale)) + 2;

                double adjustx = ((width / scale) - blocksWide) / 2;
                double adjusty = ((height / scale) - blocksHigh) / 2;
                startx += adjustx;
                starty += adjusty;

                int skipx = 0, skipy = 0;
                if (startx < 0) skipx = (int)-startx;
                if (starty < 0) skipy = (int)-starty;

                double shiftx = (startx - Math.Floor(startx)) * scale;
                double shifty = (starty - Math.Floor(starty)) * scale;
                int py, px;

                double lightR, lightG, lightB;

                // draw backgrounds

                int hellLevel = ((tilesHigh - 230) - groundLevel) / 6; //rounded
                hellLevel = hellLevel * 6 + groundLevel - 5;

                py = skipy * (int)scale;
                for (int y = skipy; y < blocksHigh; y++)
                {
                    int sy = (int)(y + starty);
                    px = skipx * (int)scale;

                    int bg = -1;
                    int bgw = 128, bgh = 16;
                    int v = sy;
                    if (sy < groundLevel)
                    {
                        bg = -1;
                        bgw = 16;
                    }
                    else if (sy == groundLevel)
                    {
                        bg = 0;
                        v = sy - groundLevel;
                    }
                    else if (sy < rockLevel)
                    {
                        bg = 1;
                        bgh = 96;
                        v = sy - groundLevel;
                    }
                    else if (sy == rockLevel)
                    {
                        bg = 2;
                        v = sy - rockLevel;
                    }
                    else if (sy < hellLevel)
                    {
                        bg = 3;
                        bgh = 96;
                        v = sy - rockLevel;
                    }
                    else if (sy == hellLevel)
                    {
                        bg = 4;
                        v = sy - hellLevel;
                    }
                    else
                    {
                        bg = 5;
                        bgh = 96;
                        v = sy - hellLevel;
                    }

                    for (int x = skipx; x < blocksWide; x++)
                    {
                        int sx = (int)(x + startx);
                        if (sx < 0 || sx >= tilesWide || sy < 0 || sy >= tilesHigh)
                            continue;

                        int bgtile=0;
                        if (bg >= 0)
                        {
                            int style = caveStyle[3];
                            if (sx <= caveX[0]) style = caveStyle[0];
                            else if (sx <= caveX[1]) style = caveStyle[1];
                            else if (sx <= caveX[2]) style = caveStyle[2];
                            if (style == 8 && jungleStyle != 0) style++;
                            bgtile = backStyles[bg + style * 6];
                            if (bg > 3) bgtile += hellStyle;
                        }
                        Texture tex = Textures.GetBackground(bgtile);
                        Tile tile = tiles[sx, sy];

                        if (light == 1)
                            lightR = lightG = lightB = tile.light;
                        else if (light == 2)
                        {
                            lightR = tile.lightR;
                            lightG = tile.lightG;
                            lightB = tile.lightB;
                        }
                        else
                            lightR = lightG = lightB = 1.0;

                        if (isHilight)
                        {
                            lightR *= 0.3;
                            lightG *= 0.3;
                            lightB *= 0.3;
                        }
                        if (fogofwar && !tile.seen)
                            lightR = lightG = lightB = 0.0;

                        int u = (sx % (bgw / 16)) * 16;
                        int vv = (v % (bgh / 16)) * 16;
                        if (bg == -1) //sky
                            vv = sy * (tex.height-16) / groundLevel;
                        drawTexture(tex, 16, 16, vv * tex.width * 4 + u * 4,
                            pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, 0);

                        px += (int)scale;
                    }
                    py += (int)scale;
                }

                //draw walls

                Texture wallOutline = Textures.GetWallOutline(0);

                py = skipy * (int)scale - (int)(scale / 2);
                for (int y = skipy; y < blocksHigh; y++)
                {
                    int sy = (int)(y + starty);

                    px = skipx * (int)scale - (int)(scale / 2);
                    for (int x = skipx; x < blocksWide; x++)
                    {
                        int sx = (int)(x + startx);

                        if (sx < 0 || sx >= tilesWide || sy < 0 || sy >= tilesHigh)
                            continue;

                        Tile tile = tiles[sx, sy];

                        if (tile.wall > 0)
                        {
                            if (tile.wallu == -1) fixWall(sx, sy, ref tiles);
                            Texture tex = Textures.GetWall(tile.wall);
                            if (light == 1)
                                lightR = lightG = lightB = tile.light;
                            else if (light == 2)
                            {
                                lightR = tile.lightR;
                                lightG = tile.lightG;
                                lightB = tile.lightB;
                            }
                            else
                                lightR = lightG = lightB = 1.0;

                            if (isHilight)
                            {
                                lightR *= 0.3;
                                lightG *= 0.3;
                                lightB *= 0.3;
                            }

                            if (fogofwar && !tile.seen)
                                lightR = lightG = lightB = 0.0;

                            drawTexture(tex, 32, 32, tile.wallv * tex.width * 4 * 2 + tile.wallu * 4 * 2,
                                pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.wallColor);
                            Int16 blend = wallInfo[tile.wall].blend;
                            if (sx > 0 && tiles[sx - 1, sy].wall > 0 &&
                                wallInfo[tiles[sx - 1, sy].wall].blend != blend)
                                drawTexture(wallOutline, 2, 16, 0,
                                    pixels, (int)(px + (scale / 2) - shiftx), (int)(py + (scale / 2) - shifty), width, height, scale / 16.0, lightR, lightG, lightB, 0);
                            double pad = 14.0 * scale / 16.0;
                            if (sx < tilesWide - 2 && tiles[sx + 1, sy].wall > 0 &&
                                wallInfo[tiles[sx + 1, sy].wall].blend != blend)
                                drawTexture(wallOutline, 2, 16, 14 * 4 * 2,
                                    pixels, (int)(px + pad + (scale / 2) - shiftx), (int)(py + (scale / 2) - shifty), width, height, scale / 16.0, lightR, lightG, lightB,0);
                            if (sy > 0 && tiles[sx, sy - 1].wall > 0 &&
                                wallInfo[tiles[sx, sy - 1].wall].blend != blend)
                                drawTexture(wallOutline, 16, 2, 0,
                                    pixels, (int)(px + (scale / 2) - shiftx), (int)(py + (scale / 2) - shifty), width, height, scale / 16.0, lightR, lightG, lightB,0);
                            if (sy < tilesHigh - 2 && tiles[sx, sy + 1].wall > 0 &&
                                wallInfo[tiles[sx, sy + 1].wall].blend != blend)
                                drawTexture(wallOutline, 16, 2, 14 * tex.width * 4 * 2,
                                    pixels, (int)(px + (scale / 2) - shiftx), (int)(py + pad + (scale / 2) - shifty), width, height, scale / 16.0, lightR, lightG, lightB,0);
                        }

                        px += (int)scale;
                    }
                    py += (int)scale;
                }

                List<Delayed> delayed = new List<Delayed>();

                //draw tiles
                py = skipy * (int)scale;
                for (int y = skipy; y < blocksHigh; y++)
                {
                    int sy = (int)(y + starty);
                    px = skipx * (int)scale;
                    for (int x = skipx; x < blocksWide; x++)
                    {
                        int sx = (int)(x + startx);

                        if (sx < 0 || sx >= tilesWide || sy < 0 || sy >= tilesHigh)
                            continue;

                        Tile tile = tiles[sx, sy];

                        if (light == 1)
                            lightR = lightG = lightB = tiles[sx, sy].light;
                        else if (light == 2)
                        {
                            lightR = tile.lightR;
                            lightG = tile.lightG;
                            lightB = tile.lightB;
                        }
                        else
                            lightR = lightG = lightB = 1.0;
                        if (tile.inactive)
                        {
                            lightR *= 0.4;
                            lightG *= 0.4;
                            lightB *= 0.4;
                        }

                        if (isHilight && (!tile.isActive || !tileInfos[tile.type, tile.u, tile.v].isHilighting))
                        {
                            lightR *= 0.3;
                            lightG *= 0.3;
                            lightB *= 0.3;
                        }
                        if (fogofwar && !tile.seen)
                            lightR = lightG = lightB = 0.0;

                        if (tile.isActive)
                        {
                            if (tile.u == -1 || tile.v == -1) fixTile(sx, sy, ref tiles);
                            bool flip = false;
                            // flip every other weed, coral, herb, banner, etc
                            if (tile.type==3 || tile.type==13 || tile.type==20 || tile.type==24 ||
                                tile.type==49 || tile.type==50 || tile.type==52 || tile.type==61 ||
                                tile.type==62 || tile.type==71 || tile.type==73 || tile.type==73 ||
                                tile.type==74 || tile.type==81 || tile.type==82 || tile.type==84 ||
                                tile.type==91 || tile.type==92 || tile.type==93 || tile.type==110 ||
                                tile.type==113 || tile.type==115 || tile.type==135 || tile.type==141 ||
                                tile.type==165 || tile.type==201 || tile.type==205 || tile.type==227)
                                flip=(sx&1)==1;

                            int texw = 16;
                            int texh = 16;
                            int toppad = 0;
                            if (tile.type == 4 && tileInfos[tiles[sx,sy-1].type].solid) //torch
                            {
                                toppad = 2;
                                if (tileInfos[tiles[sx - 1, sy + 1].type].solid ||
                                    tileInfos[tiles[sx + 1, sy + 1].type].solid)
                                    toppad = 4;
                            }
                            if (tile.type == 78 || tile.type == 85 || tile.type == 105 || tile.type==132 ||
                                tile.type == 133 || tile.type == 134 || tile.type==135 || tile.type == 139 ||
                                tile.type == 142 || tile.type == 143 || (tile.type == 178 && tile.v <= 36) ||
                                tile.type == 185 || tile.type == 186 || tile.type == 187 || tile.type == 207 ||
                                tile.type == 210 || tile.type == 215 || tile.type == 217 || tile.type == 218 ||
                                tile.type == 219 || tile.type == 220 || tile.type == 231 || tile.type == 233 ||
                                tile.type == 243 || tile.type == 244 || tile.type == 247 || tile.type == 254) //small items have a gap
                                toppad = 2;
                            if (tile.type == 33 || tile.type == 49 || tile.type == 174) //candles
                                toppad = -4;

                            //trees and weeds and others are 20 pixels tall
                            if (tile.type == 3 || tile.type == 4 || tile.type == 5 || tile.type == 24 ||
                                tile.type == 33 || tile.type == 49 || tile.type == 61 || tile.type == 71 ||
                                tile.type == 110 || tile.type == 174 || tile.type == 201)
                                texh = 20;
                            // furniture and others are 18 pixels tall
                            else if (tile.type == 14 || tile.type == 15 || tile.type == 16 || tile.type == 17 ||
                                tile.type == 18 || tile.type == 20 || tile.type == 21 || tile.type == 26 ||
                                tile.type == 27 || tile.type == 32 || tile.type == 69 || tile.type == 72 ||
                                tile.type == 77 || tile.type == 80 || tile.type == 124 || tile.type == 132 ||
                                tile.type == 135 || tile.type == 137 || tile.type == 138)
                                texh = 18;
                            if (tile.type == 52) //vines
                                toppad -= 2;
                            if (tile.type == 28 || tile.type == 238 ) //pots and purple flower
                                toppad += 2;
                            if (tile.type == 4 || tile.type == 5) //torch and tree
                                texw = 20;
                            if (tile.type == 73 || tile.type == 74 || tile.type == 113) //weeds
                            {
                                toppad -= 12;
                                texh = 32;
                            }
                            if (tile.type == 227) //dye plants
                            {
                                texw = 32;
                                texh = 38;
                                if (tile.u == 238) //orange blood root
                                    toppad -= 6;
                                else
                                    toppad -= 20;
                            }
                            if (tile.type == 184) //flowers
                            {
                                texw = 20;
                                if (tile.v <= 36)
                                    toppad = 2;
                                else if (tile.v <= 108)
                                    toppad = -2;
                            }
                            if (tile.type == 81) //coral
                            {
                                toppad -= 8;
                                texw = 24;
                                texh = 26;
                            }

                            if (tile.type == 72 && tile.u>=36) //mushroom
                                drawMushroom(tile.u, tile.v,
                                    pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB);

                            if (tile.type == 103) //bowl
                                if (tile.u == 18) texw = 14;

                            //solid tile adjacent to water
                            if (tileInfos[tile.type].solid && (tiles[sx - 1, sy].liquid > 0 ||
                                tiles[sx + 1, sy].liquid > 0 || tiles[sx, sy - 1].liquid > 0 ||
                                tiles[sx, sy + 1].liquid > 0))
                            {
                                byte waterMask = 0;
                                double sideLevel = 0.0;
                                int v = 4;
                                int waterw = 16;
                                int waterh = 16;
                                double xpad = 0.0;
                                double ypad = 0.0;
                                //lrtb
                                int mask = 0;
                                Tile edge;
                                if ((edge = tiles[sx - 1, sy]).liquid > 0)
                                {
                                    sideLevel = edge.liquid;
                                    mask |= 8; //left
                                    if (edge.isLava)
                                        waterMask |= 2;
                                    else if (edge.isHoney)
                                        waterMask |= 4;
                                    else
                                        waterMask |= 1;
                                }
                                if ((edge = tiles[sx + 1, sy]).liquid > 0)
                                {
                                    sideLevel = edge.liquid;
                                    mask |= 4; //right
                                    if (edge.isLava)
                                        waterMask |= 2;
                                    else if (edge.isHoney)
                                        waterMask |= 4;
                                    else
                                        waterMask |= 1;
                                }
                                if ((edge = tiles[sx, sy - 1]).liquid > 0)
                                {
                                    mask |= 2; //top
                                    if (edge.isLava)
                                        waterMask |= 2;
                                    else if (edge.isHoney)
                                        waterMask |= 4;
                                    else
                                        waterMask |= 1;
                                }
                                else if (!edge.isActive || !tileInfos[edge.type].solid)
                                    v = 0; // water has a ripple
                                if ((edge = tiles[sx, sy + 1]).liquid > 0)
                                {
                                    if (edge.liquid > 240)
                                        mask |= 1; //bottom is high enough
                                    if (edge.isLava)
                                        waterMask |= 2;
                                    else if (edge.isHoney)
                                        waterMask |= 4;
                                    else
                                        waterMask |= 1;
                                }
                                if ((waterMask & 3) != 3) //don't render if water *and* lava
                                {
                                    int waterid = 0; //water
                                    if ((waterMask & 2) == 2) //lava
                                        waterid = 1;
                                    if ((waterMask & 4) == 4) //honey
                                        waterid = 11;
                                    if ((mask & 0xc) != 0 && (mask & 1) == 1) //bottom and any side?
                                        mask |= 0xc; //same as both sides
                                    if (tile.half || tile.slope > 0) //half block or slope?
                                        mask |= 0x10;
                                    sideLevel = (256 - sideLevel) / 32.0;
                                    if (mask == 2) //hlrTb
                                        waterh = 4;
                                    else if (mask == 0x12) //HlrTb
                                        waterh = 12;
                                    else if ((mask & 0xf) == 1) //lrtB
                                    {
                                        waterh = 4;
                                        ypad = 12.0 * scale / 16.0;
                                    }
                                    else if ((mask & 2) != 2) //t
                                    {
                                        waterh = (int)(16 - sideLevel * 2);
                                        ypad = sideLevel * 2.0 * scale / 16.0;
                                        if ((mask & 0x1c) == 0x8) //!half Lr
                                            waterw = 4;
                                        if ((mask & 0x1c) == 0x4) //!half lR
                                        {
                                            waterw = 4;
                                            xpad = 12 * scale / 16.0;
                                        }
                                    }
                                    double alpha = waterid == 0 ? 0.5 : 0.85;
                                    Texture tex = Textures.GetLiquid(waterid);
                                    drawTextureAlpha(tex, waterw, waterh, v * tex.width * 4,
                                        pixels, (int)(px + xpad - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, 0, alpha);
                                }
                            }

                            if (tile.type == 5 && tile.v >= 198 && tile.u >= 22) //tree leaves
                            {
                                Delayed delay = new Delayed();
                                delay.px = (int)(px - shiftx);
                                delay.py = (int)(py - shifty);
                                delay.sx = sx;
                                delay.sy = sy;
                                delayed.Add(delay);
                            }
                            else if (tile.type == 128) //armor
                            {
                                int au = tile.u % 100;
                                //draw armor stand
                                Texture tex = Textures.GetTile(tile.type);
                                drawTexture(tex, texw, texh, tile.v * tex.width * 4 + au * 4,
                                    pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB,tile.color);
                                //draw armor
                                int armor = tile.u / 100;
                                if (armor > 0)
                                {
                                    Delayed delay = new Delayed();
                                    delay.sx = sx;
                                    delay.sy = sy;
                                    delay.px = (int)(px - shiftx);
                                    delay.py = (int)(py - shifty);
                                    delayed.Add(delay);
                                }
                            }
                            else if (tile.type == 237 && tile.u == 18 && tile.v == 0) //lihzahrd altar
                            {
                                Delayed delay = new Delayed();
                                delay.sx = sx;
                                delay.sy = sy;
                                delay.px = (int)(px - shiftx);
                                delay.py = (int)(py - shifty);
                                delayed.Add(delay);
                            }
                            else if (tile.type == 5) //tree
                            {
                                int wood = -1;
                                int trunkx = sx;
                                int trunky = sy;
                                if (tile.u == 66 && tile.v <= 45) trunkx++;
                                if (tile.u == 88 && tile.v >= 66 && tile.v <= 110) trunkx--;
                                if (tile.u == 22 && tile.v >= 132) trunkx--;
                                if (tile.u == 44 && tile.v >= 132) trunkx++;
                                while (tiles[trunkx, trunky].isActive && tiles[trunkx, trunky].type == 5)
                                    trunky++;
                                if (tiles[trunkx, trunky].isActive)
                                {
                                    switch (tiles[trunkx, trunky].type)
                                    {
                                        case 23: //corrupted grass
                                            wood = 0;
                                            break;
                                        case 60: //jungle grass
                                            wood = 1;
                                            if (trunky > groundLevel)
                                                wood = 5;
                                            break;
                                        case 70: //mushroom grass
                                            wood = 6;
                                            break;
                                        case 109: //hallowed grass
                                            wood = 2;
                                            break;
                                        case 147: //snow
                                            if (styles[3] != 0)
                                                wood = 3;
                                            break;
                                        case 199: //flesh
                                            wood = 4;
                                            break;
                                    }
                                }
                                Texture tex;
                                if (wood == -1)
                                    tex = Textures.GetTile(tile.type);
                                else
                                    tex = Textures.GetWood(wood);
                                drawTexture(tex, texw, texh, tile.v * tex.width * 4 + tile.u * 4,
                                    pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB,tile.color);
                            }
                            else if (tile.type == 80) //cactus
                            {
                                int cactus = -1;
                                int cactusx = sx;
                                int cactusy = sy;
                                if (tile.u == 36) cactusx--;
                                if (tile.u == 54) cactusx++;
                                if (tile.u == 108)
                                {
                                    if (tile.v == 18) cactusx--;
                                    else cactusx++;
                                }
                                while (cactusy<sy+20 && (!tiles[cactusx,cactusy].isActive
                                    || tiles[cactusx, cactusy].type == 80
                                    || !tileInfos[tiles[cactusx,cactusy].type].solid))
                                    cactusy++;
                                if (tiles[cactusx, cactusy].isActive)
                                {
                                    switch (tiles[cactusx, cactusy].type)
                                    {
                                        case 112: //ebonsand
                                            cactus = 1;
                                            break;
                                        case 116: //pearlsand
                                            cactus = 2;
                                            break;
                                        case 234: //crimsand
                                            cactus = 3;
                                            break;
                                    }
                                }
                                Texture tex;
                                if (cactus == -1)
                                    tex = Textures.GetTile(tile.type);
                                else
                                    tex = Textures.GetCactus(cactus);
                                drawTexture(tex, texw, texh, tile.v * tex.width * 4 + tile.u * 4,
                                    pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                            }
                            else
                            {
                                Texture tex;
                                tex = Textures.GetTile(tile.type);

                                double ypad = 0.0;
                                if (tile.slope > 0)
                                {
                                    if (tile.slope == 1)
                                    {
                                        for (int i = 0; i < 8; i++)
                                        {
                                            double xpad = ((double)i * 2.0) * scale / 16.0;
                                            ypad = ((double)toppad + (double)i * 2.0) * scale / 16.0;
                                            drawTexture(tex, 2, 14 - i * 2, tile.v * tex.width * 4 + (tile.u + i * 2) * 4,
                                                pixels, (int)(px + xpad - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                        }
                                    }
                                    if (tile.slope == 2)
                                    {
                                        for (int i = 0; i < 8; i++)
                                        {
                                            double xpad = (14 - (double)i * 2.0) * scale / 16.0;
                                            ypad = ((double)toppad + (double)i * 2.0) * scale / 16.0;
                                            drawTexture(tex, 2, 14 - i * 2, tile.v * tex.width * 4 + (tile.u + 14 - i * 2) * 4,
                                                pixels, (int)(px + xpad - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                        }
                                    }
                                    ypad = ((double)toppad + 14.0) * scale / 16.0;
                                    drawTexture(tex, 16, 2, (tile.v + 14) * tex.width * 4 + tile.u * 4,
                                        pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                }
                                else
                                {
                                    //non-platform solid tile next to a half tile
                                    if (!tile.half && tile.type != 19 && tileInfos[tile.type].solid && sx>0 && sx<tilesWide-2 &&
                                        (tiles[sx - 1, sy].half || tiles[sx + 1, sy].half))
                                    {
                                        if (tiles[sx - 1, sy].half && tiles[sx + 1, sy].half) //both sides
                                        {
                                            ypad = ((double)toppad + 8.0) * scale / 16.0;
                                            drawTexture(tex, texw, 8, (tile.v + 8) * tex.width * 4 + tile.u * 4,
                                                pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                            ypad = (double)toppad * scale / 16.0;
                                            drawTexture(tex, 16, 8, 126 * 4,
                                                pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                        }
                                        else
                                        {
                                            ypad = ((double)toppad + 8.0) * scale / 16.0;
                                            drawTexture(tex, texw, 8, (tile.v + 8) * tex.width * 4 + tile.u * 4,
                                                pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                            if (tiles[sx - 1, sy].half) //left side
                                            {
                                                double xpad = 4 * scale / 16.0;
                                                ypad = (double)toppad * scale / 16.0;
                                                drawTexture(tex, texw - 4, texh, tile.v * tex.width * 4 + (tile.u + 4) * 4,
                                                    pixels, (int)(px + xpad - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                                drawTexture(tex, 4, 8, 126 * 4,
                                                    pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                            }
                                            else //right side
                                            {
                                                ypad = (double)toppad * scale / 16.0;
                                                drawTexture(tex, texw - 4, texh, tile.v * tex.width * 4 + tile.u * 4,
                                                    pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                                double xpad = 12 * scale / 16.0;
                                                drawTexture(tex, 4, 8, 138 * 4,
                                                    pixels, (int)(px + xpad - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //half block on top of an empty space
                                        if (tile.half && (!tiles[sx, sy + 1].isActive || !tileInfos[tiles[sx, sy + 1].type].solid ||
                                            tiles[sx, sy + 1].half))
                                        {
                                            ypad = ((double)toppad + 8.0) * scale / 16.0;
                                            if (tile.type == 19) //platform
                                            {
                                                drawTexture(tex, texw, texh, tile.v * tex.width * 4 + tile.u * 4,
                                                    pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                            }
                                            else
                                            {
                                                drawTexture(tex, texw, texh - 12, tile.v * tex.width * 4 + tile.u * 4,
                                                    pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                                ypad = ((double)toppad + 12.0) * scale / 16.0;
                                                drawTexture(tex, texw, 4, 66 * tex.width * 4 + 144 * 4,
                                                    pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, tile.color);
                                            }
                                        }
                                        else
                                        {
                                            byte col = tile.color;
                                            // use grass shader?
                                            if (col > 0 && col < 13 && (tile.type == 0 || tile.type == 2 || tile.type == 5 ||
                                                tile.type == 23 || tile.type == 59 || tile.type == 60 || tile.type == 70 ||
                                                tile.type == 109 || tile.type == 199))
                                                col += 27;
                                            ypad = ((double)toppad + (tile.half ? 8.0 : 0.0)) * scale / 16.0;
                                            if (flip)
                                                drawTextureFlip(tex, texw - 1, texh, tile.v * tex.width * 4 + tile.u * 4,
            pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, col);
                                            else
                                                drawTexture(tex, texw, texh - (tile.half ? 8 : 0), tile.v * tex.width * 4 + tile.u * 4,
                                                pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, col);
                                        }
                                    }
                                }
                            }
                        }
                        // draw liquid
                        if (tile.liquid > 0 && (!tile.isActive || !tileInfos[tile.type].solid))
                        {
                            int waterLevel = (int)((255 - tile.liquid) / 16.0);
                            int waterid = 0;
                            if (tile.isLava) waterid = 1;
                            if (tile.isHoney) waterid = 11;
                            double alpha = waterid == 0 ? 0.5 : 0.85;
                            int waterh = 16 - waterLevel;
                            int v = 0;
                            double ypad = waterLevel * scale / 16.0;
                            //water above, no ripple
                            if (tiles[sx, sy - 1].liquid > 32 || (tiles[sx,sy-1].isActive && tileInfos[tiles[sx,sy-1].type].solid))
                                v = 4;

                            Texture tex = Textures.GetLiquid(waterid);
                            drawTextureAlpha(tex, 16, waterh, v * tex.width * 4,
                                pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, 0, alpha);
                        }
                        if (wires && tile.actuator)
                        {
                            Texture tex = Textures.GetActuator(0);
                            drawTexture(tex, 16, 16, 0,
                                pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, 0);
                        }
                        // draw wires if necessary
                        if (wires && tile.hasRedWire)
                            drawRedWire(sx, sy, pixels,
                                (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, ref tiles);
                        if (wires && tile.hasGreenWire)
                            drawGreenWire(sx, sy, pixels,
                                (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, ref tiles);
                        if (wires && tile.hasBlueWire)
                            drawBlueWire(sx, sy, pixels,
                                (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, ref tiles);

                        px += (int)scale;
                    }
                    py += (int)scale;
                }

                //draw delayed blocks
                foreach (Delayed delay in delayed)
                {
                    Texture tex;
                    Tile tile = tiles[delay.sx, delay.sy];
                    int texw = 16, texh = 16;
                    if (light == 1)
                        lightR = lightG = lightB = tiles[delay.sx, delay.sy].light;
                    else if (light == 2)
                    {
                        lightR = tile.lightR;
                        lightG = tile.lightG;
                        lightB = tile.lightB;
                    }
                    else
                        lightR = lightG = lightB = 1.0;

                    if (isHilight && !tileInfos[tile.type, tile.u, tile.v].isHilighting)
                    {
                        lightR *= 0.3;
                        lightG *= 0.3;
                        lightB *= 0.3;
                    }
                    if (fogofwar && !tile.seen)
                        lightR = lightG = lightB = 0.0;

                    if (tile.type == 128) //armor
                    {
                        double dy = 8.0;
                        int au = tile.u % 100;
                        int armor = tile.u / 100;
                        switch (tile.v)
                        {
                            case 0: //head
                                tex = Textures.GetArmorHead(armor);
                                texw = 40;
                                texh = 36;
                                dy = 12.0 * scale / 16.0;
                                break;
                            case 18: //body
                                tex = Textures.GetArmorBody(armor);
                                texw = 40;
                                texh = 54;
                                dy = 28.0 * scale / 16.0;
                                break;
                            default: //legs
                                tex = Textures.GetArmorLegs(armor);
                                texw = 40;
                                texh = 54;
                                dy = 44.0 * scale / 16.0;
                                break;
                        }
                        if (au >= 36) //reverse
                            drawTexture(tex, texw, texh, 0,
                                pixels, (int)(delay.px - 4.0 * scale / 16.0), (int)(delay.py - dy), width, height, scale / 16.0, lightR, lightG, lightB, 0);
                        else
                            drawTextureFlip(tex, texw, texh, 0,
                                pixels, (int)(delay.px - 4 * scale / 16.0), (int)(delay.py - dy), width, height, scale / 16.0, lightR, lightG, lightB, 0);
                    }
                    else if (tile.type == 5) //tree leaves
                    {
                        drawLeaves(tile.u, tile.v, delay.sx, delay.sy,
                                   pixels, delay.px, delay.py, width, height, scale / 16.0, lightR, lightG, lightB, ref tiles);
                    }
                    else if (tile.type == 237) //lihzahrd altar
                    {
                        tex = Textures.GetTile(tile.type);
                        drawTexture(tex, texw, texh, 0,
                            pixels, delay.px, delay.py, width, height, scale / 16.0, lightR, lightG, lightB, 0);
                    }
                }

                double minx = skipx + startx;
                double maxx = minx + blocksWide;
                double miny = skipy + starty;
                double maxy = miny + blocksHigh;
                // draw npcs at sx,sy
                foreach (NPC npc in npcs)
                {
                    if (npc.sprite != 0 && (npc.x / 16) >= minx && (npc.x / 16) < maxx &&
                        (npc.y / 16) >= miny && (npc.y / 16) < maxy) //npc on screen
                    {
                        Tile t = tiles[(int)(npc.x / 16), (int)(npc.y / 16)];
                        if (light == 1)
                            lightR = lightG = lightB = t.light;
                        else if (light == 2)
                        {
                            lightR = t.lightR;
                            lightG = t.lightG;
                            lightB = t.lightB;
                        }
                        else
                            lightR = lightG = lightB = 1.0;
                        if (isHilight)
                        {
                            lightR *= 0.3;
                            lightG *= 0.3;
                            lightB *= 0.3;
                        }
                        Texture tex = Textures.GetNPC(npc.sprite);
                        px = (int)(skipx + npc.x / 16 - (int)startx) * (int)scale - (int)(scale / 4);
                        py = (int)(skipy + npc.y / 16 - (int)starty) * (int)scale - (int)(scale / 4);
                        drawTexture(tex, tex.width, 56, 0, pixels,
                            (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB,0);
                    }
                    if (houses && npc.num != 0)
                    {
                        //calc home x and y
                        int hx = npc.homeX;
                        int hy = npc.homeY - 1;
                        while (!tiles[hx, hy].isActive || !tileInfos[tiles[hx, hy].type].solid)
                        {
                            hy--;
                            if (hy < 10) break;
                        }
                        hy++;
                        if (hx >= minx && hx < maxx && hy >= miny && hy < maxy) //banner on screen
                        {
                            Tile t = tiles[hx, hy];
                            if (light == 1)
                                lightR = lightG = lightB = t.light;
                            else if (light == 2)
                            {
                                lightR = t.lightR;
                                lightG = t.lightG;
                                lightB = t.lightB;
                            }
                            else
                                lightR = lightG = lightB = 1.0;
                            if (isHilight)
                            {
                                lightR *= 0.3;
                                lightG *= 0.3;
                                lightB *= 0.3;
                            }

                            int dy = 18;
                            if (tiles[hx, hy - 1].type == 19) //platform
                                dy -= 8;
                            px = (int)(skipx + hx - (int)startx) * (int)scale + (int)(scale / 2);
                            py = (int)(skipy + hy - (int)starty) * (int)scale + (int)(dy * scale / 16);
                            Texture tex = Textures.GetBanner(1); //house banner
                            int npx = (int)(px - tex.width * scale / 32.0);
                            int npy = (int)(py - tex.height * scale / 32.0);
                            drawTexture(tex, 32, 40, 0, pixels,
                                (int)(npx - shiftx), (int)(npy - shifty), width, height, scale / 16.0, lightR, lightG, lightB,0);
                            tex = Textures.GetNPCHead(npc.num);
                            npx = (int)(px - tex.width * scale / 32.0);
                            npy = (int)(py - tex.height * scale / 32.0);
                            drawTexture(tex, tex.width, tex.height, 0, pixels,
                                (int)(npx - shiftx), (int)(npy - shifty), width, height, scale / 16.0, lightR, lightG, lightB,0);
                        }
                    }
                }
            }
            else
            {
                for (int y = 0; y < height; y++)
                {
                    int bofs = y * width * 4;
                    int sy = (int)(y / scale + starty);
                    for (int x = 0; x < width; x++)
                    {
                        int sx = (int)(x / scale + startx);
                        UInt32 c = 0xffffff;
                        if (sx >= 0 && sx < tilesWide && sy >= 0 && sy < tilesHigh)
                        {
                            Tile tile = tiles[sx, sy];
                            if (sy < groundLevel)
                                c = skyColor;
                            else if (sy < rockLevel)
                                c = earthColor;
                            else
                            {
                                //fade between rockColor and hellColor...
                                double alpha = (double)(sy - rockLevel) / (double)(tilesHigh - rockLevel);
                                c = alphaBlend(rockColor, hellColor, alpha);
                            }
                            if (tile.wall > 0)
                            {
                                c = wallInfo[tile.wall].color;
                            }
                            if (tile.isActive)
                            {
                                c = tileInfos[tile.type, tile.u, tile.v].color;
                                if (tile.inactive)
                                    c = alphaBlend(c, 0x000000, 0.4);
                                if (isHilight && tileInfos[tile.type, tile.u, tile.v].isHilighting)
                                    c = alphaBlend(c, 0xff88ff, 0.9);
                            }
                            if (tile.liquid > 0)
                                c = alphaBlend(c, tile.isLava ? lavaColor : tile.isHoney ? honeyColor : waterColor, 0.5);
                            if (light == 1)
                                c = alphaBlend(0, c, tile.light);
                            else if (light == 2)
                            {
                                uint r, g, b;
                                r = (uint)((c >> 16) * tile.lightR);
                                g = (uint)(((c >> 8) & 0xff) * tile.lightG);
                                b = (uint)((c & 0xff) * tile.lightB);
                                c = (r << 16) | (g << 8) | b;
                            }
                            if (isHilight && (!tile.isActive || !tileInfos[tile.type, tile.u, tile.v].isHilighting))
                                c = alphaBlend(0, c, 0.3);
                            if (fogofwar && !tile.seen)
                                c = 0;
                        }
                        pixels[bofs++] = (byte)(c & 0xff);
                        pixels[bofs++] = (byte)((c >> 8) & 0xff);
                        pixels[bofs++] = (byte)((c >> 16) & 0xff);
                        pixels[bofs++] = 0xff;
                    }
                }
            }
        }
Example #2
0
 private void ResizeMap()
 {
     for (int y = 0; y < tilesHigh; y++)
     {
         Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate()
         {
             serverText.Text = ((int)((float)y * 100.0 / (float)tilesHigh)) + "% - Allocating tiles";
         }));
         for (int x = 0; x < tilesWide; x++)
         {
             if (tiles[x, y] == null)
                 tiles[x, y] = new Tile();
         }
     }
     if (tilesWide < Widest || tilesHigh < Highest) //free unused tiles
     {
         for (int y = 0; y < Highest; y++)
         {
             int start = tilesWide;
             if (y >= tilesHigh)
                 start = 0;
             for (int x = start; x < Widest; x++)
                 tiles[x, y] = null;
         }
     }
 }
Example #3
0
        private byte fixTile(int x, int y, ref Tile[,] tiles)
        {
            int t = -1, l = -1, r = -1, b = -1;
            int tl = -1, tr = -1, bl = -1, br = -1;
            byte c = tiles[x, y].type;
            Int16 u;
            int set = rand.Next(0, 3) * 2;

            if (x > 0)
            {
                if (tiles[x - 1, y].isActive)
                    l = tiles[x - 1, y].type;
                if (y > 0)
                {
                    if (tiles[x - 1, y - 1].isActive)
                        tl = tiles[x - 1, y - 1].type;
                }
                if (y < tilesHigh - 1)
                {
                    if (tiles[x - 1, y + 1].isActive)
                        bl = tiles[x - 1, y + 1].type;
                }
            }
            if (x < tilesWide - 1)
            {
                if (tiles[x + 1, y].isActive)
                    r = tiles[x + 1, y].type;
                if (y > 0)
                {
                    if (tiles[x + 1, y - 1].isActive)
                        tr = tiles[x + 1, y - 1].type;
                }
                if (y < tilesHigh - 1)
                {
                    if (tiles[x + 1, y + 1].isActive)
                        br = tiles[x + 1, y + 1].type;
                }
            }
            if (y > 0)
                if (tiles[x, y - 1].isActive)
                    t = tiles[x, y - 1].type;
            if (y < tilesHigh - 1)
                if (tiles[x, y + 1].isActive)
                    b = tiles[x, y + 1].type;

            int mask;
            if (c == 33 || c == 49) //candles
            {
                // these tiles don't have u/v, but are single tiles
                tiles[x, y].u = 0;
                tiles[x, y].v = 0;
                return 0;
            }
            if (c == 4) //torch
            {
                //check if left is moutable or right is mountable.. set to -1 if not
                u = 0;
                if (b < 0) //no bottom
                {
                    if (l >= 0) u = 22;
                    else u = 44;
                }
                tiles[x, y].u = u;
                tiles[x, y].v = 0;
                return 0;
            }
            if (c == 80) //cactus
            {
                fixCactus(x, y, t, b, l, r, bl, br, ref tiles);
                return 0;
            }
            if (c == 19) //wooden platform
            {
                // check if left is mountable or right is mountable.. set to -1 if not
                mask = 0;
                if (l == c) mask |= 8;
                if (r == c) mask |= 4;
                if (l == -1) mask |= 2;
                if (r == -1) mask |= 1;
                tiles[x, y].u = uvPlatforms[mask * 2];
                tiles[x, y].v = uvPlatforms[mask * 2 + 1];
                return 0;
            }

            mask = 0;
            //if tile is stone and next to stone, treat them as the same
            if (tileInfos[c].isStone)
            {
                if (t > -1 && tileInfos[t].isStone) mask |= 0x80000;
                if (b > -1 && tileInfos[b].isStone) mask |= 0x40000;
                if (l > -1 && tileInfos[l].isStone) mask |= 0x20000;
                if (r > -1 && tileInfos[r].isStone) mask |= 0x10000;
                if (tl > -1 && tileInfos[tl].isStone) mask |= 0x880;
                if (tr > -1 && tileInfos[tr].isStone) mask |= 0x440;
                if (bl > -1 && tileInfos[bl].isStone) mask |= 0x220;
                if (br > -1 && tileInfos[br].isStone) mask |= 0x110;
            }

            //if tile blends with current tile, treat as if it were current tile
            if (t > -1 && (t == c || (tileInfos[t].blend == c && (fixTile(x, y - 1, ref tiles) & 4) == 4))) mask |= 0x80000;
            if (b > -1 && (b == c || (tileInfos[b].blend == c && (fixTile(x, y + 1, ref tiles) & 8) == 8))) mask |= 0x40000;
            if (l > -1 && (l == c || (tileInfos[l].blend == c && (fixTile(x - 1, y, ref tiles) & 1) == 1))) mask |= 0x20000;
            if (r > -1 && (r == c || (tileInfos[r].blend == c && (fixTile(x + 1, y, ref tiles) & 2) == 2))) mask |= 0x10000;
            if (tl > -1 && (tileInfos[tl].blend == c || tl == c)) mask |= 0x880;
            if (tr > -1 && (tileInfos[tr].blend == c || tr == c)) mask |= 0x440;
            if (bl > -1 && (tileInfos[bl].blend == c || bl == c)) mask |= 0x220;
            if (br > -1 && (tileInfos[br].blend == c || br == c)) mask |= 0x110;

            //if current tile can blend, set up the blend rules.
            Int16 blend = tileInfos[c].blend;
            if (blend > -1)
            {
                if (t == blend) mask |= 0x88000;
                if (b == blend) mask |= 0x44000;
                if (l == blend) mask |= 0x22000;
                if (r == blend) mask |= 0x11000;
                if (tl == blend) mask |= 0x808;
                if (tr == blend) mask |= 0x404;
                if (bl == blend) mask |= 0x202;
                if (br == blend) mask |= 0x101;
            }
            //set up merge rules
            if (tileInfos[c].canMerge)
            {
                if (t > -1 && tileInfos[t].canMerge) mask |= 0x80000;
                if (b > -1 && tileInfos[b].canMerge) mask |= 0x40000;
                if (l > -1 && tileInfos[l].canMerge) mask |= 0x20000;
                if (r > -1 && tileInfos[r].canMerge) mask |= 0x10000;
                if (tl > -1 && tileInfos[tl].canMerge) mask |= 0x880;
                if (tr > -1 && tileInfos[tr].canMerge) mask |= 0x440;
                if (bl > -1 && tileInfos[bl].canMerge) mask |= 0x220;
                if (br > -1 && tileInfos[br].canMerge) mask |= 0x110;
            }

            if (c == 32 && b == 23) mask |= 0x40000; //corrupted vines above corrupted grass
            if (c == 69 && b == 60) mask |= 0x40000; //jungle thorn above jungle grass
            if (c == 51) //cobwebs blend with everything
            {
                if (t > -1) mask |= 0x80000;
                if (b > -1) mask |= 0x40000;
                if (l > -1) mask |= 0x20000;
                if (r > -1) mask |= 0x10000;
                if (tl > -1) mask |= 0x880;
                if (tr > -1) mask |= 0x440;
                if (bl > -1) mask |= 0x220;
                if (br > -1) mask |= 0x110;
            }

            if (tileInfos[c].isGrass) //do grasses
            {
                foreach (UVRule rule in grassRules[mask >> 16])
                {
                    if ((mask & rule.mask) == rule.val)
                    {
                        tiles[x, y].u = rule.uvs[set];
                        tiles[x, y].v = rule.uvs[set + 1];
                        return rule.blend;
                    }
                }
            }
            if (tileInfos[c].blend > -1 && !tileInfos[c].isGrass) //do blend-onlys
            {
                foreach (UVRule rule in blendRules[mask >> 16])
                {
                    if ((mask & rule.mask) == rule.val)
                    {
                        tiles[x, y].u = rule.uvs[set];
                        tiles[x, y].v = rule.uvs[set + 1];
                        return rule.blend;
                    }
                }
            }
            if (tileInfos[c].blend > -1) //do blend and unmatched grasses
            {
                foreach (UVRule rule in blendGrassRules[mask >> 16])
                {
                    if ((mask & rule.mask) == rule.val)
                    {
                        tiles[x, y].u = rule.uvs[set];
                        tiles[x, y].v = rule.uvs[set + 1];
                        return rule.blend;
                    }
                }
            }
            // no match, delete blends
            if (tileInfos[c].isGrass) //with grasses, blends are equal
                mask &= 0xf0f00;
            else
                mask = ((mask & 0xf0000) ^ ((mask & 0xf000) << 4)) | ((mask & 0xf0) << 4);

            foreach (UVRule rule in uvRules[mask >> 16])
            {
                if ((mask & rule.mask) == rule.val)
                {
                    tiles[x, y].u = rule.uvs[set];
                    tiles[x, y].v = rule.uvs[set + 1];
                    return rule.blend;
                }
            }
            //should be impossible to get here.
            return 0;
        }
Example #4
0
        private void fixWall(int x, int y, ref Tile[,] tiles)
        {
            byte t = 0, l = 0, r = 0, b = 0;
            byte c = tiles[x, y].wall;
            int set = rand.Next(0, 3) * 2;

            if (x > 0)
                l = tiles[x - 1, y].wall;
            if (x < tilesWide - 1)
                r = tiles[x + 1, y].wall;
            if (y > 0)
                t = tiles[x, y - 1].wall;
            if (y < tilesHigh - 1)
                b = tiles[x, y + 1].wall;

            //we don't actually care what the wall texture is, we just care if there's a wall or not.
            int mask = 0;
            if (t > 0) mask |= 0x80000;
            if (b > 0) mask |= 0x40000;
            if (l > 0) mask |= 0x20000;
            if (r > 0) mask |= 0x10000;
            if (x % 3 == 1 && y % 3 == 1) mask |= 0x300;
            else if (x % 3 == 0 && y % 3 == 0) mask |= 0xc00;
            else if (x % 3 == 2 && y % 3 == 1) mask |= 0x500;
            else if (x % 3 == 1 && y % 3 == 2) mask |= 0xa00;
            else mask |= 0xf00;

            foreach (UVRule rule in uvRules[mask >> 16])
            {
                if ((mask & rule.mask) == rule.val)
                {
                    tiles[x, y].wallu = rule.uvs[set];
                    tiles[x, y].wallv = rule.uvs[set + 1];
                    return;
                }
            }
            //again, impossible to be here.
        }
Example #5
0
 private int findCorruptGrass(int x, int y, ref Tile[,] tiles)
 {
     for (int i = 0; i < 100; i++)
     {
         Tile tile = tiles[x, y + i];
         if (tile.type == 2) //normal grass
         {
             int s = treeStyle[3];
             for (int j = 0; j < 3; j++)
                 if (x <= treeX[j])
                 {
                     s = treeStyle[j];
                     break;
                 }
             if (s == 0) return 0;
             return s + 5;
         }
         if (tile.type == 23) //corrupt grass
             return 1;
         if (tile.type == 60) //jungle grass
         {
             if (y > groundLevel)
                 return 13;
             if (styles[2] == 1)
                 return 11;
             return 2;
         }
         if (tile.type == 109) //hallowed grass
             return 3;
         if (tile.type == 147) //snow block
         {
             if (styles[3] == 0)
                 return 12;
             return 4;
         }
         if (tile.type == 70) //mushroom grass
             return 14;
         if (tile.type == 199) //flesh grass
             return 5;
     }
     return 0;
 }
Example #6
0
        private void fixCactus(int x, int y, int t, int b, int l, int r, int bl, int br, ref Tile[,] tiles)
        {
            //find the base of the cactus
            int basex = x;
            int basey = y;
            while (tiles[basex, basey].isActive &&
                tiles[basex, basey].type == 80)
            {
                basey++;
                if (!tiles[basex, basey].isActive || tiles[basex, basey].type != 80)
                {
                    if (tiles[basex - 1, basey].isActive &&
                        tiles[basex - 1, basey].type == 80 &&
                        tiles[basex - 1, basey - 1].isActive &&
                        tiles[basex - 1, basey - 1].type == 80 && basex >= x)
                        basex--;
                    if (tiles[basex + 1, basey].isActive &&
                        tiles[basex + 1, basey].type == 80 &&
                        tiles[basex + 1, basey - 1].isActive &&
                        tiles[basex + 1, basey - 1].type == 80 && basex <= x)
                        basex++;
                }
            }

            Int16 mask = 0;
            if (x < basex) mask |= 1;
            if (x > basex) mask |= 2;
            if (br == 80) mask |= 4;
            if (bl == 80) mask |= 8;
            if (r == 80) mask |= 0x10;
            if (l == 80) mask |= 0x20;
            if (b == 80) mask |= 0x40;
            if (t == 80) mask |= 0x80;

            foreach (UVRule rule in cactusRules)
            {
                if ((mask & rule.mask) == rule.val)
                {
                    tiles[x, y].u = rule.uvs[0];
                    tiles[x, y].v = rule.uvs[1];
                    return;
                }
            }
        }
Example #7
0
 private void drawRedWire(int sx, int sy, byte[] pixels, int px, int py, int w, int h, double zoom, double lightR, double lightG, double lightB, ref Tile[,] tiles)
 {
     int mask = 0;
     //udlr
     if (sx < tilesWide - 1 && tiles[sx + 1, sy].hasRedWire) mask |= 1; //right
     if (sx > 0 && tiles[sx - 1, sy].hasRedWire) mask |= 2; //left
     if (sy < tilesHigh - 1 && tiles[sx, sy + 1].hasRedWire) mask |= 4; //down
     if (sy > 0 && tiles[sx, sy - 1].hasRedWire) mask |= 8; //up
     Texture tex = Textures.GetWire(0);
     drawTexture(tex, 16, 16, uvWires[mask * 2 + 1] * tex.width * 4 + uvWires[mask * 2] * 4, pixels,
         px, py, w, h, zoom, lightR, lightG, lightB,0);
 }
Example #8
0
        private void drawLeaves(int u, int v, int sx, int sy,
            byte[] pixels, int px, int py,
            int w, int h, double zoom, double lightR, double lightG, double lightB, ref Tile[,] tiles)
        {
            if (u < 22 || v < 198) return; //not a leaf
            int variant = 0;
            if (v == 220) variant = 1;
            else if (v == 242) variant = 2;

            Texture tex;
            int leafType;
            switch (u)
            {
                case 22: //tree top
                    leafType = findCorruptGrass(sx, sy, ref tiles);
                    tex = Textures.GetTreeTops(leafType);
                    if (leafType == 3) //hallowed
                    {
                        variant += (sx % 3) * 3;
                        drawTexture(tex, 80, 140, variant * 82 * 4, pixels,
                            px - (int)(30 * zoom), py - (int)(124 * zoom), w, h, zoom, lightR, lightG, lightB,0);
                    }
                    else if (leafType == 2 || leafType==11 || leafType==13) //jungle
                        drawTexture(tex, 114, 96, variant * 116 * 4, pixels,
                            px - (int)(46 * zoom), py - (int)(80 * zoom), w, h, zoom, lightR, lightG, lightB,0);
                    else
                        drawTexture(tex, 80, 80, variant * 82 * 4, pixels,
                            px - (int)(30 * zoom), py - (int)(62 * zoom), w, h, zoom, lightR, lightG, lightB,0);
                    break;
                case 44: //left branch
                    leafType = findCorruptGrass(sx + 1, sy, ref tiles);
                    tex = Textures.GetTreeBranches(leafType);
                    if (leafType == 3) //hallowed
                        variant += (sx % 3) * 3;
                    drawTexture(tex, 40, 40, variant * 42 * tex.width * 4, pixels,
                        px - (int)(22 * zoom), py - (int)(12 * zoom), w, h, zoom, lightR, lightG, lightB,0);
                    break;
                case 66: //right branch
                    leafType = findCorruptGrass(sx - 1, sy, ref tiles);
                    tex = Textures.GetTreeBranches(leafType);
                    if (leafType == 3) //hallowed
                        variant += (sx % 3) * 3;
                    drawTexture(tex, 40, 40, variant * 42 * tex.width * 4 + 42 * 4, pixels,
                        px, py - (int)(12 * zoom), w, h, zoom, lightR, lightG, lightB,0);
                    break;
            }
        }
Example #9
0
        public void Draw(int width, int height,
            double startx, double starty,
            double scale, ref byte[] pixels,
            bool isHilight,
            int light, bool texture, bool houses, bool wires, ref Tile[,] tiles)
        {
            if (texture)
            {
                int blocksWide = (int)(width / Math.Floor(scale)) + 2; //scale=1.0 to 16.0
                int blocksHigh = (int)(height / Math.Floor(scale)) + 2;

                double adjustx = ((width / scale) - blocksWide) / 2;
                double adjusty = ((height / scale) - blocksHigh) / 2;
                startx += adjustx;
                starty += adjusty;

                int skipx = 0, skipy = 0;
                if (startx < 0) skipx = (int)-startx;
                if (starty < 0) skipy = (int)-starty;

                double shiftx = (startx - Math.Floor(startx)) * scale;
                double shifty = (starty - Math.Floor(starty)) * scale;
                int py, px;

                double lightR, lightG, lightB;

                // draw backgrounds

                int hellLevel = ((tilesHigh - 230) - groundLevel) / 6; //rounded
                hellLevel = hellLevel * 6 + groundLevel - 5;

                py = skipy * (int)scale;
                for (int y = skipy; y < blocksHigh; y++)
                {
                    int sy = (int)(y + starty);
                    px = skipx * (int)scale;

                    int bg = 0;
                    int bgw = 16, bgh = 16;
                    int v = sy;
                    if (sy < groundLevel)
                        bg = 0;
                    else if (sy == groundLevel)
                    {
                        bg = 1;
                        bgw = 96;
                        v = sy - groundLevel;
                    }
                    else if (sy < rockLevel)
                    {
                        bg = 2;
                        bgw = 96;
                        bgh = 96;
                        v = sy - groundLevel;
                    }
                    else if (sy == rockLevel)
                    {
                        bg = 4;
                        bgw = 96;
                        v = sy - rockLevel;
                    }
                    else if (sy < hellLevel)
                    {
                        bg = 3;
                        bgw = 96;
                        bgh = 96;
                        v = sy - rockLevel;
                    }
                    else if (sy == hellLevel)
                    {
                        bg = 6;
                        bgw = 96;
                        v = sy - hellLevel;
                    }
                    else
                    {
                        bg = 5;
                        bgw = 96;
                        bgh = 96;
                        v = sy - hellLevel;
                    }

                    Texture tex = Textures.GetBackground(bg);

                    for (int x = skipx; x < blocksWide; x++)
                    {
                        int sx = (int)(x + startx);
                        if (sx < 0 || sx >= tilesWide || sy < 0 || sy >= tilesHigh)
                            continue;

                        Tile tile = tiles[sx, sy];

                        if (light == 1)
                            lightR = lightG = lightB = tile.light;
                        else if (light == 2)
                        {
                            lightR = tile.lightR;
                            lightG = tile.lightG;
                            lightB = tile.lightB;
                        }
                        else
                            lightR = lightG = lightB = 1.0;

                        if (isHilight)
                        {
                            lightR *= 0.3;
                            lightG *= 0.3;
                            lightB *= 0.3;
                        }

                        int u = (sx % (bgw / 16)) * 16;
                        int vv = (v % (bgh / 16)) * 16;
                        if (bg == 0) //sky
                            vv = sy * tex.height / groundLevel;
                        drawTexture(tex, 16, 16, vv * tex.width * 4 + u * 4,
                            pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB);

                        px += (int)scale;
                    }
                    py += (int)scale;
                }

                //draw walls

                py = skipy * (int)scale - (int)(scale / 2);
                for (int y = skipy; y < blocksHigh; y++)
                {
                    int sy = (int)(y + starty);

                    px = skipx * (int)scale - (int)(scale / 2);
                    for (int x = skipx; x < blocksWide; x++)
                    {
                        int sx = (int)(x + startx);

                        if (sx < 0 || sx >= tilesWide || sy < 0 || sy >= tilesHigh)
                            continue;

                        Tile tile = tiles[sx, sy];

                        if (tile.wall > 0)
                        {
                            if (tile.wallu == -1) fixWall(sx, sy, ref tiles);
                            Texture tex = Textures.GetWall(tile.wall);
                            if (light == 1)
                                lightR = lightG = lightB = tile.light;
                            else if (light == 2)
                            {
                                lightR = tile.lightR;
                                lightG = tile.lightG;
                                lightB = tile.lightB;
                            }
                            else
                                lightR = lightG = lightB = 1.0;

                            if (isHilight)
                            {
                                lightR *= 0.3;
                                lightG *= 0.3;
                                lightB *= 0.3;
                            }

                            drawTexture(tex, 32, 32, tile.wallv * tex.width * 4 * 2 + tile.wallu * 4 * 2,
                                pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB);
                        }

                        px += (int)scale;
                    }
                    py += (int)scale;
                }

                List<Delayed> delayed = new List<Delayed>();

                //draw tiles
                py = skipy * (int)scale;
                for (int y = skipy; y < blocksHigh; y++)
                {
                    int sy = (int)(y + starty);
                    px = skipx * (int)scale;
                    for (int x = skipx; x < blocksWide; x++)
                    {
                        int sx = (int)(x + startx);

                        if (sx < 0 || sx >= tilesWide || sy < 0 || sy >= tilesHigh)
                            continue;

                        Tile tile = tiles[sx, sy];

                        if (light == 1)
                            lightR = lightG = lightB = tiles[sx, sy].light;
                        else if (light == 2)
                        {
                            lightR = tile.lightR;
                            lightG = tile.lightG;
                            lightB = tile.lightB;
                        }
                        else
                            lightR = lightG = lightB = 1.0;

                        if (isHilight && (!tile.isActive || !tileInfos[tile.type, tile.u, tile.v].isHilighting))
                        {
                            lightR *= 0.3;
                            lightG *= 0.3;
                            lightB *= 0.3;
                        }

                        if (tile.isActive)
                        {
                            if (tile.u == -1 || tile.v == -1) fixTile(sx, sy, ref tiles);

                            int texw = 16;
                            int texh = 16;

                            if (tile.type == 5) //tree
                                texw = 20;
                            if (tile.type == 72) //mushroom
                                drawMushroom(tile.u, tile.v,
                                    pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB);

                            if (tile.type == 103) //bowl
                                if (tile.u == 18) texw = 14;

                            if (tile.type == 5 && tile.v >= 198 && tile.u >= 22) //tree leaves
                            {
                                Delayed delay = new Delayed();
                                delay.px = (int)(px - shiftx);
                                delay.py = (int)(py - shifty);
                                delay.sx = sx;
                                delay.sy = sy;
                                delayed.Add(delay);
                            }
                            else if (tile.type == 128) //armor
                            {
                                int au = tile.u % 100;
                                //draw armor stand
                                Texture tex = Textures.GetTile(tile.type);
                                drawTexture(tex, texw, texh, tile.v * tex.width * 4 + au * 4,
                                    pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB);
                                //draw armor
                                int armor = tile.u / 100;
                                if (armor > 0)
                                {
                                    Delayed delay = new Delayed();
                                    delay.sx = sx;
                                    delay.sy = sy;
                                    delay.px = (int)(px - shiftx);
                                    delay.py = (int)(py - shifty);
                                    delayed.Add(delay);
                                }
                            }
                            else
                            {
                                Texture tex = Textures.GetTile(tile.type);
                                drawTexture(tex, texw, texh, tile.v * tex.width * 4 + tile.u * 4,
                                    pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB);
                            }
                        }
                        // draw liquid
                        if (tile.liquid > 0)
                        {
                            UInt32 c = tile.isLava ? lavaColor : waterColor;
                            uint r = (uint)((c >> 16) * lightR);
                            uint g = (uint)(((c >> 8) & 0xff) * lightG);
                            uint b = (uint)((c & 0xff) * lightB);
                            c = (r << 16) | (g << 8) | b;
                            drawOverlay(c, tile.isLava ? 0.85 : 0.5, tile.liquid,
                                pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0);
                        }
                        // draw wires if necessary
                        if (wires && tile.hasWire)
                        {
                            drawWire(sx, sy, pixels,
                                (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB, ref tiles);
                        }
                        px += (int)scale;
                    }
                    py += (int)scale;
                }

                //draw delayed blocks
                foreach (Delayed delay in delayed)
                {
                    Texture tex;
                    Tile tile = tiles[delay.sx, delay.sy];
                    int texw = 16, texh = 16;
                    if (light == 1)
                        lightR = lightG = lightB = tiles[delay.sx, delay.sy].light;
                    else if (light == 2)
                    {
                        lightR = tile.lightR;
                        lightG = tile.lightG;
                        lightB = tile.lightB;
                    }
                    else
                        lightR = lightG = lightB = 1.0;

                    if (isHilight && !tileInfos[tile.type, tile.u, tile.v].isHilighting)
                    {
                        lightR *= 0.3;
                        lightG *= 0.3;
                        lightB *= 0.3;
                    }

                    if (tile.type == 128) //armor
                    {
                        int dy = 8;
                        int au = tile.u % 100;
                        int armor = tile.u / 100;
                        switch (tile.v)
                        {
                            case 0: //head
                                tex = Textures.GetArmorHead(armor);
                                texw = 40;
                                texh = 36;
                                dy = 12;
                                break;
                            case 18: //body
                                tex = Textures.GetArmorBody(armor);
                                texw = 40;
                                texh = 54;
                                dy = 28;
                                break;
                            default: //legs
                                tex = Textures.GetArmorLegs(armor);
                                texw = 40;
                                texh = 54;
                                dy = 44;
                                break;
                        }
                        if (au >= 36) //reverse
                            drawTexture(tex, texw, texh, 0,
                                pixels, delay.px - 4, delay.py - dy, width, height, scale / 16.0, lightR, lightG, lightB);
                        else
                            drawTextureFlip(tex, texw, texh, 0,
                                pixels, delay.px - 4, delay.py - dy, width, height, scale / 16.0, lightR, lightG, lightB);
                    }
                    else if (tile.type == 5) //tree leaves
                    {
                        drawLeaves(tile.u, tile.v, delay.sx, delay.sy,
                                   pixels, delay.px, delay.py, width, height, scale / 16.0, lightR, lightG, lightB, ref tiles);
                    }
                }

                double minx = skipx + startx;
                double maxx = minx + blocksWide;
                double miny = skipy + starty;
                double maxy = miny + blocksHigh;
                // draw npcs at sx,sy
                foreach (NPC npc in npcs)
                {
                    if (npc.sprite != 0 && (npc.x / 16) >= minx && (npc.x / 16) < maxx &&
                        (npc.y / 16) >= miny && (npc.y / 16) < maxy) //npc on screen
                    {
                        Tile t = tiles[(int)(npc.x / 16), (int)(npc.y / 16)];
                        if (light == 1)
                            lightR = lightG = lightB = t.light;
                        else if (light == 2)
                        {
                            lightR = t.lightR;
                            lightG = t.lightG;
                            lightB = t.lightB;
                        }
                        else
                            lightR = lightG = lightB = 1.0;
                        if (isHilight)
                        {
                            lightR *= 0.3;
                            lightG *= 0.3;
                            lightB *= 0.3;
                        }
                        Texture tex = Textures.GetNPC(npc.sprite);
                        px = (int)(skipx + npc.x / 16 - (int)startx) * (int)scale - (int)(scale / 4);
                        py = (int)(skipy + npc.y / 16 - (int)starty) * (int)scale - (int)(scale / 4);
                        drawTexture(tex, 40, 56, 0, pixels,
                            (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0, lightR, lightG, lightB);
                    }
                    if (houses && npc.num != 0)
                    {
                        //calc home x and y
                        int hx = npc.homeX;
                        int hy = npc.homeY - 1;
                        while (!tiles[hx, hy].isActive || !tileInfos[tiles[hx, hy].type].solid)
                        {
                            hy--;
                            if (hy < 10) break;
                        }
                        hy++;
                        if (hx >= minx && hx < maxx && hy >= miny && hy < maxy) //banner on screen
                        {
                            Tile t = tiles[hx, hy];
                            if (light == 1)
                                lightR = lightG = lightB = t.light;
                            else if (light == 2)
                            {
                                lightR = t.lightR;
                                lightG = t.lightG;
                                lightB = t.lightB;
                            }
                            else
                                lightR = lightG = lightB = 1.0;
                            if (isHilight)
                            {
                                lightR *= 0.3;
                                lightG *= 0.3;
                                lightB *= 0.3;
                            }

                            int dy = 18;
                            if (tiles[hx, hy - 1].type == 19) //platform
                                dy -= 8;
                            px = (int)(skipx + hx - (int)startx) * (int)scale + (int)(scale / 2);
                            py = (int)(skipy + hy - (int)starty) * (int)scale + (int)(dy * scale / 16);
                            Texture tex = Textures.GetBanner(1); //house banner
                            int npx = (int)(px - tex.width * scale / 32.0);
                            int npy = (int)(py - tex.height * scale / 32.0);
                            drawTexture(tex, 32, 40, 0, pixels,
                                (int)(npx - shiftx), (int)(npy - shifty), width, height, scale / 16.0, lightR, lightG, lightB);
                            tex = Textures.GetNPCHead(npc.num);
                            npx = (int)(px - tex.width * scale / 32.0);
                            npy = (int)(py - tex.height * scale / 32.0);
                            drawTexture(tex, tex.width, tex.height, 0, pixels,
                                (int)(npx - shiftx), (int)(npy - shifty), width, height, scale / 16.0, lightR, lightG, lightB);
                        }
                    }
                }
            }
            else
            {
                for (int y = 0; y < height; y++)
                {
                    int bofs = y * width * 4;
                    int sy = (int)(y / scale + starty);
                    for (int x = 0; x < width; x++)
                    {
                        int sx = (int)(x / scale + startx);
                        UInt32 c = 0xffffff;
                        if (sx >= 0 && sx < tilesWide && sy >= 0 && sy < tilesHigh)
                        {
                            Tile tile = tiles[sx, sy];
                            if (sy < groundLevel)
                                c = skyColor;
                            else if (sy < rockLevel)
                                c = earthColor;
                            else
                            {
                                //fade between rockColor and hellColor...
                                double alpha = (double)(sy - rockLevel) / (double)(tilesHigh - rockLevel);
                                c = alphaBlend(rockColor, hellColor, alpha);
                            }
                            if (tile.wall > 0)
                            {
                                c = wallInfo[tile.wall].color;
                            }
                            if (tile.isActive)
                            {
                                c = tileInfos[tile.type, tile.u, tile.v].color;
                                if (isHilight && tileInfos[tile.type, tile.u, tile.v].isHilighting)
                                    c = alphaBlend(c, 0xff88ff, 0.9);
                            }
                            if (tile.liquid > 0)
                                c = alphaBlend(c, tile.isLava ? lavaColor : waterColor, 0.5);
                            if (light == 1)
                                c = alphaBlend(0, c, tile.light);
                            else if (light == 2)
                            {
                                uint r, g, b;
                                r = (uint)((c >> 16) * tile.lightR);
                                g = (uint)(((c >> 8) & 0xff) * tile.lightG);
                                b = (uint)((c & 0xff) * tile.lightB);
                                c = (r << 16) | (g << 8) | b;
                            }
                            if (isHilight && (!tile.isActive || !tileInfos[tile.type, tile.u, tile.v].isHilighting))
                                c = alphaBlend(0, c, 0.3);
                        }
                        pixels[bofs++] = (byte)(c & 0xff);
                        pixels[bofs++] = (byte)((c >> 8) & 0xff);
                        pixels[bofs++] = (byte)((c >> 16) & 0xff);
                        pixels[bofs++] = 0xff;
                    }
                }
            }
        }
Example #10
0
        private void fixWall(int x, int y, ref Tile[,] tiles)
        {
            byte t = 0, l = 0, r = 0, b = 0;
            byte tl = 0, tr = 0, bl = 0, br = 0;
            byte c = tiles[x, y].wall;
            int set = rand.Next(0, 3) * 2;

            if (x > 0)
            {
                l = tiles[x - 1, y].wall;
                if (y > 0)
                    tl = tiles[x - 1, y - 1].wall;
                if (y < tilesHigh - 1)
                    bl = tiles[x - 1, y + 1].wall;
            }
            if (x < tilesWide - 1)
            {
                r = tiles[x + 1, y].wall;
                if (y > 0)
                    tr = tiles[x + 1, y - 1].wall;
                if (y < tilesHigh - 1)
                    br = tiles[x + 1, y + 1].wall;
            }
            if (y > 0)
                t = tiles[x, y - 1].wall;
            if (y < tilesHigh - 1)
                b = tiles[x, y + 1].wall;

            int mask = 0;
            if (t == c) mask |= 0x80000;
            if (b == c) mask |= 0x40000;
            if (l == c) mask |= 0x20000;
            if (r == c) mask |= 0x10000;
            if (tl == c) mask |= 0x880;
            if (tr == c) mask |= 0x440;
            if (bl == c) mask |= 0x220;
            if (br == c) mask |= 0x110;

            foreach (UVRule rule in uvRules[mask >> 16])
            {
                if ((mask & rule.mask) == rule.val)
                {
                    tiles[x, y].wallu = rule.uvs[set];
                    tiles[x, y].wallv = rule.uvs[set + 1];
                    return;
                }
            }
            //again, impossible to be here.
        }
Example #11
0
 private int findCorruptGrass(int x, int y, ref Tile[,] tiles)
 {
     for (int i = 0; i < 100; i++)
     {
         Tile tile = tiles[x, y + i];
         if (tile.type == 2) //normal grass
             return 0;
         if (tile.type == 23) //corrupt grass
             return 1;
         if (tile.type == 60) //jungle grass
             return 2;
         if (tile.type == 109) //hallowed grass
             return 3;
         if (tile.type == 147) //snow block
             return 4;
     }
     return 0;
 }