#pragma clang diagnostic ignored "-Wmissing-prototypes"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Globals
{
    float4x4 uMVP;
    float4x4 uModel;
    int uTextured;
    float uLayer;
    float4 uColor;
    packed_float3 uAccent;
    int uPattern;
    float uLight;
    char _m8_pad[12];
    packed_float3 uFog;
    float uFogAmt;
    int uDynLightCount;
    float4 uDynLightPosRadius0;
    float4 uDynLightPosRadius1;
    float4 uDynLightPosRadius2;
    float4 uDynLightPosRadius3;
    float4 uDynLightColor0;
    float4 uDynLightColor1;
    float4 uDynLightColor2;
    float4 uDynLightColor3;
};

struct main0_out
{
    float4 FragColor [[color(0)]];
};

struct main0_in
{
    float2 vUV [[user(locn0)]];
    float vShade [[user(locn1)]];
    float3 vWorld [[user(locn2)]];
};

static inline __attribute__((always_inline))
float hash(thread const float2& p)
{
    return fract(sin(dot(p, float2(127.09999847412109375, 311.70001220703125))) * 43758.546875);
}

static inline __attribute__((always_inline))
float3 mobPattern(thread const float3& base, thread const float3& accent, constant Globals& _73, thread float2& vUV)
{
    float2 uv = vUV;
    float2 cell = floor(uv * 8.0);
    float2 param = cell + float2(float(_73.uPattern) * 13.0, 7.0);
    float n = hash(param);
    if (_73.uPattern == 1)
    {
        float2 param_1 = cell;
        float spot = smoothstep(0.4799999892711639404296875, 0.5, hash(param_1) - (distance(fract(uv * 4.0), float2(0.5)) * 0.85000002384185791015625));
        return mix(base, accent, float3(spot));
    }
    if (_73.uPattern == 2)
    {
        float2 param_2 = cell;
        float fleece = 0.75 + (0.25 * hash(param_2));
        float2 param_3 = floor(uv * 14.0);
        return mix(base * fleece, accent, float3(0.180000007152557373046875 * hash(param_3)));
    }
    if (_73.uPattern == 3)
    {
        float2 param_4 = float2(floor(uv.x * 5.0), 3.0);
        float stripe = step(0.560000002384185791015625, fract((uv.y * 7.0) + (hash(param_4) * 0.3499999940395355224609375)));
        return mix(base, accent, float3(stripe * 0.64999997615814208984375));
    }
    if (_73.uPattern == 4)
    {
        float band = step(0.819999992847442626953125, fract(uv.y * 5.0));
        float joint = step(0.7799999713897705078125, fract(uv.x * 4.0));
        return mix(base, accent, float3(fast::max(band, joint) * 0.449999988079071044921875));
    }
    if (_73.uPattern == 5)
    {
        float2 param_5 = cell;
        float mottled = hash(param_5);
        return mix(base * (0.7799999713897705078125 + (mottled * 0.2800000011920928955078125)), accent, float3(smoothstep(0.62000000476837158203125, 0.89999997615814208984375, mottled) * 0.550000011920928955078125));
    }
    if (_73.uPattern == 6)
    {
        float core = 1.0 - smoothstep(0.07999999821186065673828125, 0.3400000035762786865234375, distance(fract(uv * 4.0), float2(0.5)));
        float2 param_6 = cell;
        return mix(base, accent, float3(core * 0.4000000059604644775390625)) * (0.87999999523162841796875 + (hash(param_6) * 0.180000007152557373046875));
    }
    if (_73.uPattern == 7)
    {
        float flame = smoothstep(0.180000007152557373046875, 0.949999988079071044921875, uv.y + (sin(uv.x * 18.0) * 0.07999999821186065673828125));
        return mix(accent, base, float3(flame));
    }
    return base * (0.920000016689300537109375 + (0.119999997317790985107421875 * n));
}

static inline __attribute__((always_inline))
float3 pointLight(thread const float3& p, thread const float4& posRadius, thread const float4& colorIntensity)
{
    float3 d = p - posRadius.xyz;
    float a = fast::max(0.0, 1.0 - (dot(d, d) / fast::max(posRadius.w * posRadius.w, 0.001000000047497451305389404296875)));
    return colorIntensity.xyz * ((colorIntensity.w * a) * a);
}

static inline __attribute__((always_inline))
float3 dynamicLighting(thread const float3& p, constant Globals& _73)
{
    float3 l = float3(0.0);
    if (_73.uDynLightCount > 0)
    {
        float3 param = p;
        float4 param_1 = _73.uDynLightPosRadius0;
        float4 param_2 = _73.uDynLightColor0;
        l += pointLight(param, param_1, param_2);
    }
    if (_73.uDynLightCount > 1)
    {
        float3 param_3 = p;
        float4 param_4 = _73.uDynLightPosRadius1;
        float4 param_5 = _73.uDynLightColor1;
        l += pointLight(param_3, param_4, param_5);
    }
    if (_73.uDynLightCount > 2)
    {
        float3 param_6 = p;
        float4 param_7 = _73.uDynLightPosRadius2;
        float4 param_8 = _73.uDynLightColor2;
        l += pointLight(param_6, param_7, param_8);
    }
    if (_73.uDynLightCount > 3)
    {
        float3 param_9 = p;
        float4 param_10 = _73.uDynLightPosRadius3;
        float4 param_11 = _73.uDynLightColor3;
        l += pointLight(param_9, param_10, param_11);
    }
    return fast::min(l, float3(2.0));
}

fragment main0_out main0(main0_in in [[stage_in]], constant Globals& _73 [[buffer(0)]], texture2d_array<float> uAtlas [[texture(0)]], texture2d<float> uEntityTexture [[texture(1)]], sampler uAtlasSmplr [[sampler(0)]], sampler uEntityTextureSmplr [[sampler(1)]])
{
    main0_out out = {};
    float4 _404;
    if (_73.uTextured == 1)
    {
        float3 _418 = float3(in.vUV, _73.uLayer);
        _404 = uAtlas.sample(uAtlasSmplr, _418.xy, uint(rint(_418.z)));
    }
    else
    {
        float4 _424;
        if (_73.uTextured == 2)
        {
            _424 = uEntityTexture.sample(uEntityTextureSmplr, in.vUV);
        }
        else
        {
            float3 param = _73.uColor.xyz;
            float3 param_1 = float3(_73.uAccent);
            _424 = float4(mobPattern(param, param_1, _73, in.vUV), _73.uColor.w);
        }
        _404 = _424;
    }
    float4 base = _404;
    if (base.w < 0.300000011920928955078125)
    {
        discard_fragment();
    }
    float3 c = (base.xyz * in.vShade) * _73.uLight;
    if (_73.uDynLightCount > 0)
    {
        float3 param_2 = in.vWorld;
        float3 dyn = dynamicLighting(param_2, _73);
        c = fast::max(c, (base.xyz * in.vShade) * dyn);
        c += (((base.xyz * in.vShade) * dyn) * 0.07999999821186065673828125);
    }
    c = mix(c, float3(_73.uFog), float3(_73.uFogAmt));
    out.FragColor = float4(c, base.w);
    return out;
}

