using UnityEngine;
using System.Collections;

[System.Serializable]
public enum TileType
{
    Empty,
    Block,
    OneWay,

    TestSlopeMid1,
    TestSlopeMid1FX,
    TestSlopeMid1FY,
    TestSlopeMid1FXY,
    TestSlopeMid1F90,
    TestSlopeMid1F90X,
    TestSlopeMid1F90Y,
    TestSlopeMid1F90XY,

    TestSlopeMid1Rev,
    TestSlopeMid1RevFX,
    TestSlopeMid1RevFY,
    TestSlopeMid1RevFXY,
    TestSlopeMid1RevF90,
    TestSlopeMid1RevF90X,
    TestSlopeMid1RevF90Y,
    TestSlopeMid1RevF90XY,

    TestSlope45,
    TestSlope45FX,
    TestSlope45FY,
    TestSlope45FXY,
    TestSlope45F90,
    TestSlope45F90X,
    TestSlope45F90Y,
    TestSlope45F90XY,

    TestSlope22P1,
    TestSlope22P1FX,
    TestSlope22P1FY,
    TestSlope22P1FXY,
    TestSlope22P1F90,
    TestSlope22P1F90X,
    TestSlope22P1F90Y,
    TestSlope22P1F90XY,

    TestSlope22P2,
    TestSlope22P2FX,
    TestSlope22P2FY,
    TestSlope22P2FXY,
    TestSlope22P2F90,
    TestSlope22P2F90X,
    TestSlope22P2F90Y,
    TestSlope22P2F90XY,

    TestSlopeMid2,
    TestSlopeMid2FX,
    TestSlopeMid2FY,
    TestSlopeMid2FXY,
    TestSlopeMid2F90,
    TestSlopeMid2F90X,
    TestSlopeMid2F90Y,
    TestSlopeMid2F90XY,

    TestSlopeMid2Rev,
    TestSlopeMid2RevFX,
    TestSlopeMid2RevFY,
    TestSlopeMid2RevFXY,
    TestSlopeMid2RevF90,
    TestSlopeMid2RevF90X,
    TestSlopeMid2RevF90Y,
    TestSlopeMid2RevF90XY,

    TestSlope15P1,
    TestSlope15P1FX,
    TestSlope15P1FY,
    TestSlope15P1FXY,
    TestSlope15P1F90,
    TestSlope15P1F90X,
    TestSlope15P1F90Y,
    TestSlope15P1F90XY,

    TestSlope15P2,
    TestSlope15P2FX,
    TestSlope15P2FY,
    TestSlope15P2FXY,
    TestSlope15P2F90,
    TestSlope15P2F90X,
    TestSlope15P2F90Y,
    TestSlope15P2F90XY,

    TestSlope15P3,
    TestSlope15P3FX,
    TestSlope15P3FY,
    TestSlope15P3FXY,
    TestSlope15P3F90,
    TestSlope15P3F90X,
    TestSlope15P3F90Y,
    TestSlope15P3F90XY,

    TestSlopeMid3,
    TestSlopeMid3FX,
    TestSlopeMid3FY,
    TestSlopeMid3FXY,
    TestSlopeMid3F90,
    TestSlopeMid3F90X,
    TestSlopeMid3F90Y,
    TestSlopeMid3F90XY,

    TestSlopeMid3Rev,
    TestSlopeMid3RevFX,
    TestSlopeMid3RevFY,
    TestSlopeMid3RevFXY,
    TestSlopeMid3RevF90,
    TestSlopeMid3RevF90X,
    TestSlopeMid3RevF90Y,
    TestSlopeMid3RevF90XY,

    TestSlope11P1,
    TestSlope11P1FX,
    TestSlope11P1FY,
    TestSlope11P1FXY,
    TestSlope11P1F90,
    TestSlope11P1F90X,
    TestSlope11P1F90Y,
    TestSlope11P1F90XY,

    TestSlope11P2,
    TestSlope11P2FX,
    TestSlope11P2FY,
    TestSlope11P2FXY,
    TestSlope11P2F90,
    TestSlope11P2F90X,
    TestSlope11P2F90Y,
    TestSlope11P2F90XY,

    TestSlope11P3,
    TestSlope11P3FX,
    TestSlope11P3FY,
    TestSlope11P3FXY,
    TestSlope11P3F90,
    TestSlope11P3F90X,
    TestSlope11P3F90Y,
    TestSlope11P3F90XY,

    TestSlope11P4,
    TestSlope11P4FX,
    TestSlope11P4FY,
    TestSlope11P4FXY,
    TestSlope11P4F90,
    TestSlope11P4F90X,
    TestSlope11P4F90Y,
    TestSlope11P4F90XY,

    TestSlopeMid4,
    TestSlopeMid4FX,
    TestSlopeMid4FY,
    TestSlopeMid4FXY,
    TestSlopeMid4F90,
    TestSlopeMid4F90X,
    TestSlopeMid4F90Y,
    TestSlopeMid4F90XY,

    TestSlopeMid4Rev,
    TestSlopeMid4RevFX,
    TestSlopeMid4RevFY,
    TestSlopeMid4RevFXY,
    TestSlopeMid4RevF90,
    TestSlopeMid4RevF90X,
    TestSlopeMid4RevF90Y,
    TestSlopeMid4RevF90XY,


    TestOneWaySlopeMid1,
    TestOneWaySlopeMid1FX,
    TestOneWaySlopeMid1FY,
    TestOneWaySlopeMid1FXY,
    TestOneWaySlopeMid1F90,
    TestOneWaySlopeMid1F90X,
    TestOneWaySlopeMid1F90Y,
    TestOneWaySlopeMid1F90XY,

    TestOneWaySlopeMid1Rev,
    TestOneWaySlopeMid1RevFX,
    TestOneWaySlopeMid1RevFY,
    TestOneWaySlopeMid1RevFXY,
    TestOneWaySlopeMid1RevF90,
    TestOneWaySlopeMid1RevF90X,
    TestOneWaySlopeMid1RevF90Y,
    TestOneWaySlopeMid1RevF90XY,

    TestOneWaySlope45,
    TestOneWaySlope45FX,
    TestOneWaySlope45FY,
    TestOneWaySlope45FXY,
    TestOneWaySlope45F90,
    TestOneWaySlope45F90X,
    TestOneWaySlope45F90Y,
    TestOneWaySlope45F90XY,

    TestOneWaySlope22P1,
    TestOneWaySlope22P1FX,
    TestOneWaySlope22P1FY,
    TestOneWaySlope22P1FXY,
    TestOneWaySlope22P1F90,
    TestOneWaySlope22P1F90X,
    TestOneWaySlope22P1F90Y,
    TestOneWaySlope22P1F90XY,

    TestOneWaySlope22P2,
    TestOneWaySlope22P2FX,
    TestOneWaySlope22P2FY,
    TestOneWaySlope22P2FXY,
    TestOneWaySlope22P2F90,
    TestOneWaySlope22P2F90X,
    TestOneWaySlope22P2F90Y,
    TestOneWaySlope22P2F90XY,

    TestOneWaySlopeMid2,
    TestOneWaySlopeMid2FX,
    TestOneWaySlopeMid2FY,
    TestOneWaySlopeMid2FXY,
    TestOneWaySlopeMid2F90,
    TestOneWaySlopeMid2F90X,
    TestOneWaySlopeMid2F90Y,
    TestOneWaySlopeMid2F90XY,

