.
This commit is contained in:
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
bin
|
||||||
@@ -56,6 +56,12 @@ tasks.register('downloadMcLibs') {
|
|||||||
new File(outDir, 'fastutil-8.5.18.jar'))
|
new File(outDir, 'fastutil-8.5.18.jar'))
|
||||||
dl('https://libraries.minecraft.net/com/google/guava/guava/33.6.0-jre/guava-33.6.0-jre.jar',
|
dl('https://libraries.minecraft.net/com/google/guava/guava/33.6.0-jre/guava-33.6.0-jre.jar',
|
||||||
new File(outDir, 'guava-33.6.0-jre.jar'))
|
new File(outDir, 'guava-33.6.0-jre.jar'))
|
||||||
|
// Requis quand le code touche FriendlyByteBuf (codecs de paquets custom) :
|
||||||
|
// javac charge ByteBuf pour lire les annotations de type.
|
||||||
|
dl('https://libraries.minecraft.net/io/netty/netty-buffer/4.2.16.Final/netty-buffer-4.2.16.Final.jar',
|
||||||
|
new File(outDir, 'netty-buffer.jar'))
|
||||||
|
dl('https://libraries.minecraft.net/io/netty/netty-common/4.2.16.Final/netty-common-4.2.16.Final.jar',
|
||||||
|
new File(outDir, 'netty-common.jar'))
|
||||||
dl('https://libraries.minecraft.net/com/google/guava/failureaccess/1.0.3/failureaccess-1.0.3.jar',
|
dl('https://libraries.minecraft.net/com/google/guava/failureaccess/1.0.3/failureaccess-1.0.3.jar',
|
||||||
new File(outDir, 'failureaccess-1.0.3.jar'))
|
new File(outDir, 'failureaccess-1.0.3.jar'))
|
||||||
dl('https://libraries.minecraft.net/com/google/code/gson/gson/2.14.0/gson-2.14.0.jar',
|
dl('https://libraries.minecraft.net/com/google/code/gson/gson/2.14.0/gson-2.14.0.jar',
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public class Pala implements ModInitializer {
|
|||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
fr.surviepote.pala.core.PalaCore.register();
|
fr.surviepote.pala.core.PalaCore.register();
|
||||||
|
fr.surviepote.pala.network.PalaNetwork.register();
|
||||||
PalaRegistries.registerAll();
|
PalaRegistries.registerAll();
|
||||||
fr.surviepote.pala.events.PalaEvents.registerAll();
|
fr.surviepote.pala.events.PalaEvents.registerAll();
|
||||||
LOGGER.info("[SurviePote] Pala initialisé.");
|
LOGGER.info("[SurviePote] Pala initialisé.");
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
package fr.surviepote.pala;
|
package fr.surviepote.pala;
|
||||||
|
|
||||||
|
import fr.surviepote.pala.client.PalaJobsScreen;
|
||||||
|
import fr.surviepote.pala.network.JobsDataPayload;
|
||||||
|
import fr.surviepote.pala.network.JobsRequestPayload;
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderingRegistry;
|
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderingRegistry;
|
||||||
|
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
|
||||||
|
import net.fabricmc.fabric.api.client.screen.v1.Screens;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.Tooltip;
|
||||||
|
import net.minecraft.client.gui.screens.inventory.InventoryScreen;
|
||||||
import net.minecraft.client.renderer.block.FluidModel;
|
import net.minecraft.client.renderer.block.FluidModel;
|
||||||
import net.minecraft.client.resources.model.sprite.Material;
|
import net.minecraft.client.resources.model.sprite.Material;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
|
|
||||||
public class PalaClient implements ClientModInitializer {
|
public class PalaClient implements ClientModInitializer {
|
||||||
@@ -23,5 +33,25 @@ public class PalaClient implements ClientModInitializer {
|
|||||||
fluidModel("sulfuricwater_still", "sulfuricwater_flowing"));
|
fluidModel("sulfuricwater_still", "sulfuricwater_flowing"));
|
||||||
FluidRenderingRegistry.setBlockTransparency(PalaFluids.ANGELIC_WATER_BLOCK, false);
|
FluidRenderingRegistry.setBlockTransparency(PalaFluids.ANGELIC_WATER_BLOCK, false);
|
||||||
FluidRenderingRegistry.setBlockTransparency(PalaFluids.FAKE_WATER_BLOCK, false);
|
FluidRenderingRegistry.setBlockTransparency(PalaFluids.FAKE_WATER_BLOCK, false);
|
||||||
|
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(JobsDataPayload.TYPE,
|
||||||
|
(payload, context) -> context.client().execute(
|
||||||
|
() -> context.client().gui.setScreen(new PalaJobsScreen(payload.payload()))));
|
||||||
|
|
||||||
|
// Bouton "Metiers" a gauche de l'inventaire (progression des 4 metiers).
|
||||||
|
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
|
||||||
|
if (!(screen instanceof InventoryScreen)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int left = (screen.width - 176) / 2;
|
||||||
|
int top = (screen.height - 166) / 2;
|
||||||
|
Button jobs = Button.builder(
|
||||||
|
Component.literal("§6M"),
|
||||||
|
button -> ClientPlayNetworking.send(JobsRequestPayload.INSTANCE))
|
||||||
|
.bounds(left - 24, top + 6, 20, 20)
|
||||||
|
.tooltip(Tooltip.create(Component.literal("§6Métiers §7— progression")))
|
||||||
|
.build();
|
||||||
|
Screens.getWidgets(screen).add(jobs);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import net.minecraft.sounds.SoundSource;
|
|||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.portal.TeleportTransition;
|
import net.minecraft.world.level.portal.TeleportTransition;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
import fr.surviepote.pala.core.PalaConfig;
|
import fr.surviepote.pala.core.PalaConfig;
|
||||||
import fr.surviepote.pala.core.PalaJobs;
|
import fr.surviepote.pala.core.PalaJobs;
|
||||||
@@ -25,8 +26,8 @@ import fr.surviepote.pala.core.PalaStorage;
|
|||||||
|
|
||||||
// Commandes Pala : /end /overworld (permission niveau 4, legacy), /nether (gate metier
|
// Commandes Pala : /end /overworld (permission niveau 4, legacy), /nether (gate metier
|
||||||
// mineur niv.3, M0), /pala reload|info|rank (admin), /jobs (metiers), /craft (table de
|
// mineur niv.3, M0), /pala reload|info|rank (admin), /jobs (metiers), /craft (table de
|
||||||
// craft portable, wiki commandes), /spawn (tp spawn overworld, delai 3 s sans grade, wiki).
|
// craft portable, wiki commandes), /furnace (cuisson directe du stack en main), /spawn (tp spawn overworld,
|
||||||
// Voir CDC §3.8.
|
// delai 3 s sans grade, wiki). Voir CDC §3.8.
|
||||||
// Origine : CommandEnd/Nether/Overworld + procedures *CommandExecuted qui
|
// Origine : CommandEnd/Nether/Overworld + procedures *CommandExecuted qui
|
||||||
// teleportaient le joueur au spawn de la dimension visee. Ici via
|
// teleportaient le joueur au spawn de la dimension visee. Ici via
|
||||||
// TeleportTransition (API 26.x), sans le Teleporter custom du legacy.
|
// TeleportTransition (API 26.x), sans le Teleporter custom du legacy.
|
||||||
@@ -49,6 +50,35 @@ public final class PalaCommands {
|
|||||||
private record TpaTask(java.util.UUID target, long at) {
|
private record TpaTask(java.util.UUID target, long at) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zone / home serialises "dimension:x:y:z". Le separateur ':' est aussi celui de
|
||||||
|
// l'identifiant de dimension (minecraft:overworld) : on decoupe donc a l'envers
|
||||||
|
// (3 derniers segments = coordonnees) au lieu d'un split(":") naif qui produisait
|
||||||
|
// 5 morceaux et faisait echouer /home, /mine, /farm et /f home.
|
||||||
|
private record ZonePos(String dimension, int x, int y, int z) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ZonePos parseZone(String zone) {
|
||||||
|
if (zone == null || zone.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] parts = zone.split(":", 3);
|
||||||
|
if (parts.length != 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] coords = parts[2].split(":");
|
||||||
|
if (coords.length != 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new ZonePos(parts[0] + ":" + parts[1],
|
||||||
|
Integer.parseInt(coords[0]),
|
||||||
|
Integer.parseInt(coords[1]),
|
||||||
|
Integer.parseInt(coords[2]));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private PalaCommands() {
|
private PalaCommands() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +120,8 @@ public final class PalaCommands {
|
|||||||
.executes(command -> jobs(command.getSource())));
|
.executes(command -> jobs(command.getSource())));
|
||||||
dispatcher.register(Commands.literal("craft")
|
dispatcher.register(Commands.literal("craft")
|
||||||
.executes(command -> craft(command.getSource())));
|
.executes(command -> craft(command.getSource())));
|
||||||
|
dispatcher.register(Commands.literal("furnace")
|
||||||
|
.executes(command -> furnace(command.getSource())));
|
||||||
dispatcher.register(Commands.literal("spawn")
|
dispatcher.register(Commands.literal("spawn")
|
||||||
.executes(command -> spawn(command.getSource())));
|
.executes(command -> spawn(command.getSource())));
|
||||||
dispatcher.register(Commands.literal("minage")
|
dispatcher.register(Commands.literal("minage")
|
||||||
@@ -827,15 +859,15 @@ public final class PalaCommands {
|
|||||||
source.sendFailure(Component.literal("§cAucun home defini (/f sethome)."));
|
source.sendFailure(Component.literal("§cAucun home defini (/f sethome)."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
String[] parts = faction.home.split(":");
|
ZonePos home = parseZone(faction.home);
|
||||||
if (parts.length != 4) {
|
if (home == null) {
|
||||||
source.sendFailure(Component.literal("§cHome corrompu."));
|
source.sendFailure(Component.literal("§cHome corrompu."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
net.minecraft.server.MinecraftServer server = source.getServer();
|
net.minecraft.server.MinecraftServer server = source.getServer();
|
||||||
net.minecraft.server.level.ServerLevel target = null;
|
net.minecraft.server.level.ServerLevel target = null;
|
||||||
for (net.minecraft.server.level.ServerLevel level : server.getAllLevels()) {
|
for (net.minecraft.server.level.ServerLevel level : server.getAllLevels()) {
|
||||||
if (level.dimension().identifier().toString().equals(parts[0])) {
|
if (level.dimension().identifier().toString().equals(home.dimension())) {
|
||||||
target = level;
|
target = level;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -844,19 +876,8 @@ public final class PalaCommands {
|
|||||||
source.sendFailure(Component.literal("§cDimension inconnue."));
|
source.sendFailure(Component.literal("§cDimension inconnue."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int z;
|
|
||||||
try {
|
|
||||||
x = Integer.parseInt(parts[1]);
|
|
||||||
y = Integer.parseInt(parts[2]);
|
|
||||||
z = Integer.parseInt(parts[3]);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
source.sendFailure(Component.literal("§cHome corrompu."));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
teleportPlayer(player, target,
|
teleportPlayer(player, target,
|
||||||
new net.minecraft.core.BlockPos(x, y, z));
|
new net.minecraft.core.BlockPos(home.x(), home.y(), home.z()));
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
} catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) {
|
} catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1114,15 +1135,15 @@ public final class PalaCommands {
|
|||||||
"§cZone " + label + " non configuree (admin : config pala.json)."));
|
"§cZone " + label + " non configuree (admin : config pala.json)."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
String[] parts = zone.split(":");
|
ZonePos parsed = parseZone(zone);
|
||||||
if (parts.length != 4) {
|
if (parsed == null) {
|
||||||
source.sendFailure(Component.literal("§cZone " + label + " corrompue."));
|
source.sendFailure(Component.literal("§cZone " + label + " corrompue."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
net.minecraft.server.MinecraftServer server = source.getServer();
|
net.minecraft.server.MinecraftServer server = source.getServer();
|
||||||
net.minecraft.server.level.ServerLevel target = null;
|
net.minecraft.server.level.ServerLevel target = null;
|
||||||
for (net.minecraft.server.level.ServerLevel level : server.getAllLevels()) {
|
for (net.minecraft.server.level.ServerLevel level : server.getAllLevels()) {
|
||||||
if (level.dimension().identifier().toString().equals(parts[0])) {
|
if (level.dimension().identifier().toString().equals(parsed.dimension())) {
|
||||||
target = level;
|
target = level;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1131,19 +1152,8 @@ public final class PalaCommands {
|
|||||||
source.sendFailure(Component.literal("§cDimension inconnue."));
|
source.sendFailure(Component.literal("§cDimension inconnue."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int z;
|
|
||||||
try {
|
|
||||||
x = Integer.parseInt(parts[1]);
|
|
||||||
y = Integer.parseInt(parts[2]);
|
|
||||||
z = Integer.parseInt(parts[3]);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
source.sendFailure(Component.literal("§cZone " + label + " corrompue."));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
teleportPlayer(player, target,
|
teleportPlayer(player, target,
|
||||||
new net.minecraft.core.BlockPos(x, y, z));
|
new net.minecraft.core.BlockPos(parsed.x(), parsed.y(), parsed.z()));
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
} catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) {
|
} catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1394,6 +1404,60 @@ public final class PalaCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /furnace : cuit instantanement l'item (ou le stack) tenu en main, sans GUI.
|
||||||
|
// Vanilla XP de la recette de cuisson + XP metier via PalaJobs.onSmeltTake (meme
|
||||||
|
// comportement qu'une prise de resultat dans un four).
|
||||||
|
private static int furnace(CommandSourceStack source) {
|
||||||
|
try {
|
||||||
|
ServerPlayer player = source.getPlayerOrException();
|
||||||
|
net.minecraft.world.InteractionHand hand = net.minecraft.world.InteractionHand.MAIN_HAND;
|
||||||
|
ItemStack held = player.getMainHandItem();
|
||||||
|
if (held.isEmpty()) {
|
||||||
|
hand = net.minecraft.world.InteractionHand.OFF_HAND;
|
||||||
|
held = player.getOffhandItem();
|
||||||
|
}
|
||||||
|
if (held.isEmpty()) {
|
||||||
|
source.sendFailure(Component.literal("§cAucun item en main."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int count = held.getCount();
|
||||||
|
net.minecraft.world.item.crafting.SingleRecipeInput input =
|
||||||
|
new net.minecraft.world.item.crafting.SingleRecipeInput(held.copyWithCount(1));
|
||||||
|
java.util.Optional<net.minecraft.world.item.crafting.RecipeHolder<
|
||||||
|
net.minecraft.world.item.crafting.SmeltingRecipe>> found =
|
||||||
|
source.getServer().getRecipeManager().getRecipeFor(
|
||||||
|
net.minecraft.world.item.crafting.RecipeType.SMELTING,
|
||||||
|
input, player.level());
|
||||||
|
if (found.isEmpty()) {
|
||||||
|
source.sendFailure(Component.literal(
|
||||||
|
"§cCet item ne peut pas etre cuit : §e" + held.getHoverName().getString()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
net.minecraft.world.item.crafting.SmeltingRecipe recipe = found.get().value();
|
||||||
|
ItemStack result = recipe.assemble(input);
|
||||||
|
ItemStack output = result.copyWithCount(result.getCount() * count);
|
||||||
|
float xp = recipe.experience() * count;
|
||||||
|
player.setItemInHand(hand, ItemStack.EMPTY);
|
||||||
|
player.getInventory().placeItemBackInInventory(output,
|
||||||
|
net.minecraft.util.Prediction.SERVER_ONLY);
|
||||||
|
int points = net.minecraft.util.Mth.floor(xp);
|
||||||
|
if (player.getRandom().nextFloat() < xp - points) {
|
||||||
|
points++;
|
||||||
|
}
|
||||||
|
if (points > 0) {
|
||||||
|
player.giveExperiencePoints(points);
|
||||||
|
}
|
||||||
|
fr.surviepote.pala.core.PalaJobs.onSmeltTake(player, output);
|
||||||
|
final int finalPoints = points;
|
||||||
|
source.sendSuccess(() -> Component.literal("§6[Pala] §7Cuit : §e"
|
||||||
|
+ output.getCount() + " x " + output.getHoverName().getString()
|
||||||
|
+ (finalPoints > 0 ? " §7(+§a" + finalPoints + " XP§7)" : "")), false);
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
|
} catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// /spawn : tp au spawn overworld avec delai wiki 3 s (60 ticks). Pas d'annulation sur
|
// /spawn : tp au spawn overworld avec delai wiki 3 s (60 ticks). Pas d'annulation sur
|
||||||
// mouvement cote wiki (teleportation simple apres delai).
|
// mouvement cote wiki (teleportation simple apres delai).
|
||||||
private static int spawn(CommandSourceStack source) {
|
private static int spawn(CommandSourceStack source) {
|
||||||
|
|||||||
@@ -204,10 +204,6 @@ public final class PalaTabs {
|
|||||||
output.accept(PalaBlocks.CAULDRON_TANK_SUPPORT);
|
output.accept(PalaBlocks.CAULDRON_TANK_SUPPORT);
|
||||||
output.accept(PalaBlocks.MYSTICAL_BOOKSHELF);
|
output.accept(PalaBlocks.MYSTICAL_BOOKSHELF);
|
||||||
output.accept(PalaBlocks.SLEEPING_BAG);
|
output.accept(PalaBlocks.SLEEPING_BAG);
|
||||||
output.accept(PalaBlocks.FIKUTSI_STAGE0);
|
|
||||||
output.accept(PalaBlocks.FIKUTSI_STAGE1);
|
|
||||||
output.accept(PalaBlocks.FIKUTSI_STAGE2);
|
|
||||||
output.accept(PalaBlocks.FIKUTSI_STAGE3);
|
|
||||||
output.accept(PalaBlocks.FINDIUM_ORE);
|
output.accept(PalaBlocks.FINDIUM_ORE);
|
||||||
output.accept(PalaBlocks.FINDIUM_ORE_BLOCK);
|
output.accept(PalaBlocks.FINDIUM_ORE_BLOCK);
|
||||||
output.accept(PalaBlocks.PALAFORGE);
|
output.accept(PalaBlocks.PALAFORGE);
|
||||||
@@ -216,20 +212,6 @@ public final class PalaTabs {
|
|||||||
output.accept(PalaBlocks.GRINDER_FRAME);
|
output.accept(PalaBlocks.GRINDER_FRAME);
|
||||||
output.accept(PalaBlocks.KISAKAY_ORE);
|
output.accept(PalaBlocks.KISAKAY_ORE);
|
||||||
output.accept(PalaBlocks.KISAKAY_ORE_BLOCK);
|
output.accept(PalaBlocks.KISAKAY_ORE_BLOCK);
|
||||||
output.accept(PalaBlocks.KIWANO_STAGE0);
|
|
||||||
output.accept(PalaBlocks.KIWANO_STAGE1);
|
|
||||||
output.accept(PalaBlocks.KIWANO_STAGE2);
|
|
||||||
output.accept(PalaBlocks.KIWANO_STAGE3);
|
|
||||||
output.accept(PalaBlocks.KIWANO_STAGE4);
|
|
||||||
output.accept(PalaBlocks.OKAMI_STAGE0);
|
|
||||||
output.accept(PalaBlocks.OKAMI_STAGE1);
|
|
||||||
output.accept(PalaBlocks.OKAMI_STAGE2);
|
|
||||||
output.accept(PalaBlocks.OKAMI_STAGE3);
|
|
||||||
output.accept(PalaBlocks.ORANGE_BLUE_STAGE0);
|
|
||||||
output.accept(PalaBlocks.ORANGE_BLUE_STAGE1);
|
|
||||||
output.accept(PalaBlocks.ORANGE_BLUE_STAGE2);
|
|
||||||
output.accept(PalaBlocks.ORANGE_BLUE_STAGE3);
|
|
||||||
output.accept(PalaBlocks.ORANGE_BLUE_STAGE4);
|
|
||||||
output.accept(PalaBlocks.PALADIUM_CRUSHER);
|
output.accept(PalaBlocks.PALADIUM_CRUSHER);
|
||||||
output.accept(PalaBlocks.PALADIUM_FURNACE);
|
output.accept(PalaBlocks.PALADIUM_FURNACE);
|
||||||
output.accept(PalaBlocks.PALADIUM_ORE);
|
output.accept(PalaBlocks.PALADIUM_ORE);
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package fr.surviepote.pala.client;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
||||||
|
// Ecran de progression des 4 metiers, ouvert par le bouton de l'inventaire.
|
||||||
|
// Donnees recues du serveur via JobsDataPayload.
|
||||||
|
public class PalaJobsScreen extends Screen {
|
||||||
|
|
||||||
|
private record JobEntry(String key, int level, long xp, long previous, long next) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<JobEntry> jobs = new ArrayList<>();
|
||||||
|
private int panelX;
|
||||||
|
private int panelY;
|
||||||
|
private int panelWidth = 280;
|
||||||
|
private int panelHeight;
|
||||||
|
|
||||||
|
public PalaJobsScreen(String payload) {
|
||||||
|
super(Component.translatable("screen.pala.jobs"));
|
||||||
|
if (payload != null) {
|
||||||
|
for (String line : payload.split("\n")) {
|
||||||
|
String[] parts = line.split("\\|");
|
||||||
|
if (parts.length != 5) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jobs.add(new JobEntry(parts[0], Integer.parseInt(parts[1]),
|
||||||
|
Long.parseLong(parts[2]), Long.parseLong(parts[3]),
|
||||||
|
Long.parseLong(parts[4])));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
// Ligne invalide : ignoree (payload tolerant).
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
panelHeight = 44 + jobs.size() * 38 + 30;
|
||||||
|
panelX = (width - panelWidth) / 2;
|
||||||
|
panelY = (height - panelHeight) / 2;
|
||||||
|
addRenderableWidget(Button.builder(Component.literal("Fermer"), b -> onClose())
|
||||||
|
.bounds(panelX + panelWidth / 2 - 60, panelY + panelHeight - 26, 120, 20)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void extractBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY,
|
||||||
|
float partialTick) {
|
||||||
|
super.extractBackground(graphics, mouseX, mouseY, partialTick);
|
||||||
|
graphics.fill(0, 0, width, height, 0x99000000);
|
||||||
|
graphics.fill(panelX, panelY, panelX + panelWidth, panelY + panelHeight, 0xF0181818);
|
||||||
|
graphics.fill(panelX, panelY, panelX + panelWidth, panelY + 2, 0xFFFFAA00);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY,
|
||||||
|
float partialTick) {
|
||||||
|
super.extractRenderState(graphics, mouseX, mouseY, partialTick);
|
||||||
|
graphics.centeredText(font, Component.literal("§6Métiers"), panelX + panelWidth / 2,
|
||||||
|
panelY + 12, 0xFFFFAA00);
|
||||||
|
int y = panelY + 32;
|
||||||
|
if (jobs.isEmpty()) {
|
||||||
|
graphics.text(font, Component.literal("§7Aucune donnée de métier reçue."),
|
||||||
|
panelX + 16, y, 0xFFAAAAAA);
|
||||||
|
}
|
||||||
|
for (JobEntry job : jobs) {
|
||||||
|
graphics.text(font, Component.literal(displayName(job.key()) + " §7— niveau §a"
|
||||||
|
+ job.level()), panelX + 16, y, 0xFFFFFFFF);
|
||||||
|
String xpLine;
|
||||||
|
if (job.next() <= 0) {
|
||||||
|
xpLine = "§7Niveau maximum";
|
||||||
|
} else {
|
||||||
|
xpLine = "§7" + job.xp() + " / " + job.next() + " XP";
|
||||||
|
}
|
||||||
|
graphics.text(font, Component.literal(xpLine), panelX + 16, y + 12, 0xFFAAAAAA);
|
||||||
|
drawBar(graphics, panelX + 150, y + 3, 112, 8, job);
|
||||||
|
y += 38;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawBar(GuiGraphicsExtractor graphics, int x, int y, int w, int h,
|
||||||
|
JobEntry job) {
|
||||||
|
graphics.fill(x, y, x + w, y + h, 0xFF333333);
|
||||||
|
long next = job.next();
|
||||||
|
if (next <= 0) {
|
||||||
|
graphics.fill(x, y, x + w, y + h, 0xFF55FF55);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long previous = job.previous();
|
||||||
|
long span = Math.max(1L, next - previous);
|
||||||
|
long done = Math.max(0L, job.xp() - previous);
|
||||||
|
int filled = (int) Math.min(w, (done * w) / span);
|
||||||
|
graphics.fill(x, y, x + filled, y + h, 0xFF55FF55);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String displayName(String key) {
|
||||||
|
return switch (key) {
|
||||||
|
case "mineur" -> "Mineur";
|
||||||
|
case "fermier" -> "Fermier";
|
||||||
|
case "chasseur" -> "Chasseur";
|
||||||
|
case "alchimiste" -> "Alchimiste";
|
||||||
|
default -> key;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPauseScreen() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,48 +30,54 @@ public final class PalaConfig {
|
|||||||
// Cles = ids de registres (vanilla ou pala:). Map.ofEntries : Map.of limite a 10 paires.
|
// Cles = ids de registres (vanilla ou pala:). Map.ofEntries : Map.of limite a 10 paires.
|
||||||
public Map<String, Double> minerXp = new HashMap<>(Map.ofEntries(
|
public Map<String, Double> minerXp = new HashMap<>(Map.ofEntries(
|
||||||
Map.entry("minecraft:stone", 0.5),
|
Map.entry("minecraft:stone", 0.5),
|
||||||
|
Map.entry("minecraft:cobblestone", 0.5), Map.entry("minecraft:deepslate", 0.5),
|
||||||
|
Map.entry("minecraft:tuff", 0.5),
|
||||||
Map.entry("minecraft:diorite", 3.0), Map.entry("minecraft:andesite", 3.0),
|
Map.entry("minecraft:diorite", 3.0), Map.entry("minecraft:andesite", 3.0),
|
||||||
Map.entry("minecraft:coal_ore", 4.0), Map.entry("minecraft:deepslate_coal_ore", 4.0),
|
Map.entry("minecraft:coal_ore", 4.0), Map.entry("minecraft:deepslate_coal_ore", 4.0),
|
||||||
Map.entry("minecraft:quartz_ore", 6.0), Map.entry("minecraft:obsidian", 6.0),
|
Map.entry("minecraft:nether_quartz_ore", 6.0), Map.entry("minecraft:obsidian", 6.0),
|
||||||
Map.entry("minecraft:lapis_ore", 15.0), Map.entry("minecraft:redstone_ore", 15.0),
|
Map.entry("minecraft:lapis_ore", 15.0), Map.entry("minecraft:deepslate_lapis_ore", 15.0),
|
||||||
|
Map.entry("minecraft:redstone_ore", 15.0),
|
||||||
|
Map.entry("minecraft:deepslate_redstone_ore", 15.0),
|
||||||
Map.entry("minecraft:emerald_ore", 50.0),
|
Map.entry("minecraft:emerald_ore", 50.0),
|
||||||
|
Map.entry("minecraft:deepslate_emerald_ore", 50.0),
|
||||||
Map.entry("minecraft:iron_ore", 2.0), Map.entry("minecraft:deepslate_iron_ore", 2.0),
|
Map.entry("minecraft:iron_ore", 2.0), Map.entry("minecraft:deepslate_iron_ore", 2.0),
|
||||||
Map.entry("minecraft:gold_ore", 4.0), Map.entry("minecraft:deepslate_gold_ore", 4.0),
|
Map.entry("minecraft:gold_ore", 4.0), Map.entry("minecraft:deepslate_gold_ore", 4.0),
|
||||||
|
Map.entry("minecraft:nether_gold_ore", 4.0),
|
||||||
Map.entry("minecraft:diamond_ore", 8.0), Map.entry("minecraft:deepslate_diamond_ore", 8.0),
|
Map.entry("minecraft:diamond_ore", 8.0), Map.entry("minecraft:deepslate_diamond_ore", 8.0),
|
||||||
Map.entry("pala:amethyst_ore", 12.0), Map.entry("pala:titane_ore", 16.0),
|
Map.entry("pala:amethyst_ore", 12.0), Map.entry("pala:titane_ore", 16.0),
|
||||||
Map.entry("pala:paladium_ore", 20.0),
|
Map.entry("pala:paladium_ore", 20.0),
|
||||||
Map.entry("pala:paladium_green_ore", 20.0), Map.entry("pala:trixium_ore", 10.0),
|
Map.entry("pala:paladium_green_ore", 20.0), Map.entry("pala:trixium_ore", 10.0),
|
||||||
Map.entry("pala:findium_ore", 10.0)));
|
Map.entry("pala:findium_ore", 10.0)));
|
||||||
|
|
||||||
// M-mineur-xp (wiki Evolution mineur, VERIFIE) : niveaux requis par bloc.
|
// M-mineur-xp : niveaux requis par bloc. Les blocs de base sont accessibles des le
|
||||||
// Niv.1 : roche/diorite/charbon/quartz/obsidienne/lapis/redstone/emeraude ;
|
// niveau 0 (sinon un nouveau joueur ne peut jamais gagner son premier XP mineur) ;
|
||||||
// niv.5 : fer/or/diamant/amethyste/titane (+ minerais pala par interpretation
|
// les minerais de fer/or/diamant/pala restent verrouilles au niveau 5 (wiki).
|
||||||
// "Particules paladium 20@5", ECART documente).
|
|
||||||
public Map<String, Integer> minerLevels = new HashMap<>(Map.ofEntries(
|
public Map<String, Integer> minerLevels = new HashMap<>(Map.ofEntries(
|
||||||
Map.entry("minecraft:stone", 1),
|
Map.entry("minecraft:stone", 0),
|
||||||
Map.entry("minecraft:diorite", 1), Map.entry("minecraft:andesite", 1),
|
Map.entry("minecraft:cobblestone", 0), Map.entry("minecraft:deepslate", 0),
|
||||||
Map.entry("minecraft:coal_ore", 1), Map.entry("minecraft:deepslate_coal_ore", 1),
|
Map.entry("minecraft:tuff", 0),
|
||||||
Map.entry("minecraft:quartz_ore", 1), Map.entry("minecraft:obsidian", 1),
|
Map.entry("minecraft:diorite", 0), Map.entry("minecraft:andesite", 0),
|
||||||
Map.entry("minecraft:lapis_ore", 1), Map.entry("minecraft:redstone_ore", 1),
|
Map.entry("minecraft:coal_ore", 0), Map.entry("minecraft:deepslate_coal_ore", 0),
|
||||||
Map.entry("minecraft:emerald_ore", 1), Map.entry("minecraft:deepslate_emerald_ore", 1),
|
Map.entry("minecraft:nether_quartz_ore", 0), Map.entry("minecraft:obsidian", 0),
|
||||||
|
Map.entry("minecraft:lapis_ore", 0), Map.entry("minecraft:deepslate_lapis_ore", 0),
|
||||||
|
Map.entry("minecraft:redstone_ore", 0),
|
||||||
|
Map.entry("minecraft:deepslate_redstone_ore", 0),
|
||||||
|
Map.entry("minecraft:emerald_ore", 0), Map.entry("minecraft:deepslate_emerald_ore", 0),
|
||||||
Map.entry("minecraft:iron_ore", 5), Map.entry("minecraft:deepslate_iron_ore", 5),
|
Map.entry("minecraft:iron_ore", 5), Map.entry("minecraft:deepslate_iron_ore", 5),
|
||||||
Map.entry("minecraft:gold_ore", 5), Map.entry("minecraft:deepslate_gold_ore", 5),
|
Map.entry("minecraft:gold_ore", 5), Map.entry("minecraft:deepslate_gold_ore", 5),
|
||||||
|
Map.entry("minecraft:nether_gold_ore", 5),
|
||||||
Map.entry("minecraft:diamond_ore", 5), Map.entry("minecraft:deepslate_diamond_ore", 5),
|
Map.entry("minecraft:diamond_ore", 5), Map.entry("minecraft:deepslate_diamond_ore", 5),
|
||||||
Map.entry("pala:amethyst_ore", 5), Map.entry("pala:titane_ore", 5),
|
Map.entry("pala:amethyst_ore", 5), Map.entry("pala:titane_ore", 5),
|
||||||
Map.entry("pala:paladium_ore", 5), Map.entry("pala:paladium_green_ore", 5),
|
Map.entry("pala:paladium_ore", 5), Map.entry("pala:paladium_green_ore", 5),
|
||||||
Map.entry("pala:trixium_ore", 5), Map.entry("pala:findium_ore", 5)));
|
Map.entry("pala:trixium_ore", 5), Map.entry("pala:findium_ore", 5)));
|
||||||
// Courbe XP (M-xpcurve) : seuils wiki VERIFIES 2-20, formule au-dela. La table mineur
|
// Courbe XP : formule par defaut xp(n) = xpBase * n^xpExponent. Les anciens seuils
|
||||||
// s'applique aux 4 metiers (seule table publiee ; ECART documente).
|
// wiki (22 123 XP pour le niveau 2) rendaient les premiers niveaux inatteignables en
|
||||||
|
// jeu normal ; ils sont remplaces par une courbe progressive. Surcharge possible via
|
||||||
|
// levelThresholds dans pala.json (niveau -> XP total cumule).
|
||||||
|
public int configVersion = 3;
|
||||||
public double xpBase = 100.0;
|
public double xpBase = 100.0;
|
||||||
public double xpExponent = 1.5;
|
public double xpExponent = 1.5;
|
||||||
public Map<Integer, Long> levelThresholds = new HashMap<>(Map.ofEntries(
|
public Map<Integer, Long> levelThresholds = new HashMap<>();
|
||||||
Map.entry(2, 22123L), Map.entry(3, 40390L), Map.entry(4, 73751L),
|
|
||||||
Map.entry(5, 118886L), Map.entry(6, 176611L), Map.entry(7, 247616L),
|
|
||||||
Map.entry(8, 332507L), Map.entry(9, 431826L), Map.entry(10, 546062L),
|
|
||||||
Map.entry(11, 675669L), Map.entry(12, 821062L), Map.entry(13, 982632L),
|
|
||||||
Map.entry(14, 1160743L), Map.entry(15, 1355741L), Map.entry(16, 1567953L),
|
|
||||||
Map.entry(17, 1797690L), Map.entry(18, 2045248L), Map.entry(19, 2310912L),
|
|
||||||
Map.entry(20, 2594953L)));
|
|
||||||
|
|
||||||
// Niveau mineur requis pour /nether (wiki recompenses mineur niv.3, VERIFIE).
|
// Niveau mineur requis pour /nether (wiki recompenses mineur niv.3, VERIFIE).
|
||||||
public int netherMinerLevel = 3;
|
public int netherMinerLevel = 3;
|
||||||
@@ -118,6 +124,8 @@ public final class PalaConfig {
|
|||||||
// M5a (wiki VERIFIE) : chasseur = entite -> [xp, niveau requis].
|
// M5a (wiki VERIFIE) : chasseur = entite -> [xp, niveau requis].
|
||||||
// Passifs 14@0, poulpe 10@0 (page : "des le niveau 0/1"), creeper 40, wither 1000.
|
// Passifs 14@0, poulpe 10@0 (page : "des le niveau 0/1"), creeper 40, wither 1000.
|
||||||
// Moddees (chevre 20@1, escargot 25@2...) : mobs absents du portage => non listees (M8/donjons).
|
// Moddees (chevre 20@1, escargot 25@2...) : mobs absents du portage => non listees (M8/donjons).
|
||||||
|
// SurviePote : hostiles vanilla ajoutes (zombie/squelette/araignee/etc.) car la table
|
||||||
|
// wiki ne couvrait que les passifs + creeper, donc tuer des monstres ne donnait rien.
|
||||||
public Map<String, double[]> hunterKills = new HashMap<>(Map.ofEntries(
|
public Map<String, double[]> hunterKills = new HashMap<>(Map.ofEntries(
|
||||||
Map.entry("minecraft:cow", new double[]{14, 0}),
|
Map.entry("minecraft:cow", new double[]{14, 0}),
|
||||||
Map.entry("minecraft:sheep", new double[]{14, 0}),
|
Map.entry("minecraft:sheep", new double[]{14, 0}),
|
||||||
@@ -125,10 +133,60 @@ public final class PalaConfig {
|
|||||||
Map.entry("minecraft:chicken", new double[]{14, 0}),
|
Map.entry("minecraft:chicken", new double[]{14, 0}),
|
||||||
Map.entry("minecraft:rabbit", new double[]{14, 0}),
|
Map.entry("minecraft:rabbit", new double[]{14, 0}),
|
||||||
Map.entry("minecraft:horse", new double[]{14, 0}),
|
Map.entry("minecraft:horse", new double[]{14, 0}),
|
||||||
|
Map.entry("minecraft:mooshroom", new double[]{14, 0}),
|
||||||
|
Map.entry("minecraft:wolf", new double[]{14, 0}),
|
||||||
|
Map.entry("minecraft:fox", new double[]{14, 0}),
|
||||||
|
Map.entry("minecraft:cat", new double[]{10, 0}),
|
||||||
|
Map.entry("minecraft:llama", new double[]{14, 0}),
|
||||||
|
Map.entry("minecraft:trader_llama", new double[]{14, 0}),
|
||||||
|
Map.entry("minecraft:camel", new double[]{14, 0}),
|
||||||
Map.entry("minecraft:squid", new double[]{10, 0}),
|
Map.entry("minecraft:squid", new double[]{10, 0}),
|
||||||
Map.entry("minecraft:glow_squid", new double[]{10, 0}),
|
Map.entry("minecraft:glow_squid", new double[]{10, 0}),
|
||||||
|
Map.entry("minecraft:bat", new double[]{5, 0}),
|
||||||
|
Map.entry("minecraft:bee", new double[]{10, 0}),
|
||||||
|
Map.entry("minecraft:frog", new double[]{10, 0}),
|
||||||
|
Map.entry("minecraft:axolotl", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:armadillo", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:sniffer", new double[]{30, 0}),
|
||||||
|
Map.entry("minecraft:allay", new double[]{20, 0}),
|
||||||
|
Map.entry("minecraft:polar_bear", new double[]{25, 0}),
|
||||||
Map.entry("minecraft:creeper", new double[]{40, 0}),
|
Map.entry("minecraft:creeper", new double[]{40, 0}),
|
||||||
|
Map.entry("minecraft:zombie", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:husk", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:drowned", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:skeleton", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:stray", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:bogged", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:spider", new double[]{12, 0}),
|
||||||
|
Map.entry("minecraft:cave_spider", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:silverfish", new double[]{5, 0}),
|
||||||
|
Map.entry("minecraft:endermite", new double[]{8, 0}),
|
||||||
|
Map.entry("minecraft:slime", new double[]{10, 0}),
|
||||||
|
Map.entry("minecraft:magma_cube", new double[]{20, 0}),
|
||||||
|
Map.entry("minecraft:enderman", new double[]{30, 0}),
|
||||||
|
Map.entry("minecraft:witch", new double[]{25, 0}),
|
||||||
|
Map.entry("minecraft:blaze", new double[]{30, 0}),
|
||||||
|
Map.entry("minecraft:ghast", new double[]{50, 0}),
|
||||||
|
Map.entry("minecraft:guardian", new double[]{20, 0}),
|
||||||
|
Map.entry("minecraft:elder_guardian", new double[]{100, 0}),
|
||||||
|
Map.entry("minecraft:shulker", new double[]{40, 0}),
|
||||||
|
Map.entry("minecraft:phantom", new double[]{20, 0}),
|
||||||
|
Map.entry("minecraft:pillager", new double[]{20, 0}),
|
||||||
|
Map.entry("minecraft:vindicator", new double[]{25, 0}),
|
||||||
|
Map.entry("minecraft:evoker", new double[]{50, 0}),
|
||||||
|
Map.entry("minecraft:illusioner", new double[]{50, 0}),
|
||||||
|
Map.entry("minecraft:ravager", new double[]{80, 0}),
|
||||||
|
Map.entry("minecraft:vex", new double[]{20, 0}),
|
||||||
|
Map.entry("minecraft:hoglin", new double[]{30, 0}),
|
||||||
|
Map.entry("minecraft:zoglin", new double[]{30, 0}),
|
||||||
|
Map.entry("minecraft:piglin", new double[]{20, 0}),
|
||||||
|
Map.entry("minecraft:piglin_brute", new double[]{30, 0}),
|
||||||
|
Map.entry("minecraft:zombified_piglin", new double[]{15, 0}),
|
||||||
|
Map.entry("minecraft:wither_skeleton", new double[]{40, 0}),
|
||||||
|
Map.entry("minecraft:breeze", new double[]{30, 0}),
|
||||||
|
Map.entry("minecraft:warden", new double[]{200, 0}),
|
||||||
Map.entry("minecraft:wither", new double[]{1000, 0}),
|
Map.entry("minecraft:wither", new double[]{1000, 0}),
|
||||||
|
Map.entry("minecraft:ender_dragon", new double[]{5000, 0}),
|
||||||
// M-hunter-3 (wiki evolution chasseur, VERIFIE) : passifs vanilla
|
// M-hunter-3 (wiki evolution chasseur, VERIFIE) : passifs vanilla
|
||||||
// supplementaires (creatures moddees escargot/crabe/serpent/meduse/
|
// supplementaires (creatures moddees escargot/crabe/serpent/meduse/
|
||||||
// elephant SKIP M8, absentes ; peche "tres variable" + QTE SKIP).
|
// elephant SKIP M8, absentes ; peche "tres variable" + QTE SKIP).
|
||||||
@@ -156,10 +214,14 @@ public final class PalaConfig {
|
|||||||
"pala:egg_plant_fruit", new double[]{3, 8},
|
"pala:egg_plant_fruit", new double[]{3, 8},
|
||||||
"pala:okami_fruit", new double[]{4.5, 12},
|
"pala:okami_fruit", new double[]{4.5, 12},
|
||||||
"pala:kiwano", new double[]{6, 16}));
|
"pala:kiwano", new double[]{6, 16}));
|
||||||
// M-alchi-1 (wiki Evolution alchimiste VERIFIE) : XP au craft = item -> [xp, niveau].
|
// M-alchi-1 : XP au craft = item -> [xp, niveau]. La fiole est accessible des le
|
||||||
// Fiole 0.2@1. Extracteur/lightning/glueballs/portails : items/crafts en M-alchi-2+.
|
// niveau 0 (source d'entree) ; valeur remontee de 0.2 (wiki) a 1.0 pour que le
|
||||||
|
// craft de fioles reste une alternative viable au brassage.
|
||||||
public Map<String, double[]> alchemistCraft = new HashMap<>(Map.of(
|
public Map<String, double[]> alchemistCraft = new HashMap<>(Map.of(
|
||||||
"pala:flask", new double[]{0.2, 1}));
|
"pala:flask", new double[]{1.0, 0}));
|
||||||
|
// SurviePote : XP alchimiste par potion reellement brassee et recuperee du
|
||||||
|
// chaudron (mixin BrewingStand). Source principale pour demarrer le metier.
|
||||||
|
public double alchemistBrewXp = 10.0;
|
||||||
// M4a : recettes machines data-driven (CDC §3.4). Cles = ids de registres.
|
// M4a : recettes machines data-driven (CDC §3.4). Cles = ids de registres.
|
||||||
// Defauts = legacy+wiki VERIFIES (M3). Rechargeables via /pala reload.
|
// Defauts = legacy+wiki VERIFIES (M3). Rechargeables via /pala reload.
|
||||||
public Map<String, String> crusherResults = new HashMap<>(Map.of(
|
public Map<String, String> crusherResults = new HashMap<>(Map.of(
|
||||||
@@ -224,6 +286,7 @@ public final class PalaConfig {
|
|||||||
try (Reader reader = Files.newBufferedReader(path)) {
|
try (Reader reader = Files.newBufferedReader(path)) {
|
||||||
PalaConfig loaded = GSON.fromJson(reader, PalaConfig.class);
|
PalaConfig loaded = GSON.fromJson(reader, PalaConfig.class);
|
||||||
if (loaded != null) {
|
if (loaded != null) {
|
||||||
|
boolean migrateBalance = loaded.configVersion < 3;
|
||||||
if (loaded.minerXp != null && !loaded.minerXp.isEmpty()) {
|
if (loaded.minerXp != null && !loaded.minerXp.isEmpty()) {
|
||||||
instance.minerXp = loaded.minerXp;
|
instance.minerXp = loaded.minerXp;
|
||||||
}
|
}
|
||||||
@@ -236,6 +299,12 @@ public final class PalaConfig {
|
|||||||
if (loaded.xpExponent > 0) {
|
if (loaded.xpExponent > 0) {
|
||||||
instance.xpExponent = loaded.xpExponent;
|
instance.xpExponent = loaded.xpExponent;
|
||||||
}
|
}
|
||||||
|
if (loaded.levelThresholds != null) {
|
||||||
|
instance.levelThresholds = loaded.levelThresholds;
|
||||||
|
}
|
||||||
|
if (loaded.alchemistBrewXp > 0) {
|
||||||
|
instance.alchemistBrewXp = loaded.alchemistBrewXp;
|
||||||
|
}
|
||||||
if (loaded.netherMinerLevel >= 0) {
|
if (loaded.netherMinerLevel >= 0) {
|
||||||
instance.netherMinerLevel = loaded.netherMinerLevel;
|
instance.netherMinerLevel = loaded.netherMinerLevel;
|
||||||
}
|
}
|
||||||
@@ -256,6 +325,16 @@ public final class PalaConfig {
|
|||||||
instance.farmerHarvest = loaded.farmerHarvest;
|
instance.farmerHarvest = loaded.farmerHarvest;
|
||||||
mergedDefaultsApplied |= mergeDefaults(instance.farmerHarvest, __def);
|
mergedDefaultsApplied |= mergeDefaults(instance.farmerHarvest, __def);
|
||||||
}
|
}
|
||||||
|
if (loaded.crusherXp != null && !loaded.crusherXp.isEmpty()) {
|
||||||
|
java.util.Map __def = new java.util.HashMap<>(instance.crusherXp);
|
||||||
|
instance.crusherXp = loaded.crusherXp;
|
||||||
|
mergedDefaultsApplied |= mergeDefaults(instance.crusherXp, __def);
|
||||||
|
}
|
||||||
|
if (loaded.alchemistCraft != null && !loaded.alchemistCraft.isEmpty()) {
|
||||||
|
java.util.Map __def = new java.util.HashMap<>(instance.alchemistCraft);
|
||||||
|
instance.alchemistCraft = loaded.alchemistCraft;
|
||||||
|
mergedDefaultsApplied |= mergeDefaults(instance.alchemistCraft, __def);
|
||||||
|
}
|
||||||
if (loaded.crusherResults != null && !loaded.crusherResults.isEmpty()) {
|
if (loaded.crusherResults != null && !loaded.crusherResults.isEmpty()) {
|
||||||
java.util.Map __def = new java.util.HashMap<>(instance.crusherResults);
|
java.util.Map __def = new java.util.HashMap<>(instance.crusherResults);
|
||||||
instance.crusherResults = loaded.crusherResults;
|
instance.crusherResults = loaded.crusherResults;
|
||||||
@@ -275,15 +354,38 @@ public final class PalaConfig {
|
|||||||
if (loaded.furnaceFuels != null && !loaded.furnaceFuels.isEmpty()) {
|
if (loaded.furnaceFuels != null && !loaded.furnaceFuels.isEmpty()) {
|
||||||
instance.furnaceFuels = loaded.furnaceFuels;
|
instance.furnaceFuels = loaded.furnaceFuels;
|
||||||
}
|
}
|
||||||
|
// Migration v3 : les anciennes tables de balance (seuils wiki 22k+,
|
||||||
|
// blocs mineur verrouilles niv.1, alchimiste niv.1) rendaient les
|
||||||
|
// metiers impossibles a demarrer. On remet les defauts code une fois.
|
||||||
|
if (migrateBalance) {
|
||||||
|
PalaConfig defaults = new PalaConfig();
|
||||||
|
instance.minerXp = defaults.minerXp;
|
||||||
|
instance.minerLevels = defaults.minerLevels;
|
||||||
|
instance.hunterKills = defaults.hunterKills;
|
||||||
|
instance.farmerHarvest = defaults.farmerHarvest;
|
||||||
|
instance.crusherXp = defaults.crusherXp;
|
||||||
|
instance.alchemistCraft = defaults.alchemistCraft;
|
||||||
|
instance.alchemistBrewXp = defaults.alchemistBrewXp;
|
||||||
|
instance.levelThresholds = defaults.levelThresholds;
|
||||||
|
instance.xpBase = defaults.xpBase;
|
||||||
|
instance.xpExponent = defaults.xpExponent;
|
||||||
|
instance.configVersion = 3;
|
||||||
|
mergedDefaultsApplied = true;
|
||||||
|
Pala.LOGGER.info(
|
||||||
|
"[SurviePote] Config metiers migree v2 -> v3 (courbe XP et tables rebalancees).");
|
||||||
|
} else {
|
||||||
|
instance.configVersion = loaded.configVersion;
|
||||||
|
}
|
||||||
// M5a : un vieux pala.json (M0) n'a pas les nouvelles cles : les defauts
|
// M5a : un vieux pala.json (M0) n'a pas les nouvelles cles : les defauts
|
||||||
// code sont en memoire (Gson utilise le constructeur no-args, les champs
|
// code sont en memoire (Gson utilise le constructeur no-args, les champs
|
||||||
// absents gardent leurs valeurs par defaut, jamais null), on re-sauvegarde
|
// absents gardent leurs valeurs par defaut, jamais null), on re-sauvegarde
|
||||||
// pour les materialiser si une cle attendue manque. Une table explicitement
|
// pour les materialiser si une cle attendue manque. Une table explicitement
|
||||||
// videe (cle presente, tableau vide) est respectee telle quelle.
|
// videe (cle presente, tableau vide) est respectee telle quelle.
|
||||||
java.util.Set<String> expected = java.util.Set.of("minerXp", "minerLevels",
|
java.util.Set<String> expected = java.util.Set.of("configVersion",
|
||||||
|
"minerXp", "minerLevels",
|
||||||
"xpBase", "xpExponent", "levelThresholds", "netherMinerLevel", "stickCooldowns",
|
"xpBase", "xpExponent", "levelThresholds", "netherMinerLevel", "stickCooldowns",
|
||||||
"rankNodes", "hunterKills", "farmerHarvest", "crusherXp",
|
"rankNodes", "hunterKills", "farmerHarvest", "crusherXp",
|
||||||
"alchemistCraft",
|
"alchemistCraft", "alchemistBrewXp",
|
||||||
"crusherResults", "crusherFuels", "crusherInfiniteFuels",
|
"crusherResults", "crusherFuels", "crusherInfiniteFuels",
|
||||||
"furnaceSmelts", "furnaceFuels",
|
"furnaceSmelts", "furnaceFuels",
|
||||||
"serverName", "wikiUrl", "discordUrl", "shopUrl",
|
"serverName", "wikiUrl", "discordUrl", "shopUrl",
|
||||||
@@ -326,7 +428,7 @@ public final class PalaConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cout XP total pour atteindre le niveau n (n >= 1) : table wiki 2-20, formule au-dela. */
|
/** Cout XP total pour atteindre le niveau n (n >= 1), surchargeable par levelThresholds. */
|
||||||
public long xpForLevel(int level) {
|
public long xpForLevel(int level) {
|
||||||
Long exact = levelThresholds.get(level);
|
Long exact = levelThresholds.get(level);
|
||||||
if (exact != null) {
|
if (exact != null) {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package fr.surviepote.pala.core;
|
package fr.surviepote.pala.core;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
@@ -17,6 +20,10 @@ public final class PalaJobs {
|
|||||||
|
|
||||||
public static final List<String> JOBS = List.of("mineur", "fermier", "chasseur", "alchimiste");
|
public static final List<String> JOBS = List.of("mineur", "fermier", "chasseur", "alchimiste");
|
||||||
|
|
||||||
|
// Action bar : dernier affichage par joueur (throttle 1 s pour eviter le spam
|
||||||
|
// pendant le minage).
|
||||||
|
private static final Map<UUID, Long> LAST_HUD = new HashMap<>();
|
||||||
|
|
||||||
private PalaJobs() {
|
private PalaJobs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +53,32 @@ public final class PalaJobs {
|
|||||||
PalaRewards.grant(player, job, data.level);
|
PalaRewards.grant(player, job, data.level);
|
||||||
}
|
}
|
||||||
PalaStorage.get().markDirty();
|
PalaStorage.get().markDirty();
|
||||||
|
sendHud(player, job, data);
|
||||||
return data.level;
|
return data.level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Affiche la progression courante dans l'action bar (1 fois par seconde max).
|
||||||
|
// Permet de voir que l'XP monte sans rouvrir l'ecran Metiers.
|
||||||
|
private static void sendHud(ServerPlayer player, String job, PalaStorage.JobData data) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
Long last = LAST_HUD.get(player.getUUID());
|
||||||
|
if (last != null && now - last < 1000L) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LAST_HUD.put(player.getUUID(), now);
|
||||||
|
PalaConfig config = PalaConfig.get();
|
||||||
|
long next = data.level >= 100 ? 0L : config.xpForLevel(data.level + 1);
|
||||||
|
String text;
|
||||||
|
if (next <= 0L) {
|
||||||
|
text = "§6[Metier] §e" + job + " §7niveau maximum";
|
||||||
|
} else {
|
||||||
|
text = "§6[Metier] §e" + job + " §7: §e"
|
||||||
|
+ String.format(java.util.Locale.ROOT, "%.1f", data.xp)
|
||||||
|
+ " §7/ §e" + next + " XP §7(niv. " + data.level + ")";
|
||||||
|
}
|
||||||
|
player.sendOverlayMessage(Component.literal(text));
|
||||||
|
}
|
||||||
|
|
||||||
/** Hook casse-bloc : XP mineur selon la table config + niveau requis (wiki). */
|
/** Hook casse-bloc : XP mineur selon la table config + niveau requis (wiki). */
|
||||||
public static void onBlockBreak(ServerPlayer player, ServerLevel level, BlockPos pos, BlockState state) {
|
public static void onBlockBreak(ServerPlayer player, ServerLevel level, BlockPos pos, BlockState state) {
|
||||||
Identifier id = level.registryAccess()
|
Identifier id = level.registryAccess()
|
||||||
|
|||||||
@@ -160,7 +160,16 @@ public final class PalaJobEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void afterDeath(LivingEntity entity, DamageSource source) {
|
private static void afterDeath(LivingEntity entity, DamageSource source) {
|
||||||
Entity killer = source.getEntity();
|
// getKillCredit() gere deja les projectiles et les loups apprivoises (retourne
|
||||||
|
// le proprietaire). Fallback sur la source directe pour les cas exotiques.
|
||||||
|
Entity killer = entity.getKillCredit();
|
||||||
|
if (killer == null) {
|
||||||
|
killer = source.getEntity();
|
||||||
|
}
|
||||||
|
if (killer instanceof net.minecraft.world.entity.projectile.Projectile projectile
|
||||||
|
&& projectile.getOwner() instanceof ServerPlayer owner) {
|
||||||
|
killer = owner;
|
||||||
|
}
|
||||||
if (!(killer instanceof ServerPlayer player)) {
|
if (!(killer instanceof ServerPlayer player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package fr.surviepote.pala.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.core.component.DataComponents;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.component.CustomData;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import fr.surviepote.pala.core.PalaJobs;
|
||||||
|
|
||||||
|
// SurviePote : XP alchimiste quand un joueur recupere une potion fraichement brassee.
|
||||||
|
// Le marqueur "pala:brewed_xp" est pose par PalaBrewXpMixin a la fin du brassage puis
|
||||||
|
// retire ici, donc une potion deja prise (ou sortie par un hopper) ne rapporte plus rien.
|
||||||
|
@Mixin(targets = "net.minecraft.world.inventory.BrewingStandMenu$PotionSlot")
|
||||||
|
public class PalaBrewTakeXpMixin {
|
||||||
|
|
||||||
|
@Inject(method = "onTake", at = @At("TAIL"))
|
||||||
|
private void pala$brewedPotionXp(Player player, ItemStack stack, CallbackInfo ci) {
|
||||||
|
if (!(player instanceof ServerPlayer sp) || stack.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CustomData data = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||||
|
if (!data.copyTag().contains("pala:brewed_xp")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
double xp = data.copyTag().getDoubleOr("pala:brewed_xp", 0.0);
|
||||||
|
CustomData.update(DataComponents.CUSTOM_DATA, stack,
|
||||||
|
tag -> tag.remove("pala:brewed_xp"));
|
||||||
|
if (stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).isEmpty()) {
|
||||||
|
stack.remove(DataComponents.CUSTOM_DATA);
|
||||||
|
}
|
||||||
|
if (xp > 0.0) {
|
||||||
|
PalaJobs.addXp(sp, "alchimiste", xp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package fr.surviepote.pala.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.component.DataComponents;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.component.CustomData;
|
||||||
|
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import fr.surviepote.pala.core.PalaConfig;
|
||||||
|
|
||||||
|
// SurviePote : marque les potions sorties d'un chaudron avec la valeur d'XP alchimiste
|
||||||
|
// a attribuer au joueur qui les recupere. Le marqueur est lu puis retire dans
|
||||||
|
// PalaBrewTakeXpMixin (PotionSlot.onTake), ce qui evite le farm en remettant une potion
|
||||||
|
// deja recuperee dans le chaudron.
|
||||||
|
@Mixin(BrewingStandBlockEntity.class)
|
||||||
|
public class PalaBrewXpMixin {
|
||||||
|
|
||||||
|
@Inject(method = "doBrew", at = @At("TAIL"))
|
||||||
|
private static void pala$markBrewedPotions(ServerLevel level, BlockPos pos,
|
||||||
|
BrewingStandBlockEntity stand, CallbackInfo ci) {
|
||||||
|
double xp = PalaConfig.get().alchemistBrewXp;
|
||||||
|
if (xp <= 0.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Slots 0-2 = potions de sortie.
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
ItemStack stack = stand.getItem(i);
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CustomData.update(DataComponents.CUSTOM_DATA, stack,
|
||||||
|
tag -> tag.putDouble("pala:brewed_xp", xp));
|
||||||
|
}
|
||||||
|
stand.setChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package fr.surviepote.pala.network;
|
||||||
|
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
|
||||||
|
// Reponse serveur -> client : une ligne par metier "job|niveau|xp|xp_suivant".
|
||||||
|
public record JobsDataPayload(String payload) implements CustomPacketPayload {
|
||||||
|
|
||||||
|
public static final Type<JobsDataPayload> TYPE = new Type<>(
|
||||||
|
Identifier.fromNamespaceAndPath("pala", "jobs_data"));
|
||||||
|
|
||||||
|
public static final StreamCodec<FriendlyByteBuf, JobsDataPayload> CODEC =
|
||||||
|
StreamCodec.of(
|
||||||
|
(buf, value) -> buf.writeUtf(value.payload, 32767),
|
||||||
|
buf -> new JobsDataPayload(buf.readUtf(32767)));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package fr.surviepote.pala.network;
|
||||||
|
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
|
||||||
|
// Requete client -> serveur envoyee par le bouton "Metiers" de l'inventaire.
|
||||||
|
public record JobsRequestPayload() implements CustomPacketPayload {
|
||||||
|
|
||||||
|
public static final JobsRequestPayload INSTANCE = new JobsRequestPayload();
|
||||||
|
|
||||||
|
public static final Type<JobsRequestPayload> TYPE = new Type<>(
|
||||||
|
Identifier.fromNamespaceAndPath("pala", "jobs_request"));
|
||||||
|
|
||||||
|
public static final StreamCodec<FriendlyByteBuf, JobsRequestPayload> CODEC =
|
||||||
|
StreamCodec.unit(INSTANCE);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package fr.surviepote.pala.network;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|
||||||
|
import fr.surviepote.pala.core.PalaConfig;
|
||||||
|
import fr.surviepote.pala.core.PalaJobs;
|
||||||
|
|
||||||
|
// Synchronisation a la demande de la progression des metiers (bouton inventaire).
|
||||||
|
public final class PalaNetwork {
|
||||||
|
|
||||||
|
private PalaNetwork() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
PayloadTypeRegistry.serverboundPlay().register(JobsRequestPayload.TYPE, JobsRequestPayload.CODEC);
|
||||||
|
PayloadTypeRegistry.clientboundPlay().register(JobsDataPayload.TYPE, JobsDataPayload.CODEC);
|
||||||
|
|
||||||
|
ServerPlayNetworking.registerGlobalReceiver(JobsRequestPayload.TYPE,
|
||||||
|
(payload, context) -> {
|
||||||
|
ServerPlayer player = context.player();
|
||||||
|
ServerPlayNetworking.send(player, new JobsDataPayload(build(player)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String build(ServerPlayer player) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (String job : PalaJobs.JOBS) {
|
||||||
|
int level = PalaJobs.levelOf(player, job);
|
||||||
|
long xp = (long) PalaJobs.xpOf(player, job);
|
||||||
|
long previous = level <= 0 ? 0L : PalaConfig.get().xpForLevel(level);
|
||||||
|
long next = level >= 100 ? 0L : PalaConfig.get().xpForLevel(level + 1);
|
||||||
|
sb.append(job).append('|').append(level).append('|')
|
||||||
|
.append(xp).append('|').append(previous).append('|')
|
||||||
|
.append(next).append('\n');
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -264,5 +264,6 @@
|
|||||||
"item.pala.job_candy": "Job Candy",
|
"item.pala.job_candy": "Job Candy",
|
||||||
"block.pala.palaforge": "Palaforge",
|
"block.pala.palaforge": "Palaforge",
|
||||||
"item.pala.palaforge": "Palaforge",
|
"item.pala.palaforge": "Palaforge",
|
||||||
"container.pala.palaforge": "Palaforge"
|
"container.pala.palaforge": "Palaforge",
|
||||||
|
"screen.pala.jobs": "Jobs"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,30 +2,13 @@
|
|||||||
"type": "minecraft:block",
|
"type": "minecraft:block",
|
||||||
"pools": [
|
"pools": [
|
||||||
{
|
{
|
||||||
|
"condition": {
|
||||||
|
"type": "minecraft:survives_explosion"
|
||||||
|
},
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"type": "minecraft:alternatives",
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"condition": "minecraft:tool/can_silk_touch",
|
|
||||||
"name": "pala:amethyst_ore"
|
"name": "pala:amethyst_ore"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:item",
|
|
||||||
"modifier": [
|
|
||||||
{
|
|
||||||
"type": "minecraft:apply_bonus",
|
|
||||||
"enchantment": "minecraft:fortune",
|
|
||||||
"formula": "minecraft:ore_drops"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:explosion_decay"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "pala:amethyst_ingot"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1
|
"rolls": 1
|
||||||
|
|||||||
@@ -2,30 +2,13 @@
|
|||||||
"type": "minecraft:block",
|
"type": "minecraft:block",
|
||||||
"pools": [
|
"pools": [
|
||||||
{
|
{
|
||||||
|
"condition": {
|
||||||
|
"type": "minecraft:survives_explosion"
|
||||||
|
},
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"type": "minecraft:alternatives",
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"condition": "minecraft:tool/can_silk_touch",
|
|
||||||
"name": "pala:findium_ore"
|
"name": "pala:findium_ore"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:item",
|
|
||||||
"modifier": [
|
|
||||||
{
|
|
||||||
"type": "minecraft:apply_bonus",
|
|
||||||
"enchantment": "minecraft:fortune",
|
|
||||||
"formula": "minecraft:ore_drops"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:explosion_decay"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "pala:findium_gem"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1
|
"rolls": 1
|
||||||
|
|||||||
@@ -2,30 +2,13 @@
|
|||||||
"type": "minecraft:block",
|
"type": "minecraft:block",
|
||||||
"pools": [
|
"pools": [
|
||||||
{
|
{
|
||||||
|
"condition": {
|
||||||
|
"type": "minecraft:survives_explosion"
|
||||||
|
},
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"type": "minecraft:alternatives",
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"condition": "minecraft:tool/can_silk_touch",
|
|
||||||
"name": "pala:kisakay_ore"
|
"name": "pala:kisakay_ore"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:item",
|
|
||||||
"modifier": [
|
|
||||||
{
|
|
||||||
"type": "minecraft:apply_bonus",
|
|
||||||
"enchantment": "minecraft:fortune",
|
|
||||||
"formula": "minecraft:ore_drops"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:explosion_decay"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "pala:kisakay_ingot"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1
|
"rolls": 1
|
||||||
|
|||||||
@@ -2,30 +2,13 @@
|
|||||||
"type": "minecraft:block",
|
"type": "minecraft:block",
|
||||||
"pools": [
|
"pools": [
|
||||||
{
|
{
|
||||||
|
"condition": {
|
||||||
|
"type": "minecraft:survives_explosion"
|
||||||
|
},
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"type": "minecraft:alternatives",
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"condition": "minecraft:tool/can_silk_touch",
|
|
||||||
"name": "pala:paladium_green_ore"
|
"name": "pala:paladium_green_ore"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:item",
|
|
||||||
"modifier": [
|
|
||||||
{
|
|
||||||
"type": "minecraft:apply_bonus",
|
|
||||||
"enchantment": "minecraft:fortune",
|
|
||||||
"formula": "minecraft:ore_drops"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:explosion_decay"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "pala:paladium_green_ingot"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1
|
"rolls": 1
|
||||||
|
|||||||
@@ -2,30 +2,13 @@
|
|||||||
"type": "minecraft:block",
|
"type": "minecraft:block",
|
||||||
"pools": [
|
"pools": [
|
||||||
{
|
{
|
||||||
|
"condition": {
|
||||||
|
"type": "minecraft:survives_explosion"
|
||||||
|
},
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"type": "minecraft:alternatives",
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"condition": "minecraft:tool/can_silk_touch",
|
|
||||||
"name": "pala:paladium_ore"
|
"name": "pala:paladium_ore"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:item",
|
|
||||||
"modifier": [
|
|
||||||
{
|
|
||||||
"type": "minecraft:apply_bonus",
|
|
||||||
"enchantment": "minecraft:fortune",
|
|
||||||
"formula": "minecraft:ore_drops"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:explosion_decay"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "pala:paladium_ingot"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1
|
"rolls": 1
|
||||||
|
|||||||
@@ -2,30 +2,13 @@
|
|||||||
"type": "minecraft:block",
|
"type": "minecraft:block",
|
||||||
"pools": [
|
"pools": [
|
||||||
{
|
{
|
||||||
|
"condition": {
|
||||||
|
"type": "minecraft:survives_explosion"
|
||||||
|
},
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"type": "minecraft:alternatives",
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
"condition": "minecraft:tool/can_silk_touch",
|
|
||||||
"name": "pala:titane_ore"
|
"name": "pala:titane_ore"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:item",
|
|
||||||
"modifier": [
|
|
||||||
{
|
|
||||||
"type": "minecraft:apply_bonus",
|
|
||||||
"enchantment": "minecraft:fortune",
|
|
||||||
"formula": "minecraft:ore_drops"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "minecraft:explosion_decay"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "pala:titane_ingot"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rolls": 1
|
"rolls": 1
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"placement": [
|
"placement": [
|
||||||
{
|
{
|
||||||
"type": "minecraft:count",
|
"type": "minecraft:count",
|
||||||
"count": 3
|
"count": 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "minecraft:in_square"
|
"type": "minecraft:in_square"
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
"package": "fr.surviepote.pala.mixin",
|
"package": "fr.surviepote.pala.mixin",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"PalaCraftXpMixin",
|
"PalaCraftXpMixin",
|
||||||
"PalaSmeltXpMixin"
|
"PalaSmeltXpMixin",
|
||||||
|
"PalaBrewXpMixin",
|
||||||
|
"PalaBrewTakeXpMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
Zone home corrompue
|
||||||
|
|
||||||
|
/furnace manquant
|
||||||
|
|
||||||
|
Les minerais doivent drop leur bloc (sauf trixium)
|
||||||
|
|
||||||
|
Le système de métier, doit avoir un bouton dans l'inventaire pour voir leur progression
|
||||||
|
Les tree de kiwano, eggplant etc ne doievent pas être dans l'inventaire admin
|
||||||
|
|
||||||
|
augmenter un peu la luck des fillons de minerais de paladium
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
Les boom boots doivent faire tomber bien plus vite, et en fonction de la hauteur/vitesse, faire une explosion +- grosse
|
||||||
Reference in New Issue
Block a user