Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加插件:DeathDrop 怪物死亡随机和自定义掉落物品 #23

Merged
merged 3 commits into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions DeathDrop/Configuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using TShockAPI;

namespace DeathDrop
{
public class Configuration
{
public class Monster
{
[JsonProperty("生物id")]
public int NPCID { get; set; } = 0;
[JsonProperty("完全随机掉落")]
public bool FullRandomDrops { get; set; } = false;
[JsonProperty("完全随机掉落排除物品ID")]
public List<int> FullRandomExcludedItems { get; set; } = new List<int>();
[JsonProperty("普通随机掉落物")]
public List<int> CommonRandomDrops { get; set; } = new List<int>();
[JsonProperty("随机掉落数量最小值")]
public int RandomDropMinAmount { get; set; } = 1;
[JsonProperty("随机掉落数量最大值")]
public int RandomDropMaxAmount { get; set; } = 1;
[JsonProperty("掉落概率")]
public int DropChance { get; set; } = 100;
}

[JsonProperty("是否开启随机掉落")]
public bool EnableRandomDrops { get; set; } = false;
[JsonProperty("完全随机掉落")]
public bool FullRandomDrops { get; set; } = false;
[JsonProperty("完全随机掉落排除物品ID")]
public List<int> FullRandomExcludedItems { get; set; } = new List<int>();
[JsonProperty("普通随机掉落物")]
public List<int> CommonRandomDrops { get; set; } = new List<int>();
[JsonProperty("随机掉落概率")]
public int RandomDropChance { get; set; } = 100;
[JsonProperty("随机掉落数量最小值")]
public int MinRandomDropAmount { get; set; } = 1;
[JsonProperty("随机掉落数量最大值")]
public int MaxRandomDropAmount { get; set; } = 1;
[JsonProperty("是否开启自定义掉落")]
public bool EnableCustomDrops { get; set; } = false;
[JsonProperty("自定义掉落设置")]
public Monster[] DeathDropSet { get; set; } = new Monster[1]
{
new Monster()
};

public static readonly string FilePath = Path.Combine(TShock.SavePath, "死亡掉落配置表.json");
public void Write(string path)
{
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
{
var str = JsonConvert.SerializeObject(this, Formatting.Indented);
using (var sw = new StreamWriter(fs))
{
sw.Write(str);
}
}
}

public static Configuration Read(string path)
{
if (!File.Exists(path))
return new Configuration();
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var sr = new StreamReader(fs))
{
var cf = JsonConvert.DeserializeObject<Configuration>(sr.ReadToEnd());
return cf;
}
}
}
}
}
172 changes: 172 additions & 0 deletions DeathDrop/DeathDrop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
using System;
using System.IO;
using Microsoft.Xna.Framework;
using Newtonsoft.Json;
using Terraria;
using TerrariaApi.Server;
using TShockAPI;
using TShockAPI.Hooks;

namespace DeathDrop
{
[ApiVersion(2, 1)]
public class DeathDrop : TerrariaPlugin
{
public static Random RandomGenerator = new Random();
public static Configuration Config;

public override string Author => "大豆子,肝帝熙恩更新优化";
public override string Description => "怪物死亡随机和自定义掉落物品";
public override string Name => "死亡掉落";
public override Version Version => new Version(1, 0, 3);

public DeathDrop(Main game) : base(game)
{
LoadConfig();
}

public override void Initialize()
{
GeneralHooks.ReloadEvent += ReloadConfig;
ServerApi.Hooks.NpcKilled.Register(this, NPCDead);
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
GeneralHooks.ReloadEvent -= ReloadConfig;
ServerApi.Hooks.NpcKilled.Deregister(this, NPCDead);
}
base.Dispose(disposing);
}
private static void LoadConfig()
{
Config = Configuration.Read(Configuration.FilePath);
Config.Write(Configuration.FilePath);
}

private static void ReloadConfig(ReloadEventArgs args)
{
LoadConfig();
args.Player?.SendSuccessMessage("[死亡掉落] 重新加载配置完毕。");
}

private void NPCDead(NpcKilledEventArgs args)
{
int npcNetID = args.npc.netID;
Vector2 npcPosition = args.npc.position;

// 获取击杀者玩家(可能为 null)
TSPlayer player = args.npc.lastInteraction != 255 && args.npc.lastInteraction >= 0
? TShock.Players[args.npc.lastInteraction]
: null;

if (Config.EnableRandomDrops)
{
int itemId = GetRandomItemIdFromGlobalConfig(Config);

if (Candorp(Config.RandomDropChance))
{
Item item = TShock.Utils.GetItemById(itemId);
int dropAmount = RandomGenerator.Next(Config.MinRandomDropAmount, Config.MaxRandomDropAmount + 1);

int itemNumber = Item.NewItem(
null,
(int)args.npc.position.X,
(int)args.npc.position.Y,
item.width,
item.height,
item.type,
dropAmount
);

// 只有当玩家不为 null 时才发送数据包
if (player != null)
{
player.SendData(PacketTypes.SyncExtraValue, null, itemNumber);
player.SendData(PacketTypes.ItemOwner, null, itemNumber);
player.SendData(PacketTypes.TweakItem, null, itemNumber, 255f, 63f);
}
}
}

if (Config.EnableCustomDrops)
{
foreach (Configuration.Monster monster in Config.DeathDropSet)
{
if (monster.NPCID == npcNetID && Candorp(monster.DropChance))
{
int dropItemId = GetRandomItemIdFromMonsterConfig(monster);

Item dropItem = TShock.Utils.GetItemById(dropItemId);
int dropAmount = RandomGenerator.Next(monster.RandomDropMinAmount, monster.RandomDropMaxAmount + 1);

int dropItemNumber = Item.NewItem(
null,
(int)npcPosition.X,
(int)npcPosition.Y,
dropItem.width,
dropItem.height,
dropItem.type,
dropAmount
);

// 只有当玩家不为 null 时才发送数据包
if (player != null)
{
player.SendData(PacketTypes.SyncExtraValue, null, dropItemNumber);
player.SendData(PacketTypes.ItemOwner, null, dropItemNumber);
player.SendData(PacketTypes.TweakItem, null, dropItemNumber, 255f, 63f);
}
}
}
}
}

private int GetRandomItemIdFromGlobalConfig(Configuration config)
{
if (config.FullRandomDrops)
{
int itemId = RandomGenerator.Next(1, 5453);

while (config.FullRandomExcludedItems.Contains(itemId))
{
itemId = RandomGenerator.Next(1, 5453);
}

return itemId;
}
else
{
int randomIndex = RandomGenerator.Next(config.CommonRandomDrops.Count);
return config.CommonRandomDrops[randomIndex];
}
}

private int GetRandomItemIdFromMonsterConfig(Configuration.Monster monster)
{
if (monster.FullRandomDrops)
{
int itemId = RandomGenerator.Next(1, 5453);

while (monster.FullRandomExcludedItems.Contains(itemId))
{
itemId = RandomGenerator.Next(1, 5453);
}

return itemId;
}
else
{
int randomIndex = RandomGenerator.Next(monster.CommonRandomDrops.Count);
return monster.CommonRandomDrops[randomIndex];
}
}

private static bool Candorp(int probability)
{
return RandomGenerator.Next(100) <= probability;
}
}
}
3 changes: 3 additions & 0 deletions DeathDrop/DeathDrop.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\template.targets"/>
</Project>
47 changes: 47 additions & 0 deletions DeathDrop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# DeathDrop 死亡掉落

