Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
34d6c2c
海岛地形生成
Cong0707 Jul 2, 2025
d3a8669
添加gradle-wrapper.jar并优化.gitignore,为流水线自动构建并部署作准备
k-jiang Jul 6, 2025
3523814
更改依赖版本号并更改世界名字
Cong0707 Jul 7, 2025
5518e1e
成功实现毒海
Cong0707 Jul 7, 2025
932dcf7
去除潜影贝转换 去除phantom_protection
Cong0707 Jul 27, 2025
fbceb6d
page1finished -> beginner
Cong0707 Jul 27, 2025
60a41a5
海底改为-64
Cong0707 Jul 27, 2025
f9d0d76
升降温系统
Cong0707 Jul 29, 2025
055d8fb
确定世界是海岛世界
Cong0707 Jul 29, 2025
516327d
地狱改群系
Cong0707 Jul 29, 2025
6ceab06
铁砧砸方块
Cong0707 Jul 29, 2025
50f78e0
翻译 自动下载和读取 默认中文
Cong0707 Jul 29, 2025
440726f
修复paper api导致的问题
Cong0707 Jul 29, 2025
515e793
修复玩家在哪都能捡东西
Cong0707 Jul 30, 2025
86b9b0f
实现岛间的进一步隔离
Cong0707 Jul 30, 2025
082dd7a
尝试修复
Cong0707 Jul 30, 2025
d9305c0
尝试修复
Cong0707 Jul 30, 2025
5e39eb7
成功实现实体拦截和矿车拦截功能
Cong0707 Jul 31, 2025
3048a8d
改进发射器判定和掉落物判定
Cong0707 Jul 31, 2025
ddb3e06
修复浮点误差
Cong0707 Jul 31, 2025
a6c083e
实体捡物品使用isForIsland查询
Cong0707 Jul 31, 2025
aa793c1
修复Owner翻译问题
Cong0707 Jul 31, 2025
9414a83
signshop
Cong0707 Aug 1, 2025
774cfab
修复地狱门拦截 并修复一个npe
Cong0707 Aug 2, 2025
70bd122
修复飞天;阻止跨岛改为tp到上一tick的坐标
IzumiKonata Aug 3, 2025
a3ffe38
记录非玩家的掉落物归属;阻止掉落物和下落方块跨岛;统一矿车防跨岛写法;阻止跨边界防止漏斗、发射器、投掷器
IzumiKonata Aug 3, 2025
9c354d2
暂且取消wallsign右击事件,防止usb商店打开gui;signshop不受影响
IzumiKonata Aug 3, 2025
da27d83
部分事件驱动的challenge
IzumiKonata Aug 3, 2025
1a4646f
岛上生物ai不target访客
IzumiKonata Aug 3, 2025
01f0962
feat: 持久化的自定义进度追踪
kpAjun Aug 3, 2025
c9e87e7
feat: 基于自定义进度追踪的challenges
kpAjun Aug 3, 2025
30d4f60
feat: 改为使用YAML进行持久化存储
kpAjun Aug 4, 2025
5b90d15
fix: 增补事件监听器注册
kpAjun Aug 4, 2025
4e40295
feat: 基于UUID的离线玩家进度追踪
kpAjun Aug 5, 2025
b3d0720
成年猪灵捡金斧头变成猪灵蛮兵
IzumiKonata Aug 5, 2025
5b952d5
铁砧砸灵魂土0.5%掉落1个下界疣
IzumiKonata Aug 5, 2025
aae72d8
增加warden和piglin_brute的掉落物
IzumiKonata Aug 7, 2025
6d04dc6
铁砧砸两种下界菌岩互相转换
IzumiKonata Aug 8, 2025
421e425
限制试炼刷怪笼的生物类别
IzumiKonata Aug 9, 2025
c251de9
给普通宝库喂金锭刷新
IzumiKonata Aug 9, 2025
9de5eec
骷髅射杀猪灵给一个PigStep唱片
IzumiKonata Aug 9, 2025
e12934e
考古
IzumiKonata Aug 9, 2025
f296cbd
部分isSkyWorld->isSkyAssociatedWorld
IzumiKonata Aug 9, 2025
ad86523
bugfix: getKiller()->getDamageSource().getCausingEntity()
IzumiKonata Aug 9, 2025
dd5f6e2
Merge branch 'challenges' into everisland
IzumiKonata Aug 9, 2025
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
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
.classpath
bin
# Package Files #
*.jar
*.war
*.ear
**/target
**/build
/.gradle
/lib
/.classpath
/.project
Expand All @@ -17,5 +18,6 @@ bin

*.DS_Store

gradle.properties
dependency-reduced-pom.xml
deploy_rsa
deploy_rsa
7 changes: 0 additions & 7 deletions gradle.properties