    TestOneWaySlopeMid2Rev,
    TestOneWaySlopeMid2RevFX,
    TestOneWaySlopeMid2RevFY,
    TestOneWaySlopeMid2RevFXY,
    TestOneWaySlopeMid2RevF90,
    TestOneWaySlopeMid2RevF90X,
    TestOneWaySlopeMid2RevF90Y,
    TestOneWaySlopeMid2RevF90XY,

    TestOneWaySlope15P1,
    TestOneWaySlope15P1FX,
    TestOneWaySlope15P1FY,
    TestOneWaySlope15P1FXY,
    TestOneWaySlope15P1F90,
    TestOneWaySlope15P1F90X,
    TestOneWaySlope15P1F90Y,
    TestOneWaySlope15P1F90XY,

    TestOneWaySlope15P2,
    TestOneWaySlope15P2FX,
    TestOneWaySlope15P2FY,
    TestOneWaySlope15P2FXY,
    TestOneWaySlope15P2F90,
    TestOneWaySlope15P2F90X,
    TestOneWaySlope15P2F90Y,
    TestOneWaySlope15P2F90XY,

    TestOneWaySlope15P3,
    TestOneWaySlope15P3FX,
    TestOneWaySlope15P3FY,
    TestOneWaySlope15P3FXY,
    TestOneWaySlope15P3F90,
    TestOneWaySlope15P3F90X,
    TestOneWaySlope15P3F90Y,
    TestOneWaySlope15P3F90XY,

    TestOneWaySlopeMid3,
    TestOneWaySlopeMid3FX,
    TestOneWaySlopeMid3FY,
    TestOneWaySlopeMid3FXY,
    TestOneWaySlopeMid3F90,
    TestOneWaySlopeMid3F90X,
    TestOneWaySlopeMid3F90Y,
    TestOneWaySlopeMid3F90XY,

    TestOneWaySlopeMid3Rev,
    TestOneWaySlopeMid3RevFX,
    TestOneWaySlopeMid3RevFY,
    TestOneWaySlopeMid3RevFXY,
    TestOneWaySlopeMid3RevF90,
    TestOneWaySlopeMid3RevF90X,
    TestOneWaySlopeMid3RevF90Y,
    TestOneWaySlopeMid3RevF90XY,

    TestOneWaySlope11P1,
    TestOneWaySlope11P1FX,
    TestOneWaySlope11P1FY,
    TestOneWaySlope11P1FXY,
    TestOneWaySlope11P1F90,
    TestOneWaySlope11P1F90X,
    TestOneWaySlope11P1F90Y,
    TestOneWaySlope11P1F90XY,

    TestOneWaySlope11P2,
    TestOneWaySlope11P2FX,
    TestOneWaySlope11P2FY,
    TestOneWaySlope11P2FXY,
    TestOneWaySlope11P2F90,
    TestOneWaySlope11P2F90X,
    TestOneWaySlope11P2F90Y,
    TestOneWaySlope11P2F90XY,

    TestOneWaySlope11P3,
    TestOneWaySlope11P3FX,
    TestOneWaySlope11P3FY,
    TestOneWaySlope11P3FXY,
    TestOneWaySlope11P3F90,
    TestOneWaySlope11P3F90X,
    TestOneWaySlope11P3F90Y,
    TestOneWaySlope11P3F90XY,

    TestOneWaySlope11P4,
    TestOneWaySlope11P4FX,
    TestOneWaySlope11P4FY,
    TestOneWaySlope11P4FXY,
    TestOneWaySlope11P4F90,
    TestOneWaySlope11P4F90X,
    TestOneWaySlope11P4F90Y,
    TestOneWaySlope11P4F90XY,

    TestOneWaySlopeMid4,
    TestOneWaySlopeMid4FX,
    TestOneWaySlopeMid4FY,
    TestOneWaySlopeMid4FXY,
    TestOneWaySlopeMid4F90,
    TestOneWaySlopeMid4F90X,
    TestOneWaySlopeMid4F90Y,
    TestOneWaySlopeMid4F90XY,

    TestOneWaySlopeMid4Rev,
    TestOneWaySlopeMid4RevFX,
    TestOneWaySlopeMid4RevFY,
    TestOneWaySlopeMid4RevFXY,
    TestOneWaySlopeMid4RevF90,
    TestOneWaySlopeMid4RevF90X,
    TestOneWaySlopeMid4RevF90Y,
    TestOneWaySlopeMid4RevF90XY,

    Count,
}

public enum TileCollisionType
{
    Empty = 0,
    Full,

    SlopesStart,

    SlopeMid1,
    SlopeMid1FX,
    SlopeMid1FY,
    SlopeMid1FXY,
    SlopeMid1F90,
    SlopeMid1F90X,
    SlopeMid1F90Y,
    SlopeMid1F90XY,

    SlopeMid1Rev,
    SlopeMid1RevFX,
    SlopeMid1RevFY,
    SlopeMid1RevFXY,
    SlopeMid1RevF90,
    SlopeMid1RevF90X,
    SlopeMid1RevF90Y,
    SlopeMid1RevF90XY,

    Slope45,
    Slope45FX,
    Slope45FY,
    Slope45FXY,
    Slope45F90,
    Slope45F90X,
    Slope45F90Y,
    Slope45F90XY,

    Slope22P1,
    Slope22P1FX,
    Slope22P1FY,
    Slope22P1FXY,
    Slope22P1F90,
    Slope22P1F90X,
    Slope22P1F90Y,
    Slope22P1F90XY,

    Slope22P2,
    Slope22P2FX,
    Slope22P2FY,
    Slope22P2FXY,
    Slope22P2F90,
    Slope22P2F90X,
    Slope22P2F90Y,
    Slope22P2F90XY,

    SlopeMid2,
    SlopeMid2FX,
    SlopeMid2FY,
    SlopeMid2FXY,
    SlopeMid2F90,
    SlopeMid2F90X,
    SlopeMid2F90Y,
    SlopeMid2F90XY,

    SlopeMid2Rev,
    SlopeMid2RevFX,
    SlopeMid2RevFY,
    SlopeMid2RevFXY,
    SlopeMid2RevF90,
    SlopeMid2RevF90X,
    SlopeMid2RevF90Y,
    SlopeMid2RevF90XY,

    Slope15P1,
    Slope15P1FX,
    Slope15P1FY,
    Slope15P1FXY,
    Slope15P1F90,
    Slope15P1F90X,
    Slope15P1F90Y,
    Slope15P1F90XY,

    Slope15P2,
    Slope15P2FX,
    Slope15P2FY,
    Slope15P2FXY,
    Slope15P2F90,
    Slope15P2F90X,
    Slope15P2F90Y,
    Slope15P2F90XY,

    Slope15P3,
    Slope15P3FX,
    Slope15P3FY,
    Slope15P3FXY,
    Slope15P3F90,
    Slope15P3F90X,
    Slope15P3F90Y,
    Slope15P3F90XY,

    SlopeMid3,
    SlopeMid3FX,
    SlopeMid3FY,
    SlopeMid3FXY,
    SlopeMid3F90,
    SlopeMid3F90X,
    SlopeMid3F90Y,
    SlopeMid3F90XY,

    SlopeMid3Rev,
    SlopeMid3RevFX,
    SlopeMid3RevFY,
    SlopeMid3RevFXY,
    SlopeMid3RevF90,
    SlopeMid3RevF90X,
    SlopeMid3RevF90Y,
    SlopeMid3RevF90XY,

    Slope11P1,
    Slope11P1FX,
    Slope11P1FY,
    Slope11P1FXY,
    Slope11P1F90,
    Slope11P1F90X,
    Slope11P1F90Y,
    Slope11P1F90XY,