- 作者: 大豆子,肝帝熙恩更新优化
- 出处: TShock中文官方群
- 允许自定义怪物死亡时的掉落物。
- 随机or自定义,互不影响

## 更新日志

```
- v1.0.3 使用reload来重载配置,原先是杀一只怪就重载一次,感觉会爆
```

## 指令

```
暂无
```

## 配置

```json
{
"是否开启随机掉落": false,//随机掉落的总开关,必须设置这个为true能设置除了自定义以外的内容
"完全随机掉落": false,//完全随机掉落,从1-5452里面选一个或多个物品
"完全随机掉落排除物品ID": [],//不会选择这里面的物品
"普通随机掉落物": [],//如果完全随机掉落为false,你可以在这里面自定义所有怪物一起的随机掉落物,随机掉落物从这里面选取
"随机掉落概率": 100,//概率,同时影响完全随机掉落和普通随机掉落
"随机掉落数量最小值": 1,//随机掉落数量最小值,同时影响完全随机掉落和普通随机掉落
"随机掉落数量最大值": 1,//随机掉落数量最小值,同时影响完全随机掉落和普通随机掉落
"是否开启自定义掉落": false,//自定义掉落,不受上面所有设置的影响,独立作用
"自定义掉落设置": [
{
"生物id": 0,
"完全随机掉落": false,
"完全随机掉落排除物品ID": [],
"普通随机掉落物": [],
"随机掉落数量最小值": 1,
"随机掉落数量最大值": 1,
"掉落概率": 100
}
]
}
```
## 反馈
- 共同维护的插件库:https://github.com/THEXN/TShockPlugin/
- 国内社区trhub.cn 或 TShock官方群等
10 changes: 10 additions & 0 deletions Plugin.sln
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CriticalHit", "CriticalHit\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PacketsStop", "PacketsStop\PacketsStop.csproj", "{852705B7-607D-4591-8359-860D3DD2B6A9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeathDrop", "DeathDrop\DeathDrop.csproj", "{7901BF97-3A58-4D80-B99F-FE9D41AB4729}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -356,6 +358,14 @@ Global
{852705B7-607D-4591-8359-860D3DD2B6A9}.Release|Any CPU.Build.0 = Release|Any CPU
{852705B7-607D-4591-8359-860D3DD2B6A9}.Release|x64.ActiveCfg = Release|Any CPU
{852705B7-607D-4591-8359-860D3DD2B6A9}.Release|x64.Build.0 = Release|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|x64.ActiveCfg = Debug|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Debug|x64.Build.0 = Debug|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|Any CPU.Build.0 = Release|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|x64.ActiveCfg = Release|Any CPU
{7901BF97-3A58-4D80-B99F-FE9D41AB4729}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
| [RegionView](RegionView/README.md) | 显示区域边界 | 无 |
| [Noagent](Noagent/README.md) | 禁止代理 ip 进入 | 无 |
| [SwitchCommands](SwitchCommands/README.md) | 区域执行指令 | 无 |
| [GolfRewards](GolfRewards/README.md) | 高尔夫奖励 | 无 |
| [GolfRewards](GolfRewards/README.md) | 高尔夫奖励 | 无 |
| [DataSync](DataSync/README.md) | 进度同步 | 无 |
| [ProgressRestrict](ProgressRestrict/README.md) | 超进度检测 | DataSync |
| [PacketsStop](PacketsStop/README.md) | 数据包拦截 | 无 |
| [PacketsStop](PacketsStop/README.md) | 数据包拦截 | 无 |
| [DeathDrop](DeathDrop/README.md) |怪物死亡随机和自定义掉落物品 | 无 |
Loading