尿石

尿石

按Frost Prime的愿望,用Piss Rock替换瀑布巨人

游戏玩法

尿石模组(Piss Rock)

视频开始时间 5:17:55 的上下文

[youtube]kO-6SiDtB3I[/youtube]

安装说明

此模组适用于公开测试版分支

(因为它修改了新的背景)

(但也许在 0.103.0 版本上也能用,我不确定)

进入《杀戮尖塔2》的 Steam 文件夹

Windows 路径

C:\Program Files (x86)\Steam\steamapps\common\Slay the Spire 2

Mac 路径

/Users/<用户名>/Library/Application Support/Steam/steamapps/common/Slay the Spire 2/SlayTheSpire2.app/Contents/MacOS/

创建一个 mods 文件夹,然后将 zip 压缩包解压进去,最终结构如下:

C:\Program Files (x86)\Steam\steamapps\common\Slay the Spire 2\
└── mods\
    └── PissRock\
        ├──  PissRock.dll
        ├──  PissRock.pck
        └──  PissRock.json

PissRock 文件夹不是必须的,只要这三个文件(dll、pck、json)一起解压放在 mods 文件夹下的任意位置即可。)


这是 DLL 中的完整代码。我可不想让雇主看到公开的“尿石”GitHub 仓库,哈哈。

这个模组只是修改了瀑布巨人场景的一些颜色值(因为我懒得手动替换整个场景),并替换了一些资源文件。

using Godot;
using HarmonyLib;
using MegaCrit.Sts2.Core.Modding;
using MegaCrit.Sts2.Core.Nodes.Rooms;
using MegaCrit.Sts2.Core.Rooms;

namespace PissRock.PissRockCode;

[ModInitializer(nameof(Initialize))]
public partial class PissRockMainFile : Node
{
    public const string ModId = "PissRock"; //目前,这只用于日志记录器和 Harmony 的名称。

    public static MegaCrit.Sts2.Core.Logging.Logger Logger { get; } =
        new(ModId, MegaCrit.Sts2.Core.Logging.LogType.Generic);

    public static void Initialize()
    {
        Harmony harmony = new(ModId);

        harmony.PatchAll();
    }
}

[HarmonyPatch(typeof(NCombatBackground), "SetLayers")]
static class NCombatBackgroundSetLayersHuePatch
{
    const string ShaderCode = @"
shader_type canvas_item;
uniform float hue_shift = -0.36944;
vec3 rgb2hsv(vec3 c){vec4 K=vec4(0.0,-1.0/3.0,2.0/3.0,-1.0);vec4 p=mix(vec4(c.bg,K.wz),vec4(c.gb,K.xy),step(c.b,c.g));vec4 q=mix(vec4(p.xyw,c.r),vec4(c.r,p.yzx),step(p.x,c.r));float d=q.x-min(q.w,q.y);float e=1.0e-10;return vec3(abs(q.z+(q.w-q.y)/(6.0*d+e)),d/(q.x+e),q.x);}
vec3 hsv2rgb(vec3 c){vec4 K=vec4(1.0,2.0/3.0,1.0/3.0,3.0);vec3 p=abs(fract(c.xxx+K.xyz)*6.0-K.www);return c.z*mix(K.xxx,clamp(p-K.xxx,0.0,1.0),c.y);}
void fragment(){vec4 b=texture(TEXTURE,UV)*COLOR;vec3 h=rgb2hsv(b.rgb);h.x=fract(h.x+hue_shift);COLOR=vec4(hsv2rgb(h),b.a);}";

    const float HueShift = -133f / 360f;   // Godot 的色相范围是 0–1,而不是角度制
    static ShaderMaterial? _mat;

    [HarmonyPostfix]
    static void Postfix(NCombatBackground __instance, BackgroundAssets bg)
    {
        var path = bg.BackgroundScenePath?.ToLowerInvariant().Replace("_", "") ?? "";
        if (!path.Contains("waterfallgiant")) return;

        _mat ??= new ShaderMaterial { Shader = new Shader { Code = ShaderCode } };

        var layer = __instance.GetNodeOrNull("Layer_00");
        if (layer == null) return;
        Walk(layer);
    }

    static void Walk(Node node)
    {
        switch (node)
        {
            case GpuParticles2D p:
                p.Material = _mat;
                break;
            case Sprite2D s:
            {
                var c = s.Modulate;
                var h = Mathf.PosMod(c.H + HueShift, 1f);   // PosMod 用于处理负偏移量的环绕
                s.Modulate = Color.FromHsv(h, c.S, c.V, c.A);
                break;
            }
        }

        foreach (var child in node.GetChildren())
            Walk(child);
    }
}