增加一些动作/结构并且补注释:( 呜呜呜补注释好累头号疼

This commit is contained in:
Starrysky
2026-02-17 00:07:42 +08:00
parent 65f516a11f
commit 67e286981e
26 changed files with 572 additions and 34 deletions

View File

@@ -1,11 +1,9 @@
package top.sunsetlab.utils;
import com.google.gson.Gson;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.World;
import org.bukkit.*;
import org.bukkit.block.BlockType;
import org.jspecify.annotations.NonNull;
import top.sunsetlab.PluginMain;
import java.io.BufferedReader;
@@ -22,12 +20,22 @@ class JsonStructureData {
int[] center;
String id;
ArrayList<String> actions;
String precondition_task;
ArrayList<String> noclear;
}
/// Json定义的结构
public class JsonStructure {
/// 结构数据
private final JsonStructureData data;
/// 结构资源文件位置
private final String structure_loc;
/**
* 构造函数
* @param location 资源文件的位置
* @throws RuntimeException 在无法读取资源文件时抛出
*/
public JsonStructure(String location) throws RuntimeException {
InputStream file = JsonStructure.class.getResourceAsStream("/" + location);
if (file == null) {
@@ -40,7 +48,13 @@ public class JsonStructure {
structure_loc = location;
}
/**
* 尝试匹配结构
* @param pos 结构中心点位置
* @return 结构是否匹配?
*/
public boolean match(Location pos) {
// 确定起始点,终点
World world = pos.getWorld();
Location currentpos = new Location(
world,
@@ -59,7 +73,14 @@ public class JsonStructure {
PluginMain.LOGGER.log(Level.INFO, "Matching structure " + structure_loc
+ "; From " + currentpos + " To " + endpos);
}
// 记录方块种类 - 仅在需要时生成
ArrayList<BlockType> types = null;
// 循环匹配每个方块
// TODO 有没有更好的方法
while (!currentpos.equals(endpos)) {
// 相对西北角的位置
int rx = currentpos.getBlockX() - startpos.getBlockX();
int rz = currentpos.getBlockZ() - startpos.getBlockZ();
// if (PluginMain.DEBUG) {
@@ -67,28 +88,50 @@ public class JsonStructure {
// + currentpos
// + "(relative (" + rx + "," + rz + "))");
// }
// 应该存在的方块
String mark = String.valueOf(data.structure.get(rz).charAt(rx));
String type = data.marks.get(mark);
if (type == null) {
throw new RuntimeException("In Structure "+ structure_loc +"; Undefined mark: " + mark);
}
NamespacedKey key = NamespacedKey.fromString(type);
if (key == null) {
throw new RuntimeException("In Structure "+ structure_loc +"; Invalid key: " + type);
}
BlockType blockType = Registry.BLOCK.get(key);
if (blockType == null) {
throw new RuntimeException("In Structure "+ structure_loc +"; Invalid block type: " + type);
}
if (!Objects.equals(world.getBlockAt(currentpos).getType().asBlockType(), blockType)) {
if (PluginMain.DEBUG) {
if (!type.equals("any")) {
// 匹配特定方块
BlockType blockType = getBlockType(type);
if (!Objects.equals(world.getBlockAt(currentpos).getType().asBlockType(), blockType)) {
if (PluginMain.DEBUG) {
PluginMain.LOGGER.log(Level.INFO, "Block Mismatch at " + currentpos
+ "(relative (" + rx + "," + rz + "))"
+ "; Expected " + blockType
+ ", but got " + world.getBlockAt(currentpos).getType());
}
return false;
}
}else {
// 匹配任意方块
if (types == null) {
types = new ArrayList<>();
for (String s : data.marks.values()) {
if (s.equals("any")) {
continue;
}
types.add(getBlockType(s));
}
}
// 是否为空气
boolean isAir = Objects.equals(world.getBlockAt(currentpos).getType().asBlockType(), Material.AIR.asBlockType());
// 是否在列表内 - 为了防止玩家摆个正方形导致怪异的匹配
boolean isInList = types.contains(world.getBlockAt(currentpos).getType().asBlockType());
// 当非空气且在列表内时终止
if (!isAir && isInList ) {
PluginMain.LOGGER.log(Level.INFO, "Block Mismatch at " + currentpos
+ "(relative (" + rx + "," + rz + "))"
+ "; Expected " + blockType
+ ", but got " + world.getBlockAt(currentpos).getType());
+ " Tried any, but got " + world.getBlockAt(currentpos).getType());
return false;
}
return false;
}
// 递增当前坐标
currentpos.add(1,0,0);
if (currentpos.getBlockX() == endpos.getBlockX() + 1) {
currentpos.setX(startpos.getBlockX());
@@ -101,11 +144,96 @@ public class JsonStructure {
return true;
}
/**
* 通过id获取方块类型
* @param type 方块id
* @return 方块类型
*/
private @NonNull BlockType getBlockType(String type) {
NamespacedKey key = NamespacedKey.fromString(type);
if (key == null) {
throw new RuntimeException("In Structure " + structure_loc + "; Invalid key: " + type);
}
BlockType blockType = Registry.BLOCK.get(key);
if (blockType == null) {
throw new RuntimeException("In Structure " + structure_loc + "; Invalid block type: " + type);
}
return blockType;
}
/**
* 获取结构id
* @return 结构id
*/
public String getId() {
return data.id;
}
/**
* 获取要执行的动作列表
* @return 动作列表
*/
public ArrayList<String> getActions() {
return data.actions;
}
/**
* 破坏整个结构
* @param pos 结构中心位置
*/
public void breakStructure(Location pos) {
// 清理赦免:D (学生物学的)
// FIXME 这东西用不了
ArrayList<BlockType> noclears = new ArrayList<>();
if (data.noclear != null) {
// 已知这里正常
for (String s : data.noclear) {
if (PluginMain.DEBUG) {
PluginMain.LOGGER.log(Level.INFO, "Will not clear " + s);
}
noclears.add(getBlockType(s));
}
}
// 确认起始点和终点
World world = pos.getWorld();
Location beginPos = new Location(
pos.getWorld(),
pos.getBlockX() - data.center[0],
pos.getBlockY(),
pos.getBlockZ() - data.center[1]
);
Location currentPos = beginPos.clone();
Location endPos = new Location(
pos.getWorld(),
pos.getBlockX() + data.center[0],
pos.getBlockY(),
pos.getBlockZ() + data.center[1]
);
// 遍历每一个方块
// TODO 有没有更好的方法
while (!beginPos.equals(endPos)) {
// 这里的判断貌似有问题
if (!noclears.contains(world.getBlockAt(beginPos).getType().asBlockType())) {
world.getBlockAt(currentPos).setType(Material.AIR);
}
currentPos.add(1,0,0);
if (currentPos.getBlockX() == endPos.getBlockX() + 1) {
currentPos.setX(beginPos.getBlockX());
currentPos.setZ(currentPos.getBlockZ() + 1);
if (currentPos.getBlockZ() == endPos.getBlockZ() + 1) {
break;
}
}
}
}
/**
* 获取门控任务(仅当该任务成功时执行任务列表)
* @return 门控任务id
*/
public String getPreConditionTask() {
return data.precondition_task;
}
}