Skip to content

Commit

Permalink
Merge pull request #19 from THEXN/master
Browse files Browse the repository at this point in the history
添加插件:GolfRewards 高尔夫奖励
  • Loading branch information
Controllerdestiny authored Apr 14, 2024
2 parents f2337a1 + 869d389 commit 3982e73
Show file tree
Hide file tree
Showing 10 changed files with 453 additions and 1 deletion.
65 changes: 65 additions & 0 deletions GolfRewards/ConfigFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

namespace RewardSection
{
public class ConfigFile
{
public static ConfigFile Read(string path)
{
if (!File.Exists(path))
{
return new ConfigFile
{
RewardTable = new List<RewardSection>
{
new RewardSection(0, 0, new List<ItemSections> { new ItemSections(757, 1, 0) }, new List<string> { "/time noon" }),
new RewardSection(0, 0, new List<ItemSections> { new ItemSections(757, 1, 0) }, new List<string> { "/time night" })
}
};
}

using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var streamReader = new StreamReader(fileStream))
{
var configFile = JsonConvert.DeserializeObject<ConfigFile>(streamReader.ReadToEnd());
ConfigR?.Invoke(configFile);
return configFile;
}
}

public static ConfigFile Read(Stream stream)
{
using (var streamReader = new StreamReader(stream))
{
var configFile = JsonConvert.DeserializeObject<ConfigFile>(streamReader.ReadToEnd());
ConfigR?.Invoke(configFile);
return configFile;
}
}

public void Write(string path)
{
using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
{
Write(fileStream);
}
}

public void Write(Stream stream)
{
var value = JsonConvert.SerializeObject(this, Formatting.Indented);
using (var streamWriter = new StreamWriter(stream))
{
streamWriter.Write(value);
}
}

[JsonProperty("奖励表")]
public List<RewardSection> RewardTable { get; set; } = new List<RewardSection>();

public static Action<ConfigFile> ConfigR;
}
}
158 changes: 158 additions & 0 deletions GolfRewards/GolfRewards.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using Terraria;
using TerrariaApi.Server;
using TShockAPI;
using TShockAPI.Hooks;

namespace RewardSection
{
[ApiVersion(2, 1)]
public class GolfRewards : TerrariaPlugin
{
public override string Name => "高尔夫奖励";
public override string Author => "GK 阁下 由 鸽子 定制,肝帝熙恩更新适配1449";
public override string Description => "将高尔夫打入球洞会得到奖励.";
public override Version Version => new Version(1, 0, 5);

public GolfRewards(Main game) : base(game)
{
base.Order = 5;
LC.RI();
}

private void OnInitialize(EventArgs args)
{
GeneralHooks.ReloadEvent += CMD;
LC.RC();

Commands.ChatCommands.Add(new Command("物块坐标", CMD2, "物块坐标")
{
HelpText = "输入/物块坐标后敲击物块确认坐标"
});
}


public override void Initialize()
{
GeneralHooks.ReloadEvent -= CMD;
ServerApi.Hooks.NetGetData.Register(this, GetData);

ServerApi.Hooks.GameInitialize.Register(this, OnInitialize);

ServerApi.Hooks.NetGreetPlayer.Register(this, OnGreetPlayer);

ServerApi.Hooks.ServerLeave.Register(this, OnLeave);

GetDataHandlers.TileEdit += TileEdit;

GetDataHandlers.LandGolfBallInCup += Golf;
}


protected override void Dispose(bool disposing)
{
if (disposing)
{
ServerApi.Hooks.NetGetData.Deregister(this, GetData);

ServerApi.Hooks.GameInitialize.Deregister(this, OnInitialize);

ServerApi.Hooks.NetGreetPlayer.Deregister(this, OnGreetPlayer);

ServerApi.Hooks.ServerLeave.Deregister(this, OnLeave);

GetDataHandlers.TileEdit -= TileEdit;

GetDataHandlers.LandGolfBallInCup -= Golf;
}
base.Dispose(disposing);
}


private void CMD(ReloadEventArgs args)
{
LC.RC();
args.Player.SendSuccessMessage("[高尔夫奖励] 重读配置完毕!");
}

private void CMD2(CommandArgs args)
{
if (LC.LPlayers.TryGetValue(args.Player.Index, out LPlayer player) && player != null)
{
player.tip = true;
}
args.Player.SendSuccessMessage("敲击物块以确认其坐标!");
}

private void OnGreetPlayer(GreetPlayerEventArgs e)
{
LC.LPlayers.AddOrUpdate(e.Who, new LPlayer(e.Who), (_, existingPlayer) => existingPlayer);
}

private void OnLeave(LeaveEventArgs e)
{
LC.LPlayers.TryRemove(e.Who, out _);
}

private void TileEdit(object sender, GetDataHandlers.TileEditEventArgs args)
{
if (args.Handled)
return;

TSPlayer tsplayer = TShock.Players[args.Player.Index];
if (tsplayer == null)
return;

if (LC.LPlayers.TryGetValue(args.Player.Index, out LPlayer player) && player != null && player.tip)
{
player.tip = false;
tsplayer.SendInfoMessage($"目标坐标为: X{args.X} Y{args.Y}");
}
}


public void Golf(object sender, GetDataHandlers.LandGolfBallInCupEventArgs args)
{
if (args.Handled)
return;

var player = args.Player;
if (player == null)
return;

int tileX = args.TileX;
int tileY = args.TileY;
int hits = args.Hits;

foreach (var RewardSection in LC.LConfig.RewardTable)
{
if (RewardSection.HolePositionX != tileX || RewardSection.HolePositionY != tileY)
continue;

if (hits <= RewardSection.MinSwings || hits > RewardSection.MaxSwings)
continue;

if (!string.IsNullOrEmpty(RewardSection.HitPrompt))
TShock.Utils.Broadcast(RewardSection.HitPrompt, byte.MaxValue, 215, 0);

var randomItems = RewardSection.GetRandomItems();
if (randomItems != null && randomItems.ItemId != 0 && randomItems.ItemStack > 0)
player.GiveItem(randomItems.ItemId, randomItems.ItemStack, randomItems.ItemPrefix);

var randomCMD = RewardSection.GetRandomCMD();
if (!string.IsNullOrEmpty(randomCMD))
{
bool cmdSuccess = Commands.HandleCommand(TSPlayer.Server, randomCMD.Replace("{name}", player.Name));
if (!cmdSuccess)
Console.WriteLine($"指令 {randomCMD} 执行失败! ");
}

if (RewardSection.OnlyClaimRewardAtThisLocation)
break;
}
}

private void GetData(GetDataEventArgs args)
{
}
}
}
5 changes: 5 additions & 0 deletions GolfRewards/GolfRewards.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\template.targets" />