This file was deleted.

Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
73 changes: 73 additions & 0 deletions progress_requirements_example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Progress Requirements 配置示例
# 这个文件展示了如何在challenges.yml中配置Progress Requirements

ranks:
novice:
displayName: "新手"
challenges:
mining_challenge:
name: "挖矿达人"
description: "成为一名挖矿专家"
type: "onPlayer"
requiredItems:
- "DIAMOND_PICKAXE:1"
requiredProgress:
- "blocks_mined:100" # 简单格式:需要挖掘100个方块
- "stone_mined:50" # 需要挖掘50个石头
reward:
items:
- "DIAMOND:5"
currency: 1000
xp: 500
repeatable: true

farming_expert:
name: "农业专家"
description: "种植大量作物"
type: "onPlayer"
requiredProgress:
- "crops_harvested:200:+:25" # 扩展格式:基础200,每次重复增加25
- "seeds_planted:100:*:1.2" # 基础100,每次重复乘以1.2
reward:
items:
- "GOLDEN_HOE:1"
currency: 2000
xp: 800
repeatable: true
repeatLimit: 10

expert:
displayName: "专家"
requiredChallenges:
- "mining_challenge"
challenges:
monster_slayer:
name: "怪物猎人"
description: "击败大量怪物"
type: "onPlayer"
requiredProgress:
- "monsters_killed:500"
- "boss_kills:5"
- "damage_dealt:10000"
reward:
items:
- "DIAMOND_SWORD:1"
currency: 5000
xp: 2000

# Progress Keys 说明:
# - blocks_mined: 挖掘的方块总数
# - stone_mined: 挖掘的石头数量
# - crops_harvested: 收获的作物数量
# - seeds_planted: 种植的种子数量
# - monsters_killed: 击杀的怪物数量
# - boss_kills: 击杀的Boss数量
# - damage_dealt: 造成的总伤害
# - distance_traveled: 行走的总距离
# - items_crafted: 制作的物品数量
# - fish_caught: 钓到的鱼数量

