diff --git a/README.md b/README.md index da0bc99..4e11cd6 100644 --- a/README.md +++ b/README.md @@ -82,8 +82,25 @@ Additionally, every message type has few own local variables. /* and others */ }, "blacklistedWorlds": [ // Allows to block creation of graves with worlds with matching id + "world:id" /*...*/ ], + "blacklistedAreas": { // Allows to block area within a world + "world:id2": [ + { + "x1": -10, + "y1": -100, + "z1": -20, + "x2": 4, + "y2": 256, + "z2": 30, + } + ] + }, + "blacklistedDamageSources": [ // Allows to blacklist damage sources by name from creating graves + "damageSourceName" + /*...*/ // Use /graves display_damage_sources to find correct names to entry + ], "tryDetectionSoulbound": true, // Toggles automatic detection of soulbound enchantment (it's hit or miss) "skippedEnchantments": [ // Allows to add own enchantments that end up being skipped from adding to grave /*...*/ diff --git a/build.gradle b/build.gradle index 2655330..b83151b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,9 @@ plugins { id 'fabric-loom' version '0.10-SNAPSHOT' id 'maven-publish' - id "com.modrinth.minotaur" version "1.2.1" + id "com.modrinth.minotaur" version "2.+" id 'com.matthewprenger.cursegradle' version '1.4.0' } -import com.modrinth.minotaur.TaskModrinthUpload -import com.modrinth.minotaur.request.VersionType sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 @@ -58,11 +56,11 @@ dependencies { modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - modImplementation include("eu.pb4:sgui:1.0.1+1.18.2") + modImplementation include("eu.pb4:sgui:1.0.2+1.18.2") modImplementation include("eu.pb4:hologram-api:0.2.1+1.18-pre5") modImplementation include("eu.pb4:placeholder-api:1.1.3+1.17.1") - modImplementation include("eu.pb4:polymer:0.2.0-beta.36+1.18.2") - modImplementation include("fr.catcore:server-translations-api:1.4.9+1.18.2-rc1") + modImplementation include("eu.pb4:polymer:0.2.0-pre.4+1.18.2") + modImplementation include("fr.catcore:server-translations-api:1.4.12+1.18.2") //modImplementation include("fr.catcore:server-translations-api:1.4.8+1.18-pre1") modImplementation include("me.lucko:fabric-permissions-api:0.1-SNAPSHOT") @@ -155,25 +153,26 @@ curseforge { options { forgeGradleIntegration = false } -} -task publishModrinth (type: TaskModrinthUpload){ - onlyIf { - System.getenv("MODRINTH") + remapJar { + finalizedBy project.tasks.curseforge } - - token = System.getenv("MODRINTH") - projectId = 'yn9u3ypm' - versionNumber = version - versionType = VersionType.RELEASE - changelog = System.getenv("CHANGELOG") - // On fabric, use 'remapJar' instead of 'jar' - uploadFile = remapJar - addGameVersion((String) project.minecraft_version) - addLoader('fabric') } -remapJar { - finalizedBy publishModrinth - finalizedBy project.tasks.curseforge -} +if (System.getenv("MODRINTH")) { + modrinth { + token = System.getenv("MODRINTH") + projectId = 'yn9u3ypm' + versionNumber = version + versionType = "release" + changelog = System.getenv("CHANGELOG") + // On fabric, use 'remapJar' instead of 'jar' + uploadFile = remapJar + gameVersions = [((String) project.minecraft_version)] + loaders = ["fabric", "quilt"] + } + + remapJar { + finalizedBy project.tasks.modrinth + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2d2ba33..be98074 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ loader_version=0.13.3 #Fabric api fabric_version=0.48.0+1.18.2 # Mod Properties - mod_version = 2.0.0+1.18.2 + mod_version = 2.0.1+1.18.2 maven_group = eu.pb4 archives_base_name = graves diff --git a/src/main/java/eu/pb4/graves/GravesMod.java b/src/main/java/eu/pb4/graves/GravesMod.java index 89b4b00..092b12b 100644 --- a/src/main/java/eu/pb4/graves/GravesMod.java +++ b/src/main/java/eu/pb4/graves/GravesMod.java @@ -50,8 +50,7 @@ public void onInitialize() { GraveBlockEntity.BLOCK_ENTITY_TYPE = Registry.register(Registry.BLOCK_ENTITY_TYPE, "universal_graves:grave", FabricBlockEntityTypeBuilder.create(GraveBlockEntity::new, GraveBlock.INSTANCE).build(null)); VisualGraveBlockEntity.BLOCK_ENTITY_TYPE = Registry.register(Registry.BLOCK_ENTITY_TYPE, "universal_graves:visual_grave", FabricBlockEntityTypeBuilder.create(VisualGraveBlockEntity::new, VisualGraveBlock.INSTANCE).build(null)); Commands.register(); - PolymerBlockUtils.registerBlockEntity(GraveBlockEntity.BLOCK_ENTITY_TYPE); - PolymerBlockUtils.registerBlockEntity(VisualGraveBlockEntity.BLOCK_ENTITY_TYPE); + PolymerBlockUtils.registerBlockEntity(GraveBlockEntity.BLOCK_ENTITY_TYPE, VisualGraveBlockEntity.BLOCK_ENTITY_TYPE); GraveNetworking.initialize(); new GraveGameRules(); diff --git a/src/main/java/eu/pb4/graves/config/Config.java b/src/main/java/eu/pb4/graves/config/Config.java index 4a40ff7..5c76291 100644 --- a/src/main/java/eu/pb4/graves/config/Config.java +++ b/src/main/java/eu/pb4/graves/config/Config.java @@ -23,6 +23,7 @@ import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -100,6 +101,7 @@ public final class Config { public final ItemStack guiQuickPickupIcon; public final ItemStack guiBarItem; + public final HashMap> blacklistedAreas; public Config(ConfigData data) { this.configData = data; @@ -164,6 +166,22 @@ public Config(ConfigData data) { if (id != null) { this.worldNameOverrides.put(id, parse(entry.getValue(), null)); + + } + } + + this.blacklistedAreas = new HashMap<>(); + + for (var entry : data.blacklistedAreas.entrySet()) { + var id = Identifier.tryParse(entry.getKey()); + + if (id != null) { + var list = new ArrayList(); + this.blacklistedAreas.put(id, list); + + for (var area : entry.getValue()) { + list.add(new Box(area.x1, area.y1, area.z1, area.x2, area.y2, area.z2)); + } } } } diff --git a/src/main/java/eu/pb4/graves/config/data/ConfigData.java b/src/main/java/eu/pb4/graves/config/data/ConfigData.java index 541e464..e4c3aa5 100644 --- a/src/main/java/eu/pb4/graves/config/data/ConfigData.java +++ b/src/main/java/eu/pb4/graves/config/data/ConfigData.java @@ -11,7 +11,7 @@ import java.util.*; -public class ConfigData extends VersionedConfigData implements Cloneable { +public class ConfigData extends VersionedConfigData { public String _comment = "Before changing anything, see https://github.com/Patbox/UniversalGraves#configuration"; public String graveStyle = GravesLookType.CLIENT_MODEL_OR_HEAD.name; @@ -99,13 +99,14 @@ public class ConfigData extends VersionedConfigData implements Cloneable { public Map worldNameOverrides = new HashMap<>(); public List blacklistedWorlds = new ArrayList<>(); + public Map> blacklistedAreas = new HashMap<>(); + public Set blacklistedDamageSources = new HashSet<>(); @Deprecated public boolean tryDetectionSoulbound = false; public List skippedEnchantments = new ArrayList<>(); - public String guiPreviousPageText = ""; public String guiPreviousPageBlockedText = ""; @@ -223,12 +224,12 @@ private static List getDefaultSign() { return list; } - @Override - public ConfigData clone() { - try { - return (ConfigData) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(); - } + public class Arena { + public int x1; + public int y1; + public int z1; + public int x2; + public int y2; + public int z2; } } diff --git a/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java b/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java index 9d7fa7a..f50373e 100644 --- a/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java +++ b/src/main/java/eu/pb4/graves/mixin/LivingEntityMixin.java @@ -25,8 +25,8 @@ import net.minecraft.network.MessageType; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.state.property.Properties; -import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; +import net.minecraft.text.*; +import net.minecraft.util.Formatting; import net.minecraft.util.ItemScatterer; import net.minecraft.util.Util; import net.minecraft.util.collection.DefaultedList; @@ -38,6 +38,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.*; @@ -52,6 +53,25 @@ private void graves_onKill(CallbackInfo ci) { this.graves_commandKill = true; } + @Inject(method = "damage", at = @At("TAIL")) + private void graves_printDamage1(DamageSource source, float amount, CallbackInfoReturnable cir) { + if (((Object) this) instanceof ServerPlayerEntity player && ((PlayerAdditions) player).graves_getPrintNextDamageSource()) { + player.sendMessage(new TranslatableText("text.graves.damage_source_info", + new LiteralText(source.name).setStyle(Style.EMPTY.withUnderline(true).withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, source.name))) + ), false); + } + } + + @Inject(method = "applyDamage", at = @At("TAIL")) + private void graves_printDamage2(DamageSource source, float amount, CallbackInfo ci) { + if (((Object) this) instanceof ServerPlayerEntity player && ((PlayerAdditions) player).graves_getPrintNextDamageSource()) { + player.sendMessage(new TranslatableText("text.graves.damage_source_info", + new LiteralText(source.name).setStyle(Style.EMPTY.withUnderline(true).withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, source.name))) + ), false); + } + } + + @Inject(method = "drop", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;dropInventory()V", shift = At.Shift.BEFORE), cancellable = true) private void replaceWithGrave(DamageSource source, CallbackInfo ci) { if (((Object) this) instanceof ServerPlayerEntity player) { @@ -68,13 +88,12 @@ private void replaceWithGrave(DamageSource source, CallbackInfo ci) { "world", GraveUtils.toWorldName(player.getWorld().getRegistryKey().getValue()) ); - if (!config.configData.createFromPvP && source.getAttacker() instanceof PlayerEntity) { text = config.creationFailedPvPMessage; - } else if (!config.configData.createFromCommandDeaths && this.graves_commandKill) { + } else if ((!config.configData.createFromCommandDeaths && this.graves_commandKill) || config.configData.blacklistedDamageSources.contains(source.name)) { } else if (!config.configData.createFromVoid && source == DamageSource.OUT_OF_WORLD && !this.graves_commandKill) { - text = config.creationFailedPvPMessage; + text = config.creationFailedVoidMessage; } else { var eventResult = PlayerGraveCreationEvent.EVENT.invoker().shouldCreate(player); diff --git a/src/main/java/eu/pb4/graves/mixin/ServerPlayerEntityMixin.java b/src/main/java/eu/pb4/graves/mixin/ServerPlayerEntityMixin.java index d1393ae..07557f8 100644 --- a/src/main/java/eu/pb4/graves/mixin/ServerPlayerEntityMixin.java +++ b/src/main/java/eu/pb4/graves/mixin/ServerPlayerEntityMixin.java @@ -25,6 +25,8 @@ @Mixin(ServerPlayerEntity.class) public abstract class ServerPlayerEntityMixin extends PlayerEntity implements PlayerAdditions { + private boolean graves_printNextSource = false; + public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) { super(world, pos, yaw, profile); } @@ -89,4 +91,14 @@ public long graves_lastGrave() { public void graves_setLastGrave(long id) { this.graves_location = id; } + + @Override + public void graves_setPrintNextDamageSource(boolean value) { + this.graves_printNextSource = value; + } + + @Override + public boolean graves_getPrintNextDamageSource() { + return this.graves_printNextSource; + } } diff --git a/src/main/java/eu/pb4/graves/other/Commands.java b/src/main/java/eu/pb4/graves/other/Commands.java index 0d76b19..eec21e7 100644 --- a/src/main/java/eu/pb4/graves/other/Commands.java +++ b/src/main/java/eu/pb4/graves/other/Commands.java @@ -14,6 +14,7 @@ import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.LiteralText; +import net.minecraft.text.TranslatableText; import net.minecraft.util.Formatting; import java.util.ArrayList; @@ -45,6 +46,9 @@ public static void register() { )) .then(literal("about").executes(Commands::about)) + .then(literal("display_damage_sources") + .requires(Permissions.require("universal_graves.display_damage_sources", 3)) + .executes(Commands::toggleDamageSourceInfo)) .then(literal("reload") .requires(Permissions.require("universal_graves.reload", 4)) @@ -54,6 +58,15 @@ public static void register() { }); } + private static int toggleDamageSourceInfo(CommandContext context) throws CommandSyntaxException { + var pl = (PlayerAdditions) context.getSource().getPlayer(); + var bl = pl.graves_getPrintNextDamageSource(); + + pl.graves_setPrintNextDamageSource(!bl); + context.getSource().sendFeedback(new TranslatableText("text.graves.damage_source_info." + (bl ? "disabled" : "enabled")), false); + return 0; + } + private static int list(CommandContext context, boolean canModify) throws CommandSyntaxException { ServerPlayerEntity player = context.getSource().getPlayer(); diff --git a/src/main/java/eu/pb4/graves/other/GraveUtils.java b/src/main/java/eu/pb4/graves/other/GraveUtils.java index 46dd969..e9dbabb 100644 --- a/src/main/java/eu/pb4/graves/other/GraveUtils.java +++ b/src/main/java/eu/pb4/graves/other/GraveUtils.java @@ -1,6 +1,7 @@ package eu.pb4.graves.other; +import eu.pb4.graves.config.Config; import eu.pb4.graves.config.ConfigManager; import eu.pb4.graves.event.GraveValidPosCheckEvent; import eu.pb4.graves.registry.SafeXPEntity; @@ -55,24 +56,26 @@ private > String nameValue(Property property, Compara public static BlockCheckResult findGravePosition(ServerPlayerEntity player, ServerWorld world, BlockPos blockPos, int maxDistance, boolean anyBlock) { var border = world.getWorldBorder(); blockPos = new BlockPos(MathHelper.clamp(blockPos.getX(), border.getBoundWest() + 1, border.getBoundEast() - 1), MathHelper.clamp(blockPos.getY(), world.getBottomY(), world.getTopY() - 1), MathHelper.clamp(blockPos.getZ(), border.getBoundNorth() + 1, border.getBoundSouth() - 1)); - var result = isValidPos(player, world, border, blockPos, false); + var config = ConfigManager.getConfig(); + + var result = isValidPos(player, world, border, blockPos, false, config); if (result.allow) { return new BlockCheckResult(blockPos, result); } else { - var checkResult = findPos(player, world, blockPos, maxDistance, false, 0); + var checkResult = findPos(player, world, blockPos, maxDistance, false, 0, config); if (!checkResult.result.allow && anyBlock) { - checkResult = findPos(player, world, blockPos, maxDistance, true, 0); + checkResult = findPos(player, world, blockPos, maxDistance, true, 0, config); } return checkResult; } } - private static BlockCheckResult findPos(ServerPlayerEntity player, ServerWorld world, BlockPos blockPos, int maxDistance, boolean allowAnyBlock, int iteration) { + private static BlockCheckResult findPos(ServerPlayerEntity player, ServerWorld world, BlockPos blockPos, int maxDistance, boolean allowAnyBlock, int iteration, Config config) { int line = 1; var border = world.getWorldBorder(); - BlockResult result = isValidPos(player, world, border, blockPos, allowAnyBlock); + BlockResult result = isValidPos(player, world, border, blockPos, allowAnyBlock, config); if (result.allow) { return new BlockCheckResult(blockPos, result); @@ -92,7 +95,7 @@ private static BlockCheckResult findPos(ServerPlayerEntity player, ServerWorld w continue; } - tempResult = isValidPos(player, world, border, pos, allowAnyBlock); + tempResult = isValidPos(player, world, border, pos, allowAnyBlock, config); if (tempResult.priority >= result.priority) { result = tempResult; } @@ -117,10 +120,18 @@ public static void spawnExp(ServerWorld world, Vec3d pos, int amount) { } - private static BlockResult isValidPos(ServerPlayerEntity player, ServerWorld world, WorldBorder border, BlockPos pos, boolean anyBlock) { + private static BlockResult isValidPos(ServerPlayerEntity player, ServerWorld world, WorldBorder border, BlockPos pos, boolean anyBlock, Config config) { BlockState state = world.getBlockState(pos); if (state.getBlock() != TempBlock.INSTANCE && border.contains(pos) && pos.getY() >= world.getBottomY() && pos.getY() < world.getTopY() && !state.hasBlockEntity() && (state.isAir() || anyBlock || state.isIn(REPLACEABLE_TAG))) { + var areas = config.blacklistedAreas.get(world.getRegistryKey().getValue()); + if (areas != null) { + for (var area : areas) { + if (area.contains(pos.getX(), pos.getY(), pos.getZ())) { + return BlockResult.BLOCK_CLAIM; + } + } + } return GraveValidPosCheckEvent.EVENT.invoker().isValid(player, world, pos); } else { return BlockResult.BLOCK; diff --git a/src/main/java/eu/pb4/graves/other/PlayerAdditions.java b/src/main/java/eu/pb4/graves/other/PlayerAdditions.java index 349b0f8..919fc50 100644 --- a/src/main/java/eu/pb4/graves/other/PlayerAdditions.java +++ b/src/main/java/eu/pb4/graves/other/PlayerAdditions.java @@ -11,4 +11,7 @@ public interface PlayerAdditions { long graves_lastGrave(); void graves_setLastGrave(long graveId); + + void graves_setPrintNextDamageSource(boolean value); + boolean graves_getPrintNextDamageSource(); } diff --git a/src/main/resources/data/universal_graves/lang/en_us.json b/src/main/resources/data/universal_graves/lang/en_us.json index a2776a7..3b2b2d8 100644 --- a/src/main/resources/data/universal_graves/lang/en_us.json +++ b/src/main/resources/data/universal_graves/lang/en_us.json @@ -19,6 +19,10 @@ "text.graves.creation_failed_pvp": "Grave wasn't created, because player killed you! Your items were dropped at %s (%s)", "text.graves.creation_failed_claim": "Grave wasn't created, because you were in a claim! Your items were dropped at %s (%s)", + "text.graves.damage_source_info": "You were damaged by: %s", + "text.graves.damage_source_info.enabled": "Enabled displaying of next damage sources! Type this command again to disable.", + "text.graves.damage_source_info.disabled": "Disabled displaying of damage sources!", + "text.graves.about.version": "Version: %s", "text.graves.about.contributors": "Contributors",