</Project>
27 changes: 27 additions & 0 deletions GolfRewards/ItemSections.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Newtonsoft.Json;
using System;

namespace RewardSection
{
public class ItemSections
{
[JsonProperty("物品ID")]
public int ItemId { get; set; }

[JsonProperty("物品数量")]
public int ItemStack { get; set; }

public ItemSections(int id, int stack, int prefix)
{
ItemId = id;
ItemStack = stack;
ItemPrefix = prefix;
}

[JsonProperty("相对概率")]
public int RelativeProbability { get; set; } = 1;

[JsonProperty("物品前缀")]
public int ItemPrefix { get; set; } = 0;
}
}
39 changes: 39 additions & 0 deletions GolfRewards/LC.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using TShockAPI;

namespace RewardSection
{
internal class LC
{
public static ConfigFile LConfig { get; set; }
internal static string LConfigPath => Path.Combine(TShock.SavePath, "高尔夫奖励.json");
public static ConcurrentDictionary<int, LPlayer> LPlayers { get; set; }
public static Random LRadom = new Random();

public static void RI()
{
LConfig = new ConfigFile();
// 初始化 LPlayers 为 ConcurrentDictionary
LPlayers = new ConcurrentDictionary<int, LPlayer>();
}

public static void RC()
{
try
{
if (!File.Exists(LConfigPath))
{
TShock.Log.ConsoleError("未找到高尔夫奖励配置文件,已为您创建!");
}
LConfig = ConfigFile.Read(LConfigPath);
LConfig.Write(LConfigPath);
}
catch (Exception ex)
{
TShock.Log.ConsoleError("高尔夫奖励插件错误配置读取错误:" + ex.ToString());
}
}
}
}
16 changes: 16 additions & 0 deletions GolfRewards/LPlayer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace RewardSection
{
public class LPlayer
{
public int Index { get; set; }
public bool tip { get; set; }

public LPlayer(int index)
{
this.Index = index;
this.tip = false;
}
}
}
59 changes: 59 additions & 0 deletions GolfRewards/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# GolfRewards 高尔夫奖励

- 作者: GK 阁下 由 鸽子 定制,肝帝熙恩更新适配1449
- 出处: TShock中文官方群
- 玩家在高尔夫球洞中击球,根据击球次数(杆数)获得相应的奖励。
- 插件支持自定义奖励表,包括物品奖励和执行的命令。

## 更新日志

```
暂无
```

## 指令

| 语法 | 权限 | 说明 |
| -------------- | :-----------------: | :------: |
| /物块坐标 | 物块坐标 | 辅助指令,确定方块坐标|

## 配置

每个奖励节点(`奖励节`)包含以下属性:

- `球洞坐标X`:球洞在X轴上的坐标。
- `球洞坐标Y`:球洞在Y轴上的坐标。
- `最少杆数`:玩家击球进入球洞所需的最少杆数。
- `最多杆数`:玩家击球进入球洞所需的最多杆数。
- `本位置仅领取该奖励`:如果为`true`,则玩家在该位置只能领取一次奖励。
- `物品节`:一个列表,包含了玩家可以获得的物品奖励。每个物品奖励包含物品ID、数量和物品前缀。
- `指令节`:一个列表,包含了玩家击球成功后可能执行的命令。

```json
{
"奖励表": [
{
"球洞坐标X": 0,
"球洞坐标Y": 0,
"最少杆数": 0,
"最多杆数": 999,
"本位置仅领取该奖励": false,
"物品节": [
{
"物品ID": 757, // 物品的ID,例如757是泰拉刀
"物品数量": 1, // 物品的数量
"物品前缀": 0 // 物品的前缀,0表示无前缀
}
],
"指令节": [
"/time noon", // 执行的命令,例如设置游戏时间为中午
"/time night" // 另一个可能的命令,设置游戏时间为夜晚
],
"命中提示": "高尔夫击中奖励球" // 玩家击球成功后的提示信息
}
]
}
```
## 反馈
- 共同维护的插件库:https://github.com/THEXN/TShockPlugin/
- 国内社区trhub.cn 或 TShock官方群等
Loading

0 comments on commit 3982e73

Please sign in to comment.