    Slope11P2,
    Slope11P2FX,
    Slope11P2FY,
    Slope11P2FXY,
    Slope11P2F90,
    Slope11P2F90X,
    Slope11P2F90Y,
    Slope11P2F90XY,

    Slope11P3,
    Slope11P3FX,
    Slope11P3FY,
    Slope11P3FXY,
    Slope11P3F90,
    Slope11P3F90X,
    Slope11P3F90Y,
    Slope11P3F90XY,

    Slope11P4,
    Slope11P4FX,
    Slope11P4FY,
    Slope11P4FXY,
    Slope11P4F90,
    Slope11P4F90X,
    Slope11P4F90Y,
    Slope11P4F90XY,

    SlopeMid4,
    SlopeMid4FX,
    SlopeMid4FY,
    SlopeMid4FXY,
    SlopeMid4F90,
    SlopeMid4F90X,
    SlopeMid4F90Y,
    SlopeMid4F90XY,

    SlopeMid4Rev,
    SlopeMid4RevFX,
    SlopeMid4RevFY,
    SlopeMid4RevFXY,
    SlopeMid4RevF90,
    SlopeMid4RevF90X,
    SlopeMid4RevF90Y,
    SlopeMid4RevF90XY,

    OneWayStart,

    OneWaySlopeMid1 = OneWayStart,
    OneWaySlopeMid1FX,
    OneWaySlopeMid1FY,
    OneWaySlopeMid1FXY,
    OneWaySlopeMid1F90,
    OneWaySlopeMid1F90X,
    OneWaySlopeMid1F90Y,
    OneWaySlopeMid1F90XY,

    OneWaySlopeMid1Rev,
    OneWaySlopeMid1RevFX,
    OneWaySlopeMid1RevFY,
    OneWaySlopeMid1RevFXY,
    OneWaySlopeMid1RevF90,
    OneWaySlopeMid1RevF90X,
    OneWaySlopeMid1RevF90Y,
    OneWaySlopeMid1RevF90XY,

    OneWaySlope45,
    OneWaySlope45FX,
    OneWaySlope45FY,
    OneWaySlope45FXY,
    OneWaySlope45F90,
    OneWaySlope45F90X,
    OneWaySlope45F90Y,
    OneWaySlope45F90XY,

    OneWaySlope22P1,
    OneWaySlope22P1FX,
    OneWaySlope22P1FY,
    OneWaySlope22P1FXY,
    OneWaySlope22P1F90,
    OneWaySlope22P1F90X,
    OneWaySlope22P1F90Y,
    OneWaySlope22P1F90XY,

    OneWaySlope22P2,
    OneWaySlope22P2FX,
    OneWaySlope22P2FY,
    OneWaySlope22P2FXY,
    OneWaySlope22P2F90,
    OneWaySlope22P2F90X,
    OneWaySlope22P2F90Y,
    OneWaySlope22P2F90XY,

    OneWaySlopeMid2,
    OneWaySlopeMid2FX,
    OneWaySlopeMid2FY,
    OneWaySlopeMid2FXY,
    OneWaySlopeMid2F90,
    OneWaySlopeMid2F90X,
    OneWaySlopeMid2F90Y,
    OneWaySlopeMid2F90XY,

    OneWaySlopeMid2Rev,
    OneWaySlopeMid2RevFX,
    OneWaySlopeMid2RevFY,
    OneWaySlopeMid2RevFXY,
    OneWaySlopeMid2RevF90,
    OneWaySlopeMid2RevF90X,
    OneWaySlopeMid2RevF90Y,
    OneWaySlopeMid2RevF90XY,

    OneWaySlope15P1,
    OneWaySlope15P1FX,
    OneWaySlope15P1FY,
    OneWaySlope15P1FXY,
    OneWaySlope15P1F90,
    OneWaySlope15P1F90X,
    OneWaySlope15P1F90Y,
    OneWaySlope15P1F90XY,

    OneWaySlope15P2,
    OneWaySlope15P2FX,
    OneWaySlope15P2FY,
    OneWaySlope15P2FXY,
    OneWaySlope15P2F90,
    OneWaySlope15P2F90X,
    OneWaySlope15P2F90Y,
    OneWaySlope15P2F90XY,

    OneWaySlope15P3,
    OneWaySlope15P3FX,
    OneWaySlope15P3FY,
    OneWaySlope15P3FXY,
    OneWaySlope15P3F90,
    OneWaySlope15P3F90X,
    OneWaySlope15P3F90Y,
    OneWaySlope15P3F90XY,

    OneWaySlopeMid3,
    OneWaySlopeMid3FX,
    OneWaySlopeMid3FY,
    OneWaySlopeMid3FXY,
    OneWaySlopeMid3F90,
    OneWaySlopeMid3F90X,
    OneWaySlopeMid3F90Y,
    OneWaySlopeMid3F90XY,

    OneWaySlopeMid3Rev,
    OneWaySlopeMid3RevFX,
    OneWaySlopeMid3RevFY,
    OneWaySlopeMid3RevFXY,
    OneWaySlopeMid3RevF90,
    OneWaySlopeMid3RevF90X,
    OneWaySlopeMid3RevF90Y,
    OneWaySlopeMid3RevF90XY,

    OneWaySlope11P1,
    OneWaySlope11P1FX,
    OneWaySlope11P1FY,
    OneWaySlope11P1FXY,
    OneWaySlope11P1F90,
    OneWaySlope11P1F90X,
    OneWaySlope11P1F90Y,
    OneWaySlope11P1F90XY,

    OneWaySlope11P2,
    OneWaySlope11P2FX,
    OneWaySlope11P2FY,
    OneWaySlope11P2FXY,
    OneWaySlope11P2F90,
    OneWaySlope11P2F90X,
    OneWaySlope11P2F90Y,
    OneWaySlope11P2F90XY,

    OneWaySlope11P3,
    OneWaySlope11P3FX,
    OneWaySlope11P3FY,
    OneWaySlope11P3FXY,
    OneWaySlope11P3F90,
    OneWaySlope11P3F90X,
    OneWaySlope11P3F90Y,
    OneWaySlope11P3F90XY,

    OneWaySlope11P4,
    OneWaySlope11P4FX,
    OneWaySlope11P4FY,
    OneWaySlope11P4FXY,
    OneWaySlope11P4F90,
    OneWaySlope11P4F90X,
    OneWaySlope11P4F90Y,
    OneWaySlope11P4F90XY,

    OneWaySlopeMid4,
    OneWaySlopeMid4FX,
    OneWaySlopeMid4FY,
    OneWaySlopeMid4FXY,
    OneWaySlopeMid4F90,
    OneWaySlopeMid4F90X,
    OneWaySlopeMid4F90Y,
    OneWaySlopeMid4F90XY,

    OneWaySlopeMid4Rev,
    OneWaySlopeMid4RevFX,
    OneWaySlopeMid4RevFY,
    OneWaySlopeMid4RevFXY,
    OneWaySlopeMid4RevF90,
    OneWaySlopeMid4RevF90X,
    OneWaySlopeMid4RevF90Y,
    OneWaySlopeMid4RevF90XY,

    SlopeEnd = OneWaySlopeMid4RevF90XY,

    OneWayFull,

    OneWayEnd,

    Count,
}

[System.Serializable]
public struct SlopeOffsetSB
{
    public sbyte freeLeft, freeRight, freeDown, freeUp, collidingLeft, collidingRight, collidingBottom, collidingTop;

