From 283777f9101b8013a79c8509cb87748099a05b74 Mon Sep 17 00:00:00 2001 From: cheaterpaul Date: Wed, 17 Jan 2024 14:58:22 +0100 Subject: [PATCH] create skill stat tab to statistics screen --- .../blockentity/MotherBlockEntity.java | 3 +- .../blockentity/TotemBlockEntity.java | 6 +- .../blocks/AlchemicalCauldronBlock.java | 2 +- .../vampirism/blocks/AlchemyTableBlock.java | 2 +- .../vampirism/blocks/AltarInfusionBlock.java | 4 +- .../blocks/AltarInspirationBlock.java | 4 +- .../vampirism/blocks/CoffinBlock.java | 2 +- .../vampirism/blocks/FogDiffuserBlock.java | 2 +- .../vampirism/blocks/GarlicDiffuserBlock.java | 2 +- .../vampirism/blocks/GrinderBlock.java | 2 +- .../vampirism/blocks/HunterTableBlock.java | 2 +- .../vampirism/blocks/MedChairBlock.java | 2 +- .../vampirism/blocks/PedestalBlock.java | 2 +- .../vampirism/blocks/PotionTableBlock.java | 2 +- .../vampirism/blocks/ThroneBlock.java | 2 +- .../vampirism/blocks/TotemTopBlock.java | 2 +- .../vampirism/blocks/VampireBeaconBlock.java | 2 +- .../gui/components/ActionStatisticsList.java | 131 +++++++++++++----- .../de/teamlapen/vampirism/core/ModStats.java | 82 ++++------- .../de/teamlapen/vampirism/core/ModTasks.java | 20 +-- .../vampirism/effects/OblivionEffect.java | 4 +- .../vampirism/entity/player/TaskManager.java | 4 +- .../entity/player/actions/ActionHandler.java | 6 +- .../entity/player/skills/SkillHandler.java | 19 ++- .../entity/player/vampire/VampirePlayer.java | 6 +- .../player/vampire/actions/InfectAction.java | 2 +- .../inventory/WeaponTableCraftingSlot.java | 2 +- .../teamlapen/vampirism/items/StakeItem.java | 2 +- .../assets/vampirism/lang/en_us.json | 4 +- .../sprites/statistics/skills_forgotten.png | Bin 0 -> 839 bytes .../statistics/skills_forgotten.png.mcmeta | 10 ++ .../sprites/statistics/skills_unlocked.png | Bin 0 -> 151 bytes 32 files changed, 190 insertions(+), 145 deletions(-) create mode 100644 src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_forgotten.png create mode 100644 src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_forgotten.png.mcmeta create mode 100644 src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_unlocked.png diff --git a/src/main/java/de/teamlapen/vampirism/blockentity/MotherBlockEntity.java b/src/main/java/de/teamlapen/vampirism/blockentity/MotherBlockEntity.java index 6616937bae..ea7346e6b7 100644 --- a/src/main/java/de/teamlapen/vampirism/blockentity/MotherBlockEntity.java +++ b/src/main/java/de/teamlapen/vampirism/blockentity/MotherBlockEntity.java @@ -1,7 +1,6 @@ package de.teamlapen.vampirism.blockentity; import de.teamlapen.lib.lib.util.SpawnHelper; -import de.teamlapen.vampirism.VampirismMod; import de.teamlapen.vampirism.blocks.mother.IRemainsBlock; import de.teamlapen.vampirism.blocks.mother.MotherTreeStructure; import de.teamlapen.vampirism.core.*; @@ -324,7 +323,7 @@ public void concludeFight() { for (LivingEntity livingentity : involvedEntities) { if (livingentity instanceof ServerPlayer serverplayer) { ModAdvancements.TRIGGER_MOTHER_WIN.get().trigger(serverplayer); - serverplayer.awardStat(ModStats.mother_defeated.get(), 1); + serverplayer.awardStat(ModStats.MOTHER_DEFEATED.get(), 1); FactionPlayerHandler.getOpt(serverplayer).filter(s -> s.getCurrentFaction() != null && s.getCurrentLevel() < s.getCurrentFaction().getHighestReachableLevel()).ifPresent(handler -> { handler.setFactionLevel(handler.getCurrentFaction(), handler.getCurrentLevel() + 1); }); diff --git a/src/main/java/de/teamlapen/vampirism/blockentity/TotemBlockEntity.java b/src/main/java/de/teamlapen/vampirism/blockentity/TotemBlockEntity.java index 166ec6795f..a14ebb39f6 100644 --- a/src/main/java/de/teamlapen/vampirism/blockentity/TotemBlockEntity.java +++ b/src/main/java/de/teamlapen/vampirism/blockentity/TotemBlockEntity.java @@ -834,11 +834,11 @@ private void applyVictoryBonus(boolean attackWin) { if (!attackWin) { player.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, Math.max(this.badOmenLevel - 1, 0), false, false, true)); } - player.awardStat(ModStats.win_village_capture.get()); + player.awardStat(ModStats.WIN_VILLAGE_CAPTURE.get()); if (attackWin) { - player.awardStat(ModStats.capture_village.get()); + player.awardStat(ModStats.CAPTURE_VILLAGE.get()); } else { - player.awardStat(ModStats.defend_village.get()); + player.awardStat(ModStats.DEFEND_VILLAGE.get()); } } } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/AlchemicalCauldronBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/AlchemicalCauldronBlock.java index e847ebdab2..be32235618 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/AlchemicalCauldronBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/AlchemicalCauldronBlock.java @@ -99,7 +99,7 @@ protected void openContainer(@NotNull Level world, @NotNull BlockPos blockPos, @ BlockEntity tile = world.getBlockEntity(blockPos); if (tile instanceof AlchemicalCauldronBlockEntity) { playerEntity.openMenu((MenuProvider) tile); - playerEntity.awardStat(ModStats.interact_alchemical_cauldron.get()); + playerEntity.awardStat(ModStats.INTERACT_ALCHEMICAL_CAULDRON.get()); } } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/AlchemyTableBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/AlchemyTableBlock.java index 4c720a6bdd..d8642e038d 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/AlchemyTableBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/AlchemyTableBlock.java @@ -69,7 +69,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level level, @N BlockEntity tileentity = level.getBlockEntity(pos); if (tileentity instanceof AlchemyTableBlockEntity) { player.openMenu((AlchemyTableBlockEntity) tileentity); - player.awardStat(ModStats.interact_with_alchemy_table.get()); + player.awardStat(ModStats.INTERACT_WITH_ALCHEMY_TABLE.get()); } } else { player.displayClientMessage(Component.translatable("text.vampirism.unfamiliar"), true); diff --git a/src/main/java/de/teamlapen/vampirism/blocks/AltarInfusionBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/AltarInfusionBlock.java index a4673ccac2..0fa38348c7 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/AltarInfusionBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/AltarInfusionBlock.java @@ -122,7 +122,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level worldIn, case INVMISSING -> player.displayClientMessage(Component.translatable("text.vampirism.altar_infusion.ritual_missing_times"), true); case OK -> { if (heldItem.isEmpty()) { - player.awardStat(ModStats.altar_of_infusion_rituals_performed.get()); + player.awardStat(ModStats.ALTAR_OF_INFUSION_RITUALS_PERFORMED.get()); te.startRitual(player); return InteractionResult.SUCCESS; } @@ -135,7 +135,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level worldIn, } } player.openMenu(te); - player.awardStat(ModStats.interact_with_altar_of_infusion.get()); + player.awardStat(ModStats.INTERACT_WITH_ALTAR_OF_INFUSION.get()); return InteractionResult.SUCCESS; } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/AltarInspirationBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/AltarInspirationBlock.java index 11f2c8731c..0220084aca 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/AltarInspirationBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/AltarInspirationBlock.java @@ -85,7 +85,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level worldIn, if (opt.isPresent()) { AltarInspirationBlockEntity tileEntity = (AltarInspirationBlockEntity) worldIn.getBlockEntity(pos); if (!player.isShiftKeyDown() && tileEntity != null) { - player.awardStat(ModStats.interact_with_altar_inspiration.get()); + player.awardStat(ModStats.INTERACT_WITH_ALTAR_INSPIRATION.get()); FluidUtil.interactWithFluidHandler(player, hand, worldIn, pos, hit.getDirection()); } return InteractionResult.SUCCESS; @@ -93,7 +93,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level worldIn, } else { BlockEntity tileEntity = worldIn.getBlockEntity(pos); if (tileEntity instanceof AltarInspirationBlockEntity altar) { - player.awardStat(ModStats.altar_of_inspiration_rituals_performed.get()); + player.awardStat(ModStats.ALTAR_OF_INSPIRATION_RITUALS_PERFORMED.get()); altar.startRitual(player); } } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/CoffinBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/CoffinBlock.java index 8d39a9aee2..9e8c6768fb 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/CoffinBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/CoffinBlock.java @@ -198,7 +198,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level worldIn, return InteractionResult.CONSUME; } } - player.awardStat(ModStats.interact_with_coffin.get()); + player.awardStat(ModStats.INTERACT_WITH_COFFIN.get()); if (player.isShiftKeyDown() && !state.getValue(BedBlock.OCCUPIED)) { worldIn.setBlock(pos, state.setValue(CLOSED, !state.getValue(CLOSED)), 3); BlockPos otherPos = getOtherPos(pos, state); diff --git a/src/main/java/de/teamlapen/vampirism/blocks/FogDiffuserBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/FogDiffuserBlock.java index 0adee1e360..ff7a22e681 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/FogDiffuserBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/FogDiffuserBlock.java @@ -52,7 +52,7 @@ public FogDiffuserBlock(@NotNull Properties properties) { public @NotNull InteractionResult use(@NotNull BlockState pState, @NotNull Level pLevel, @NotNull BlockPos pPos, @NotNull Player pPlayer, @NotNull InteractionHand pHand, @NotNull BlockHitResult pHit) { ItemStack itemInHand = pPlayer.getItemInHand(pHand); getBlockEntity(pLevel, pPos).ifPresent(blockEntity -> { - pPlayer.awardStat(ModStats.interact_with_fog_diffuser.get()); + pPlayer.awardStat(ModStats.INTERACT_WITH_FOG_DIFFUSER.get()); if(!blockEntity.interact(itemInHand)) { VampirismMod.proxy.displayFogDiffuserScreen(blockEntity, getName()); } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/GarlicDiffuserBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/GarlicDiffuserBlock.java index 752b8d05b4..56bd020a47 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/GarlicDiffuserBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/GarlicDiffuserBlock.java @@ -148,7 +148,7 @@ public BlockState rotate(@NotNull BlockState state, @NotNull Rotation rot) { @Override public InteractionResult use(@NotNull BlockState state, @NotNull Level world, @NotNull BlockPos pos, @NotNull Player player, @NotNull InteractionHand hand, @NotNull BlockHitResult hit) { ItemStack heldItem = player.getItemInHand(hand); - player.awardStat(ModStats.interact_with_garlic_diffuser.get()); + player.awardStat(ModStats.INTERACT_WITH_GARLIC_DIFFUSER.get()); if (!heldItem.isEmpty() && ModItems.PURIFIED_GARLIC.get() == heldItem.getItem()) { if (!world.isClientSide) { GarlicDiffuserBlockEntity t = getTile(world, pos); diff --git a/src/main/java/de/teamlapen/vampirism/blocks/GrinderBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/GrinderBlock.java index e5089d8d2a..8949bcc8b1 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/GrinderBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/GrinderBlock.java @@ -131,7 +131,7 @@ public BlockState rotate(@NotNull BlockState state, @NotNull Rotation rot) { @Override public InteractionResult use(@NotNull BlockState state, @NotNull Level world, @NotNull BlockPos pos, @NotNull Player player, @NotNull InteractionHand hand, @NotNull BlockHitResult hit) { if (world.isClientSide) return InteractionResult.SUCCESS; - player.awardStat(ModStats.interact_with_blood_grinder.get()); + player.awardStat(ModStats.INTERACT_WITH_BLOOD_GRINDER.get()); player.openMenu(world.getBlockEntity(pos) instanceof BloodGrinderBlockEntity ? (BloodGrinderBlockEntity) world.getBlockEntity(pos) : null); return InteractionResult.SUCCESS; } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/HunterTableBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/HunterTableBlock.java index 553cc31f8c..8e33ba3764 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/HunterTableBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/HunterTableBlock.java @@ -118,7 +118,7 @@ public void neighborChanged(@NotNull BlockState state, @NotNull Level worldIn, @ public InteractionResult use(@NotNull BlockState state, @NotNull Level worldIn, @NotNull BlockPos pos, @NotNull Player player, @NotNull InteractionHand hand, @NotNull BlockHitResult hit) { if (!worldIn.isClientSide) { if (player instanceof ServerPlayer serverPlayer) { - serverPlayer.awardStat(ModStats.interact_with_research_table.get()); + serverPlayer.awardStat(ModStats.INTERACT_WITH_RESEARCH_TABLE.get()); if (Helper.isHunter(serverPlayer)) { player.openMenu(new SimpleMenuProvider((id, playerInventory, playerIn) -> new HunterTableMenu(id, playerInventory, ContainerLevelAccess.create(playerIn.level(), pos)), Component.translatable("container.crafting")), pos); } else { diff --git a/src/main/java/de/teamlapen/vampirism/blocks/MedChairBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/MedChairBlock.java index 4969d7b461..0621dca341 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/MedChairBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/MedChairBlock.java @@ -80,7 +80,7 @@ public MedChairBlock() { public InteractionResult use(@NotNull BlockState state, @NotNull Level world, @NotNull BlockPos pos, @NotNull Player player, @NotNull InteractionHand hand, @NotNull BlockHitResult hit) { if (player.isAlive()) { ItemStack stack = player.getItemInHand(hand); - player.awardStat(ModStats.interact_with_injection_chair.get()); + player.awardStat(ModStats.INTERACT_WITH_INJECTION_CHAIR.get()); if (handleInjections(player, world, stack, pos)) { stack.shrink(1); if (stack.isEmpty()) { diff --git a/src/main/java/de/teamlapen/vampirism/blocks/PedestalBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/PedestalBlock.java index 07eb4d0398..9e3a9fbf5d 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/PedestalBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/PedestalBlock.java @@ -91,7 +91,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level world, @N ItemStack stack = player.getItemInHand(hand); if (stack.isEmpty() && !tile.extractItem(0, 1, true).isEmpty()) { ItemStack stack2 = tile.extractItem(0, 1, false); - player.awardStat(ModStats.items_filled_on_blood_pedestal.get()); + player.awardStat(ModStats.ITEMS_FILLED_ON_BLOOD_PEDESTAL.get()); takeItemPlayer(player, hand, stack2); return InteractionResult.SUCCESS; diff --git a/src/main/java/de/teamlapen/vampirism/blocks/PotionTableBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/PotionTableBlock.java index 984752178d..6c991f6b92 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/PotionTableBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/PotionTableBlock.java @@ -85,7 +85,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level worldIn, if (tile instanceof PotionTableBlockEntity) { if (((PotionTableBlockEntity) tile).canOpen(player)) { player.openMenu((PotionTableBlockEntity) tile, buffer -> buffer.writeBoolean(((PotionTableBlockEntity) tile).isExtended())); - player.awardStat(ModStats.interact_with_potion_table.get()); + player.awardStat(ModStats.INTERACT_WITH_POTION_TABLE.get()); } } } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/ThroneBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/ThroneBlock.java index abcce0767a..e1cbe75446 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/ThroneBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/ThroneBlock.java @@ -30,7 +30,7 @@ public ThroneBlock() { public @NotNull InteractionResult use(@NotNull BlockState state, Level world, BlockPos pos, Player player, InteractionHand p_225533_5_, BlockHitResult traceResult) { Part part = state.getValue(PART); Direction oppFacing = state.getValue(FACING).getOpposite(); - player.awardStat(ModStats.interact_with_throne.get()); + player.awardStat(ModStats.INTERACT_WITH_THRONE.get()); if (part == Part.MAIN && (traceResult.getDirection() == Direction.UP || traceResult.getDirection() == oppFacing)) { SitHandler.startSitting(player, world, pos, 0.5); return InteractionResult.SUCCESS; diff --git a/src/main/java/de/teamlapen/vampirism/blocks/TotemTopBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/TotemTopBlock.java index 3322051724..a589f348e7 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/TotemTopBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/TotemTopBlock.java @@ -143,7 +143,7 @@ public InteractionResult use(@NotNull BlockState state, @NotNull Level world, @N if (world.isClientSide) return InteractionResult.SUCCESS; TotemBlockEntity t = getTile(world, pos); if (t != null && world.getBlockState(pos.below()).getBlock().equals(ModBlocks.TOTEM_BASE.get())) { - player.awardStat(ModStats.interact_with_totem.get()); + player.awardStat(ModStats.INTERACT_WITH_TOTEM.get()); t.initiateCapture(player); return InteractionResult.SUCCESS; } diff --git a/src/main/java/de/teamlapen/vampirism/blocks/VampireBeaconBlock.java b/src/main/java/de/teamlapen/vampirism/blocks/VampireBeaconBlock.java index 9c12c047d2..32cb31dc26 100644 --- a/src/main/java/de/teamlapen/vampirism/blocks/VampireBeaconBlock.java +++ b/src/main/java/de/teamlapen/vampirism/blocks/VampireBeaconBlock.java @@ -60,7 +60,7 @@ public BlockEntityTicker getTicker(@NotNull Level pLe public @NotNull InteractionResult use(@NotNull BlockState pState, @NotNull Level pLevel, @NotNull BlockPos pPos, @NotNull Player pPlayer, @NotNull InteractionHand pHand, @NotNull BlockHitResult pHit) { if (!pLevel.isClientSide) { if (pPlayer instanceof ServerPlayer serverPlayer) { - serverPlayer.awardStat(ModStats.interact_with_ancient_beacon.get()); + serverPlayer.awardStat(ModStats.INTERACT_WITH_ANCIENT_BEACON.get()); if (Helper.isHunter(serverPlayer)) { if (pLevel.getBlockEntity(pPos) instanceof VampireBeaconBlockEntity blockentity) { pPlayer.openMenu(blockentity); diff --git a/src/main/java/de/teamlapen/vampirism/client/gui/components/ActionStatisticsList.java b/src/main/java/de/teamlapen/vampirism/client/gui/components/ActionStatisticsList.java index 5251ca7293..36dcc6b9d5 100644 --- a/src/main/java/de/teamlapen/vampirism/client/gui/components/ActionStatisticsList.java +++ b/src/main/java/de/teamlapen/vampirism/client/gui/components/ActionStatisticsList.java @@ -1,8 +1,10 @@ package de.teamlapen.vampirism.client.gui.components; -import com.google.common.collect.Sets; import de.teamlapen.vampirism.REFERENCE; import de.teamlapen.vampirism.api.entity.player.actions.IAction; +import de.teamlapen.vampirism.api.entity.player.actions.ILastingAction; +import de.teamlapen.vampirism.api.entity.player.skills.IActionSkill; +import de.teamlapen.vampirism.api.entity.player.skills.ISkill; import de.teamlapen.vampirism.core.ModRegistries; import de.teamlapen.vampirism.core.ModStats; import de.teamlapen.vampirism.mixin.client.StatsScreenAccessor; @@ -18,11 +20,9 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.stats.Stat; import net.minecraft.stats.StatType; -import net.minecraft.stats.StatsCounter; import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; -import net.neoforged.fml.common.Mod; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -32,28 +32,42 @@ import java.util.Set; import java.util.stream.Collectors; -public class ActionStatisticsList extends ObjectSelectionList { +public class ActionStatisticsList extends ObjectSelectionList { + protected final List>> skillColumns; protected final List>> actionColumns; private final ResourceLocation[] iconSprites = new ResourceLocation[] { + new ResourceLocation( REFERENCE.MODID, "statistics/skills_unlocked"), + new ResourceLocation( REFERENCE.MODID, "statistics/skills_forgotten"), new ResourceLocation( "statistics/item_used"), new ResourceLocation(REFERENCE.MODID, "statistics/time"), - new ResourceLocation(REFERENCE.MODID, "statistics/cooldown") + null + }; + private final ItemStack[] itemSprites = new ItemStack[] { + null, + null, + null, + null, + Items.RED_BED.getDefaultInstance() }; protected int headerPressed = -1; private final StatsScreenAccessor screen; private final Font font; - protected final Comparator itemStatSorter = new ActionRowComparator(); + protected final Comparator itemStatSorter = new ActionRowComparator(); @Nullable protected StatType sortColumn; protected int sortOrder; public ActionStatisticsList(Minecraft minecraft, StatsScreen screen, int width, int height) { super(minecraft, width, height, 32, 20); + this.skillColumns = List.of(ModStats.SKILL_UNLOCKED.get(), ModStats.SKILL_FORGOTTEN.get()); this.actionColumns = List.of(ModStats.ACTION_USED.get(), ModStats.ACTION_TIME.get(), ModStats.ACTION_COOLDOWN_TIME.get()); this.font = screen.font; this.screen = (StatsScreenAccessor) screen; this.setRenderHeader(true, 20); - ModRegistries.ACTIONS.stream().filter(x -> actionColumns.stream().mapToInt(y -> this.screen.getStats().getValue(y.get(x))).sum() > 0).collect(Collectors.toSet()).forEach(x -> addEntry(new ActionRow(x))); + Set> skills = new HashSet<>(); + skills.addAll(ModRegistries.SKILLS.stream().filter(x -> skillColumns.stream().mapToInt(y -> this.screen.getStats().getValue(y.get(x))).sum() > 0).collect(Collectors.toSet())); + skills.addAll(ModRegistries.ACTIONS.stream().filter(x -> actionColumns.stream().mapToInt(y -> this.screen.getStats().getValue(y.get(x))).sum() > 0).map(IAction::asSkill).toList()); + skills.forEach(s -> addEntry(new SkillRow(s))); } @Override @@ -64,6 +78,7 @@ protected void renderHeader(@NotNull GuiGraphics pGuiGraphics, int pX, int pY) { for (int i = 0; i < this.iconSprites.length; i++) { ResourceLocation loc = this.headerPressed == i ? StatsScreen.SLOT_SPRITE : StatsScreen.HEADER_SPRITE; screen.invokeBlitSlotIcon(pGuiGraphics, pX + screen.invokeGetColumnX(i) - 18, pY + 1, loc); + } if (this.sortColumn != null) { @@ -74,7 +89,15 @@ protected void renderHeader(@NotNull GuiGraphics pGuiGraphics, int pX, int pY) { for(int k = 0; k < this.iconSprites.length; ++k) { int l = this.headerPressed == k ? 1 : 0; - screen.invokeBlitSlotIcon(pGuiGraphics, pX + screen.invokeGetColumnX(k) - 18 + l, pY + 1 + l, this.iconSprites[k]); + ResourceLocation iconSprite = this.iconSprites[k]; + if (iconSprite != null) { + screen.invokeBlitSlotIcon(pGuiGraphics, pX + screen.invokeGetColumnX(k) - 18 + l, pY + 1 + l, this.iconSprites[k]); + } else { + ItemStack itemSprite = this.itemSprites[k]; + if (itemSprite != null) { + pGuiGraphics.renderFakeItem(itemSprite, pX + screen.invokeGetColumnX(k) - 18 + l, pY + 1 + l); + } + } } } @@ -110,24 +133,30 @@ protected boolean clickedHeader(int p_97036_, int p_97037_) { } private StatType getColumn(int pIndex) { - return this.actionColumns.get(pIndex); + return pIndex < this.skillColumns.size() ? this.skillColumns.get(pIndex) : this.actionColumns.get(pIndex - this.skillColumns.size()); } private int getColumnIndex(StatType pStatType) { - return this.actionColumns.indexOf(pStatType); + int i = this.skillColumns.indexOf(pStatType); + if (i >= 0) { + return i; + } else { + int j = this.actionColumns.indexOf(pStatType); + return j >= 0 ? j + this.skillColumns.size() : -1; + } } @Override protected void renderDecorations(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) { if (pMouseY >= this.getY() && pMouseY <= this.getBottom()) { - ActionRow statsscreen$itemstatisticslist$itemrow = this.getHovered(); + SkillRow statsscreen$itemstatisticslist$itemrow = this.getHovered(); int i = (this.width - this.getRowWidth()) / 2; if (statsscreen$itemstatisticslist$itemrow != null) { if (pMouseX < i + 40 || pMouseX > i + 40 + 20) { return; } - IAction item = statsscreen$itemstatisticslist$itemrow.getAction(); + ISkill item = statsscreen$itemstatisticslist$itemrow.getSkill(); pGuiGraphics.renderTooltip(this.font, this.getString(item), pMouseX, pMouseY); } else { Component component = null; @@ -148,7 +177,7 @@ protected void renderDecorations(@NotNull GuiGraphics pGuiGraphics, int pMouseX, } } - protected Component getString(IAction pItem) { + protected Component getString(ISkill pItem) { return pItem.getName(); } @@ -166,43 +195,69 @@ protected void sortByColumn(StatType pStatType) { this.children().sort(this.itemStatSorter); } - public class ActionRow extends ObjectSelectionList.Entry { + public class SkillRow extends ObjectSelectionList.Entry { static final ResourceLocation SLOT_SPRITE = new ResourceLocation("container/slot"); - private final IAction action; + private final ISkill skill; - public ActionRow(IAction action) { - this.action = action; + public SkillRow(ISkill action) { + this.skill = action; } - public IAction getAction() { - return action; + public ISkill getSkill() { + return skill; } @SuppressWarnings("NullableProblems") @Override public Component getNarration() { - return Component.translatable("narrator.select", this.action.getName()); + return Component.translatable("narrator.select", this.skill.getName()); } @Override public void render(GuiGraphics pGuiGraphics, int pIndex, int pTop, int pLeft, int pWidth, int pHeight, int pMouseX, int pMouseY, boolean pHovering, float pPartialTick) { - ResourceLocation id = RegUtil.id(action); - ResourceLocation texture = new ResourceLocation(id.getNamespace(), "textures/actions/" + id.getPath() + ".png"); pGuiGraphics.setColor(1,1,1,1); pGuiGraphics.blitSprite(SLOT_SPRITE,pLeft+40+1, pTop+1 ,0,18,18); - pGuiGraphics.blit(texture, pLeft+40+1+1, pTop+1+1, 0, 0, 0, 16, 16, 16, 16); + renderSkill(pGuiGraphics, pTop, pLeft); - for(int i = 0; i < ActionStatisticsList.this.actionColumns.size(); ++i) { - Stat> stat; - if (this.action instanceof IAction) { - stat = ActionStatisticsList.this.actionColumns.get(i).get(this.action); + for(int i = 0; i < skillColumns.size(); ++i) { + Stat> stat; + if (getSkill() instanceof ISkill) { + stat = skillColumns.get(i).get(this.getSkill()); } else { stat = null; } this.renderStat(pGuiGraphics, stat, pLeft + screen.invokeGetColumnX(i), pTop, pIndex % 2 == 0); } + + for(int j = 0; j < actionColumns.size(); ++j) { + Stat> stat; + if (this.skill instanceof IActionSkill actionSkill) { + StatType> stats = actionColumns.get(j); + IAction action = actionSkill.getAction(); + if (stats != ModStats.ACTION_TIME.get() || action instanceof ILastingAction) { + stat = actionColumns.get(j).get(actionSkill.getAction()); + } else { + stat = null; + } + } else { + stat = null; + } + this.renderStat(pGuiGraphics, stat, pLeft + screen.invokeGetColumnX(j + skillColumns.size()), pTop, pIndex % 2 == 0); + } + } + + public void renderSkill(GuiGraphics pGuiGraphics, int pTop, int pLeft) { + ResourceLocation texture; + if (skill instanceof IActionSkill actionSkill) { + ResourceLocation id = RegUtil.id(actionSkill.getAction()); + texture = new ResourceLocation(id.getNamespace(), "textures/actions/" + id.getPath() + ".png"); + } else { + ResourceLocation id = RegUtil.id(skill); + texture = new ResourceLocation(id.getNamespace(), "textures/skills/" + id.getPath() + ".png"); + } + pGuiGraphics.blit(texture,pLeft+40+1+1, pTop+1+1, 0, 0, 0, 16, 16, 16, 16); } protected void renderStat(GuiGraphics pGuiGraphics, @Nullable Stat pStat, int pX, int pY, boolean pEvenRow) { @@ -211,17 +266,21 @@ protected void renderStat(GuiGraphics pGuiGraphics, @Nullable Stat pStat, int } } - public class ActionRowComparator implements Comparator { - public int compare(ActionRow pRow1, ActionRow pRow2) { - IAction item = pRow1.getAction(); - IAction item1 = pRow2.getAction(); + public class ActionRowComparator implements Comparator { + public int compare(SkillRow pRow1, SkillRow pRow2) { + ISkill item = pRow1.getSkill(); + ISkill item1 = pRow2.getSkill(); int i; int j; if (ActionStatisticsList.this.sortColumn == null) { i = 0; j = 0; - } else { + } else if (actionColumns.contains(sortColumn)) { StatType> stattype1 = (StatType>) ActionStatisticsList.this.sortColumn; + i = item instanceof IActionSkill actionSkill ? screen.getStats().getValue(stattype1, actionSkill.getAction()) : -1; + j = item1 instanceof IActionSkill actionSkill ? screen.getStats().getValue(stattype1, actionSkill.getAction()) : -1; + } else { + StatType> stattype1 = (StatType>) ActionStatisticsList.this.sortColumn; i = screen.getStats().getValue(stattype1, item); j = screen.getStats().getValue(stattype1, item1); } @@ -229,8 +288,8 @@ public int compare(ActionRow pRow1, ActionRow pRow2) { return i == j ? ActionStatisticsList.this.sortOrder * Integer.compare(getId(item), getId(item1)) : ActionStatisticsList.this.sortOrder * Integer.compare(i, j); } - private int getId(IAction action) { - return ModRegistries.ACTIONS.getId(action); + private int getId(ISkill action) { + return ModRegistries.SKILLS.getId(action); } } } diff --git a/src/main/java/de/teamlapen/vampirism/core/ModStats.java b/src/main/java/de/teamlapen/vampirism/core/ModStats.java index 743868f321..611429d22d 100644 --- a/src/main/java/de/teamlapen/vampirism/core/ModStats.java +++ b/src/main/java/de/teamlapen/vampirism/core/ModStats.java @@ -33,38 +33,35 @@ public class ModStats { public static final DeferredHolder, CustomStatType>> ACTION_TIME = STAT_TYPES.register("action_time", () -> new CustomStatType<>(ModRegistries.ACTIONS, Component.translatable("stat_type." + REFERENCE.MODID + ".action_time"), StatFormatter.TIME)); public static final DeferredHolder, CustomStatType>> ACTION_COOLDOWN_TIME = STAT_TYPES.register("action_cooldown", () -> new CustomStatType<>(ModRegistries.ACTIONS, Component.translatable("stat_type." + REFERENCE.MODID + ".action_cooldown_time"), StatFormatter.TIME)); - public static final DeferredHolder weapon_table = add("weapon_table"); - public static final DeferredHolder interact_alchemical_cauldron = add("interact_alchemical_cauldron"); - public static final DeferredHolder interact_with_alchemy_table = add("interact_with_alchemy_table"); - public static final DeferredHolder interact_with_altar_of_infusion = add("interact_with_altar_of_infusion"); - public static final DeferredHolder interact_with_altar_inspiration = add("interact_with_altar_inspiration"); - public static final DeferredHolder interact_with_blood_grinder = add("interact_with_blood_grinder"); - public static final DeferredHolder interact_with_garlic_diffuser = add("interact_with_garlic_diffuser"); - public static final DeferredHolder interact_with_fog_diffuser = add("interact_with_fog_diffuser"); - public static final DeferredHolder interact_with_research_table = add("interact_with_research_table"); - public static final DeferredHolder interact_with_ancient_beacon = add("interact_with_ancient_beacon"); - public static final DeferredHolder interact_with_totem = add("interact_with_totem"); - public static final DeferredHolder interact_with_potion_table = add("interact_with_potion_table"); - public static final DeferredHolder interact_with_injection_chair = add("interact_with_injection_chair"); - public static final DeferredHolder interact_with_coffin = add("interact_with_coffin"); - public static final DeferredHolder interact_with_throne = add("interact_with_throne"); - public static final DeferredHolder capture_village = add("capture_village"); - public static final DeferredHolder defend_village = add("defend_village"); - public static final DeferredHolder win_village_capture = add("win_village_capture"); - public static final DeferredHolder infected_creatures = add("infected_creatures"); - public static final DeferredHolder mother_defeated = add("mother_defeated"); - public static final DeferredHolder killed_with_stake = add("killed_with_stake"); - public static final DeferredHolder resurrected = add("resurrected"); - public static final DeferredHolder actions_used = add("actions_used"); - public static final DeferredHolder skills_unlocked = add("skills_unlocked"); - public static final DeferredHolder skills_reset = add("skills_reset"); - public static final DeferredHolder tasks_accepted = add("tasks_accepted"); - public static final DeferredHolder tasks_completed = add("tasks_completed"); - public static final DeferredHolder blood_drunk = add("blood_drunk", BUCKED_FORMATTER); - public static final DeferredHolder amount_bitten = add("amount_bitten"); - public static final DeferredHolder altar_of_inspiration_rituals_performed = add("altar_of_inspiration_rituals_performed"); - public static final DeferredHolder altar_of_infusion_rituals_performed = add("altar_of_infusion_rituals_performed"); - public static final DeferredHolder items_filled_on_blood_pedestal = add("items_filled_on_blood_pedestal"); + public static final DeferredHolder WEAPON_TABLE = add("weapon_table"); + public static final DeferredHolder INTERACT_ALCHEMICAL_CAULDRON = add("interact_alchemical_cauldron"); + public static final DeferredHolder INTERACT_WITH_ALCHEMY_TABLE = add("interact_with_alchemy_table"); + public static final DeferredHolder INTERACT_WITH_ALTAR_OF_INFUSION = add("interact_with_altar_of_infusion"); + public static final DeferredHolder INTERACT_WITH_ALTAR_INSPIRATION = add("interact_with_altar_inspiration"); + public static final DeferredHolder INTERACT_WITH_BLOOD_GRINDER = add("interact_with_blood_grinder"); + public static final DeferredHolder INTERACT_WITH_GARLIC_DIFFUSER = add("interact_with_garlic_diffuser"); + public static final DeferredHolder INTERACT_WITH_FOG_DIFFUSER = add("interact_with_fog_diffuser"); + public static final DeferredHolder INTERACT_WITH_RESEARCH_TABLE = add("interact_with_research_table"); + public static final DeferredHolder INTERACT_WITH_ANCIENT_BEACON = add("interact_with_ancient_beacon"); + public static final DeferredHolder INTERACT_WITH_TOTEM = add("interact_with_totem"); + public static final DeferredHolder INTERACT_WITH_POTION_TABLE = add("interact_with_potion_table"); + public static final DeferredHolder INTERACT_WITH_INJECTION_CHAIR = add("interact_with_injection_chair"); + public static final DeferredHolder INTERACT_WITH_COFFIN = add("interact_with_coffin"); + public static final DeferredHolder INTERACT_WITH_THRONE = add("interact_with_throne"); + public static final DeferredHolder CAPTURE_VILLAGE = add("capture_village"); + public static final DeferredHolder DEFEND_VILLAGE = add("defend_village"); + public static final DeferredHolder WIN_VILLAGE_CAPTURE = add("win_village_capture"); + public static final DeferredHolder INFECTED_CREATURES = add("infected_creatures"); + public static final DeferredHolder MOTHER_DEFEATED = add("mother_defeated"); + public static final DeferredHolder KILLED_WITH_STAKE = add("killed_with_stake"); + public static final DeferredHolder RESURRECTED = add("resurrected"); + public static final DeferredHolder TASKS_ACCEPTED = add("tasks_accepted"); + public static final DeferredHolder TASKS_COMPLETED = add("tasks_completed"); + public static final DeferredHolder BLOOD_DRUNK = add("blood_drunk", BUCKED_FORMATTER); + public static final DeferredHolder AMOUNT_BITTEN = add("amount_bitten"); + public static final DeferredHolder ALTAR_OF_INSPIRATION_RITUALS_PERFORMED = add("altar_of_inspiration_rituals_performed"); + public static final DeferredHolder ALTAR_OF_INFUSION_RITUALS_PERFORMED = add("altar_of_infusion_rituals_performed"); + public static final DeferredHolder ITEMS_FILLED_ON_BLOOD_PEDESTAL = add("items_filled_on_blood_pedestal"); private static DeferredHolder add(String name) { return add(name, StatFormatter.DEFAULT); @@ -83,27 +80,6 @@ public static void register(IEventBus eventBus) { STAT_TYPES.register(eventBus); } - public static void skillUnlocked(Player player, ISkill skill) { - player.awardStat(SKILL_UNLOCKED.get().get(skill)); - } - - public static void skillForgotten(Player player, ISkill skill) { - player.awardStat(SKILL_FORGOTTEN.get().get(skill)); - } - - public static void updateActionTime(Player player, ILastingAction action) { - player.awardStat(ACTION_TIME.get().get(action)); - } - - public static void updateActionCooldownTime(Player player, IAction action) { - player.awardStat(ACTION_COOLDOWN_TIME.get().get(action)); - } - - public static void actionUsed(Player player, IAction action) { - player.awardStat(actions_used.get()); - player.awardStat(ACTION_USED.get().get(action)); - } - @ApiStatus.Internal public static void registerFormatter() { CUSTOM_STAT_FORMATTERS.forEach(Stats.CUSTOM::get); diff --git a/src/main/java/de/teamlapen/vampirism/core/ModTasks.java b/src/main/java/de/teamlapen/vampirism/core/ModTasks.java index 88a772ae9f..762f8d6868 100644 --- a/src/main/java/de/teamlapen/vampirism/core/ModTasks.java +++ b/src/main/java/de/teamlapen/vampirism/core/ModTasks.java @@ -125,16 +125,16 @@ private static ResourceKey key(String path) { public static void createTasks(BootstapContext context) { context.register(FEEDING_ADAPTER, TaskBuilder.builder(FEEDING_ADAPTER).defaultTitle().unlockedBy(new LvlUnlocker(4)).addRequirement(ModTags.Entities.ADVANCED_HUNTER, 10).addRequirement(new ItemStack(Items.GOLD_INGOT, 5)).setReward(new ItemStack(ModItems.FEEDING_ADAPTER.get())).build()); - context.register(VAMPIRE_LORD_1, TaskBuilder.builder(VAMPIRE_LORD_1).defaultTitle().unlockedBy(new LvlUnlocker(VReference.VAMPIRE_FACTION.getHighestReachableLevel())).addRequirement(ModStats.infected_creatures.get(), 25).addRequirement(new ItemStack(ModItems.PURE_BLOOD_4.get(), 5)).addRequirement(new ItemStack(Items.GOLD_INGOT, 32)).addRequirement(ModStats.win_village_capture.get(), 3).setReward(new LordLevelReward(1, Component.translatable("task.vampirism.vampire_lord1.reward"))).build()); + context.register(VAMPIRE_LORD_1, TaskBuilder.builder(VAMPIRE_LORD_1).defaultTitle().unlockedBy(new LvlUnlocker(VReference.VAMPIRE_FACTION.getHighestReachableLevel())).addRequirement(ModStats.INFECTED_CREATURES.get(), 25).addRequirement(new ItemStack(ModItems.PURE_BLOOD_4.get(), 5)).addRequirement(new ItemStack(Items.GOLD_INGOT, 32)).addRequirement(ModStats.WIN_VILLAGE_CAPTURE.get(), 3).setReward(new LordLevelReward(1, Component.translatable("task.vampirism.vampire_lord1.reward"))).build()); context.register(VAMPIRE_LORD_2, TaskBuilder.builder(VAMPIRE_LORD_2).defaultTitle().unlockedBy(new LordLvlUnlocker(1, true)).addRequirement(ModTags.Entities.HUNTER, 30).addRequirement(new ItemStack(ModItems.PURE_BLOOD_4.get(), 5)).addRequirement(new ItemStack(Items.GOLD_INGOT, 48)).setReward(new LordLevelReward(2)).build()); context.register(VAMPIRE_LORD_3, TaskBuilder.builder(VAMPIRE_LORD_3).defaultTitle().unlockedBy(new LordLvlUnlocker(2, true)).addRequirement(ModTags.Entities.HUNTER, 30).addRequirement(new ItemStack(ModItems.PURE_BLOOD_4.get(), 5)).addRequirement(new ItemStack(Items.GOLD_INGOT, 48)).setReward(new LordLevelReward(3)).build()); context.register(VAMPIRE_LORD_4, TaskBuilder.builder(VAMPIRE_LORD_4).defaultTitle().unlockedBy(new LordLvlUnlocker(3, true)).addRequirement(ModTags.Entities.ADVANCED_HUNTER, 5).addRequirement(new ItemStack(ModItems.PURE_BLOOD_4.get(), 10)).addRequirement(new ItemStack(Items.GOLD_INGOT, 64)).setReward(new LordLevelReward(4)).build()); - context.register(VAMPIRE_LORD_5, TaskBuilder.builder(VAMPIRE_LORD_5).defaultTitle().unlockedBy(new LordLvlUnlocker(4, true)).addRequirement(ModStats.infected_creatures.get(), 50).addRequirement(new ItemStack(ModItems.PURE_BLOOD_4.get(), 20)).addRequirement(new ItemStack(Items.GOLD_INGOT, 64)).addRequirement(ModStats.capture_village.get(), 6).setReward(new LordLevelReward(5)).build()); - context.register(HUNTER_LORD_1, TaskBuilder.builder(HUNTER_LORD_1).defaultTitle().unlockedBy(new LvlUnlocker(VReference.HUNTER_FACTION.getHighestReachableLevel())).addRequirement(ModTags.Entities.VAMPIRE, 50).addRequirement(new ItemStack(Items.GOLD_INGOT, 32)).addRequirement(ModStats.win_village_capture.get(), 3).setReward(new LordLevelReward(1, Component.translatable("task.vampirism.hunter_lord1.reward"))).build()); + context.register(VAMPIRE_LORD_5, TaskBuilder.builder(VAMPIRE_LORD_5).defaultTitle().unlockedBy(new LordLvlUnlocker(4, true)).addRequirement(ModStats.INFECTED_CREATURES.get(), 50).addRequirement(new ItemStack(ModItems.PURE_BLOOD_4.get(), 20)).addRequirement(new ItemStack(Items.GOLD_INGOT, 64)).addRequirement(ModStats.CAPTURE_VILLAGE.get(), 6).setReward(new LordLevelReward(5)).build()); + context.register(HUNTER_LORD_1, TaskBuilder.builder(HUNTER_LORD_1).defaultTitle().unlockedBy(new LvlUnlocker(VReference.HUNTER_FACTION.getHighestReachableLevel())).addRequirement(ModTags.Entities.VAMPIRE, 50).addRequirement(new ItemStack(Items.GOLD_INGOT, 32)).addRequirement(ModStats.WIN_VILLAGE_CAPTURE.get(), 3).setReward(new LordLevelReward(1, Component.translatable("task.vampirism.hunter_lord1.reward"))).build()); context.register(HUNTER_LORD_2, TaskBuilder.builder(HUNTER_LORD_2).defaultTitle().unlockedBy(new LordLvlUnlocker(1, true)).addRequirement(ModTags.Entities.VAMPIRE, 50).addRequirement(new ItemStack(Items.GOLD_INGOT, 32)).setReward(new LordLevelReward(2)).build()); context.register(HUNTER_LORD_3, TaskBuilder.builder(HUNTER_LORD_3).defaultTitle().unlockedBy(new LordLvlUnlocker(2, true)).addRequirement(ModTags.Entities.VAMPIRE, 50).addRequirement(new ItemStack(Items.GOLD_INGOT, 32)).setReward(new LordLevelReward(3)).build()); context.register(HUNTER_LORD_4, TaskBuilder.builder(HUNTER_LORD_4).defaultTitle().unlockedBy(new LordLvlUnlocker(3, true)).addRequirement(ModTags.Entities.VAMPIRE, 75).addRequirement(new ItemStack(Items.GOLD_INGOT, 64)).setReward(new LordLevelReward(4)).build()); - context.register(HUNTER_LORD_5, TaskBuilder.builder(HUNTER_LORD_5).defaultTitle().unlockedBy(new LordLvlUnlocker(4, true)).addRequirement(ModTags.Entities.VAMPIRE, 100).addRequirement(new ItemStack(Items.GOLD_INGOT, 64)).addRequirement(ModStats.capture_village.get(), 6).setReward(new LordLevelReward(5)).build()); + context.register(HUNTER_LORD_5, TaskBuilder.builder(HUNTER_LORD_5).defaultTitle().unlockedBy(new LordLvlUnlocker(4, true)).addRequirement(ModTags.Entities.VAMPIRE, 100).addRequirement(new ItemStack(Items.GOLD_INGOT, 64)).addRequirement(ModStats.CAPTURE_VILLAGE.get(), 6).setReward(new LordLevelReward(5)).build()); context.register(OBLIVION_POTION, TaskBuilder.builder(OBLIVION_POTION).defaultTitle().addRequirement(PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.POISON)).addRequirement(new ItemStack(ModItems.VAMPIRE_BLOOD_BOTTLE.get())).setReward(new ItemStack(ModItems.OBLIVION_POTION.get())).build()); context.register(FIRE_RESISTANCE_1, TaskBuilder.builder(FIRE_RESISTANCE_1).defaultTitle().addRequirement(new ItemStack(Items.MAGMA_CREAM, 3)).addRequirement(ModTags.Entities.HUNTER, 10).setReward(PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotions.VAMPIRE_FIRE_RESISTANCE.get())).build()); context.register(FIRE_RESISTANCE_2, TaskBuilder.builder(FIRE_RESISTANCE_2).defaultTitle().unlockedBy(new LvlUnlocker(7)).addRequirement(new ItemStack(Items.MAGMA_CREAM, 5)).addRequirement(ModTags.Entities.HUNTER, 15).setReward(PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotions.LONG_VAMPIRE_FIRE_RESISTANCE.get())).build()); @@ -146,16 +146,16 @@ public static void createTasks(BootstapContext context) { context.register(HUNTER_MINION_UPGRADE_SIMPLE, TaskBuilder.builder(HUNTER_MINION_UPGRADE_SIMPLE).defaultTitle().unlockedBy(new LordLvlUnlocker(2)).addRequirement(ModTags.Entities.ADVANCED_VAMPIRE, 8).addRequirement(new ItemStack(Items.GOLD_BLOCK, 16)).setReward(new ItemStack(ModItems.HUNTER_MINION_UPGRADE_SIMPLE.get())).build()); context.register(HUNTER_MINION_UPGRADE_ENHANCED, TaskBuilder.builder(HUNTER_MINION_UPGRADE_ENHANCED).defaultTitle().unlockedBy(new LordLvlUnlocker(3)).addRequirement(ModEntities.VAMPIRE_BARON.get(), 10).addRequirement(new ItemStack(ModItems.VAMPIRE_BLOOD_BOTTLE.get(), 16)).addRequirement(new ItemStack(ModItems.VAMPIRE_BOOK.get())).addRequirement(new ItemStack(Items.DIAMOND_BLOCK, 3)).setReward(new ItemStack(ModItems.HUNTER_MINION_UPGRADE_ENHANCED.get())).build()); context.register(HUNTER_MINION_UPGRADE_SPECIAL, TaskBuilder.builder(HUNTER_MINION_UPGRADE_SPECIAL).defaultTitle().unlockedBy(new LordLvlUnlocker(5)).addRequirement(ModEntities.VAMPIRE_BARON.get(), 20).addRequirement(new ItemStack(ModItems.VAMPIRE_BLOOD_BOTTLE.get(), 32)).addRequirement(new ItemStack(ModItems.VAMPIRE_BOOK.get())).addRequirement(new ItemStack(Items.DIAMOND_BLOCK, 8)).setReward(new ItemStack(ModItems.HUNTER_MINION_UPGRADE_SPECIAL.get())).build()); - context.register(V_INFECT_1, TaskBuilder.builder(V_INFECT_1).defaultTitle().addRequirement(ModStats.infected_creatures.get(), 20).setReward(new ItemStack(Items.GOLD_INGOT, 5)).build()); - context.register(V_INFECT_2, TaskBuilder.builder(V_INFECT_2).defaultTitle().addRequirement(ModStats.infected_creatures.get(), 25).setReward(new ItemStack(Items.GOLD_INGOT, 15)).build()); - context.register(V_INFECT_3, TaskBuilder.builder(V_INFECT_3).defaultTitle().addRequirement(ModStats.infected_creatures.get(), 15).setReward(new ItemStack(Items.IRON_INGOT, 5)).build()); - context.register(V_CAPTURE_1, TaskBuilder.builder(V_CAPTURE_1).defaultTitle().addRequirement(ModStats.capture_village.get(), 1).setReward(new ItemStack(Items.EMERALD, 10)).build()); - context.register(V_CAPTURE_2, TaskBuilder.builder(V_CAPTURE_2).defaultTitle().addRequirement(ModStats.capture_village.get(), 1).setReward(new ItemStack(Items.EMERALD, 5)).build()); + context.register(V_INFECT_1, TaskBuilder.builder(V_INFECT_1).defaultTitle().addRequirement(ModStats.INFECTED_CREATURES.get(), 20).setReward(new ItemStack(Items.GOLD_INGOT, 5)).build()); + context.register(V_INFECT_2, TaskBuilder.builder(V_INFECT_2).defaultTitle().addRequirement(ModStats.INFECTED_CREATURES.get(), 25).setReward(new ItemStack(Items.GOLD_INGOT, 15)).build()); + context.register(V_INFECT_3, TaskBuilder.builder(V_INFECT_3).defaultTitle().addRequirement(ModStats.INFECTED_CREATURES.get(), 15).setReward(new ItemStack(Items.IRON_INGOT, 5)).build()); + context.register(V_CAPTURE_1, TaskBuilder.builder(V_CAPTURE_1).defaultTitle().addRequirement(ModStats.CAPTURE_VILLAGE.get(), 1).setReward(new ItemStack(Items.EMERALD, 10)).build()); + context.register(V_CAPTURE_2, TaskBuilder.builder(V_CAPTURE_2).defaultTitle().addRequirement(ModStats.CAPTURE_VILLAGE.get(), 1).setReward(new ItemStack(Items.EMERALD, 5)).build()); context.register(V_KILL_1, TaskBuilder.builder(V_KILL_1).defaultTitle().addRequirement(ModTags.Entities.HUNTER, 10).setReward(new ItemStack(ModItems.HUMAN_HEART.get(), 5)).build()); context.register(V_KILL_2, TaskBuilder.builder(V_KILL_2).defaultTitle().addRequirement(ModTags.Entities.ADVANCED_HUNTER, 4).setReward(new ItemStack(ModItems.HUMAN_HEART.get(), 8)).build()); context.register(H_KILL_1, TaskBuilder.builder(H_KILL_1).defaultTitle().addRequirement(ModTags.Entities.VAMPIRE, 20).setReward(new ItemStack(Items.DIAMOND, 2)).build()); context.register(H_KILL_2, TaskBuilder.builder(H_KILL_2).defaultTitle().addRequirement(ModTags.Entities.VAMPIRE, 15).setReward(new ItemStack(Items.DIAMOND, 2)).build()); - context.register(H_CAPTURE_1, TaskBuilder.builder(H_CAPTURE_1).defaultTitle().addRequirement(ModStats.capture_village.get(), 2).setReward(new ItemStack(ModItems.VAMPIRE_BLOOD_BOTTLE.get(), 10)).build()); + context.register(H_CAPTURE_1, TaskBuilder.builder(H_CAPTURE_1).defaultTitle().addRequirement(ModStats.CAPTURE_VILLAGE.get(), 2).setReward(new ItemStack(ModItems.VAMPIRE_BLOOD_BOTTLE.get(), 10)).build()); context.register(BREAK_BONES_1, TaskBuilder.builder(BREAK_BONES_1).defaultTitle().addRequirement(EntityType.SKELETON, 20).setReward(new ItemStack(Items.CHAINMAIL_CHESTPLATE)).build()); context.register(BREAK_BONES_2, TaskBuilder.builder(BREAK_BONES_2).defaultTitle().addRequirement(EntityType.SKELETON, 14).setReward(new ItemStack(Items.CHAINMAIL_LEGGINGS)).build()); context.register(BREAK_BONES_3, TaskBuilder.builder(BREAK_BONES_3).defaultTitle().addRequirement(EntityType.SKELETON, 10).setReward(new ItemStack(Items.CHAINMAIL_BOOTS)).build()); diff --git a/src/main/java/de/teamlapen/vampirism/effects/OblivionEffect.java b/src/main/java/de/teamlapen/vampirism/effects/OblivionEffect.java index 8921cffdd2..078e7fdcbc 100644 --- a/src/main/java/de/teamlapen/vampirism/effects/OblivionEffect.java +++ b/src/main/java/de/teamlapen/vampirism/effects/OblivionEffect.java @@ -40,7 +40,7 @@ public void fillEffectCures(Set cures, MobEffectInstance effectInsta @Override public void applyEffectTick(@NotNull LivingEntity entityLivingBaseIn, int amplifier) { if (!entityLivingBaseIn.getCommandSenderWorld().isClientSide) { - if (entityLivingBaseIn instanceof Player) { + if (entityLivingBaseIn instanceof Player player) { entityLivingBaseIn.addEffect(new MobEffectInstance(MobEffects.CONFUSION, getTickDuration(amplifier), 5, false, false, false, null, Optional.empty())); FactionPlayerHandler.getOpt(((Player) entityLivingBaseIn)).map(FactionPlayerHandler::getCurrentFactionPlayer).flatMap(factionPlayer -> factionPlayer).ifPresent(factionPlayer -> { ISkillHandler skillHandler = factionPlayer.getSkillHandler(); @@ -49,13 +49,13 @@ public void applyEffectTick(@NotNull LivingEntity entityLivingBaseIn, int amplif for (Holder> element : nodeOPT.get().skills()) { //noinspection unchecked,rawtypes skillHandler.disableSkill((ISkill)element.value()); + player.awardStat(ModStats.SKILL_FORGOTTEN.get().get(element.value())); } } else { entityLivingBaseIn.removeEffect(ModEffects.OBLIVION.get()); ((Player) entityLivingBaseIn).displayClientMessage(Component.translatable("text.vampirism.skill.skills_reset"), true); LOGGER.debug(LogUtil.FACTION, "Skills were reset for {}", entityLivingBaseIn.getName().getString()); VampirismLogger.info(VampirismLogger.SKILLS, "Skills were reset for {}", entityLivingBaseIn.getName().getString()); - ((Player) entityLivingBaseIn).awardStat(ModStats.skills_reset.get()); } }); } diff --git a/src/main/java/de/teamlapen/vampirism/entity/player/TaskManager.java b/src/main/java/de/teamlapen/vampirism/entity/player/TaskManager.java index 86d8828ef4..81a05b2578 100644 --- a/src/main/java/de/teamlapen/vampirism/entity/player/TaskManager.java +++ b/src/main/java/de/teamlapen/vampirism/entity/player/TaskManager.java @@ -84,7 +84,7 @@ public void abortTask(UUID taskBoardId, @NotNull UUID taskInstance, boolean remo @Override public void acceptTask(UUID taskBoardId, @NotNull UUID taskInstance) { - this.player.awardStat(ModStats.tasks_accepted.get()); + this.player.awardStat(ModStats.TASKS_ACCEPTED.get()); ITaskInstance ins = this.taskWrapperMap.get(taskBoardId).acceptTask(taskInstance, this.player.level().getGameTime() + getTaskTimeConfig() * 1200L); this.updateStats(ins); } @@ -138,7 +138,7 @@ public void completeTask(UUID taskBoardId, @NotNull UUID taskInstance) { } this.removeRequirements(ins); this.applyRewards(ins); - this.player.awardStat(ModStats.tasks_completed.get()); + this.player.awardStat(ModStats.TASKS_COMPLETED.get()); } /** diff --git a/src/main/java/de/teamlapen/vampirism/entity/player/actions/ActionHandler.java b/src/main/java/de/teamlapen/vampirism/entity/player/actions/ActionHandler.java index fcb0912e5b..98a315fdbf 100755 --- a/src/main/java/de/teamlapen/vampirism/entity/player/actions/ActionHandler.java +++ b/src/main/java/de/teamlapen/vampirism/entity/player/actions/ActionHandler.java @@ -325,7 +325,7 @@ public IAction.PERM toggleAction(@NotNull IAction action, IAction.ActivationC ActionEvent.ActionActivatedEvent activationEvent = VampirismEventFactory.fireActionActivatedEvent(player, action, action.getCooldown(player), duration); if(activationEvent.isCanceled()) return IAction.PERM.DISALLOWED; if (action.onActivated(player, context)) { - ModStats.actionUsed(player.getRepresentingPlayer(), action); + player.getRepresentingPlayer().awardStat(ModStats.ACTION_USED.get().get(action)); //Even though lasting actions do not activate their cooldown until they deactivate //we probably want to keep this here so that they are edited by one event. int cooldown = activationEvent.getCooldown(); @@ -405,7 +405,7 @@ public boolean updateActions() { for (Iterator> it = cooldownTimers.object2IntEntrySet().iterator(); it.hasNext(); ) { Object2IntMap.Entry entry = it.next(); int value = entry.getIntValue(); - ModStats.updateActionCooldownTime(player.getRepresentingPlayer(), RegUtil.getAction(entry.getKey())); + player.getRepresentingPlayer().awardStat(ModStats.ACTION_COOLDOWN_TIME.get().get(RegUtil.getAction(entry.getKey()))); if (value <= 1) { //<= Just in case we have missed something expectedCooldownTimes.removeInt(entry); it.remove(); @@ -438,7 +438,7 @@ public boolean updateActions() { if (shouldDeactivate) { entry.setValue(1); //Value of means they are deactivated next tick and onUpdate is not called again } else { - ModStats.updateActionTime(player.getRepresentingPlayer(), action); + player.getRepresentingPlayer().awardStat(ModStats.ACTION_TIME.get().get(action)); entry.setValue(newtimer); } } diff --git a/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java b/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java index 867e9dab54..0e15f26678 100755 --- a/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java +++ b/src/main/java/de/teamlapen/vampirism/entity/player/skills/SkillHandler.java @@ -134,23 +134,21 @@ public void disableAllSkills() { public void disableSkill(@NotNull ISkill skill) { if (enabledSkills.remove(skill)) { skill.onDisable(player); - ModStats.skillForgotten(this.player.getRepresentingPlayer(), skill); dirty = true; } - - } @Override - public void enableSkill(@NotNull ISkill skill) { + public void enableSkill(@NotNull ISkill skill, boolean fromLoading) { if (!enabledSkills.contains(skill)) { skill.onEnable(player); enabledSkills.add(skill); + if (!fromLoading) { + this.player.getRepresentingPlayer().awardStat(ModStats.SKILL_UNLOCKED.get().get(skill)); + } dirty = true; - ModStats.skillUnlocked(this.player.getRepresentingPlayer(), skill); //noinspection ConstantValue if (this.player.getRepresentingPlayer() instanceof ServerPlayer serverPlayer && serverPlayer.connection != null) { - serverPlayer.awardStat(ModStats.skills_unlocked.get()); ModAdvancements.TRIGGER_SKILL_UNLOCKED.get().trigger(serverPlayer, skill); } } @@ -183,7 +181,7 @@ public void removeRefinementItem(IRefinementItem.@NotNull AccessorySlotType slot @Override public void updateUnlockedSkillTrees(Collection> skillTrees) { - List> removedTrees = this.unlockedTrees.stream().filter(x -> !skillTrees.contains(x)).collect(Collectors.toList()); + List> removedTrees = this.unlockedTrees.stream().filter(x -> !skillTrees.contains(x)).toList(); removedTrees.forEach(this::lockSkillTree); skillTrees.stream().filter(x -> !this.unlockedTrees.contains(x)).forEach(this::unlockSkillTree); this.dirty = true; @@ -192,7 +190,7 @@ public void updateUnlockedSkillTrees(Collection> skillTrees) private void unlockSkillTree(Holder tree) { this.unlockedTrees.add(tree); SkillTreeConfiguration.SkillTreeNodeConfiguration root = this.treeData.root(tree); - root.elements().forEach(x -> enableSkill((ISkill) x.value())); + root.elements().forEach(x -> enableSkill((ISkill) x.value(), true)); this.dirty = true; } @@ -229,6 +227,7 @@ public void addSkillPoints(int points) { public void reset() { disableAllSkills(); resetRefinements(); + this.unlockedTrees.clear(); this.maxSkillpoints = 0; this.dirty = true; } @@ -291,7 +290,7 @@ public void loadFromNbt(@NotNull CompoundTag nbt) { LOGGER.warn("Skill {} does not exist anymore", id); continue; } - enableSkill(skill); + enableSkill(skill, true); } } @@ -354,7 +353,7 @@ public void readUpdateFromServer(@NotNull CompoundTag nbt) { if (old.contains(skill)) { old.remove(skill); } else { - enableSkill(skill); + enableSkill(skill, true); } diff --git a/src/main/java/de/teamlapen/vampirism/entity/player/vampire/VampirePlayer.java b/src/main/java/de/teamlapen/vampirism/entity/player/vampire/VampirePlayer.java index 15d9707ec7..82208da3e7 100644 --- a/src/main/java/de/teamlapen/vampirism/entity/player/vampire/VampirePlayer.java +++ b/src/main/java/de/teamlapen/vampirism/entity/player/vampire/VampirePlayer.java @@ -233,7 +233,7 @@ public void biteEntity(int entityId) { if (e instanceof LivingEntity) { if (e.distanceTo(player) <= player.getAttribute(NeoForgeMod.BLOCK_REACH.value()).getValue() + 1) { feed_victim_bite_type = determineBiteType((LivingEntity) e); - player.awardStat(ModStats.amount_bitten.get()); + player.awardStat(ModStats.AMOUNT_BITTEN.get()); switch (feed_victim_bite_type) { case HUNTER_CREATURE: player.addEffect(new MobEffectInstance(ModEffects.POISON.get(), 60)); @@ -327,7 +327,7 @@ public void drinkBlood(int amt, float saturationMod, boolean useRemaining, IDrin if (event.useRemaining() && remainingBlood > 0) { handleSpareBlood(remainingBlood); } - this.player.awardStat(ModStats.blood_drunk.get(), amt * VReference.FOOD_TO_FLUID_BLOOD); + this.player.awardStat(ModStats.BLOOD_DRUNK.get(), amt * VReference.FOOD_TO_FLUID_BLOOD); } /** @@ -1014,7 +1014,7 @@ public void tryResurrect() { this.sync(true); int duration = (int) player.getAttributeValue(ModAttributes.NEONATAL_DURATION.get()); this.player.addEffect(new MobEffectInstance(ModEffects.NEONATAL.get(), duration)); - this.player.awardStat(ModStats.resurrected.get()); + this.player.awardStat(ModStats.RESURRECTED.get()); if (this.player instanceof ServerPlayer serverPlayer) { ModAdvancements.TRIGGER_VAMPIRE_ACTION.get().trigger(serverPlayer, VampireActionCriterionTrigger.Action.RESURRECT); } diff --git a/src/main/java/de/teamlapen/vampirism/entity/player/vampire/actions/InfectAction.java b/src/main/java/de/teamlapen/vampirism/entity/player/vampire/actions/InfectAction.java index cc11cc143b..34987729cf 100644 --- a/src/main/java/de/teamlapen/vampirism/entity/player/vampire/actions/InfectAction.java +++ b/src/main/java/de/teamlapen/vampirism/entity/player/vampire/actions/InfectAction.java @@ -43,7 +43,7 @@ protected boolean activate(@NotNull IVampirePlayer vampire, @NotNull ActivationC return deriveBiteableEntry(target).map(e -> e.tryInfect(vampire)).orElse(false); }).orElse(null); if(creature != null ){ - player.awardStat(ModStats.infected_creatures.get()); + player.awardStat(ModStats.INFECTED_CREATURES.get()); player.level().playSound(null, creature.getX(), creature.getY() + 1.5d, creature.getZ(), ModSounds.VAMPIRE_BITE.get(), SoundSource.PLAYERS, 1, 1); } else { player.playNotifySound(SoundEvents.NOTE_BLOCK_BANJO.value(), SoundSource.PLAYERS, 1, 1); diff --git a/src/main/java/de/teamlapen/vampirism/inventory/WeaponTableCraftingSlot.java b/src/main/java/de/teamlapen/vampirism/inventory/WeaponTableCraftingSlot.java index c2bb4f2df3..cd1711f954 100644 --- a/src/main/java/de/teamlapen/vampirism/inventory/WeaponTableCraftingSlot.java +++ b/src/main/java/de/teamlapen/vampirism/inventory/WeaponTableCraftingSlot.java @@ -91,7 +91,7 @@ public void onTake(@NotNull Player playerIn, @NotNull ItemStack stack) { world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), ModSounds.WEAPON_TABLE_CRAFTING.get(), SoundSource.PLAYERS, 1f, 1f); } })); - playerIn.awardStat(ModStats.weapon_table.get()); + playerIn.awardStat(ModStats.WEAPON_TABLE.get()); } @NotNull diff --git a/src/main/java/de/teamlapen/vampirism/items/StakeItem.java b/src/main/java/de/teamlapen/vampirism/items/StakeItem.java index 2cddd54677..b95e1a5321 100644 --- a/src/main/java/de/teamlapen/vampirism/items/StakeItem.java +++ b/src/main/java/de/teamlapen/vampirism/items/StakeItem.java @@ -75,7 +75,7 @@ public boolean hurtEnemy(@NotNull ItemStack stack, @NotNull LivingEntity target, if (canKillInstant(target, attacker)) { DamageHandler.hurtModded(target, sources -> sources.stake(attacker), 10000F); if (attacker instanceof ServerPlayer player) { - player.awardStat(ModStats.killed_with_stake.get()); + player.awardStat(ModStats.KILLED_WITH_STAKE.get()); ModAdvancements.TRIGGER_HUNTER_ACTION.get().trigger(player, HunterActionCriterionTrigger.Action.STAKE); } diff --git a/src/main/resources/assets/vampirism/lang/en_us.json b/src/main/resources/assets/vampirism/lang/en_us.json index ee13ba6d11..95488fb53b 100644 --- a/src/main/resources/assets/vampirism/lang/en_us.json +++ b/src/main/resources/assets/vampirism/lang/en_us.json @@ -1481,5 +1481,7 @@ "__comment": "stat types", "stat_type.vampirism.action_used": "Action Activated", "stat_type.vampirism.action_time": "Action Active", - "stat_type.vampirism.action_cooldown_time": "Action On Cooldown" + "stat_type.vampirism.action_cooldown_time": "Action On Cooldown", + "stat_type.vampirism.skill_unlocked": "Skill Unlocked", + "stat_type.vampirism.skill_forgotten": "Skill Forgotten" } diff --git a/src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_forgotten.png b/src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_forgotten.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0f2e1bb2388bdfac3da748990d9f5e976783ed GIT binary patch literal 839 zcmV-N1GxN&P)Px&0ZBwbR9JdV}3E zlSz`<Omce27qp>XMwlpl`5_|ifdlUPD!eHxHy=L zM;D3VB(&J5ml|gnW%YHD7@w$E1W^>D$n$b#K2}_FM7mM_KNg?WYNVne<3d8eNo485 z(XJGgf+9tQmv-qv+MgOK*I{RDTOm+6>PR#I z{7imX;vJ%n!ACpk|XN^YZ#!$!}L9kzLl6{(-!(?nYiTb=`@RfGpIN+(p2N zxF>fLNHKBkf4N&IE0wd$TJfeL(hYR*qXf(Ol@~G+T>pHD1fW`ZvZW>SwZSEe%m?7s zXmbl*uCDD6iLVN+L-YyBa<}lU6$bKgZ>hTuQ9d*tY_jf^b6)wHlF``WQtd%1Y2jof#i1G zw}R&V4i`_pveZL*zu3%G?e{{Y8<5~pFE!K(e@&w)N%(}iv9E2mLqtA3_zTACYMfUJ Re|i7_002ovPDHLkV1ftqhQa^< literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_forgotten.png.mcmeta b/src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_forgotten.png.mcmeta new file mode 100644 index 0000000000..dbd949bc5e --- /dev/null +++ b/src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_forgotten.png.mcmeta @@ -0,0 +1,10 @@ +{ + "animation": { + "frames": [ + 0, + 1, + 2, + 3 + ] + } +} diff --git a/src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_unlocked.png b/src/main/resources/assets/vampirism/textures/gui/sprites/statistics/skills_unlocked.png new file mode 100644 index 0000000000000000000000000000000000000000..725eaa9cd5b846abcd5c6f317ffc7ec3af3c163e GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh<3?#J|q#XfLJOMr-uK)l4XSQT!u4882!OZ_# z