# 操作符说明:
# + : 每次重复增加固定值
# - : 每次重复减少固定值
# * : 每次重复乘以倍数
6 changes: 4 additions & 2 deletions uSkyBlock-Core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ dependencies {
testImplementation("junit:junit:4.13.2")
testImplementation("org.junit.vintage:junit-vintage-engine:5.9.0")
testImplementation("org.mockito:mockito-core:5.14.2")
testImplementation("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
testImplementation("org.spigotmc:spigot-api:1.21.1-R0.1-SNAPSHOT")
testImplementation("com.sk89q.worldedit:worldedit-bukkit:7.2.19")
compileOnly("net.milkbowl.vault:VaultUnlockedAPI:2.10")
compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.21.1-R0.1-SNAPSHOT")
compileOnly("com.onarandombox.multiversecore:Multiverse-Core:4.3.1")
compileOnly("com.onarandombox.multiverseinventories:Multiverse-Inventories:4.2.3")
compileOnly("com.sk89q.worldedit:worldedit-bukkit:7.2.19")
Expand All @@ -36,6 +36,8 @@ dependencies {
compileOnly("org.apache.commons:commons-text:1.12.0")
compileOnly("org.apache.httpcomponents:httpclient:4.5.14")
compileOnly("org.apache.maven:maven-artifact:3.8.6")

compileOnly(files("libs/SignShop-5.0.0-dev.jar"))
}

description = "uSkyBlock-Core"
Binary file added uSkyBlock-Core/libs/SignShop-5.0.0-dev.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public static boolean loadPluginConfig(FileConfiguration config) {
extras_sendToSpawn = config.getBoolean("options.extras.sendToSpawn");
extras_respawnAtIsland = config.getBoolean("options.extras.respawnAtIsland");
island_useTopTen = config.getBoolean("options.island.useTopTen");
general_worldName = config.getString("options.general.worldName", "skyworld");
general_worldName = config.getString("options.general.worldName", "world_acidisland_nether");
island_removeCreaturesByTeleport = config.getBoolean("options.island.removeCreaturesByTeleport");
island_allowIslandLock = config.getBoolean("options.island.allowIslandLock");
island_topTenTimeout = Duration.ofMinutes(config.getLong("options.island.topTenTimeout", 7));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,7 @@
import us.talabrek.ultimateskyblock.PluginConfig;
import us.talabrek.ultimateskyblock.Settings;
import us.talabrek.ultimateskyblock.chat.ChatEvents;
import us.talabrek.ultimateskyblock.event.ExploitEvents;
import us.talabrek.ultimateskyblock.event.GriefEvents;
import us.talabrek.ultimateskyblock.event.InternalEvents;
import us.talabrek.ultimateskyblock.event.ItemDropEvents;
import us.talabrek.ultimateskyblock.event.MenuEvents;
import us.talabrek.ultimateskyblock.event.NetherTerraFormEvents;
import us.talabrek.ultimateskyblock.event.PlayerEvents;
import us.talabrek.ultimateskyblock.event.SpawnEvents;
import us.talabrek.ultimateskyblock.event.ToolMenuEvents;
import us.talabrek.ultimateskyblock.event.WitherTagEvents;
import us.talabrek.ultimateskyblock.event.WorldGuardEvents;
import us.talabrek.ultimateskyblock.event.*;
import us.talabrek.ultimateskyblock.gui.GuiListener;
import us.talabrek.ultimateskyblock.signs.SignEvents;
import us.talabrek.ultimateskyblock.command.InviteHandler;
Expand All @@ -38,6 +28,7 @@ public class Listeners {
private final WitherTagEvents witherTagEvents;
private final GriefEvents griefEvents;
private final ItemDropEvents itemDropEvents;
private final IslandBorderEvent islandBorderEvent;
private final SpawnEvents spawnEvents;
private final WorldGuardEvents worldGuardEvents;
private final NetherTerraFormEvents netherTerraFormEvents;
Expand All @@ -58,6 +49,7 @@ public Listeners(
@NotNull WitherTagEvents witherTagEvents,
@NotNull GriefEvents griefEvents,
@NotNull ItemDropEvents itemDropEvents,
@NotNull IslandBorderEvent islandBorderEvent,
@NotNull SpawnEvents spawnEvents,
@NotNull WorldGuardEvents worldGuardEvents,
@NotNull NetherTerraFormEvents netherTerraFormEvents,
Expand All @@ -76,6 +68,7 @@ public Listeners(
this.witherTagEvents = witherTagEvents;
this.griefEvents = griefEvents;
this.itemDropEvents = itemDropEvents;
this.islandBorderEvent = islandBorderEvent;
this.spawnEvents = spawnEvents;
this.worldGuardEvents = worldGuardEvents;
this.netherTerraFormEvents = netherTerraFormEvents;
Expand All @@ -99,6 +92,8 @@ public void registerListeners(Plugin plugin) {
manager.registerEvents(inviteHandler, plugin);
manager.registerEvents(playerDB, plugin);

manager.registerEvents(islandBorderEvent, plugin);

// TODO minoneer 06.02.2025: Move this logic. Either into the appropriate listener, or into submodules if we don't want all features active (e.g., the nether)
if (config.getYamlConfig().getBoolean("options.protection.enabled", true)) {
manager.registerEvents(griefEvents, plugin);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.jetbrains.annotations.NotNull;
import us.talabrek.ultimateskyblock.player.PlayerInfo;
import us.talabrek.ultimateskyblock.uSkyBlock;
import us.talabrek.ultimateskyblock.util.TranslationUtil;

import java.time.Duration;
import java.util.ArrayList;
Expand Down Expand Up @@ -50,6 +51,7 @@ static Type from(String s) {
private final List<EntityMatch> requiredEntities;
private final List<String> requiredChallenges;
private final double requiredLevel;
private List<ProgressRequirement> requiredProgress;
private final Rank rank;
private final Duration resetDuration;
private final ItemStack displayItem;
Expand All @@ -64,7 +66,7 @@ static Type from(String s) {

public Challenge(String name, String displayName, String description, Type type, List<ItemRequirement> requiredItems,
@NotNull List<BlockRequirement> requiredBlocks, List<EntityMatch> requiredEntities,
List<String> requiredChallenges, double requiredLevel, Rank rank,
List<String> requiredChallenges, double requiredLevel, List<ProgressRequirement> requiredProgress, Rank rank,
Duration resetDuration, ItemStack displayItem, String tool, ItemStack lockedItem, int offset,
boolean takeItems, int radius, Reward reward, Reward repeatReward, int repeatLimit) {
this.name = name;
Expand All @@ -75,6 +77,7 @@ public Challenge(String name, String displayName, String description, Type type,
this.requiredEntities = requiredEntities;
this.requiredChallenges = requiredChallenges;
this.requiredLevel = requiredLevel;
this.requiredProgress = requiredProgress;
this.rank = rank;
this.resetDuration = resetDuration;
this.displayItem = displayItem;
Expand Down Expand Up @@ -138,6 +141,10 @@ public List<String> getRequiredChallenges() {
return requiredChallenges;
}

public List<ProgressRequirement> getRequiredProgress() {
return requiredProgress != null ? requiredProgress : Collections.emptyList();
}

public Rank getRank() {
return rank;
}
Expand Down Expand Up @@ -182,10 +189,24 @@ public ItemStack getDisplayItem(ChallengeCompletion completion, boolean withCurr
}
Map<ItemStack, Integer> requiredItemsForChallenge = getRequiredItems(timesCompleted);
if (!requiredItemsForChallenge.isEmpty() || !requiredBlocks.isEmpty()
|| (requiredEntities != null && !requiredEntities.isEmpty())) {
|| (requiredEntities != null && !requiredEntities.isEmpty()) || !getRequiredProgress().isEmpty()) {
lores.add(tr("\u00a7eThis challenge requires:"));
}
List<String> details = new ArrayList<>();

// Add progress requirements to details
List<ProgressRequirement> progressRequirements = getRequiredProgress();
if (!progressRequirements.isEmpty()) {
for (ProgressRequirement progressReq : progressRequirements) {
if (wrappedDetails(details).size() >= MAX_DETAILS) {
details.add(tr("\u00a77and more..."));
break;
}
double requiredAmount = progressReq.amountForRepetitions(timesCompleted);
details.add(tr("\u00a7f{0}: {1}", progressReq.key(), requiredAmount));
}
}

if (!requiredItemsForChallenge.isEmpty()) {
for (Map.Entry<ItemStack, Integer> requiredItem : requiredItemsForChallenge.entrySet()) {
if (wrappedDetails(details).size() >= MAX_DETAILS) {
Expand All @@ -195,8 +216,8 @@ public ItemStack getDisplayItem(ChallengeCompletion completion, boolean withCurr
int requiredAmount = requiredItem.getValue();
ItemStack requiredType = requiredItem.getKey();
details.add(requiredAmount > 1
? tr("\u00a7f{0}x \u00a77{1}", requiredAmount, ItemStackUtil.getItemName(requiredType))
: tr("\u00a77{0}", ItemStackUtil.getItemName(requiredType)));
? tr("\u00a7f{0}x \u00a77{1}", requiredAmount, TranslationUtil.INSTANCE.getItemLocalizedName(requiredType))
: tr("\u00a77{0}", TranslationUtil.INSTANCE.getItemLocalizedName(requiredType)));
}
}
if (!requiredBlocks.isEmpty() && wrappedDetails(details).size() < MAX_DETAILS) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ public static Challenge createChallenge(Rank rank, ConfigurationSection section,
repeatReward = reward;
}
List<String> requiredChallenges = section.getStringList("requiredChallenges");
List<ProgressRequirement> requiredProgress = createProgressRequirements(section.getStringList("requiredProgress"));
int offset = section.getInt("offset", 0);
int repeatLimit = section.getInt("repeatLimit", 0);
return new Challenge(name, displayName, description, type,
requiredItems, requiredBlocks, requiredEntities, requiredChallenges, section.getDouble("requiredLevel", 0d),
rank, resetDuration, displayItem, section.getString("tool", null), lockedItem, offset, takeItems,
requiredProgress, rank, resetDuration, displayItem, section.getString("tool", null), lockedItem, offset, takeItems,
radius, reward, repeatReward, repeatLimit);
}

Expand Down Expand Up @@ -107,6 +108,59 @@ private static List<EntityMatch> createEntities(List<String> requiredEntities) {
return entities;
}

private static List<ProgressRequirement> createProgressRequirements(List<String> progressRequirements) {
List<ProgressRequirement> requirements = new ArrayList<>();
for (String progressString : progressRequirements) {
requirements.add(createProgressRequirement(progressString));
}
return requirements;
}

private static ProgressRequirement createProgressRequirement(String progressString) {
// Format: "key:amount" or "key:amount:operator:increment"
// Examples: "kills:10", "blocks_mined:100:+:5", "trees_planted:50:*:1.5"
String[] parts = progressString.split(":");
if (parts.length < 2) {
throw new IllegalArgumentException("Invalid progress requirement format: " + progressString +
". Expected format: 'key:amount' or 'key:amount:operator:increment'");
}

String key = parts[0];
double amount;
try {
amount = Double.parseDouble(parts[1]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid amount in progress requirement: " + progressString, e);
}

if (parts.length == 2) {
// Simple format: just key and amount
return ProgressRequirement.of(key, amount);
} else if (parts.length == 4) {
// Extended format with operator and increment
String operatorStr = parts[2];
double increment;
try {
increment = Double.parseDouble(parts[3]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid increment in progress requirement: " + progressString, e);
}

ItemRequirement.Operator operator = switch (operatorStr) {
case "+" -> ItemRequirement.Operator.ADD;
case "-" -> ItemRequirement.Operator.SUBTRACT;
case "*" -> ItemRequirement.Operator.MULTIPLY;
default -> throw new IllegalArgumentException("Invalid operator in progress requirement: " + operatorStr +
". Supported operators: +, -, *");
};

return ProgressRequirement.of(key, amount, operator, increment);
} else {
throw new IllegalArgumentException("Invalid progress requirement format: " + progressString +
". Expected format: 'key:amount' or 'key:amount:operator:increment'");
}
}

private static Reward createReward(ConfigurationSection section) {
if (section == null) {
return null;
Expand Down
Loading