    public SlopeOffsetSB(sbyte _freeLeft, sbyte _freeRight, sbyte _freeDown, sbyte _freeUp, sbyte _collidingLeft, sbyte _collidingRight, sbyte _collidingBottom, sbyte _collidingTop)
    {
        freeLeft = _freeLeft;
        freeRight = _freeRight;
        freeDown = _freeDown;
        freeUp = _freeUp;

        collidingLeft = _collidingLeft;
        collidingRight = _collidingRight;
        collidingBottom = _collidingBottom;
        collidingTop = _collidingTop;
    }
}

[System.Serializable]
public struct SlopeOffsetI
{
    public int freeLeft, freeRight, freeDown, freeUp, collidingLeft, collidingRight, collidingBottom, collidingTop;

    public SlopeOffsetI(int _freeLeft, int _freeRight, int _freeDown, int _freeUp, int _collidingLeft, int _collidingRight, int _collidingBottom, int _collidingTop)
    {
        freeLeft = _freeLeft;
        freeRight = _freeRight;
        freeDown = _freeDown;
        freeUp = _freeUp;

        collidingLeft = _collidingLeft;
        collidingRight = _collidingRight;
        collidingBottom = _collidingBottom;
        collidingTop = _collidingTop;
    }

    public SlopeOffsetI(SlopeOffsetSB other)
    {
        freeLeft = other.freeLeft;
        freeRight = other.freeRight;
        freeDown = other.freeDown;
        freeUp = other.freeUp;

        collidingLeft = other.collidingLeft;
        collidingRight = other.collidingRight;
        collidingBottom = other.collidingBottom;
        collidingTop = other.collidingTop;
    }
}

public static class Slopes
{
    public static readonly sbyte[] empty = new sbyte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    public static sbyte[][] emptyMaxHeight = CacheSlopeHeightByPosAndLength(empty);

    public static readonly sbyte[] full = new sbyte[16] { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 };
    public static sbyte[][] blockMaxHeight = CacheSlopeHeightByPosAndLength(full);

