fix(sanctuary): compter rubis et saphirs aux rangs inventaire 4/5 et 5/5 #10
@@ -74,6 +74,7 @@ tasks.register("verifyBlackMarket") {
|
||||
inputs.file(file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/QuestBoardGenerator.java"))
|
||||
inputs.file(file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/QuestBoardService.java"))
|
||||
inputs.file(file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/QuestBoardTier.java"))
|
||||
inputs.file(file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/api/inventory/SanctuaryPlayerInventoryView.java"))
|
||||
doLast {
|
||||
def data = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/BlackMarketData.java").text
|
||||
def service = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/BlackMarketService.java").text
|
||||
@@ -81,6 +82,7 @@ tasks.register("verifyBlackMarket") {
|
||||
def shop = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/ShopService.java").text
|
||||
def questData = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/QuestBoardData.java").text
|
||||
def quests = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/QuestBoardService.java").text
|
||||
def inventoryView = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/api/inventory/SanctuaryPlayerInventoryView.java").text
|
||||
if (!data.contains('SAVE_KEY = "black_market"') || !data.contains("DATA_VERSION = 2")
|
||||
|| !data.contains("ItemStack.CODEC.fieldOf(\"item\")") || !data.contains("replaceListing")
|
||||
|| !service.contains("LISTING_FEE_RUBIES = 1") || !service.contains("COMMISSION_PERCENT = 5")
|
||||
@@ -88,6 +90,11 @@ tasks.register("verifyBlackMarket") {
|
||||
|| !service.contains("loadedDeliveryBox") || !service.contains("PARCEL_RETENTION_MILLIS")
|
||||
|| !policy.contains("DataComponents.CONTAINER") || !policy.contains("DataComponents.BUNDLE_CONTENTS")
|
||||
|| !shop.contains("public static final boolean OPEN = true")
|
||||
|| !shop.contains("BlackMarketService.countPlayerItem")
|
||||
|| !shop.contains("BlackMarketService.removePlayerItem")
|
||||
|| shop.contains("getContainerSize()")
|
||||
|| !inventoryView.contains("getNonEquipmentItems")
|
||||
|| !service.contains("currencyStacks")
|
||||
|| !questData.contains('SAVE_KEY = "black_market_quests"')
|
||||
|| !quests.contains("ServerLivingEntityEvents.AFTER_DEATH")
|
||||
|| !quests.contains("QuestBoardTier.ACTIVATION_COST")
|
||||
|
||||
+10
-3
@@ -33,8 +33,10 @@ public final class SanctuaryPlayerInventoryView {
|
||||
|
||||
List<SlotReference> slots = new ArrayList<>(rows * SanctuaryInventoryCapacity.ROW_SIZE);
|
||||
Inventory inventory = player.getInventory();
|
||||
int vanillaSlots = Math.min(rows, SanctuaryInventoryCapacity.VANILLA_ROW_COUNT)
|
||||
* SanctuaryInventoryCapacity.ROW_SIZE;
|
||||
int vanillaSlots = Math.min(
|
||||
Math.min(rows, SanctuaryInventoryCapacity.VANILLA_ROW_COUNT)
|
||||
* SanctuaryInventoryCapacity.ROW_SIZE,
|
||||
inventory.getNonEquipmentItems().size());
|
||||
for (int slot = 0; slot < vanillaSlots; slot++) {
|
||||
slots.add(new SlotReference(inventory, slot, slot < SanctuaryInventoryCapacity.ROW_SIZE));
|
||||
}
|
||||
@@ -65,11 +67,16 @@ public final class SanctuaryPlayerInventoryView {
|
||||
|
||||
public record SlotReference(Container container, int slot, boolean hotbar) {
|
||||
public ItemStack stack() {
|
||||
if (container instanceof Inventory inventory && slot >= 0 && slot < Inventory.INVENTORY_SIZE) {
|
||||
List<ItemStack> items = inventory.getNonEquipmentItems();
|
||||
if (slot < items.size()) return items.get(slot);
|
||||
}
|
||||
return container.getItem(slot);
|
||||
}
|
||||
|
||||
public ItemStack remove(int count) {
|
||||
ItemStack removed = container.removeItem(slot, count);
|
||||
ItemStack stored = stack();
|
||||
ItemStack removed = stored.split(count);
|
||||
container.setChanged();
|
||||
return removed;
|
||||
}
|
||||
|
||||
+50
-5
@@ -4,11 +4,16 @@ import fr.koka99cab.sanctuary26.sanctuary.SanctuaryMod;
|
||||
import fr.koka99cab.sanctuary26.sanctuary.api.inventory.SanctuaryPlayerInventoryView;
|
||||
import fr.koka99cab.sanctuary26.sanctuary.network.BlackMarketCreatePayload;
|
||||
import fr.koka99cab.sanctuary26.sanctuary.network.BlackMarketEditorPayload;
|
||||
import fr.koka99cab.sanctuary26.sanctuary.gameplay.SanctuaryOverflowAccess;
|
||||
import fr.koka99cab.sanctuary26.sanctuary.gameplay.SanctuaryOverflowContainer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HexFormat;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
@@ -29,8 +34,11 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.permissions.Permissions;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
@@ -345,21 +353,58 @@ public final class BlackMarketService {
|
||||
}
|
||||
private static int countCurrency(ServerPlayer player, Item item) { return countPlayerItem(player, item); }
|
||||
static int countPlayerItem(ServerPlayer player, Item item) {
|
||||
if (item == null) return 0;
|
||||
long count = 0L;
|
||||
for (var slot : SanctuaryPlayerInventoryView.unlockedRows(player))
|
||||
if (slot.stack().is(item)) count += slot.stack().getCount();
|
||||
for (ItemStack stack : currencyStacks(player)) {
|
||||
if (stack.is(item)) count += stack.getCount();
|
||||
}
|
||||
return (int) Math.min(Integer.MAX_VALUE, count);
|
||||
}
|
||||
private static void removeCurrency(ServerPlayer player, Item item, int amount) { removePlayerItem(player, item, amount); }
|
||||
static void removePlayerItem(ServerPlayer player, Item item, int amount) {
|
||||
int remaining = amount;
|
||||
for (var slot : SanctuaryPlayerInventoryView.unlockedRows(player)) {
|
||||
for (ItemStack stack : currencyStacks(player)) {
|
||||
if (remaining <= 0) break;
|
||||
ItemStack stack = slot.stack();
|
||||
if (!stack.is(item)) continue;
|
||||
int removed = Math.min(remaining, stack.getCount());
|
||||
stack.shrink(removed); remaining -= removed; slot.markChanged();
|
||||
stack.shrink(removed);
|
||||
remaining -= removed;
|
||||
}
|
||||
player.getInventory().setChanged();
|
||||
SanctuaryOverflowAccess.of(player).setChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rank 4 (5 rows) puts the second-to-last visual bank on vanilla slots 27-35;
|
||||
* rank 5 (6 rows) puts it on overflow. Count both the 26.2 main stacks and the
|
||||
* inventory menu so those banks match what the player sees.
|
||||
*/
|
||||
private static List<ItemStack> currencyStacks(ServerPlayer player) {
|
||||
IdentityHashMap<ItemStack, Boolean> seen = new IdentityHashMap<>();
|
||||
List<ItemStack> stacks = new ArrayList<>();
|
||||
for (Slot slot : player.inventoryMenu.slots) {
|
||||
if (!countsAsPlayerStorage(slot)) continue;
|
||||
remember(stacks, seen, slot.getItem());
|
||||
}
|
||||
for (var slot : SanctuaryPlayerInventoryView.unlockedRows(player)) {
|
||||
remember(stacks, seen, slot.stack());
|
||||
}
|
||||
remember(stacks, seen, SanctuaryPlayerInventoryView.offhand(player).stack());
|
||||
return stacks;
|
||||
}
|
||||
|
||||
private static boolean countsAsPlayerStorage(Slot slot) {
|
||||
Container container = slot.container;
|
||||
if (container instanceof SanctuaryOverflowContainer) return slot.isActive();
|
||||
if (!(container instanceof Inventory)) return false;
|
||||
int index = slot.getContainerSlot();
|
||||
return index >= 0 && index < Inventory.INVENTORY_SIZE;
|
||||
}
|
||||
|
||||
private static void remember(List<ItemStack> stacks, IdentityHashMap<ItemStack, Boolean> seen,
|
||||
ItemStack stack) {
|
||||
if (stack == null || stack.isEmpty() || seen.put(stack, Boolean.TRUE) != null) return;
|
||||
stacks.add(stack);
|
||||
}
|
||||
private static void writeSign(ServerLevel level, SignBlockEntity sign, BlackMarketData.Listing listing) {
|
||||
SignText text = new SignText()
|
||||
|
||||
@@ -237,24 +237,13 @@ public final class ShopService {
|
||||
}
|
||||
private static Item currency(Identifier id) { return BuiltInRegistries.ITEM.getOptional(id).orElse(null); }
|
||||
private static int countCurrency(ServerPlayer player, Item item) {
|
||||
if (item == null) return 0;
|
||||
int total = 0;
|
||||
for (int slot = 0; slot < player.getInventory().getContainerSize(); slot++) {
|
||||
ItemStack stack = player.getInventory().getItem(slot); if (stack.is(item)) total += stack.getCount();
|
||||
}
|
||||
return total;
|
||||
return item == null ? 0 : BlackMarketService.countPlayerItem(player, item);
|
||||
}
|
||||
private static boolean hasCurrency(ServerPlayer player, Item item, int count) {
|
||||
return countCurrency(player, item) >= count;
|
||||
}
|
||||
private static void removeCurrency(ServerPlayer player, Item item, int count) {
|
||||
int remaining = count;
|
||||
for (int slot = 0; slot < player.getInventory().getContainerSize() && remaining > 0; slot++) {
|
||||
ItemStack stack = player.getInventory().getItem(slot);
|
||||
if (!stack.is(item)) continue;
|
||||
int removed = Math.min(remaining, stack.getCount()); stack.shrink(removed); remaining -= removed;
|
||||
}
|
||||
player.getInventory().setChanged();
|
||||
BlackMarketService.removePlayerItem(player, item, count);
|
||||
}
|
||||
private static void celebrate(ServerLevel level, BlockPos pos, java.util.UUID owner, ItemStack parcel) {
|
||||
level.playSound(null, pos, SoundEvents.PLAYER_LEVELUP, SoundSource.BLOCKS, 0.65F, 1.35F);
|
||||
|
||||
+10
@@ -1,5 +1,7 @@
|
||||
package fr.koka99cab.sanctuary26.sanctuary.shop;
|
||||
|
||||
import fr.koka99cab.sanctuary26.sanctuary.gameplay.SanctuaryInventoryCapacity;
|
||||
import fr.koka99cab.sanctuary26.sanctuary.progression.SanctuaryStat;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
public final class ShopDeliveryTimingSmoke {
|
||||
@@ -35,5 +37,13 @@ public final class ShopDeliveryTimingSmoke {
|
||||
|| ShopProgression.slotCost(10) != -1) {
|
||||
throw new AssertionError("Shop capacity bounds are invalid");
|
||||
}
|
||||
if (SanctuaryInventoryCapacity.VANILLA_ROW_COUNT != 4
|
||||
|| SanctuaryInventoryCapacity.MAX_ROW_COUNT != 6) {
|
||||
throw new AssertionError("Shop currency counting must include overflow rows 5-6");
|
||||
}
|
||||
if (SanctuaryStat.INVENTORY.valueAt(4) != 5.0
|
||||
|| SanctuaryStat.INVENTORY.valueAt(5) != 6.0) {
|
||||
throw new AssertionError("Inventory ranks 4/5 and 5/5 no longer map to 5 and 6 rows");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user