连锁挖矿示例 - github-user-64/tPlainModLoader GitHub Wiki
自定义修补玩家类
关于自定义修补的更多信息
[HarmonyPatch(typeof(Player))]//表示修补玩家类中的方法
internal static class PPlayer
{
public static bool Enable = true;//启用
public static ushort Size = 10;//挖掘半径
public static bool PickEffect = true;//挖掘效果
private static int type = -1;
[HarmonyPatch("PickTile")]//表示修补挖掘方块
[HarmonyPrefix]//表示在挖掘方块前
internal static void PickTilePr(int x, int y, int pickPower)
{
if (Enable == false) return;
type = -1;
Tile tile = Main.tile[x, y];
if (tile == null) return;
if (tile.active() == false) return;//没方块
if (TileID.Sets.Ore[tile.type] == false) return;//不是矿
type = tile.type;
}
[HarmonyPatch("PickTile")]//表示修补挖掘方块
[HarmonyPostfix]//表示在挖掘方块后
internal static void PickTilePo(int x, int y, int pickPower)
{
if (PPlayer.type < 0) return;
int type = PPlayer.type;
PPlayer.type = -1;
//
bool kill = Main.tile[x, y]?.active() == false;//方块是否被挖掉
//遍历范围内的方块, 即使没相连也会被一起挖掉
for (int i = x - Size; i < x + Size; i++)
{
for (int j = y - Size; j < y + Size; j++)
{
if (i == x && j == y) continue;
if (WorldGen.InWorld(i, j) == false) continue;//超出世界
Tile tile = Main.tile[i, j];
if (tile == null) continue;
if (tile.type != type) continue;//类型不同
if (tile.active() == false) continue;//没方块
if (kill)
{
WorldGen.KillTile(i, j);//破坏方块
if (Main.netMode == 1)//如果是客户端就发送消息, 这样在多人才能用
{
NetMessage.TrySendData(MessageID.TileManipulation, -1, -1, null, 0, i, j);
}
if (PickEffect) Main.LocalPlayer.hitTile.Prune();
}
else if(PickEffect)
{
//如果方块没被挖掉就添加碎裂效果, 可以不加
Main.LocalPlayer.PickTile_DetermineDamage(i, j, pickPower, tile, out int bufferIndex, out int damage);
Main.LocalPlayer.hitTile.AddDamage(bufferIndex, damage);
}
}
}
}
}
初始化修补
internal class PatchInit : Mod
{
private const string patchId = "tPlainModLoader.Mod.test1.gamePatch";//修补的id, 应该写啥都行
private Harmony harmony = null;
public override void AddPatch(IAddPatch addPatch)//添加修补
{
harmony = new Harmony(patchId);
harmony.PatchAll();//修补全部
}
public override void Unload()
{
harmony?.UnpatchAll(patchId);//卸载修补
harmony = null;
}
}
UI窗口
internal class PickWindow : UIWindow//继承了模板UIWindow
{
public PickWindow(string title, int width, int height) : base(title, width, height)
{
UIStackPanel sp = new UIStackPanel();//竖向排列子控件
sp.Width.Set(0, 1);
sp.Height.Set(0, 1);
Child.Append(sp);//将sp添加到窗口. 要向窗口添加控件就用这个
UIItemSwitch enable = new UIItemSwitch(null, "启用");
enable.OnValUpdate += v => PPlayer.Enable = v;
enable.SetVal(PPlayer.Enable);
sp.Append(enable);
UIItemTextBox size = new UIItemTextBox(text: "半径");
size.OnTextChanged += v =>
{
if (ushort.TryParse(v, out ushort val)) PPlayer.Size = val;
};
size.SetText(PPlayer.Size.ToString());
sp.Append(size);
UIItemSwitch pickEffect = new UIItemSwitch(null, "挖掘效果");
pickEffect.OnValUpdate += v => PPlayer.PickEffect = v;
pickEffect.SetVal(PPlayer.PickEffect);
sp.Append(pickEffect);
}
}
添加UI
internal class ModifyInterfaceLayers : PatchMain
{
private UIState state = null;
private UserInterface ui = null;
private PickWindow window = null;
//和tModLoader中一样在这插入ui
public override void SetupDrawInterfaceLayersPostfix(List<GameInterfaceLayer> gameInterfaceLayers)
{
//"Vanilla: Inventory"是物品栏图层的名称
int index = gameInterfaceLayers.FindIndex(i => i.Name == "Vanilla: Inventory");
if (index == -1) return;
window = new PickWindow("简易连锁挖矿", 260, 160);
state = new UIState();
ui = new UserInterface();
//state.Append(window);控件在这里添加就行了, 由于UIWindow在打开的时候会自动添加所以不需要这句
//state.Append(ui1);
//state.Append(ui2);
//state.Append(ui...);
//在物品栏前插入
gameInterfaceLayers.Insert(index, new LegacyGameInterfaceLayer(
"StaticTile.test1: Inventory Prefix(属于你的图层名称, 写啥都行)",
() =>
{
ui.Draw(Main.spriteBatch, Main.gameTimeCache);//绘制ui
return true;
},
InterfaceScaleType.UI));
}
public override void UpdateUIStatesPostfix(GameTime gameTime)
{
if (ui == null) return;
if (Main.gameMenu)//在游戏外
{
ui.SetState(null);//禁用ui
return;
}
ui.SetState(state);//启用ui
ui.Update(gameTime);//更新ui
//快捷键'P'开关窗口
if (Main.keyState.IsKeyDown(Keys.P) && Main.oldKeyState.IsKeyUp(Keys.P))
{
if (window.IsOpen) window.Close();//从state删除
else window.Open(state);//添加到state
}
}
}
实际效果
https://github.com/user-attachments/assets/9a899bd3-24f6-4289-a454-d6f87630dbca