    public static readonly sbyte[] slopeMid1 = new sbyte[16] { 1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1 };
    public static readonly sbyte[] slopeMid1Rev = new sbyte[16] { 15, 14, 13, 12, 11, 10, 9, 8, 8, 9, 10, 11, 12, 13, 14, 15 };
    public static readonly sbyte[] slope45 = new sbyte[16] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
    public static readonly sbyte[] slope22P1 = new sbyte[16] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 };
    public static readonly sbyte[] slope22P2 = new sbyte[16] { 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16 };
    public static readonly sbyte[] slopeMid2 = new sbyte[16] { 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 11, 11, 10, 10, 9, 9 };
    public static readonly sbyte[] slopeMid2Rev = new sbyte[16] { 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 6, 6, 7, 7, 8, 8 };
    public static readonly sbyte[] slope15P1 = new sbyte[16] { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6 };
    public static readonly sbyte[] slope15P2 = new sbyte[16] { 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11 };
    public static readonly sbyte[] slope15P3 = new sbyte[16] { 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16 };
    public static readonly sbyte[] slopeMid3 = new sbyte[16] { 11, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 11 };
    public static readonly sbyte[] slopeMid3Rev = new sbyte[16] { 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6 };
    public static readonly sbyte[] slope11P1 = new sbyte[16] { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };
    public static readonly sbyte[] slope11P2 = new sbyte[16] { 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8 };
    public static readonly sbyte[] slope11P3 = new sbyte[16] { 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12 };
    public static readonly sbyte[] slope11P4 = new sbyte[16] { 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16 };
    public static readonly sbyte[] slopeMid4 = new sbyte[16] { 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13 };
    public static readonly sbyte[] slopeMid4Rev = new sbyte[16] { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 };

    public static sbyte[][] slopesHeights;
    public static sbyte[][][] slopesExtended;
    public static sbyte[][][] slopeHeightByPosAndSizeCaches;
    public static SlopeOffsetSB[][][][][] slopeOffsets;
    public static sbyte[][] posByHeightCaches;

    public static sbyte[][] Extend(sbyte[] slope)
    {
        sbyte[][] extended = new sbyte[slope.Length][];

        for (int x = 0; x < slope.Length; ++x)
        {
            extended[x] = new sbyte[slope.Length];

            for (int y = 0; y < slope.Length; ++y)
                extended[x][y] = System.Convert.ToSByte(y < slope[x]);
        }

        return extended;
    }

    public static sbyte[] MirrorX(sbyte[] heightMap)
    {
        sbyte[] ret = new sbyte[heightMap.Length];

        for (int i = 0; i < ret.Length; ++i)
            ret[i] = heightMap[ret.Length - 1 - i];

        return ret;
    }

    public static sbyte[] CachePosByHeight(sbyte[] slope)
    {
        var posByHeight = new sbyte[slope.Length];

        for (int i = 0; i < slope.Length; ++i)
        {
            posByHeight[i] = -1;

            for (int j = 0; j < slope.Length; ++j)
            {
                if (slope[j] >= i)
                {
                    posByHeight[i] = slope[j];
                    break;
                }
            }
        }

        return posByHeight;
    }

    public static sbyte[][] CacheSlopeHeightByPosAndLength(sbyte[] slope)
    {
        var maxHeightCache = new sbyte[slope.Length][];

        for (sbyte pos = 0; pos < slope.Length; ++pos)
        {
            maxHeightCache[pos] = new sbyte[slope.Length];
            for (int dist = 0; dist < slope.Length; ++dist)
            {
                sbyte maxHeight = 0;
                for (int k = pos; k <= Mathf.Min(pos + dist, slope.Length - 1); ++k)
                {
                    if (slope[k] > maxHeight)
                        maxHeight = slope[k];
                }
                maxHeightCache[pos][dist] = maxHeight;
            }
        }

        return maxHeightCache;
    }

    public static SlopeOffsetSB[][][][] CacheSlopeOffsets(sbyte[][] slopeExtended)
    {
        var offsetCache = new SlopeOffsetSB[slopeExtended.Length][][][];

        for (int x = 0; x < slopeExtended.Length; ++x)
        {
            offsetCache[x] = new SlopeOffsetSB[slopeExtended.Length][][];

            for (int y = 0; y < slopeExtended.Length; ++y)
            {
                offsetCache[x][y] = new SlopeOffsetSB[slopeExtended.Length][];

                for (int w = 0; w < slopeExtended.Length; ++w)
                {
                    offsetCache[x][y][w] = new SlopeOffsetSB[slopeExtended.Length];

                    for (int h = 0; h < slopeExtended.Length; ++h)
                    {
                        offsetCache[x][y][w][h] = GetOffset(slopeExtended, (sbyte)x, (sbyte)y, (sbyte)w, (sbyte)h);
                    }
                }
            }
        }

        return offsetCache;
    }

    public static bool Collides(sbyte[][] slopeExtended, sbyte posX, sbyte posY, sbyte w, sbyte h)
    {
        for (int x = posX; x <= posX + w && x < slopeExtended.Length; ++x)
        {
            for (int y = posY; y <= posY + h && y < slopeExtended.Length; ++y)
            {
                if (slopeExtended[x][y] == 1)
                    return true;
            }
        }

        return false;
    }

    public static SlopeOffsetSB GetOffset(sbyte[][] slopeExtended, sbyte posX, sbyte posY, sbyte w, sbyte h)
    {
        sbyte freeUp = 0, freeDown = 0, collidingTop = 0, collidingBottom = 0;
        sbyte freeLeft = 0, freeRight = 0, collidingLeft = 0, collidingRight = 0;

        sbyte movH = h;
        while (movH >= 0 && posY + freeUp < slopeExtended.Length && Collides(slopeExtended, posX, (sbyte)(posY + freeUp), w, movH))
        {
            if (posY + freeUp == slopeExtended.Length)
                --movH;
            else
                ++freeUp;
        }

        freeUp += (sbyte)(h - movH);

        movH = h;
        while (movH >= 0 && posY + freeDown >= 0 && Collides(slopeExtended, posX, (sbyte)(posY + freeDown), w, movH))
        {
            if (posY + freeDown == 0)
                --movH;
            else
                --freeDown;
        }

        freeDown -= (sbyte)(h - movH);

        if (freeUp == 0)
        {
            movH = h;
            while (movH >= 0 && posY + collidingTop < slopeExtended.Length && !Collides(slopeExtended, posX, (sbyte)(posY + collidingTop), w, movH))
            {
                if (posY + collidingTop == slopeExtended.Length)
                    --movH;
                else
                    ++collidingTop;
            }

            collidingTop += (sbyte)(h - movH);
            collidingTop -= 1;
        }
        else
            collidingBottom = freeUp;

        if (freeDown == 0)
        {
            movH = h;
            while (movH >= 0 && posY + collidingBottom >= 0 && !Collides(slopeExtended, posX, (sbyte)(posY + collidingBottom), w, movH))
            {
                if (posY + collidingBottom == 0)
                    --movH;
                else
                    --collidingBottom;
            }

            collidingBottom -= (sbyte)(h - movH);
            collidingBottom += 1;
        }
        else
            collidingTop = freeDown;

        //width

        sbyte movW = w;
        while (movW >= 0 && posY + freeRight < slopeExtended.Length && Collides(slopeExtended, (sbyte)(posX + freeRight), posY, movW, h))
        {
            if (posX + freeRight == slopeExtended.Length)
                --movW;
            else
                ++freeRight;
        }

        freeRight += (sbyte)(w - movW);

        movW = w;
        while (movW >= 0 && posX + freeLeft >= 0 && Collides(slopeExtended, (sbyte)(posX + freeLeft), posY, movW, h))
        {
            if (posX + freeLeft == 0)
                --movW;
            else
                --freeLeft;
        }

        freeLeft -= (sbyte)(w - movW);

        if (freeRight == 0)
        {
            movW = w;
            while (movW >= 0 && posX + collidingRight < slopeExtended.Length && !Collides(slopeExtended, (sbyte)(posX + collidingRight), posY, movW, h))
            {
                if (posX + collidingRight == slopeExtended.Length)
                    --movW;
                else
                    ++collidingRight;
            }

            collidingRight += (sbyte)(w - movW);
            collidingRight -= 1;
        }
        else
            collidingLeft = freeRight;

        if (freeLeft == 0)
        {
            movW = w;
            while (movW >= 0 && posX + collidingLeft >= 0 && !Collides(slopeExtended, (sbyte)(posX + collidingLeft), posY, movW, w))
            {
                if (posX + collidingLeft == 0)
                    --movW;
                else
                    --collidingLeft;
            }

            collidingLeft -= (sbyte)(w - movW);
            collidingLeft += 1;
        }
        else
            collidingRight = freeLeft;

        return new SlopeOffsetSB(freeLeft, freeRight, freeDown, freeUp, collidingLeft, collidingRight, collidingBottom, collidingTop);
    }

    public static SlopeOffsetI GetOffset(Vector2 tileCenter, float leftX, float rightX, float bottomY, float topY, TileCollisionType tileCollisionType)
    {
        int posX, posY, sizeX, sizeY;

        float leftTileEdge = tileCenter.x - Map.cTileSize / 2;
        float rightTileEdge = leftTileEdge + Map.cTileSize;
        float bottomTileEdge = tileCenter.y - Map.cTileSize / 2;
        float topTileEdge = bottomTileEdge + Map.cTileSize;
        SlopeOffsetI offset;

        if (!IsFlipped90(tileCollisionType))
        {
            if (IsFlippedX(tileCollisionType))
            {
                posX = (int)Mathf.Clamp(rightTileEdge - rightX, 0.0f, Map.cTileSize - 1);
                sizeX = (int)Mathf.Clamp((rightTileEdge - posX) - leftX, 0.0f, Map.cTileSize - 1);
            }
            else
            {
                posX = (int)Mathf.Clamp(leftX - leftTileEdge, 0.0f, Map.cTileSize - 1);
                sizeX = (int)Mathf.Clamp(rightX - (leftTileEdge + posX), 0.0f, Map.cTileSize - 1);
            }

            if (IsFlippedY(tileCollisionType))
            {
                posY = (int)Mathf.Clamp(topTileEdge - topY, 0.0f, Map.cTileSize - 1);
                sizeY = (int)Mathf.Clamp((topTileEdge - posY) - bottomY, 0.0f, Map.cTileSize - 1);
            }
            else
            {
                posY = (int)Mathf.Clamp(bottomY - bottomTileEdge, 0.0f, Map.cTileSize - 1);
                sizeY = (int)Mathf.Clamp(topY - (bottomTileEdge + posY), 0.0f, Map.cTileSize - 1);
            }

            offset = new SlopeOffsetI(slopeOffsets[(int)tileCollisionType][posX][posY][sizeX][sizeY]);

            if (IsFlippedY(tileCollisionType))
            {
                int tmp = offset.freeDown;
                offset.freeDown = -offset.freeUp;
                offset.freeUp = -tmp;
                tmp = offset.collidingTop;
                offset.collidingTop = -offset.collidingBottom;
                offset.collidingBottom = -tmp;
            }
        }
        else
        {
            if (IsFlippedY(tileCollisionType))
            {
                posX = (int)Mathf.Clamp(bottomY - bottomTileEdge, 0.0f, Map.cTileSize - 1);
                sizeX = (int)Mathf.Clamp(topY - (bottomTileEdge + posX), 0.0f, Map.cTileSize - 1);
            }
            else
            {
                posX = (int)Mathf.Clamp(topTileEdge - topY, 0.0f, Map.cTileSize - 1);
                sizeX = (int)Mathf.Clamp((topTileEdge - posX) - bottomY, 0.0f, Map.cTileSize - 1);
            }

            if (IsFlippedX(tileCollisionType))
            {
                posY = (int)Mathf.Clamp(rightTileEdge - rightX, 0.0f, Map.cTileSize - 1);
                sizeY = (int)Mathf.Clamp((rightTileEdge - posY) - leftX, 0.0f, Map.cTileSize - 1);
            }
            else
            {
                posY = (int)Mathf.Clamp(leftX - leftTileEdge, 0.0f, Map.cTileSize - 1);
                sizeY = (int)Mathf.Clamp(rightX - (leftTileEdge + posY), 0.0f, Map.cTileSize - 1);
            }

            offset = new SlopeOffsetI(slopeOffsets[(int)tileCollisionType][posX][posY][sizeX][sizeY]);

            if (IsFlippedY(tileCollisionType))
            {
                offset.collidingBottom = offset.collidingLeft;
                offset.freeDown = offset.freeLeft;
                offset.collidingTop = offset.collidingRight;
                offset.freeUp = offset.freeRight;
            }
            else
            {
                offset.collidingBottom = -offset.collidingRight;
                offset.freeDown = -offset.freeRight;
                offset.collidingTop = -offset.collidingLeft;
                offset.freeUp = -offset.freeLeft;
            }
        }

        if (topTileEdge < topY)
        {
            if (offset.freeDown < 0)
                offset.freeDown -= (int)(topY - topTileEdge);
            offset.collidingTop = offset.freeDown;
        }
        if (bottomTileEdge > bottomY)
        {
            if (offset.freeUp > 0)
                offset.freeUp += (int)bottomTileEdge - (int)bottomY;
            offset.collidingBottom = offset.freeUp;
        }

        return offset;
    }

    public static int GetSlopeHeightFromBottom(int x, TileCollisionType type)
    {
        switch (type)
        {
            case TileCollisionType.Empty:
                return 0;
            case TileCollisionType.Full:
            case TileCollisionType.OneWayFull:
                return Map.cTileSize;
        }

        if (IsFlippedX(type))
            x = Map.cTileSize - 1 - x;

        if (!IsFlipped90(type))
        {
            var offset = new SlopeOffsetI(slopeOffsets[(int)type][x][0][0][Map.cTileSize - 1]);
            return IsFlippedY(type) ? -offset.collidingTop : offset.collidingBottom;
        }
        else
        {
            var offset = new SlopeOffsetI(slopeOffsets[(int)type][0][x][Map.cTileSize - 1][0]);
            return IsFlippedY(type) ? offset.collidingLeft : -offset.collidingRight;
        }
    }

    public static bool IsOneWay(TileCollisionType type)
    {
        return ((int)type > (int)TileCollisionType.OneWayStart && (int)type < (int)TileCollisionType.OneWayEnd);
    }

    public static bool IsFlipped90(TileCollisionType type)
    {
        int typeId = ((int)type - ((int)TileCollisionType.SlopesStart + 1)) % 8;

        return (typeId > 3);
    }

    public static bool IsFlippedX(TileCollisionType type)
    {
        int typeId = ((int)type - ((int)TileCollisionType.SlopesStart + 1)) % 8;

        switch (typeId)
        {
            case 1:
            case 3:
            case 5:
            case 7:
                return true;
        }

        return false;
    }

    public static bool IsFlippedY(TileCollisionType type)
    {
        int typeId = ((int)type - ((int)TileCollisionType.SlopesStart + 1)) % 8;

        switch (typeId)
        {
            case 2:
            case 3:
            case 6:
            case 7:
                return true;
        }

        return false;
    }


    public static void Init()
    {
        slopesHeights = new sbyte[(int)TileCollisionType.Count][];
        slopesExtended = new sbyte[(int)TileCollisionType.Count][][];
        slopeHeightByPosAndSizeCaches = new sbyte[(int)TileCollisionType.Count][][];
        posByHeightCaches = new sbyte[(int)TileCollisionType.Count][];
        slopeOffsets = new SlopeOffsetSB[(int)TileCollisionType.Count][][][][];

        for (int i = 0; i < (int)TileCollisionType.Count; ++i)
        {
            switch ((TileCollisionType)i)
            {
                case TileCollisionType.Empty:
                    slopesHeights[i] = empty;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;

                case TileCollisionType.Full:
                    slopesHeights[i] = full;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.OneWayFull:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Full];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Full];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Full];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Full];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Full];
                    break;

                case TileCollisionType.Slope45:
                    slopesHeights[i] = slope45;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope45FX:
                case TileCollisionType.Slope45FY:
                case TileCollisionType.Slope45FXY:
                case TileCollisionType.Slope45F90:
                case TileCollisionType.Slope45F90X:
                case TileCollisionType.Slope45F90XY:
                case TileCollisionType.Slope45F90Y:
                case TileCollisionType.OneWaySlope45:
                case TileCollisionType.OneWaySlope45FX:
                case TileCollisionType.OneWaySlope45FY:
                case TileCollisionType.OneWaySlope45FXY:
                case TileCollisionType.OneWaySlope45F90:
                case TileCollisionType.OneWaySlope45F90X:
                case TileCollisionType.OneWaySlope45F90XY:
                case TileCollisionType.OneWaySlope45F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope45];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope45];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope45];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope45];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope45];
                    break;

                case TileCollisionType.SlopeMid1:
                    slopesHeights[i] = slopeMid1;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid1FX:
                case TileCollisionType.SlopeMid1FY:
                case TileCollisionType.SlopeMid1FXY:
                case TileCollisionType.SlopeMid1F90:
                case TileCollisionType.SlopeMid1F90X:
                case TileCollisionType.SlopeMid1F90XY:
                case TileCollisionType.SlopeMid1F90Y:
                case TileCollisionType.OneWaySlopeMid1:
                case TileCollisionType.OneWaySlopeMid1FX:
                case TileCollisionType.OneWaySlopeMid1FY:
                case TileCollisionType.OneWaySlopeMid1FXY:
                case TileCollisionType.OneWaySlopeMid1F90:
                case TileCollisionType.OneWaySlopeMid1F90X:
                case TileCollisionType.OneWaySlopeMid1F90XY:
                case TileCollisionType.OneWaySlopeMid1F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid1];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid1];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid1];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid1];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid1];
                    break;

                case TileCollisionType.SlopeMid1Rev:
                    slopesHeights[i] = slopeMid1Rev;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid1RevFX:
                case TileCollisionType.SlopeMid1RevFY:
                case TileCollisionType.SlopeMid1RevFXY:
                case TileCollisionType.SlopeMid1RevF90:
                case TileCollisionType.SlopeMid1RevF90X:
                case TileCollisionType.SlopeMid1RevF90XY:
                case TileCollisionType.SlopeMid1RevF90Y:
                case TileCollisionType.OneWaySlopeMid1Rev:
                case TileCollisionType.OneWaySlopeMid1RevFX:
                case TileCollisionType.OneWaySlopeMid1RevFY:
                case TileCollisionType.OneWaySlopeMid1RevFXY:
                case TileCollisionType.OneWaySlopeMid1RevF90:
                case TileCollisionType.OneWaySlopeMid1RevF90X:
                case TileCollisionType.OneWaySlopeMid1RevF90XY:
                case TileCollisionType.OneWaySlopeMid1RevF90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid1Rev];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid1Rev];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid1Rev];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid1Rev];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid1Rev];
                    break;

                case TileCollisionType.Slope22P1:
                    slopesHeights[i] = slope22P1;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope22P1FX:
                case TileCollisionType.Slope22P1FY:
                case TileCollisionType.Slope22P1FXY:
                case TileCollisionType.Slope22P1F90:
                case TileCollisionType.Slope22P1F90X:
                case TileCollisionType.Slope22P1F90XY:
                case TileCollisionType.Slope22P1F90Y:
                case TileCollisionType.OneWaySlope22P1:
                case TileCollisionType.OneWaySlope22P1FX:
                case TileCollisionType.OneWaySlope22P1FY:
                case TileCollisionType.OneWaySlope22P1FXY:
                case TileCollisionType.OneWaySlope22P1F90:
                case TileCollisionType.OneWaySlope22P1F90X:
                case TileCollisionType.OneWaySlope22P1F90XY:
                case TileCollisionType.OneWaySlope22P1F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope22P1];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope22P1];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope22P1];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope22P1];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope22P1];
                    break;

                case TileCollisionType.Slope22P2:
                    slopesHeights[i] = slope22P2;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope22P2FX:
                case TileCollisionType.Slope22P2FY:
                case TileCollisionType.Slope22P2FXY:
                case TileCollisionType.Slope22P2F90:
                case TileCollisionType.Slope22P2F90X:
                case TileCollisionType.Slope22P2F90XY:
                case TileCollisionType.Slope22P2F90Y:
                case TileCollisionType.OneWaySlope22P2:
                case TileCollisionType.OneWaySlope22P2FX:
                case TileCollisionType.OneWaySlope22P2FY:
                case TileCollisionType.OneWaySlope22P2FXY:
                case TileCollisionType.OneWaySlope22P2F90:
                case TileCollisionType.OneWaySlope22P2F90X:
                case TileCollisionType.OneWaySlope22P2F90XY:
                case TileCollisionType.OneWaySlope22P2F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope22P2];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope22P2];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope22P2];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope22P2];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope22P2];
                    break;

                case TileCollisionType.SlopeMid2:
                    slopesHeights[i] = slopeMid2;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid2FX:
                case TileCollisionType.SlopeMid2FY:
                case TileCollisionType.SlopeMid2FXY:
                case TileCollisionType.SlopeMid2F90:
                case TileCollisionType.SlopeMid2F90X:
                case TileCollisionType.SlopeMid2F90XY:
                case TileCollisionType.SlopeMid2F90Y:
                case TileCollisionType.OneWaySlopeMid2:
                case TileCollisionType.OneWaySlopeMid2FX:
                case TileCollisionType.OneWaySlopeMid2FY:
                case TileCollisionType.OneWaySlopeMid2FXY:
                case TileCollisionType.OneWaySlopeMid2F90:
                case TileCollisionType.OneWaySlopeMid2F90X:
                case TileCollisionType.OneWaySlopeMid2F90XY:
                case TileCollisionType.OneWaySlopeMid2F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid2];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid2];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid2];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid2];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid2];
                    break;

                case TileCollisionType.SlopeMid2Rev:
                    slopesHeights[i] = slopeMid2Rev;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid2RevFX:
                case TileCollisionType.SlopeMid2RevFY:
                case TileCollisionType.SlopeMid2RevFXY:
                case TileCollisionType.SlopeMid2RevF90:
                case TileCollisionType.SlopeMid2RevF90X:
                case TileCollisionType.SlopeMid2RevF90XY:
                case TileCollisionType.SlopeMid2RevF90Y:
                case TileCollisionType.OneWaySlopeMid2Rev:
                case TileCollisionType.OneWaySlopeMid2RevFX:
                case TileCollisionType.OneWaySlopeMid2RevFY:
                case TileCollisionType.OneWaySlopeMid2RevFXY:
                case TileCollisionType.OneWaySlopeMid2RevF90:
                case TileCollisionType.OneWaySlopeMid2RevF90X:
                case TileCollisionType.OneWaySlopeMid2RevF90XY:
                case TileCollisionType.OneWaySlopeMid2RevF90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid2Rev];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid2Rev];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid2Rev];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid2Rev];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid2Rev];
                    break;

                case TileCollisionType.Slope15P1:
                    slopesHeights[i] = slope15P1;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope15P1FX:
                case TileCollisionType.Slope15P1FY:
                case TileCollisionType.Slope15P1FXY:
                case TileCollisionType.Slope15P1F90:
                case TileCollisionType.Slope15P1F90X:
                case TileCollisionType.Slope15P1F90XY:
                case TileCollisionType.Slope15P1F90Y:
                case TileCollisionType.OneWaySlope15P1:
                case TileCollisionType.OneWaySlope15P1FX:
                case TileCollisionType.OneWaySlope15P1FY:
                case TileCollisionType.OneWaySlope15P1FXY:
                case TileCollisionType.OneWaySlope15P1F90:
                case TileCollisionType.OneWaySlope15P1F90X:
                case TileCollisionType.OneWaySlope15P1F90XY:
                case TileCollisionType.OneWaySlope15P1F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope15P1];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope15P1];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope15P1];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope15P1];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope15P1];
                    break;

                case TileCollisionType.Slope15P2:
                    slopesHeights[i] = slope15P2;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope15P2FX:
                case TileCollisionType.Slope15P2FY:
                case TileCollisionType.Slope15P2FXY:
                case TileCollisionType.Slope15P2F90:
                case TileCollisionType.Slope15P2F90X:
                case TileCollisionType.Slope15P2F90XY:
                case TileCollisionType.Slope15P2F90Y:
                case TileCollisionType.OneWaySlope15P2:
                case TileCollisionType.OneWaySlope15P2FX:
                case TileCollisionType.OneWaySlope15P2FY:
                case TileCollisionType.OneWaySlope15P2FXY:
                case TileCollisionType.OneWaySlope15P2F90:
                case TileCollisionType.OneWaySlope15P2F90X:
                case TileCollisionType.OneWaySlope15P2F90XY:
                case TileCollisionType.OneWaySlope15P2F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope15P2];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope15P2];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope15P2];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope15P2];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope15P2];
                    break;

                case TileCollisionType.Slope15P3:
                    slopesHeights[i] = slope15P3;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope15P3FX:
                case TileCollisionType.Slope15P3FY:
                case TileCollisionType.Slope15P3FXY:
                case TileCollisionType.Slope15P3F90:
                case TileCollisionType.Slope15P3F90X:
                case TileCollisionType.Slope15P3F90XY:
                case TileCollisionType.Slope15P3F90Y:
                case TileCollisionType.OneWaySlope15P3:
                case TileCollisionType.OneWaySlope15P3FX:
                case TileCollisionType.OneWaySlope15P3FY:
                case TileCollisionType.OneWaySlope15P3FXY:
                case TileCollisionType.OneWaySlope15P3F90:
                case TileCollisionType.OneWaySlope15P3F90X:
                case TileCollisionType.OneWaySlope15P3F90XY:
                case TileCollisionType.OneWaySlope15P3F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope15P3];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope15P3];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope15P3];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope15P3];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope15P3];
                    break;

                case TileCollisionType.SlopeMid3:
                    slopesHeights[i] = slopeMid3;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid3FX:
                case TileCollisionType.SlopeMid3FY:
                case TileCollisionType.SlopeMid3FXY:
                case TileCollisionType.SlopeMid3F90:
                case TileCollisionType.SlopeMid3F90X:
                case TileCollisionType.SlopeMid3F90XY:
                case TileCollisionType.SlopeMid3F90Y:
                case TileCollisionType.OneWaySlopeMid3:
                case TileCollisionType.OneWaySlopeMid3FX:
                case TileCollisionType.OneWaySlopeMid3FY:
                case TileCollisionType.OneWaySlopeMid3FXY:
                case TileCollisionType.OneWaySlopeMid3F90:
                case TileCollisionType.OneWaySlopeMid3F90X:
                case TileCollisionType.OneWaySlopeMid3F90XY:
                case TileCollisionType.OneWaySlopeMid3F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid3];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid3];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid3];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid3];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid3];
                    break;

                case TileCollisionType.SlopeMid3Rev:
                    slopesHeights[i] = slopeMid3Rev;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid3RevFX:
                case TileCollisionType.SlopeMid3RevFY:
                case TileCollisionType.SlopeMid3RevFXY:
                case TileCollisionType.SlopeMid3RevF90:
                case TileCollisionType.SlopeMid3RevF90X:
                case TileCollisionType.SlopeMid3RevF90XY:
                case TileCollisionType.SlopeMid3RevF90Y:
                case TileCollisionType.OneWaySlopeMid3Rev:
                case TileCollisionType.OneWaySlopeMid3RevFX:
                case TileCollisionType.OneWaySlopeMid3RevFY:
                case TileCollisionType.OneWaySlopeMid3RevFXY:
                case TileCollisionType.OneWaySlopeMid3RevF90:
                case TileCollisionType.OneWaySlopeMid3RevF90X:
                case TileCollisionType.OneWaySlopeMid3RevF90XY:
                case TileCollisionType.OneWaySlopeMid3RevF90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid3Rev];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid3Rev];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid3Rev];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid3Rev];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid3Rev];
                    break;

                case TileCollisionType.Slope11P1:
                    slopesHeights[i] = slope11P1;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope11P1FX:
                case TileCollisionType.Slope11P1FY:
                case TileCollisionType.Slope11P1FXY:
                case TileCollisionType.Slope11P1F90:
                case TileCollisionType.Slope11P1F90X:
                case TileCollisionType.Slope11P1F90XY:
                case TileCollisionType.Slope11P1F90Y:
                case TileCollisionType.OneWaySlope11P1:
                case TileCollisionType.OneWaySlope11P1FX:
                case TileCollisionType.OneWaySlope11P1FY:
                case TileCollisionType.OneWaySlope11P1FXY:
                case TileCollisionType.OneWaySlope11P1F90:
                case TileCollisionType.OneWaySlope11P1F90X:
                case TileCollisionType.OneWaySlope11P1F90XY:
                case TileCollisionType.OneWaySlope11P1F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope11P1];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope11P1];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope11P1];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope11P1];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope11P1];
                    break;

                case TileCollisionType.Slope11P2:
                    slopesHeights[i] = slope11P2;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope11P2FX:
                case TileCollisionType.Slope11P2FY:
                case TileCollisionType.Slope11P2FXY:
                case TileCollisionType.Slope11P2F90:
                case TileCollisionType.Slope11P2F90X:
                case TileCollisionType.Slope11P2F90XY:
                case TileCollisionType.Slope11P2F90Y:
                case TileCollisionType.OneWaySlope11P2:
                case TileCollisionType.OneWaySlope11P2FX:
                case TileCollisionType.OneWaySlope11P2FY:
                case TileCollisionType.OneWaySlope11P2FXY:
                case TileCollisionType.OneWaySlope11P2F90:
                case TileCollisionType.OneWaySlope11P2F90X:
                case TileCollisionType.OneWaySlope11P2F90XY:
                case TileCollisionType.OneWaySlope11P2F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope11P2];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope11P2];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope11P2];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope11P2];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope11P2];
                    break;

                case TileCollisionType.Slope11P3:
                    slopesHeights[i] = slope11P3;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope11P3FX:
                case TileCollisionType.Slope11P3FY:
                case TileCollisionType.Slope11P3FXY:
                case TileCollisionType.Slope11P3F90:
                case TileCollisionType.Slope11P3F90X:
                case TileCollisionType.Slope11P3F90XY:
                case TileCollisionType.Slope11P3F90Y:
                case TileCollisionType.OneWaySlope11P3:
                case TileCollisionType.OneWaySlope11P3FX:
                case TileCollisionType.OneWaySlope11P3FY:
                case TileCollisionType.OneWaySlope11P3FXY:
                case TileCollisionType.OneWaySlope11P3F90:
                case TileCollisionType.OneWaySlope11P3F90X:
                case TileCollisionType.OneWaySlope11P3F90XY:
                case TileCollisionType.OneWaySlope11P3F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope11P3];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope11P3];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope11P3];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope11P3];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope11P3];
                    break;

                case TileCollisionType.Slope11P4:
                    slopesHeights[i] = slope11P4;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.Slope11P4FX:
                case TileCollisionType.Slope11P4FY:
                case TileCollisionType.Slope11P4FXY:
                case TileCollisionType.Slope11P4F90:
                case TileCollisionType.Slope11P4F90X:
                case TileCollisionType.Slope11P4F90XY:
                case TileCollisionType.Slope11P4F90Y:
                case TileCollisionType.OneWaySlope11P4:
                case TileCollisionType.OneWaySlope11P4FX:
                case TileCollisionType.OneWaySlope11P4FY:
                case TileCollisionType.OneWaySlope11P4FXY:
                case TileCollisionType.OneWaySlope11P4F90:
                case TileCollisionType.OneWaySlope11P4F90X:
                case TileCollisionType.OneWaySlope11P4F90XY:
                case TileCollisionType.OneWaySlope11P4F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.Slope11P4];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.Slope11P4];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.Slope11P4];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.Slope11P4];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.Slope11P4];
                    break;

                case TileCollisionType.SlopeMid4:
                    slopesHeights[i] = slopeMid4;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid4FX:
                case TileCollisionType.SlopeMid4FY:
                case TileCollisionType.SlopeMid4FXY:
                case TileCollisionType.SlopeMid4F90:
                case TileCollisionType.SlopeMid4F90X:
                case TileCollisionType.SlopeMid4F90XY:
                case TileCollisionType.SlopeMid4F90Y:
                case TileCollisionType.OneWaySlopeMid4:
                case TileCollisionType.OneWaySlopeMid4FX:
                case TileCollisionType.OneWaySlopeMid4FY:
                case TileCollisionType.OneWaySlopeMid4FXY:
                case TileCollisionType.OneWaySlopeMid4F90:
                case TileCollisionType.OneWaySlopeMid4F90X:
                case TileCollisionType.OneWaySlopeMid4F90XY:
                case TileCollisionType.OneWaySlopeMid4F90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid4];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid4];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid4];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid4];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid4];
                    break;

                case TileCollisionType.SlopeMid4Rev:
                    slopesHeights[i] = slopeMid4Rev;
                    slopesExtended[i] = Extend(slopesHeights[i]);
                    posByHeightCaches[i] = CachePosByHeight(slopesHeights[i]);
                    slopeHeightByPosAndSizeCaches[i] = CacheSlopeHeightByPosAndLength(slopesHeights[i]);
                    slopeOffsets[i] = CacheSlopeOffsets(slopesExtended[i]);
                    break;
                case TileCollisionType.SlopeMid4RevFX:
                case TileCollisionType.SlopeMid4RevFY:
                case TileCollisionType.SlopeMid4RevFXY:
                case TileCollisionType.SlopeMid4RevF90:
                case TileCollisionType.SlopeMid4RevF90X:
                case TileCollisionType.SlopeMid4RevF90XY:
                case TileCollisionType.SlopeMid4RevF90Y:
                case TileCollisionType.OneWaySlopeMid4Rev:
                case TileCollisionType.OneWaySlopeMid4RevFX:
                case TileCollisionType.OneWaySlopeMid4RevFY:
                case TileCollisionType.OneWaySlopeMid4RevFXY:
                case TileCollisionType.OneWaySlopeMid4RevF90:
                case TileCollisionType.OneWaySlopeMid4RevF90X:
                case TileCollisionType.OneWaySlopeMid4RevF90XY:
                case TileCollisionType.OneWaySlopeMid4RevF90Y:
                    slopesHeights[i] = slopesHeights[(int)TileCollisionType.SlopeMid4Rev];
                    slopesExtended[i] = slopesExtended[(int)TileCollisionType.SlopeMid4Rev];
                    posByHeightCaches[i] = posByHeightCaches[(int)TileCollisionType.SlopeMid4Rev];
                    slopeHeightByPosAndSizeCaches[i] = slopeHeightByPosAndSizeCaches[(int)TileCollisionType.SlopeMid4Rev];
                    slopeOffsets[i] = slopeOffsets[(int)TileCollisionType.SlopeMid4Rev];
                    break;
            }
        }
    }
}