From 8fa9f7b0d32d227fab8858cb32bea64452dee724 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 31 May 2026 21:56:38 +0200 Subject: [PATCH] Add even more Advancements --- .../src/de/steamwar/sql/CheckedSchematic.kt | 18 ++ .../SQL/src/de/steamwar/sql/EventFight.kt | 32 +++ .../SQL/src/de/steamwar/sql/FightPlayer.kt | 25 ++ .../advancements/Advancement.java | 15 +- .../advancements/Advancements.java | 226 +++++++++++++++++- 5 files changed, 312 insertions(+), 4 deletions(-) diff --git a/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt b/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt index a7b0104c..a8da2737 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/CheckedSchematic.kt @@ -86,6 +86,24 @@ class CheckedSchematic(id: EntityID) : CompositeEntity(id) { useDb { find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.seen eq false) }.orderBy(CheckedSchematicTable.endTime to SortOrder.DESC).toList() } + + @JvmStatic + fun countAccepted(owner: SteamwarUser) = + useDb { + find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.declineReason eq "freigegeben") }.count() + } + + @JvmStatic + fun countAccepted(owner: SteamwarUser, type: String) = + useDb { + find { (CheckedSchematicTable.nodeOwner eq owner.id) and (CheckedSchematicTable.declineReason eq "freigegeben") and (CheckedSchematicTable.nodeType like "$type%") }.count() + } + + @JvmStatic + fun countChecked(validator: SteamwarUser) = + useDb { + find { CheckedSchematicTable.validator eq validator.id }.count() + } } val node by CheckedSchematicTable.nodeId.transform({ it?.let { EntityID(it, SchematicNodeTable) } }, { it?.value }) diff --git a/CommonCore/SQL/src/de/steamwar/sql/EventFight.kt b/CommonCore/SQL/src/de/steamwar/sql/EventFight.kt index ae214915..7f6d2de2 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/EventFight.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/EventFight.kt @@ -130,6 +130,38 @@ class EventFight(id: EntityID) : IntEntity(id), Comparable { } ) } + + @JvmStatic + fun countEventFights(fighter: SteamwarUser) = + useDb { + exec( + "SELECT COUNT(DISTINCT F.FightID) AS FightCount FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID INNER JOIN EventFight EF on F.FightID = EF.Fight WHERE UserID = ?", + args = listOf(IntegerColumnType() to fighter.id.value) + ) { + if (it.next()) { + it.getLong("FightCount") + } else { + 0 + } + } + ?: 0 + } + + @JvmStatic + fun getHighestPlacement(fighter: SteamwarUser) = + useDb { + exec( + "SELECT MIN(TT.Placement) AS Placement FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID INNER JOIN EventFight EF on F.FightID = EF.Fight INNER JOIN TeamTeilnahme TT on TT.EventID = EF.EventID WHERE UserID = ?", + args = listOf(IntegerColumnType() to fighter.id.value) + ) { + if (it.next()) { + it.getInt("Placement") + } else { + Int.MAX_VALUE + } + } + ?: Int.MAX_VALUE + } } val fightID by EventFightTable.id.transform({ EntityID(it, EventFightTable) }, { it.value }) diff --git a/CommonCore/SQL/src/de/steamwar/sql/FightPlayer.kt b/CommonCore/SQL/src/de/steamwar/sql/FightPlayer.kt index 626440fb..23ff78a0 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/FightPlayer.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/FightPlayer.kt @@ -20,9 +20,12 @@ package de.steamwar.sql import de.steamwar.sql.internal.useDb +import org.jetbrains.exposed.v1.core.IntegerColumnType +import org.jetbrains.exposed.v1.core.VarCharColumnType import org.jetbrains.exposed.v1.core.dao.id.CompositeID import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable import org.jetbrains.exposed.v1.core.dao.id.EntityID +import org.jetbrains.exposed.v1.core.eq import org.jetbrains.exposed.v1.core.inList import org.jetbrains.exposed.v1.dao.CompositeEntity import org.jetbrains.exposed.v1.dao.CompositeEntityClass @@ -69,6 +72,28 @@ class FightPlayer(id: EntityID) : CompositeEntity(id) { useDb { find { FightPlayerTable.fightId inList fightIds.toList() }.toList() } + + @JvmStatic + fun countFights(userId: Int) = + useDb { + find { FightPlayerTable.userId eq userId }.count() + } + + @JvmStatic + fun countFights(userId: Int, type: String) = + useDb { + exec( + "SELECT COUNT(*) AS FightCount FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID WHERE UserID = ? AND GameMode LIKE ?", + args = listOf(IntegerColumnType() to userId, VarCharColumnType() to "$type%") + ) { + if (it.next()) { + it.getInt("FightCount") + } else { + 0 + } + } + ?: 0 + } } val fightID by FightPlayerTable.fightId.transform({ EntityID(it, FightTable) }, { it.value }) diff --git a/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancement.java b/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancement.java index 012b426b..d250ed51 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancement.java +++ b/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancement.java @@ -125,7 +125,20 @@ public class Advancement { return false; } } - }; + }, + WITH_PREVIOUS { + @Override + public boolean hidden(Data data) { + if (data.advancement.parent.isPresent()) { + Advancement parent = data.advancement.parent.get(); + Advancement.Data parentData = parent.get(data.user); + return parentData.hidden; + } else { + return false; + } + } + }, + ; public abstract boolean hidden(Data data); } diff --git a/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancements.java b/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancements.java index 5d0f0460..9128bf7b 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancements.java +++ b/VelocityCore/src/de/steamwar/velocitycore/advancements/Advancements.java @@ -21,6 +21,9 @@ package de.steamwar.velocitycore.advancements; import de.steamwar.messages.Chatter; import de.steamwar.persistent.Storage; +import de.steamwar.sql.CheckedSchematic; +import de.steamwar.sql.EventFight; +import de.steamwar.sql.FightPlayer; import lombok.Getter; import lombok.experimental.UtilityClass; import net.kyori.adventure.text.Component; @@ -49,7 +52,7 @@ public class Advancements { Advancement.Display.FrameType.CHALLENGE, Optional.of("minecraft:gui/advancements/backgrounds/adventure"), 0f, - 0f + 3f ), Advancement.HidePolicy.NEVER, 1, @@ -70,7 +73,7 @@ public class Advancements { "clock", Advancement.Display.FrameType.TASK, i + 1f, - 0f + 3f ), Advancement.HidePolicy.PREVIOUS_UNFINISHED, Math.min(neededPlayTime, 100), @@ -80,10 +83,227 @@ public class Advancements { playtime /= 60d * 60d; if (playtime > neededPlayTime) return Math.min(neededPlayTime, 100); - return (int) (playtime / (neededPlayTime / 100)); + return (int) (playtime / Math.max(neededPlayTime / 100.0, 1)); } ); playtime.add(previous); } } + + static { + Advancement previous = ROOT; + int[] fightCounts = new int[]{1, 10, 50, 100, 200, 500, 1000, 2500, 5000, 7500, 10000, 15000, 20000}; + for (int i = 0; i < fightCounts.length; i++) { + int fightCount = fightCounts[i]; + previous = new Advancement( + "steamwar:advancements/fights_" + fightCount, + Optional.of(previous), + new Advancement.Display( + Component.text(fightCount + " Fight" + (fightCount > 1 ? "s" : "")), + Component.text(fightCount + " Fight" + (fightCount > 1 ? "s" : "")), + "iron_sword", + Advancement.Display.FrameType.TASK, + i + 1f, + 4f + ), + Advancement.HidePolicy.PREVIOUS_UNFINISHED, + Math.min(fightCount, 100), + user -> { + long fights = FightPlayer.countFights(user.getId()); + if (fights > fightCount) return Math.min(fightCount, 100); + return (int) (fights / Math.max(fightCount / 100.0, 1)); + } + ); + + if (i == 0) { + fightsPerType(previous, 5f, "WarGear", "stone_bricks"); + fightsPerType(previous, 6f, "MiniWarGear", "stone_brick_slab"); + fightsPerType(previous, 7f, "WarShip", "dark_oak_boat"); + } + } + } + + private static void fightsPerType(Advancement previous, float yCoord, String type, String item) { + int[] fightCounts = new int[]{1, 10, 25, 50, 75, 100, 250, 500, 750, 1000}; + for (int i = 0; i < fightCounts.length; i++) { + int fightCount = fightCounts[i]; + previous = new Advancement( + "steamwar:advancements/fights_" + type + "_" + fightCount, + Optional.of(previous), + new Advancement.Display( + Component.text(type + " " + fightCount + " Fight" + (fightCount > 1 ? "s" : "")), + Component.text(type + " " + fightCount + " Fight" + (fightCount > 1 ? "s" : "")), + item, + Advancement.Display.FrameType.TASK, + i + 2f, + yCoord + ), + i == 0 ? Advancement.HidePolicy.WITH_PREVIOUS : Advancement.HidePolicy.PREVIOUS_UNFINISHED, + Math.min(fightCount, 100), + user -> { + long fights = FightPlayer.countFights(user.getId(), type); + if (fights > fightCount) return Math.min(fightCount, 100); + return (int) (fights / Math.max(fightCount / 100.0, 1)); + } + ); + } + } + + static { + Advancement previous = ROOT; + int[] eventFightCounts = new int[]{1, 5, 10, 15, 25, 50, 100, 150, 200, 250}; + for (int i = 0; i < eventFightCounts.length; i++) { + int eventFightCount = eventFightCounts[i]; + previous = new Advancement( + "steamwar:advancements/event_fights_" + eventFightCount, + Optional.of(previous), + new Advancement.Display( + Component.text(eventFightCount + " Event-Fight" + (eventFightCount > 1 ? "s" : "")), + Component.text(eventFightCount + " Event-Fight" + (eventFightCount > 1 ? "s" : "")), + "golden_sword", + Advancement.Display.FrameType.TASK, + i + 1f, + 8f + ), + Advancement.HidePolicy.PREVIOUS_UNFINISHED, + Math.min(eventFightCount, 100), + user -> { + long fights = EventFight.countEventFights(user); + if (fights > eventFightCount) return Math.min(eventFightCount, 100); + return (int) (fights / Math.max(eventFightCount / 100.0, 1)); + } + ); + // playtime.add(previous); + // TODO: Implement per Type counter! + + if (i == 0) { + Advancement third = new Advancement( + "steamwar:advancements/event_placement_3", + Optional.of(previous), + new Advancement.Display( + Component.text("3. Place in Event"), + Component.text(""), + "copper_block", + Advancement.Display.FrameType.TASK, + 2f, + 9.5f + ), + Advancement.HidePolicy.PREVIOUS_UNFINISHED, + 1, + user -> EventFight.getHighestPlacement(user) <= 3 ? 1 : 0 + ); + Advancement first = new Advancement( + "steamwar:advancements/event_placement_1", + Optional.of(third), + new Advancement.Display( + Component.text("1. Place in Event"), + Component.text(""), + "gold_block", + Advancement.Display.FrameType.CHALLENGE, + 3f, + 9f + ), + Advancement.HidePolicy.WITH_PREVIOUS, + 1, + user -> EventFight.getHighestPlacement(user) == 1 ? 1 : 0 + ); + new Advancement( + "steamwar:advancements/event_placement_2", + Optional.of(first), + new Advancement.Display( + Component.text("2. Place in Event"), + Component.text(""), + "iron_block", + Advancement.Display.FrameType.GOAL, + 4f, + 9.25f + ), + Advancement.HidePolicy.WITH_PREVIOUS, + 1, + user -> EventFight.getHighestPlacement(user) <= 2 ? 1 : 0 + ); + } + } + } + + static { + Advancement previous = ROOT; + int[] checkedCounts = new int[]{1, 10, 100, 250, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000}; + for (int i = 0; i < checkedCounts.length; i++) { + int checkedCount = checkedCounts[i]; + previous = new Advancement( + "steamwar:advancements/checked_" + checkedCount, + Optional.of(previous), + new Advancement.Display( + Component.text(checkedCount + " Check Session" + (checkedCount > 1 ? "s" : "")), + Component.text(checkedCount + " Check Session" + (checkedCount > 1 ? "s" : "")), + "paper", + Advancement.Display.FrameType.TASK, + i + 1f, + 0f + ), + i == 0 ? Advancement.HidePolicy.NO_PROGRESS : Advancement.HidePolicy.PREVIOUS_UNFINISHED, + Math.min(checkedCount, 100), + user -> { + long checked = CheckedSchematic.countChecked(user); + if (checked > checkedCount) return Math.min(checkedCount, 100); + return (int) (checked / Math.max(checkedCount / 100.0, 1)); + } + ); + } + } + + static { + // WarGear + // MiniWarGear + // WarShip + Advancement previous = ROOT; + int[] acceptedCounts = new int[]{1, 5, 10, 15, 25, 50, 100, 150, 200, 250, 500, 750, 1000}; + for (int i = 0; i < acceptedCounts.length; i++) { + int acceptedCount = acceptedCounts[i]; + previous = new Advancement( + "steamwar:advancements/accepted_" + acceptedCount, + Optional.of(previous), + new Advancement.Display( + Component.text(acceptedCount + " Accepted Schematic" + (acceptedCount > 1 ? "s" : "")), + Component.text(acceptedCount + " Accepted Schematic" + (acceptedCount > 1 ? "s" : "")), + "cauldron", + Advancement.Display.FrameType.TASK, + i + 1f, + 2f + ), + Advancement.HidePolicy.PREVIOUS_UNFINISHED, + Math.min(acceptedCount, 100), + user -> { + long accepted = CheckedSchematic.countAccepted(user); + if (accepted > acceptedCount) return Math.min(acceptedCount, 100); + return (int) (accepted / Math.max(acceptedCount / 100.0, 1)); + } + ); + + if (i == 0) { + acceptedPerType(previous, 2f, "WarGear", "end_stone_bricks"); + acceptedPerType(previous, 3f, "MiniWarGear", "end_stone_brick_slab"); + acceptedPerType(previous, 4f, "WarShip", "oak_boat"); + } + } + } + + private static void acceptedPerType(Advancement previous, float xCoord, String type, String item) { + new Advancement( + "steamwar:advancements/accepted_" + type, + Optional.of(previous), + new Advancement.Display( + Component.text(type + " Accepted"), + Component.text(""), + item, + Advancement.Display.FrameType.GOAL, + xCoord, + 1f + ), + Advancement.HidePolicy.WITH_PREVIOUS, + 1, + user -> CheckedSchematic.countAccepted(user, type) > 0 ? 1 : 0 + ); + } }