由于我未寻找到tModLoader给出相关方法,在物品在收藏时调用,我使用favorited作为关键字查找,最后找到了状态修改的地方,这个是私有方法,被LeftClick调用,隶属于Terraria.UI.ItemSlot,在调用前后均没有看到有钩子的迹象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
private static bool OverrideLeftClick(Item[] inv, int context = 0, int slot = 0)
{
if (Main.cursorOverride == 3) {
if (!canFavoriteAt[Math.Abs(context)])
return false;
item.favorited = !item.favorited;
SoundEngine.PlaySound(12);
return true;
public static void LeftClick(Item[] inv, int context = 0, int slot = 0)
{
Player player = Main.player[Main.myPlayer];
bool flag = Main.mouseLeftRelease && Main.mouseLeft;
if (flag) {
if (OverrideLeftClick(inv, context, slot))
return;
|
现在我们要求其更改时服务器能收到消息,所以要对他进行挂钩。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
[ModuleInitializer]
internal static void HookItemSlot()
{
On_ItemSlot.OverrideLeftClick += On_ItemSlot_OverrideLeftClick; ;
}
private static bool On_ItemSlot_OverrideLeftClick(On_ItemSlot.orig_OverrideLeftClick orig, Item[] inv, int context, int slot)
{
var oldFavoritedStatu = inv[slot].favorited;
var retValue = orig.Invoke(inv, context, slot);
var newFavoritedStatu = inv[slot].favorited;
if(oldFavoritedStatu != newFavoritedStatu) {
var packet = ModLoader.GetMod(nameof(NoNPCSpawn)).GetPacket();
packet.Write(slot);
packet.Write(newFavoritedStatu);
packet.Send();
}
return retValue;
}
public override void HandlePacket(BinaryReader reader, int whoAmI)
{
//这里看需求,如果其他客户端需要知道状态,可进行 (netmode == server) 后转发
var slot = reader.ReadInt32();
var newFavoritedStatu = reader.ReadBoolean();
Main.player[whoAmI].inventory[slot].favorited = newFavoritedStatu;
base.HandlePacket(reader, whoAmI);
}
|
如果玩家进入世界前就收藏了物品,需要手动同步一下状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public class NoNPCSpawnPlayer : ModPlayer
{
private volatile List<Action> updateExter = [];
public override void PostUpdate()
{
foreach (var action in updateExter) {
action.Invoke();
}
updateExter.Clear();
base.PostUpdate();
}
public override void OnEnterWorld()
{
updateExter.Add(SendItemFavorited);
base.OnEnterWorld();
}
private void SendItemFavorited()
{
if (Main.netMode == NetmodeID.MultiplayerClient) {
var packet = ModLoader.GetMod(nameof(NoNPCSpawn)).GetPacket();
List<int> items = [];
for (int i = 0; i < Player.inventory.Length; i++) {
if (Player.inventory[i].favorited) {
items.Add(i);
}
}
items.ForEach(f => {
packet.Write(f);
packet.Write(true);
packet.Send();
});
}
}
}
|