diff --git a/.github/workflows/build.yml.disabled b/.github/workflows/build.yml.disabled deleted file mode 100644 index 7c20868..0000000 --- a/.github/workflows/build.yml.disabled +++ /dev/null @@ -1,30 +0,0 @@ -name: build -on: - push: - branches: - - '**' - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - loader: [fabric, forge, neoforge] - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - name: Validate gradle wrapper - uses: gradle/wrapper-validation-action@v1 - - name: Setup JDK - uses: actions/setup-java@v3 - with: - java-version: 21 - distribution: temurin - - name: Make gradle wrapper executable - run: chmod +x ./gradlew - - name: Build - run: ./gradlew :${{ matrix.loader }}:build - env: - GPR_USERNAME: ${{secrets.GPR_USERNAME}} - GPR_TOKEN: ${{secrets.GPR_TOKEN}} - GPR_BUILD_NUMBER: ${{github.run_number}} \ No newline at end of file diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 38ac5aa..64ae451 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -2,15 +2,21 @@ name: publish-release on: workflow_dispatch: inputs: - bump: - description: 'The bump in version for this release' + forge: + description: 'Forge' required: true - type: choice - default: patch - options: - - major - - minor - - patch + type: boolean + default: true + fabric: + description: 'Fabric' + required: true + type: boolean + default: true + neoforge: + description: 'NeoForge' + required: true + type: boolean + default: true jobs: create-release: @@ -18,18 +24,20 @@ jobs: outputs: ref: v${{ steps.bump-version.outputs.version }} version: ${{ steps.bump-version.outputs.version }} + build-matrix: ${{ steps.set-build-matrix.outputs.result }} + publish-matrix: ${{ steps.set-publish-matrix.outputs.result }} steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Extracting version from properties shell: bash - run: echo "version=$(cat gradle.properties | grep -w "\bversion" | cut -d= -f2)" >> $GITHUB_OUTPUT + run: echo "version=$(cat gradle.properties | grep -w "\bversion\s*=" | cut -d= -f2)" >> $GITHUB_OUTPUT id: extract-version - name: Bumping version uses: TwelveIterationMods/bump-version@v1 with: version: ${{ steps.extract-version.outputs.version }} - bump: ${{ inputs.bump }} + bump: patch id: bump-version - name: Updating version properties run: | @@ -43,36 +51,136 @@ jobs: shell: bash env: BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + - name: Preparing build matrix + id: set-build-matrix + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const settingsGradle = fs.readFileSync('settings.gradle', 'utf8'); + const includePattern = /^(?!\s*\/\/)\s*include\s*\(\s*(['"]([^'"]+)['"](?:,\s*['"]([^'"]+)['"])*\s*)\)/gm; + const includes = [...settingsGradle.matchAll(includePattern)].flatMap(match => match[0].match(/['"]([^'"]+)['"]/g).map(item => item.replace(/['"]/g, ''))); + const includeFabric = includes.includes('fabric') && ${{inputs.fabric}}; + const includeForge = includes.includes('forge') && ${{inputs.forge}}; + const includeNeoForge = includes.includes('neoforge') && ${{inputs.neoforge}}; + return { + loader: [includeFabric ? 'fabric' : false, includeForge ? 'forge' : false, includeNeoForge ? 'neoforge' : false].filter(Boolean), + } + - name: Preparing publish matrix + id: set-publish-matrix + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const settingsGradle = fs.readFileSync('settings.gradle', 'utf8'); + const includePattern = /^(?!\s*\/\/)\s*include\s*\(\s*(['"]([^'"]+)['"](?:,\s*['"]([^'"]+)['"])*\s*)\)/gm; + const includes = [...settingsGradle.matchAll(includePattern)].flatMap(match => match[0].match(/['"]([^'"]+)['"]/g).map(item => item.replace(/['"]/g, ''))); + const includeFabric = includes.includes('fabric') && ${{inputs.fabric}}; + const includeForge = includes.includes('forge') && ${{inputs.forge}}; + const includeNeoForge = includes.includes('neoforge') && ${{inputs.neoforge}}; + const gradleProperties = fs.readFileSync('gradle.properties', 'utf8'); + const curseForgeProjectId = gradleProperties.match(/^(?!#)curseforge_project_id\s*=\s*(.+)/m); + const modrinthProjectId = gradleProperties.match(/^(?!#)modrinth_project_id\s*=\s*(.+)/m); + const mavenReleases = gradleProperties.match(/^(?!#)maven_releases\s*=\s*(.+)/m); + return { + loader: ['common', includeFabric ? 'fabric' : false, includeForge ? 'forge' : false, includeNeoForge ? 'neoforge' : false].filter(Boolean), + site: [curseForgeProjectId ? 'curseforge' : '', modrinthProjectId ? 'modrinth' : '', mavenReleases ? 'publish' : ''].filter(Boolean), + exclude: [ + {loader: 'common', site: 'curseforge'}, + {loader: 'common', site: 'modrinth'} + ] + } + build-common: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ needs.create-release.outputs.ref }} + - name: Validate gradle wrapper + uses: gradle/actions/wrapper-validation@v3 + - name: Setup JDK + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: temurin + cache: 'gradle' + - name: Make gradle wrapper executable + run: chmod +x ./gradlew + - name: Build common artifact + run: ./gradlew :common:build '-Pversion=${{needs.create-release.outputs.version}}' + - name: Upload common artifact + uses: actions/upload-artifact@v4 + with: + name: common-artifact + path: common/build + needs: create-release + build-release: + runs-on: ubuntu-latest + strategy: + matrix: ${{fromJson(needs.create-release.outputs.build-matrix)}} + fail-fast: false + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ needs.create-release.outputs.ref }} + - name: Validate gradle wrapper + uses: gradle/actions/wrapper-validation@v3 + - name: Setup JDK + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: temurin + cache: 'gradle' + - name: Make gradle wrapper executable + run: chmod +x ./gradlew + - name: Download common artifact + uses: actions/download-artifact@v4 + with: + name: common-artifact + path: common/build + - name: Build ${{ matrix.loader }} artifact + run: ./gradlew :${{ matrix.loader }}:build '-Pversion=${{needs.create-release.outputs.version}}' + - name: Upload ${{ matrix.loader }} artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.loader }}-artifact + path: ${{ matrix.loader }}/build + needs: + - create-release + - build-common publish-release: runs-on: ubuntu-latest - permissions: - packages: write strategy: - matrix: - loader: [ common, fabric, forge, neoforge ] - site: [ curseforge, modrinth, publish ] - exclude: - - loader: common - site: curseforge - - loader: common - site: modrinth + matrix: ${{fromJson(needs.create-release.outputs.publish-matrix)}} + fail-fast: false steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ needs.create-release.outputs.ref }} + - name: Download ${{ matrix.loader }} artifact + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.loader }}-artifact + path: ${{ matrix.loader }}/build - name: Validate gradle wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation@v3 - name: Setup JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 21 distribution: temurin + cache: 'gradle' - name: Make gradle wrapper executable run: chmod +x ./gradlew - name: Publish - run: ./gradlew :${{ matrix.loader }}:${{ matrix.site }} '-Pversion=${{needs.create-release.outputs.version}}' '-PtwelveIterationsNexusUsername=${{ secrets.NEXUS_USER }}' '-PtwelveIterationsNexusPassword=${{ secrets.NEXUS_PASSWORD }}' + run: ./gradlew :${{ matrix.loader }}:${{ matrix.site }} '-Pversion=${{needs.create-release.outputs.version}}' '-PmavenUsername=${{ secrets.MAVEN_USER }}' '-PmavenPassword=${{ secrets.MAVEN_PASSWORD }}' env: CURSEFORGE_TOKEN: ${{secrets.CURSEFORGE_TOKEN}} MODRINTH_TOKEN: ${{secrets.MODRINTH_TOKEN}} - needs: create-release \ No newline at end of file + needs: + - create-release + - build-common + - build-release \ No newline at end of file diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index a23204f..9cae1f5 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -17,7 +17,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - name: Validate gradle wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/actions/wrapper-validation@v3 - name: Setup JDK uses: actions/setup-java@v3 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 271ae12..066f116 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1 @@ -- Reduced default rescueDistance to 3 instead of 5 -- Require Line of Sight for rescuing to initiate -- Require the player to be looking towards the downed player for rescuing to initiate \ No newline at end of file +- Added stats for Players Revived and Times Revived \ No newline at end of file diff --git a/build.gradle b/build.gradle index 98c4692..7ce200a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.7-SNAPSHOT' apply(false) + id 'fabric-loom' version '1.9-SNAPSHOT' apply(false) id 'net.neoforged.moddev' version '0.1.110' apply(false) id 'net.darkhax.curseforgegradle' version '1.1.18' apply(false) id "com.modrinth.minotaur" version "2.+" apply(false) diff --git a/common/src/generated/resources/data/hardcorerevival/tags/item/passthrough_death_when_held.json b/common/src/generated/resources/data/hardcorerevival/tags/item/passthrough_death_when_held.json new file mode 100644 index 0000000..e89bd49 --- /dev/null +++ b/common/src/generated/resources/data/hardcorerevival/tags/item/passthrough_death_when_held.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:totem_of_undying" + ] +} \ No newline at end of file diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevival.java b/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevival.java index 730e39e..686bad5 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevival.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevival.java @@ -1,30 +1,23 @@ package net.blay09.mods.hardcorerevival; import net.blay09.mods.balm.api.Balm; -import net.blay09.mods.balm.api.proxy.SidedProxy; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalDataImpl; -import net.blay09.mods.hardcorerevival.capability.InvalidHardcoreRevivalData; +import net.blay09.mods.balm.common.config.ConfigLocalization; import net.blay09.mods.hardcorerevival.command.ReviveCommand; import net.blay09.mods.hardcorerevival.compat.Compat; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.blay09.mods.hardcorerevival.handler.*; import net.blay09.mods.hardcorerevival.network.ModNetworking; import net.blay09.mods.hardcorerevival.stats.ModStats; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class HardcoreRevival { public static final String MOD_ID = "hardcorerevival"; - private static final SidedProxy manager = Balm.sidedProxy("net.blay09.mods.hardcorerevival.HardcoreRevivalManager", "net.blay09.mods.hardcorerevival.client.HardcoreRevivalClientManager"); - private static final HardcoreRevivalData clientRevivalData = new HardcoreRevivalDataImpl(); - public static final Logger logger = LogManager.getLogger(); public static void initialize() { + ConfigLocalization.enableModernTranslationKeys(MOD_ID); HardcoreRevivalConfig.initialize(); ModNetworking.initialize(Balm.getNetworking()); @@ -39,18 +32,7 @@ public static void initialize() { RescueHandler.initialize(); Balm.initializeIfLoaded(Compat.MR_CRAYFISHS_GUN_MOD, "net.blay09.mods.hardcorerevival.compat.MrCrayfishsGunModAddon"); - } - - public static HardcoreRevivalManager getManager() { - return manager.get(); - } - - public static HardcoreRevivalData getRevivalData(Entity entity) { - return entity instanceof Player player ? getManager().getRevivalData(player) : InvalidHardcoreRevivalData.INSTANCE; - } - - public static HardcoreRevivalData getClientRevivalData() { - return clientRevivalData; + Balm.initializeIfLoaded(Compat.INVENTORY_TOTEM, "new.blay09.mods.hardcorerevival.compat.InventoryTotemAddon"); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevivalManager.java b/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevivalManager.java index 881ba4a..9efe9dc 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevivalManager.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/HardcoreRevivalManager.java @@ -4,8 +4,6 @@ import net.blay09.mods.hardcorerevival.api.PlayerKnockedOutEvent; import net.blay09.mods.hardcorerevival.api.PlayerRescuedEvent; import net.blay09.mods.hardcorerevival.api.PlayerRevivedEvent; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; -import net.blay09.mods.hardcorerevival.capability.InvalidHardcoreRevivalData; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfigData; import net.blay09.mods.hardcorerevival.handler.KnockoutSyncHandler; @@ -32,14 +30,8 @@ public class HardcoreRevivalManager { public static final ResourceKey NOT_RESCUED_IN_TIME = ResourceKey.create(Registries.DAMAGE_TYPE, ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "not_rescued_in_time")); - public HardcoreRevivalData getRevivalData(Player player) { - HardcoreRevivalData provider = Balm.getProviders().getProvider(player, HardcoreRevivalData.class); - return provider != null ? provider : InvalidHardcoreRevivalData.INSTANCE; - } - - public void knockout(Player player, DamageSource source) { - HardcoreRevivalData revivalData = getRevivalData(player); - if (revivalData.isKnockedOut()) { + public static void knockout(Player player, DamageSource source) { + if (PlayerHardcoreRevivalManager.isKnockedOut(player)) { return; } @@ -47,25 +39,25 @@ public void knockout(Player player, DamageSource source) { player.stopRiding(); player.removeEffect(MobEffects.REGENERATION); - revivalData.setKnockedOut(true); - revivalData.setKnockoutTicksPassed(0); - revivalData.setLastKnockoutAt(System.currentTimeMillis()); + PlayerHardcoreRevivalManager.setKnockedOut(player, true); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(player, 0); + PlayerHardcoreRevivalManager.setLastKnockoutAt(player, System.currentTimeMillis()); player.awardStat(ModStats.knockouts); // Punish consecutive knockouts - final var lastRescuedAt = revivalData.getLastRescuedAt(); + final var lastRescuedAt = PlayerHardcoreRevivalManager.getLastRescuedAt(player); final var consecutiveThresholdSeconds = HardcoreRevivalConfig.getActive().consecutiveKnockoutThresholdSeconds; final var secondsSinceLastRescue = (System.currentTimeMillis() - lastRescuedAt) / 1000; final var isConsecutiveKnockout = consecutiveThresholdSeconds > 0 && lastRescuedAt > 0 && secondsSinceLastRescue <= consecutiveThresholdSeconds; if (isConsecutiveKnockout) { if (HardcoreRevivalConfig.getActive().resumeTimerOnConsecutiveKnockout) { - revivalData.setKnockoutTicksPassed(revivalData.getLastKnockoutTicksPassed()); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(player, PlayerHardcoreRevivalManager.getLastKnockoutTicksPassed(player)); } final var multiplyTimerOnConsecutiveKnockout = HardcoreRevivalConfig.getActive().multiplyTimerOnConsecutiveKnockout; final var maxTicksUntilDeath = HardcoreRevivalConfig.getActive().secondsUntilDeath * 20; - final var ticksLeft = maxTicksUntilDeath - revivalData.getKnockoutTicksPassed(); + final var ticksLeft = maxTicksUntilDeath - PlayerHardcoreRevivalManager.getKnockoutTicksPassed(player); final var newTicksLeft = (int) (ticksLeft * multiplyTimerOnConsecutiveKnockout); - revivalData.setKnockoutTicksPassed(maxTicksUntilDeath - newTicksLeft); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(player, maxTicksUntilDeath - newTicksLeft); } // Fire event for compatibility addons @@ -91,15 +83,15 @@ public void knockout(Player player, DamageSource source) { updateKnockoutEffects(player); } - public void wakeup(Player player) { + public static void wakeup(Player player) { wakeup(player, true); } - public void wakeup(Player player, boolean applyEffects) { - final var revivalData = getRevivalData(player); - revivalData.setLastRescuedAt(System.currentTimeMillis()); - revivalData.setLastKnockoutTicksPassed(revivalData.getKnockoutTicksPassed()); + public static void wakeup(Player player, boolean applyEffects) { + PlayerHardcoreRevivalManager.setLastRescuedAt(player, System.currentTimeMillis()); + PlayerHardcoreRevivalManager.setLastKnockoutTicksPassed(player, PlayerHardcoreRevivalManager.getKnockoutTicksPassed(player)); reset(player); + player.awardStat(ModStats.timesRescued); if (applyEffects) { HardcoreRevivalConfigData config = HardcoreRevivalConfig.getActive(); @@ -128,7 +120,7 @@ public void wakeup(Player player, boolean applyEffects) { Balm.getEvents().fireEvent(new PlayerRevivedEvent(player)); } - private int tryParseInt(@Nullable String text, int defaultVal) { + private static int tryParseInt(@Nullable String text, int defaultVal) { if (text != null) { try { return Integer.parseInt(text); @@ -139,41 +131,41 @@ private int tryParseInt(@Nullable String text, int defaultVal) { return defaultVal; } - public void finishRescue(Player player) { - HardcoreRevivalData revivalData = getRevivalData(player); - Player rescueTarget = revivalData.getRescueTarget(); + public static void finishRescue(Player player) { + Player rescueTarget = PlayerHardcoreRevivalManager.getRescueTarget(player); if (rescueTarget != null) { MinecraftServer server = rescueTarget.getServer(); if (server != null) { wakeup(rescueTarget); + player.awardStat(ModStats.playersRevived); Balm.getNetworking().sendTo(player, new RevivalProgressMessage(rescueTarget.getId(), -1f)); Balm.getNetworking().sendTo(rescueTarget, new RevivalSuccessMessage(rescueTarget.getId())); Balm.getNetworking().sendToTracking(rescueTarget, new RevivalSuccessMessage(rescueTarget.getId())); - revivalData.setRescueTarget(null); + PlayerHardcoreRevivalManager.setRescueTarget(player, null); Balm.getEvents().fireEvent(new PlayerRescuedEvent(rescueTarget, player)); } } Balm.getHooks().setForcedPose(player, null); + } - public void abortRescue(Player player) { - HardcoreRevivalData revivalData = getRevivalData(player); - Player rescueTarget = revivalData.getRescueTarget(); + public static void abortRescue(Player player) { + Player rescueTarget = PlayerHardcoreRevivalManager.getRescueTarget(player); if (rescueTarget != null) { - revivalData.setRescueTime(0); - revivalData.setRescueTarget(null); + PlayerHardcoreRevivalManager.setRescueTime(player, 0); + PlayerHardcoreRevivalManager.setRescueTarget(player, null); Balm.getNetworking().sendTo(player, new RevivalProgressMessage(-1, -1)); - KnockoutSyncHandler.sendHardcoreRevivalData(rescueTarget, rescueTarget, getRevivalData(rescueTarget)); + KnockoutSyncHandler.sendHardcoreRevivalData(rescueTarget, rescueTarget); Balm.getHooks().setForcedPose(player, null); } } - public void notRescuedInTime(Player player) { + public static void notRescuedInTime(Player player) { // Disable respawn invulnerability to prevent players from surviving knockout after login with offline timer enabled if (player instanceof ServerPlayerAccessor accessor) { accessor.setSpawnInvulnerableTime(0); @@ -181,48 +173,43 @@ public void notRescuedInTime(Player player) { final var damageTypes = player.level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE); final var damageSource = new DamageSource(damageTypes.getHolderOrThrow(NOT_RESCUED_IN_TIME)); - final var revivalData = getRevivalData(player); - revivalData.setLastKnockoutTicksPassed(0); + PlayerHardcoreRevivalManager.setLastKnockoutTicksPassed(player, 0); reset(player); player.hurt(damageSource, Float.MAX_VALUE); } - public void reset(Player player) { - HardcoreRevivalData revivalData = getRevivalData(player); - revivalData.setKnockedOut(false); - revivalData.setKnockoutTicksPassed(0); + public static void reset(Player player) { + PlayerHardcoreRevivalManager.setKnockedOut(player, false); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(player, 0); updateKnockoutEffects(player); } - public void updateKnockoutEffects(Player player) { - HardcoreRevivalData revivalData = getRevivalData(player); + public static void updateKnockoutEffects(Player player) { if (HardcoreRevivalConfig.getActive().glowOnKnockout) { - player.setGlowingTag(revivalData.isKnockedOut()); + player.setGlowingTag(PlayerHardcoreRevivalManager.isKnockedOut(player)); } - Balm.getHooks().setForcedPose(player, revivalData.isKnockedOut() ? Pose.FALL_FLYING : null); + Balm.getHooks().setForcedPose(player, PlayerHardcoreRevivalManager.isKnockedOut(player) ? Pose.FALL_FLYING : null); - KnockoutSyncHandler.sendHardcoreRevivalDataToWatching(player, revivalData); + KnockoutSyncHandler.sendHardcoreRevivalDataToWatching(player); } - public void startRescue(Player player, Player target) { - HardcoreRevivalData revivalData = getRevivalData(player); - revivalData.setRescueTarget(target); - revivalData.setRescueTime(0); + public static void startRescue(Player player, Player target) { + PlayerHardcoreRevivalManager.setRescueTarget(player, target); + PlayerHardcoreRevivalManager.setRescueTime(player, 0); Balm.getNetworking().sendTo(player, new RevivalProgressMessage(target.getId(), 0.1f)); - KnockoutSyncHandler.sendHardcoreRevivalData(target, target, getRevivalData(target), true); + KnockoutSyncHandler.sendHardcoreRevivalData(target, target, true); Balm.getHooks().setForcedPose(player, Pose.CROUCHING); } - public boolean isRescuing(Player player) { - HardcoreRevivalData revivalData = getRevivalData(player); - Player rescueTarget = revivalData.getRescueTarget(); + public static boolean isRescuing(Player player) { + Player rescueTarget = PlayerHardcoreRevivalManager.getRescueTarget(player); return rescueTarget != null; } - boolean isKnockedOut(Player player) { - return getRevivalData(player).isKnockedOut(); + public static boolean isKnockedOut(Player player) { + return PlayerHardcoreRevivalManager.isKnockedOut(player); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/capability/InvalidHardcoreRevivalData.java b/common/src/main/java/net/blay09/mods/hardcorerevival/InMemoryPlayerRevivalData.java similarity index 50% rename from common/src/main/java/net/blay09/mods/hardcorerevival/capability/InvalidHardcoreRevivalData.java rename to common/src/main/java/net/blay09/mods/hardcorerevival/InMemoryPlayerRevivalData.java index 5a1dd72..b748578 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/capability/InvalidHardcoreRevivalData.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/InMemoryPlayerRevivalData.java @@ -1,92 +1,80 @@ -package net.blay09.mods.hardcorerevival.capability; +package net.blay09.mods.hardcorerevival; -import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; import org.jetbrains.annotations.Nullable; -public class InvalidHardcoreRevivalData implements HardcoreRevivalData { +class InMemoryPlayerRevivalData { + private boolean knockedOut; + private int knockoutTicksPassed; + private int lastKnockoutTicksPassed; + private long lastRescuedAt; + private long lastKnockoutAt; + private long lastLogoutAt; + private int rescueTime; + private Player rescueTarget; - public static final HardcoreRevivalData INSTANCE = new InvalidHardcoreRevivalData(); - - @Override - public void setKnockedOut(boolean knockedOut) { - } - - @Override public boolean isKnockedOut() { - return false; + return knockedOut; } - @Override - public void setKnockoutTicksPassed(int knockoutTicksPassed) { + public void setKnockedOut(boolean knockedOut) { + this.knockedOut = knockedOut; } - @Override public int getKnockoutTicksPassed() { - return 0; + return knockoutTicksPassed; } - @Override - public void setLastKnockoutTicksPassed(int lastKnockoutTicksPassed) { + public void setKnockoutTicksPassed(int knockoutTicksPassed) { + this.knockoutTicksPassed = knockoutTicksPassed; } - @Override public int getLastKnockoutTicksPassed() { - return 0; + return lastKnockoutTicksPassed; } - @Override - public void setLastRescuedAt(long lastRescuedAt) { + public void setLastKnockoutTicksPassed(int lastKnockoutTicksPassed) { + this.lastKnockoutTicksPassed = lastKnockoutTicksPassed; } - @Override public long getLastRescuedAt() { - return 0; + return lastRescuedAt; } - @Override - public void setLastKnockoutAt(long lastKnockoutAt) { + public void setLastRescuedAt(long lastRescuedAt) { + this.lastRescuedAt = lastRescuedAt; } - @Override public long getLastKnockoutAt() { - return 0; + return lastKnockoutAt; } - @Override - public void setLastLogoutAt(long lastLogoutAt) { + public void setLastKnockoutAt(long lastKnockoutAt) { + this.lastKnockoutAt = lastKnockoutAt; } - @Override public long getLastLogoutAt() { - return 0; + return lastLogoutAt; } - @Override - public void setRescueTime(int rescueTime) { + public void setLastLogoutAt(long lastLogoutAt) { + this.lastLogoutAt = lastLogoutAt; } - @Override public int getRescueTime() { - return 0; + return rescueTime; } - @Override - public void setRescueTarget(@Nullable Player rescueTarget) { + public void setRescueTime(int rescueTime) { + this.rescueTime = rescueTime; } @Nullable - @Override public Player getRescueTarget() { - return null; + return rescueTarget; } - @Override - public CompoundTag serialize() { - return new CompoundTag(); - } - - @Override - public void deserialize(CompoundTag tag) { + public void setRescueTarget(@Nullable Player rescueTarget) { + this.rescueTarget = rescueTarget; } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/InMemoryRevivalDataProvider.java b/common/src/main/java/net/blay09/mods/hardcorerevival/InMemoryRevivalDataProvider.java new file mode 100644 index 0000000..545bf2c --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/InMemoryRevivalDataProvider.java @@ -0,0 +1,96 @@ +package net.blay09.mods.hardcorerevival; + +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class InMemoryRevivalDataProvider implements RevivalDataProvider { + + private final Map playerData = new HashMap<>(); + + private InMemoryPlayerRevivalData getPlayerData(Player player) { + return playerData.computeIfAbsent(player.getUUID(), uuid -> new InMemoryPlayerRevivalData()); + } + + @Override + public void setKnockedOut(Player player, boolean knockedOut) { + getPlayerData(player).setKnockedOut(knockedOut); + } + + @Override + public boolean isKnockedOut(Player player) { + return getPlayerData(player).isKnockedOut(); + } + + @Override + public void setKnockoutTicksPassed(Player player, int knockoutTicksPassed) { + getPlayerData(player).setKnockoutTicksPassed(knockoutTicksPassed); + } + + @Override + public int getKnockoutTicksPassed(Player player) { + return getPlayerData(player).getKnockoutTicksPassed(); + } + + @Override + public void setLastKnockoutTicksPassed(Player player, int lastKnockoutTicksPassed) { + getPlayerData(player).setLastKnockoutTicksPassed(lastKnockoutTicksPassed); + } + + @Override + public int getLastKnockoutTicksPassed(Player player) { + return getPlayerData(player).getLastKnockoutTicksPassed(); + } + + @Override + public void setLastRescuedAt(Player player, long lastRescuedAt) { + getPlayerData(player).setLastRescuedAt(lastRescuedAt); + } + + @Override + public long getLastRescuedAt(Player player) { + return getPlayerData(player).getLastRescuedAt(); + } + + @Override + public void setLastKnockoutAt(Player player, long lastKnockoutAt) { + getPlayerData(player).setLastKnockoutAt(lastKnockoutAt); + } + + @Override + public long getLastKnockoutAt(Player player) { + return getPlayerData(player).getLastKnockoutAt(); + } + + @Override + public void setLastLogoutAt(Player player, long lastLogoutAt) { + getPlayerData(player).setLastLogoutAt(lastLogoutAt); + } + + @Override + public long getLastLogoutAt(Player player) { + return getPlayerData(player).getLastLogoutAt(); + } + + @Override + public void setRescueTime(Player player, int rescueTime) { + getPlayerData(player).setRescueTime(rescueTime); + } + + @Override + public int getRescueTime(Player player) { + return getPlayerData(player).getRescueTime(); + } + + @Override + public void setRescueTarget(Player player, @Nullable Player rescueTarget) { + getPlayerData(player).setRescueTarget(rescueTarget); + } + + @Override + public Player getRescueTarget(Player player) { + return getPlayerData(player).getRescueTarget(); + }} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/InternalMethodsImpl.java b/common/src/main/java/net/blay09/mods/hardcorerevival/InternalMethodsImpl.java index 31fc41b..b8bb40e 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/InternalMethodsImpl.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/InternalMethodsImpl.java @@ -8,22 +8,22 @@ public class InternalMethodsImpl implements InternalMethods { @Override public void knockout(Player player, DamageSource damageSource) { - HardcoreRevival.getManager().knockout(player, damageSource); + HardcoreRevivalManager.knockout(player, damageSource); } @Override public void wakeup(Player player, boolean applyEffects) { - HardcoreRevival.getManager().wakeup(player, applyEffects); + HardcoreRevivalManager.wakeup(player, applyEffects); } @Override public boolean isKnockedOut(Player player) { - return HardcoreRevival.getManager().isKnockedOut(player); + return PlayerHardcoreRevivalManager.isKnockedOut(player); } @Override public int getKnockoutTicksPassed(Player player) { - return HardcoreRevival.getManager().getRevivalData(player).getKnockoutTicksPassed(); + return PlayerHardcoreRevivalManager.getKnockoutTicksPassed(player); } @Override diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/MixinHooks.java b/common/src/main/java/net/blay09/mods/hardcorerevival/MixinHooks.java index 69f585e..1738110 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/MixinHooks.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/MixinHooks.java @@ -1,22 +1,24 @@ package net.blay09.mods.hardcorerevival; +import net.blay09.mods.hardcorerevival.handler.KnockoutRestrictionHandler; import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; public class MixinHooks { public static boolean shouldCancelMovement(Entity entity) { - return entity instanceof Player && HardcoreRevival.getRevivalData(entity).isKnockedOut(); + return entity instanceof Player player && PlayerHardcoreRevivalManager.isKnockedOut(player); } - public static boolean shouldCancelHealing(Player entity) { - return HardcoreRevival.getRevivalData(entity).isKnockedOut(); + public static boolean shouldCancelHealing(Player player) { + return PlayerHardcoreRevivalManager.isKnockedOut(player); } public static boolean shouldCancelFire(Entity entity) { - return HardcoreRevival.getRevivalData(entity).isKnockedOut(); + return entity instanceof Player player && PlayerHardcoreRevivalManager.isKnockedOut(player); } public static void handleProcessPlayerRotation(ServerPlayer player, ServerboundMovePlayerPacket packet) { @@ -24,4 +26,12 @@ public static void handleProcessPlayerRotation(ServerPlayer player, ServerboundM float pitch = packet.getXRot(player.getXRot()); player.absMoveTo(player.getX(), player.getY(), player.getZ(), yaw, pitch); } + + public static boolean shouldCancelToss(Player player, ItemStack itemStack) { + return PlayerHardcoreRevivalManager.isKnockedOut(player) && !KnockoutRestrictionHandler.mayTossItemKnockedOut(itemStack); + } + + public static boolean shouldCancelTossAll(Player player) { + return PlayerHardcoreRevivalManager.isKnockedOut(player); + } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/PersistentRevivalDataProvider.java b/common/src/main/java/net/blay09/mods/hardcorerevival/PersistentRevivalDataProvider.java new file mode 100644 index 0000000..779bf0d --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/PersistentRevivalDataProvider.java @@ -0,0 +1,114 @@ +package net.blay09.mods.hardcorerevival; + +import net.blay09.mods.balm.api.Balm; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.Nullable; + +public class PersistentRevivalDataProvider implements RevivalDataProvider { + + private static final String TAG_NAME = "HardcoreRevivalData"; + private static final String KNOCKED_OUT = "KnockedOut"; + private static final String KNOCKOUT_TICKS_PASSED = "KnockoutTicksPassed"; + private static final String LAST_KNOCKOUT_TICKS_PASSED = "LastKnockoutTicksPassed"; + private static final String LAST_RESCUED_AT = "LastRescuedAt"; + private static final String LAST_KNOCKOUT_AT = "LastKnockoutAt"; + private static final String LAST_LOGOUT_AT = "LastLogoutAt"; + private static final String RESCUE_TARGET = "RescueTarget"; + + private static CompoundTag getRevivalData(Player player) { + CompoundTag persistedData = Balm.getHooks().getPersistentData(player); + CompoundTag compound = persistedData.getCompound(TAG_NAME); + persistedData.put(TAG_NAME, compound); + return compound; + } + + @Override + public void setKnockedOut(Player player, boolean knockedOut) { + getRevivalData(player).putBoolean(KNOCKED_OUT, knockedOut); + } + + @Override + public boolean isKnockedOut(Player player) { + return getRevivalData(player).getBoolean(KNOCKED_OUT); + } + + @Override + public void setKnockoutTicksPassed(Player player, int knockoutTicksPassed) { + getRevivalData(player).putInt(KNOCKOUT_TICKS_PASSED, knockoutTicksPassed); + } + + @Override + public int getKnockoutTicksPassed(Player player) { + return getRevivalData(player).getInt(KNOCKOUT_TICKS_PASSED); + } + + @Override + public void setLastKnockoutTicksPassed(Player player, int lastKnockoutTicksPassed) { + getRevivalData(player).putInt(LAST_KNOCKOUT_TICKS_PASSED, lastKnockoutTicksPassed); + } + + @Override + public int getLastKnockoutTicksPassed(Player player) { + return getRevivalData(player).getInt(LAST_KNOCKOUT_TICKS_PASSED); + } + + @Override + public void setLastRescuedAt(Player player, long lastRescuedAt) { + getRevivalData(player).putLong(LAST_RESCUED_AT, lastRescuedAt); + } + + @Override + public long getLastRescuedAt(Player player) { + return getRevivalData(player).getLong(LAST_RESCUED_AT); + } + + @Override + public void setLastKnockoutAt(Player player, long lastKnockoutAt) { + getRevivalData(player).putLong(LAST_KNOCKOUT_AT, lastKnockoutAt); + } + + @Override + public long getLastKnockoutAt(Player player) { + return getRevivalData(player).getLong(LAST_KNOCKOUT_AT); + } + + @Override + public void setLastLogoutAt(Player player, long lastLogoutAt) { + getRevivalData(player).putLong(LAST_LOGOUT_AT, lastLogoutAt); + } + + @Override + public long getLastLogoutAt(Player player) { + return getRevivalData(player).getLong(LAST_LOGOUT_AT); + } + + @Override + public void setRescueTime(Player player, int rescueTime) { + getRevivalData(player).putInt(LAST_RESCUED_AT, rescueTime); + } + + @Override + public int getRescueTime(Player player) { + return getRevivalData(player).getInt(LAST_RESCUED_AT); + } + + @Override + public void setRescueTarget(Player player, @Nullable Player rescueTarget) { + if (rescueTarget != null) { + getRevivalData(player).putUUID(RESCUE_TARGET, rescueTarget.getGameProfile().getId()); + } else { + getRevivalData(player).remove(RESCUE_TARGET); + } + } + + @Override + public Player getRescueTarget(Player player) { + final var server = player.level().getServer(); + if (server != null) { + final var tag = getRevivalData(player); + return tag.contains(RESCUE_TARGET) ? server.getPlayerList().getPlayer(tag.getUUID(RESCUE_TARGET)) : null; + } + return null; + } +} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/PlayerHardcoreRevivalManager.java b/common/src/main/java/net/blay09/mods/hardcorerevival/PlayerHardcoreRevivalManager.java new file mode 100644 index 0000000..3a9086c --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/PlayerHardcoreRevivalManager.java @@ -0,0 +1,80 @@ +package net.blay09.mods.hardcorerevival; + +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +public class PlayerHardcoreRevivalManager { + + private static final RevivalDataProvider persistentDataProvider = new PersistentRevivalDataProvider(); + private static final RevivalDataProvider inMemoryDataProvider = new InMemoryRevivalDataProvider(); + + public static RevivalDataProvider getRevivalDataProvider(@Nullable Level world) { + return world == null || world.isClientSide ? inMemoryDataProvider : persistentDataProvider; + } + + public static void setKnockedOut(Player player, boolean knockedOut) { + getRevivalDataProvider(player.level()).setKnockedOut(player, knockedOut); + } + + public static boolean isKnockedOut(Player player) { + return getRevivalDataProvider(player.level()).isKnockedOut(player); + } + + public static void setKnockoutTicksPassed(Player player, int knockoutTicksPassed) { + getRevivalDataProvider(player.level()).setKnockoutTicksPassed(player, knockoutTicksPassed); + } + + public static int getKnockoutTicksPassed(Player player) { + return getRevivalDataProvider(player.level()).getKnockoutTicksPassed(player); + } + + public static void setLastKnockoutTicksPassed(Player player, int lastKnockoutTicksPassed) { + getRevivalDataProvider(player.level()).setLastKnockoutTicksPassed(player, lastKnockoutTicksPassed); + } + + public static int getLastKnockoutTicksPassed(Player player) { + return getRevivalDataProvider(player.level()).getLastKnockoutTicksPassed(player); + } + + public static void setLastRescuedAt(Player player, long lastRescuedAt) { + getRevivalDataProvider(player.level()).setLastRescuedAt(player, lastRescuedAt); + } + + public static long getLastRescuedAt(Player player) { + return getRevivalDataProvider(player.level()).getLastRescuedAt(player); + } + + public static void setLastKnockoutAt(Player player, long lastKnockoutAt) { + getRevivalDataProvider(player.level()).setLastKnockoutAt(player, lastKnockoutAt); + } + + public static long getLastKnockoutAt(Player player) { + return getRevivalDataProvider(player.level()).getLastKnockoutAt(player); + } + + public static void setLastLogoutAt(Player player, long lastLogoutAt) { + getRevivalDataProvider(player.level()).setLastLogoutAt(player, lastLogoutAt); + } + + public static long getLastLogoutAt(Player player) { + return getRevivalDataProvider(player.level()).getLastLogoutAt(player); + } + + public static void setRescueTime(Player player, int rescueTime) { + getRevivalDataProvider(player.level()).setRescueTime(player, rescueTime); + } + + public static int getRescueTime(Player player) { + return getRevivalDataProvider(player.level()).getRescueTime(player); + } + + public static void setRescueTarget(Player player, @Nullable Player rescueTarget) { + getRevivalDataProvider(player.level()).setRescueTarget(player, rescueTarget); + } + + @Nullable + public static Player getRescueTarget(Player player) { + return getRevivalDataProvider(player.level()).getRescueTarget(player); + } +} \ No newline at end of file diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/RevivalDataProvider.java b/common/src/main/java/net/blay09/mods/hardcorerevival/RevivalDataProvider.java new file mode 100644 index 0000000..b6bad91 --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/RevivalDataProvider.java @@ -0,0 +1,37 @@ +package net.blay09.mods.hardcorerevival; + +import net.minecraft.world.entity.player.Player; + +public interface RevivalDataProvider { + void setKnockedOut(Player player, boolean knockedOut); + + boolean isKnockedOut(Player player); + + void setKnockoutTicksPassed(Player player, int knockoutTicksPassed); + + int getKnockoutTicksPassed(Player player); + + void setLastKnockoutTicksPassed(Player player, int lastKnockoutTicksPassed); + + int getLastKnockoutTicksPassed(Player player); + + void setLastRescuedAt(Player player, long lastRescuedAt); + + long getLastRescuedAt(Player player); + + void setLastKnockoutAt(Player player, long lastKnockoutAt); + + long getLastKnockoutAt(Player player); + + void setLastLogoutAt(Player player, long lastLogoutAt); + + long getLastLogoutAt(Player player); + + void setRescueTime(Player player, int rescueTime); + + int getRescueTime(Player player); + + void setRescueTarget(Player player, Player rescueTarget); + + Player getRescueTarget(Player player); +} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/capability/HardcoreRevivalData.java b/common/src/main/java/net/blay09/mods/hardcorerevival/capability/HardcoreRevivalData.java deleted file mode 100644 index c9b6034..0000000 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/capability/HardcoreRevivalData.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.blay09.mods.hardcorerevival.capability; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.entity.player.Player; - -public interface HardcoreRevivalData { - void setKnockedOut(boolean knockedOut); - - boolean isKnockedOut(); - - void setKnockoutTicksPassed(int knockoutTicksPassed); - - int getKnockoutTicksPassed(); - - void setLastKnockoutTicksPassed(int lastKnockoutTicksPassed); - - int getLastKnockoutTicksPassed(); - - void setLastRescuedAt(long lastRescuedAt); - - long getLastRescuedAt(); - - void setLastKnockoutAt(long lastKnockoutAt); - - long getLastKnockoutAt(); - - void setLastLogoutAt(long lastLogoutAt); - - long getLastLogoutAt(); - - void setRescueTime(int rescueTime); - - int getRescueTime(); - - void setRescueTarget(Player rescueTarget); - - Player getRescueTarget(); - - CompoundTag serialize(); - - void deserialize(CompoundTag tag); -} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/capability/HardcoreRevivalDataImpl.java b/common/src/main/java/net/blay09/mods/hardcorerevival/capability/HardcoreRevivalDataImpl.java deleted file mode 100644 index 0dc90b5..0000000 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/capability/HardcoreRevivalDataImpl.java +++ /dev/null @@ -1,124 +0,0 @@ -package net.blay09.mods.hardcorerevival.capability; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.entity.player.Player; - -public class HardcoreRevivalDataImpl implements HardcoreRevivalData { - private static final String KNOCKED_OUT = "KnockedOut"; - private static final String KNOCKOUT_TICKS_PASSED = "KnockoutTicksPassed"; - private static final String LAST_KNOCKOUT_TICKS_PASSED = "LastKnockoutTicksPassed"; - private static final String LAST_RESCUED_AT = "LastRescuedAt"; - private static final String LAST_KNOCKOUT_AT = "LastKnockoutAt"; - private static final String LAST_LOGOUT_AT = "LastLogoutAt"; - - private boolean knockedOut; - private int knockoutTicksPassed; - private int lastKnockoutTicksPassed; - private long lastRescuedAt; - private long lastKnockoutAt; - private long lastLogoutAt; - private int rescueTime; - private Player rescueTarget; - - @Override - public void setKnockedOut(boolean knockedOut) { - this.knockedOut = knockedOut; - } - - @Override - public boolean isKnockedOut() { - return knockedOut; - } - - @Override - public void setKnockoutTicksPassed(int knockoutTicksPassed) { - this.knockoutTicksPassed = knockoutTicksPassed; - } - - @Override - public int getKnockoutTicksPassed() { - return knockoutTicksPassed; - } - - @Override - public void setLastKnockoutTicksPassed(int lastKnockoutTicksPassed) { - this.lastKnockoutTicksPassed = lastKnockoutTicksPassed; - } - - @Override - public int getLastKnockoutTicksPassed() { - return lastKnockoutTicksPassed; - } - - @Override - public void setLastKnockoutAt(long lastKnockoutAt) { - this.lastKnockoutAt = lastKnockoutAt; - } - - @Override - public void setLastRescuedAt(long lastRescuedAt) { - this.lastRescuedAt = lastRescuedAt; - } - - @Override - public long getLastRescuedAt() { - return lastRescuedAt; - } - - @Override - public long getLastKnockoutAt() { - return lastKnockoutAt; - } - - @Override - public void setLastLogoutAt(long lastLogoutAt) { - this.lastLogoutAt = lastLogoutAt; - } - - @Override - public long getLastLogoutAt() { - return lastLogoutAt; - } - - @Override - public void setRescueTime(int rescueTime) { - this.rescueTime = rescueTime; - } - - @Override - public int getRescueTime() { - return rescueTime; - } - - @Override - public void setRescueTarget(Player rescueTarget) { - this.rescueTarget = rescueTarget; - } - - @Override - public Player getRescueTarget() { - return rescueTarget; - } - - @Override - public CompoundTag serialize() { - CompoundTag tagCompound = new CompoundTag(); - tagCompound.putBoolean(KNOCKED_OUT, isKnockedOut()); - tagCompound.putInt(KNOCKOUT_TICKS_PASSED, getKnockoutTicksPassed()); - tagCompound.putInt(LAST_KNOCKOUT_TICKS_PASSED, getLastKnockoutTicksPassed()); - tagCompound.putLong(LAST_LOGOUT_AT, getLastLogoutAt()); - tagCompound.putLong(LAST_KNOCKOUT_AT, getLastKnockoutAt()); - tagCompound.putLong(LAST_RESCUED_AT, getLastRescuedAt()); - return tagCompound; - } - - @Override - public void deserialize(CompoundTag tag) { - setKnockedOut(tag.getBoolean(KNOCKED_OUT)); - setKnockoutTicksPassed(tag.getInt(KNOCKOUT_TICKS_PASSED)); - setLastKnockoutTicksPassed(tag.getInt(LAST_KNOCKOUT_TICKS_PASSED)); - setLastLogoutAt(tag.getLong(LAST_LOGOUT_AT)); - setLastKnockoutAt(tag.getLong(LAST_KNOCKOUT_AT)); - setLastRescuedAt(tag.getLong(LAST_RESCUED_AT)); - } -} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/client/GuiHelper.java b/common/src/main/java/net/blay09/mods/hardcorerevival/client/GuiHelper.java index ea21fe2..14481b3 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/client/GuiHelper.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/client/GuiHelper.java @@ -1,6 +1,7 @@ package net.blay09.mods.hardcorerevival.client; import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -28,7 +29,7 @@ public static void renderDeathTimer(GuiGraphics guiGraphics, int width, int heig } else { int maxTicksUntilDeath = HardcoreRevivalConfig.getActive().secondsUntilDeath * 20; if (maxTicksUntilDeath > 0) { - int deathSecondsLeft = Math.max(0, (maxTicksUntilDeath - HardcoreRevival.getClientRevivalData().getKnockoutTicksPassed()) / 20); + int deathSecondsLeft = Math.max(0, (maxTicksUntilDeath - PlayerHardcoreRevivalManager.getKnockoutTicksPassed(Minecraft.getInstance().player)) / 20); guiGraphics.drawCenteredString(font, I18n.get("gui.hardcorerevival.rescue_time_left", deathSecondsLeft), width / 2, height / 2 + 10, 16777215); } else { guiGraphics.drawCenteredString(font, I18n.get("gui.hardcorerevival.wait_for_rescue"), width / 2, height / 2 + 10, 16777215); diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/client/HardcoreRevivalClient.java b/common/src/main/java/net/blay09/mods/hardcorerevival/client/HardcoreRevivalClient.java index a6ddd78..da53dcd 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/client/HardcoreRevivalClient.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/client/HardcoreRevivalClient.java @@ -6,10 +6,8 @@ import net.blay09.mods.balm.api.event.TickType; import net.blay09.mods.balm.api.event.client.FovUpdateEvent; import net.blay09.mods.balm.api.event.client.GuiDrawEvent; -import net.blay09.mods.balm.api.event.client.KeyInputEvent; import net.blay09.mods.balm.api.event.client.OpenScreenEvent; -import net.blay09.mods.hardcorerevival.HardcoreRevival; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.blay09.mods.hardcorerevival.network.RescueMessage; import net.minecraft.client.Minecraft; @@ -34,7 +32,6 @@ public class HardcoreRevivalClient { public static void initialize() { Balm.getEvents().onEvent(OpenScreenEvent.class, HardcoreRevivalClient::onOpenScreen); Balm.getEvents().onEvent(FovUpdateEvent.class, HardcoreRevivalClient::onFovUpdate); - Balm.getEvents().onEvent(KeyInputEvent.class, HardcoreRevivalClient::onKeyInput); Balm.getEvents().onEvent(GuiDrawEvent.Pre.class, HardcoreRevivalClient::onGuiDrawPre); Balm.getEvents().onEvent(GuiDrawEvent.Post.class, HardcoreRevivalClient::onGuiDrawPost); @@ -43,7 +40,7 @@ public static void initialize() { private static boolean isKnockedOut() { LocalPlayer player = Minecraft.getInstance().player; - return HardcoreRevival.getClientRevivalData().isKnockedOut() && player != null && player.isAlive(); + return player != null && PlayerHardcoreRevivalManager.isKnockedOut(player) && player.isAlive(); } public static void onOpenScreen(OpenScreenEvent event) { @@ -61,7 +58,7 @@ public static void onFovUpdate(FovUpdateEvent event) { public static void onGuiDrawPre(GuiDrawEvent.Pre event) { // Flash the health bar red if the player is knocked out if (event.getElement() == GuiDrawEvent.Element.HEALTH && isKnockedOut()) { - int knockoutTicksPassed = HardcoreRevival.getClientRevivalData().getKnockoutTicksPassed(); + int knockoutTicksPassed = PlayerHardcoreRevivalManager.getKnockoutTicksPassed(Minecraft.getInstance().player); float redness = (float) Math.sin(knockoutTicksPassed / 2f); RenderSystem.setShaderColor(1f, 1f - redness, 1 - redness, 1f); } @@ -113,11 +110,10 @@ public static void onGuiDrawPost(GuiDrawEvent.Post event) { } } - if (!HardcoreRevival.getClientRevivalData() - .isKnockedOut() && mc.player != null && !mc.player.isSpectator() && mc.player.isAlive() && !isRescuing) { + if (!PlayerHardcoreRevivalManager.isKnockedOut(mc.player) && mc.player != null && !mc.player.isSpectator() && mc.player.isAlive() && !isRescuing) { Entity pointedEntity = Minecraft.getInstance().crosshairPickEntity; - if (pointedEntity != null && HardcoreRevival.getRevivalData(pointedEntity) - .isKnockedOut() && mc.player.distanceTo(pointedEntity) <= HardcoreRevivalConfig.getActive().rescueDistance) { + if (pointedEntity instanceof Player pointedPlayer && PlayerHardcoreRevivalManager.isKnockedOut(pointedPlayer) && mc.player.distanceTo( + pointedEntity) <= HardcoreRevivalConfig.getActive().rescueDistance) { Component rescueKeyText = mc.options.keyUse.getTranslatedKeyMessage(); var textComponent = Component.translatable("gui.hardcorerevival.hold_to_rescue", rescueKeyText); guiGraphics.drawString(mc.font, @@ -135,15 +131,6 @@ public static void onGuiDrawPost(GuiDrawEvent.Post event) { } } - public static void onKeyInput(KeyInputEvent event) { - Minecraft mc = Minecraft.getInstance(); - // Suppress item drops and movement when knocked out - if (isKnockedOut()) { - //noinspection StatementWithEmptyBody - while (mc.options.keyDrop.consumeClick()) ; - } - } - public static void onClientTick(Minecraft client) { if (client.player != null) { if (isKnockedOut()) { @@ -153,8 +140,7 @@ public static void onClientTick(Minecraft client) { wasKnockedOut = true; } - HardcoreRevivalData revivalData = HardcoreRevival.getRevivalData(client.player); - revivalData.setKnockoutTicksPassed(revivalData.getKnockoutTicksPassed() + 1); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(client.player, PlayerHardcoreRevivalManager.getKnockoutTicksPassed(client.player) + 1); } else { if (wasKnockedOut) { Balm.getHooks().setForcedPose(client.player, null); @@ -167,8 +153,8 @@ public static void onClientTick(Minecraft client) { } // If right mouse is held down, and player is not in spectator mode, send rescue packet - if (client.options.keyUse.isDown() && !client.player.isSpectator() && client.player.isAlive() && !HardcoreRevival.getClientRevivalData() - .isKnockedOut()) { + if (client.options.keyUse.isDown() && !client.player.isSpectator() && client.player.isAlive() && !PlayerHardcoreRevivalManager.isKnockedOut( + client.player)) { if (!isRescuing) { Balm.getNetworking().sendToServer(new RescueMessage(true)); isRescuing = true; diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/client/HardcoreRevivalClientManager.java b/common/src/main/java/net/blay09/mods/hardcorerevival/client/HardcoreRevivalClientManager.java deleted file mode 100644 index 0a482fc..0000000 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/client/HardcoreRevivalClientManager.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.blay09.mods.hardcorerevival.client; - -import net.blay09.mods.hardcorerevival.HardcoreRevival; -import net.blay09.mods.hardcorerevival.HardcoreRevivalManager; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; -import net.minecraft.client.Minecraft; -import net.minecraft.world.entity.player.Player; - -public class HardcoreRevivalClientManager extends HardcoreRevivalManager { - - @Override - public HardcoreRevivalData getRevivalData(Player player) { - if (Minecraft.getInstance().player == player) { - return HardcoreRevival.getClientRevivalData(); - } - - return super.getRevivalData(player); - } - -} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/command/ReviveCommand.java b/common/src/main/java/net/blay09/mods/hardcorerevival/command/ReviveCommand.java index 5b5049d..e15ea45 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/command/ReviveCommand.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/command/ReviveCommand.java @@ -3,7 +3,7 @@ import com.google.common.collect.ImmutableList; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.BoolArgumentType; -import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.HardcoreRevivalManager; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.EntityArgument; @@ -27,7 +27,7 @@ public static void register(CommandDispatcher dispatcher) { private static int reviveEntities(CommandSourceStack source, Collection targets, boolean skipEffects) { for (Entity entity : targets) { if (entity instanceof Player player) { - HardcoreRevival.getManager().wakeup(player, !skipEffects); + HardcoreRevivalManager.wakeup(player, !skipEffects); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/compat/Compat.java b/common/src/main/java/net/blay09/mods/hardcorerevival/compat/Compat.java index e7f68ce..4ddce33 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/compat/Compat.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/compat/Compat.java @@ -2,4 +2,7 @@ public class Compat { public static final String MR_CRAYFISHS_GUN_MOD = "cgm"; + public static final String INVENTORY_TOTEM = "inventorytotem"; + public static final String TRINKETS = "trinkets"; + public static final String CURIOS = "curios"; } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/compat/InventoryTotemAddon.java b/common/src/main/java/net/blay09/mods/hardcorerevival/compat/InventoryTotemAddon.java new file mode 100644 index 0000000..ced4841 --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/compat/InventoryTotemAddon.java @@ -0,0 +1,21 @@ +package net.blay09.mods.hardcorerevival.compat; + +import net.blay09.mods.balm.api.Balm; +import net.blay09.mods.hardcorerevival.api.PlayerAboutToKnockOutEvent; +import net.blay09.mods.hardcorerevival.tag.ModItemTags; +import net.minecraft.world.item.Items; + +public class InventoryTotemAddon { + public InventoryTotemAddon() { + Balm.getEvents().onEvent(PlayerAboutToKnockOutEvent.class, event -> { + final var player = event.getPlayer(); + final var inventory = player.getInventory(); + for (int i = 0; i < inventory.getContainerSize(); i++) { + final var itemStack = inventory.getItem(i); + if (itemStack.is(ModItemTags.PASSTHROUGH_DEATH_WHEN_HELD)) { + event.setCanceled(true); + } + } + }); + } +} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/config/HardcoreRevivalConfigData.java b/common/src/main/java/net/blay09/mods/hardcorerevival/config/HardcoreRevivalConfigData.java index beb705d..2f67350 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/config/HardcoreRevivalConfigData.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/config/HardcoreRevivalConfigData.java @@ -76,4 +76,8 @@ public class HardcoreRevivalConfigData implements BalmConfigData { @Comment("The damage sources that kill a player instantly, without a K.O. period.") @ExpectedType(ResourceLocation.class) public Set instantDeathSources = Set.of(ResourceLocation.withDefaultNamespace("lava")); + + @Comment("The source entity types that kill a player instantly, without a K.O. period.") + @ExpectedType(ResourceLocation.class) + public Set instantDeathEntityTypes = Set.of(); } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutHandler.java b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutHandler.java index 2bbd2fe..f606861 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutHandler.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutHandler.java @@ -4,19 +4,24 @@ import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.api.event.*; import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.api.PlayerAboutToKnockOutEvent; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.blay09.mods.hardcorerevival.HardcoreRevivalManager; -import net.blay09.mods.hardcorerevival.mixin.LivingEntityAccessor; +import net.blay09.mods.hardcorerevival.tag.ModItemTags; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.DamageTypeTags; +import net.minecraft.world.InteractionHand; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Pose; +import net.minecraft.world.item.Items; + +import java.util.Objects; public class KnockoutHandler { @@ -32,7 +37,7 @@ public static void onPlayerDamage(LivingDamageEvent event) { if (event.getEntity() instanceof ServerPlayer player) { DamageSource damageSource = event.getDamageSource(); - if (HardcoreRevival.getRevivalData(event.getEntity()).isKnockedOut()) { + if (PlayerHardcoreRevivalManager.isKnockedOut(player)) { Entity attacker = damageSource.getEntity(); if (attacker instanceof Mob mob) { mob.setTarget(null); @@ -45,22 +50,28 @@ public static void onPlayerDamage(LivingDamageEvent event) { boolean wouldDie = player.getHealth() - event.getDamageAmount() <= 0f; if (wouldDie && isKnockoutEnabledFor(player, damageSource)) { - // Reduce damage to prevent the player from dying - event.setDamageAmount(Math.min(event.getDamageAmount(), Math.max(0f, player.getHealth() - 1f))); - final var aboutToKnockOutEvent = new PlayerAboutToKnockOutEvent(player, damageSource); Balm.getEvents().fireEvent(aboutToKnockOutEvent); - // Trigger knockout for this player, if totem does not protect player - if (aboutToKnockOutEvent.isCanceled() || ((LivingEntityAccessor) player).callCheckTotemDeathProtection(damageSource)) { - aboutToKnockOutEvent.setCanceled(true); - } else { - HardcoreRevival.getManager().knockout(player, damageSource); + if (!aboutToKnockOutEvent.isCanceled()) { + event.setDamageAmount(Math.min(event.getDamageAmount(), Math.max(0f, player.getHealth() - 1f))); + HardcoreRevivalManager.knockout(player, damageSource); } } } } + private static boolean holdsDeathProtectionItem(ServerPlayer player) { + for (final var hand : InteractionHand.values()) { + final var itemStack = player.getItemInHand(hand); + if (itemStack.is(ModItemTags.PASSTHROUGH_DEATH_WHEN_HELD)) { + return true; + } + } + + return false; + } + private static boolean isKnockoutEnabledFor(ServerPlayer player, DamageSource damageSource) { final var server = player.getServer(); if (server == null) { @@ -73,37 +84,48 @@ private static boolean isKnockoutEnabledFor(ServerPlayer player, DamageSource da return false; } + final var attacker = damageSource.getEntity(); + if (attacker != null) { + final var entityTypeId = BuiltInRegistries.ENTITY_TYPE.getKey(attacker.getType()); + if (HardcoreRevivalConfig.getActive().instantDeathEntityTypes.contains(entityTypeId)) { + return false; + } + } + if (HardcoreRevivalConfig.getActive().disableInSingleplayer && server.isSingleplayer() && server.getPlayerCount() == 1) { return false; } else if (HardcoreRevivalConfig.getActive().disableInLonelyMultiplayer && !server.isSingleplayer() && server.getPlayerCount() == 1) { return false; } + if (holdsDeathProtectionItem(player)) { + return false; + } + return true; } public static void onPlayerTick(ServerPlayer player) { //if (event.phase == TickEvent.Phase.START && event.side == LogicalSide.SERVER) { - HardcoreRevivalData revivalData = HardcoreRevival.getRevivalData(player); - if (revivalData.isKnockedOut() && player.isAlive()) { + if (PlayerHardcoreRevivalManager.isKnockedOut(player) && player.isAlive()) { // Make sure health stays locked at half a heart player.setHealth(1f); - revivalData.setKnockoutTicksPassed(revivalData.getKnockoutTicksPassed() + 1); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(player, PlayerHardcoreRevivalManager.getKnockoutTicksPassed(player) + 1); if (player.tickCount % 20 == 0) { - Balm.getHooks().setForcedPose(player, revivalData.isKnockedOut() ? Pose.FALL_FLYING : null); + Balm.getHooks().setForcedPose(player, PlayerHardcoreRevivalManager.isKnockedOut(player) ? Pose.FALL_FLYING : null); } int maxTicksUntilDeath = HardcoreRevivalConfig.getActive().secondsUntilDeath * 20; - if (maxTicksUntilDeath > 0 && revivalData.getKnockoutTicksPassed() >= maxTicksUntilDeath) { - HardcoreRevival.getManager().notRescuedInTime(player); + if (maxTicksUntilDeath > 0 && PlayerHardcoreRevivalManager.getKnockoutTicksPassed(player) >= maxTicksUntilDeath) { + HardcoreRevivalManager.notRescuedInTime(player); } } } public static void onPlayerRespawn(PlayerRespawnEvent event) { - HardcoreRevival.getManager().reset(event.getNewPlayer()); + HardcoreRevivalManager.reset(event.getNewPlayer()); } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutRestrictionHandler.java b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutRestrictionHandler.java index 8395a3a..1530aba 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutRestrictionHandler.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutRestrictionHandler.java @@ -1,24 +1,26 @@ package net.blay09.mods.hardcorerevival.handler; -import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.api.event.*; -import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; -import net.minecraft.server.players.PlayerList; +import net.blay09.mods.hardcorerevival.tag.ModBlockTags; +import net.blay09.mods.hardcorerevival.tag.ModItemTags; +import net.minecraft.core.BlockPos; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BowItem; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; public class KnockoutRestrictionHandler { public static void initialize() { Balm.getEvents().onEvent(UseBlockEvent.class, KnockoutRestrictionHandler::onUseBlock, EventPriority.Highest); Balm.getEvents().onEvent(UseItemEvent.class, KnockoutRestrictionHandler::onUseItem, EventPriority.Highest); - Balm.getEvents().onEvent(TossItemEvent.class, KnockoutRestrictionHandler::onTossItem, EventPriority.Highest); Balm.getEvents().onEvent(PlayerAttackEvent.class, KnockoutRestrictionHandler::onAttack, EventPriority.Highest); Balm.getEvents().onEvent(DigSpeedEvent.class, KnockoutRestrictionHandler::onDigSpeed, EventPriority.Highest); Balm.getEvents().onEvent(LivingHealEvent.class, KnockoutRestrictionHandler::onHeal); @@ -44,7 +46,7 @@ public static void onCommand(CommandEvent event) { return; } - if (HardcoreRevival.getRevivalData(player).isKnockedOut()) { + if (PlayerHardcoreRevivalManager.isKnockedOut(player)) { player.sendSystemMessage(Component.translatable("commands.disabled_when_knocked_out").withStyle(ChatFormatting.RED)); event.setCanceled(true); } @@ -52,7 +54,7 @@ public static void onCommand(CommandEvent event) { public static void onHeal(LivingHealEvent event) { if (event.getEntity() instanceof Player player) { - if (HardcoreRevival.getRevivalData(player).isKnockedOut()) { + if (PlayerHardcoreRevivalManager.isKnockedOut(player)) { event.setCanceled(false); } } @@ -60,50 +62,75 @@ public static void onHeal(LivingHealEvent event) { public static void onDigSpeed(DigSpeedEvent event) { Player player = event.getPlayer(); - if (player != null && HardcoreRevival.getRevivalData(player).isKnockedOut()) { - event.setSpeedOverride(0f); - event.setCanceled(true); + if (player != null && PlayerHardcoreRevivalManager.isKnockedOut(player)) { + if (!mayBreakBlockKnockedOut(event.getState())) { + event.setSpeedOverride(0f); + event.setCanceled(true); + } } } public static void onUseBlock(UseBlockEvent event) { Player player = event.getPlayer(); - if (HardcoreRevival.getRevivalData(player).isKnockedOut()) { + if (PlayerHardcoreRevivalManager.isKnockedOut(player)) { ItemStack itemStack = player.getItemInHand(event.getHand()); - if (!HardcoreRevivalConfig.getActive().allowBows || !(itemStack.getItem() instanceof BowItem)) { + final var level = event.getLevel(); + final var pos = event.getHitResult().getBlockPos(); + if (!mayUseItemKnockedOut(itemStack) && !mayUseBlockKnockedOut(level, pos, itemStack)) { event.setCanceled(true); } } } public static void onUseItem(UseItemEvent event) { - LivingEntity player = event.getPlayer(); - if (HardcoreRevival.getRevivalData(player).isKnockedOut()) { + final var player = event.getPlayer(); + if (PlayerHardcoreRevivalManager.isKnockedOut(player)) { ItemStack itemStack = player.getItemInHand(event.getHand()); - if (!HardcoreRevivalConfig.getActive().allowBows || !(itemStack.getItem() instanceof BowItem)) { + if (!mayUseItemKnockedOut(itemStack)) { event.setCanceled(true); } } } - public static void onTossItem(TossItemEvent event) { + public static void onAttack(PlayerAttackEvent event) { Player player = event.getPlayer(); - if (HardcoreRevival.getRevivalData(player).isKnockedOut()) { - // We try to suppress the drop on the client too, but if that failed for some reason, just try to revert the action - if (player.addItem(event.getItemStack())) { + if (player != null && PlayerHardcoreRevivalManager.isKnockedOut(player)) { + final var itemStack = player.getMainHandItem(); + if (HardcoreRevivalConfig.getActive().allowUnarmedMelee && itemStack.isEmpty()) { + return; + } + + if (!mayAttackWithItemKnockedOut(itemStack)) { event.setCanceled(true); } } } - public static void onAttack(PlayerAttackEvent event) { - Player player = event.getPlayer(); - if (player != null && HardcoreRevival.getRevivalData(player).isKnockedOut()) { - if (HardcoreRevivalConfig.getActive().allowUnarmedMelee && player.getMainHandItem().isEmpty()) { - return; - } + private static boolean mayUseItemKnockedOut(ItemStack itemStack) { + if (HardcoreRevivalConfig.getActive().allowBows && (itemStack.getItem() instanceof BowItem)) { + return true; + } - event.setCanceled(true); + return itemStack.is(ModItemTags.ALLOW_USE_WHILE_KNOCKED_OUT); + } + + public static boolean mayTossItemKnockedOut(ItemStack itemStack) { + return itemStack.is(ModItemTags.ALLOW_TOSS_WHILE_KNOCKED_OUT); + } + + private static boolean mayAttackWithItemKnockedOut(ItemStack itemStack) { + return itemStack.is(ModItemTags.ALLOW_ATTACK_WHILE_KNOCKED_OUT); + } + + private static boolean mayUseBlockKnockedOut(Level level, BlockPos pos, ItemStack itemStack) { + if (!itemStack.isEmpty()) { + return false; } + + return level.getBlockState(pos).is(ModBlockTags.ALLOW_USE_WHILE_KNOCKED_OUT); + } + + private static boolean mayBreakBlockKnockedOut(BlockState state) { + return state.is(ModBlockTags.ALLOW_BREAK_WHILE_KNOCKED_OUT); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutSyncHandler.java b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutSyncHandler.java index 3099d29..31db718 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutSyncHandler.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/KnockoutSyncHandler.java @@ -2,12 +2,10 @@ import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.api.event.ChunkTrackingEvent; -import net.blay09.mods.hardcorerevival.HardcoreRevival; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.network.HardcoreRevivalDataMessage; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; public class KnockoutSyncHandler { @@ -18,25 +16,30 @@ public static void initialize() { public static void onStartChunkTracking(ChunkTrackingEvent.Start event) { MinecraftServer server = event.getLevel().getServer(); for (ServerPlayer player : server.getPlayerList().getPlayers()) { - HardcoreRevivalData revivalData = HardcoreRevival.getRevivalData(player); - if (revivalData.isKnockedOut()) { - sendHardcoreRevivalData(event.getPlayer(), player, revivalData); + if (PlayerHardcoreRevivalManager.isKnockedOut(player)) { + sendHardcoreRevivalData(event.getPlayer(), player); } } } - public static void sendHardcoreRevivalDataToWatching(Player player, HardcoreRevivalData revivalData) { - HardcoreRevivalDataMessage message = new HardcoreRevivalDataMessage(player.getId(), revivalData.isKnockedOut(), revivalData.getKnockoutTicksPassed(), false); + public static void sendHardcoreRevivalDataToWatching(Player player) { + HardcoreRevivalDataMessage message = new HardcoreRevivalDataMessage(player.getId(), + PlayerHardcoreRevivalManager.isKnockedOut(player), + PlayerHardcoreRevivalManager.getKnockoutTicksPassed(player), + false); Balm.getNetworking().sendToTracking(player, message); - sendHardcoreRevivalData(player, player, revivalData); + sendHardcoreRevivalData(player, player); } - public static void sendHardcoreRevivalData(Player player, Entity entity, HardcoreRevivalData revivalData) { - sendHardcoreRevivalData(player, entity, revivalData, false); + public static void sendHardcoreRevivalData(Player toPlayer, Player forPlayer) { + sendHardcoreRevivalData(toPlayer, forPlayer, false); } - public static void sendHardcoreRevivalData(Player player, Entity entity, HardcoreRevivalData revivalData, boolean beingRescued) { - HardcoreRevivalDataMessage message = new HardcoreRevivalDataMessage(entity.getId(), revivalData.isKnockedOut(), revivalData.getKnockoutTicksPassed(), beingRescued); - Balm.getNetworking().sendTo(player, message); + public static void sendHardcoreRevivalData(Player toPlayer, Player forPlayer, boolean beingRescued) { + HardcoreRevivalDataMessage message = new HardcoreRevivalDataMessage(forPlayer.getId(), + PlayerHardcoreRevivalManager.isKnockedOut(forPlayer), + PlayerHardcoreRevivalManager.getKnockoutTicksPassed(forPlayer), + beingRescued); + Balm.getNetworking().sendTo(toPlayer, message); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/LoginLogoutHandler.java b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/LoginLogoutHandler.java index 667fd35..7ca4285 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/LoginLogoutHandler.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/LoginLogoutHandler.java @@ -3,11 +3,9 @@ import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.api.event.PlayerLoginEvent; import net.blay09.mods.balm.api.event.PlayerLogoutEvent; -import net.blay09.mods.hardcorerevival.HardcoreRevival; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; +import net.blay09.mods.hardcorerevival.HardcoreRevivalManager; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; @@ -21,31 +19,22 @@ public static void initialize() { public static void onPlayerLogin(PlayerLoginEvent event) { ServerPlayer player = event.getPlayer(); - CompoundTag data = Balm.getHooks().getPersistentData(player); - HardcoreRevivalData revivalData = HardcoreRevival.getRevivalData(player); - revivalData.deserialize(data.getCompound("HardcoreRevival")); - if (HardcoreRevivalConfig.getActive().continueTimerWhileOffline && revivalData.isKnockedOut()) { + if (HardcoreRevivalConfig.getActive().continueTimerWhileOffline && PlayerHardcoreRevivalManager.isKnockedOut(player)) { final var now = System.currentTimeMillis(); - final var then = revivalData.getLastLogoutAt(); + final var then = PlayerHardcoreRevivalManager.getLastLogoutAt(player); final var millisPassed = (int) Math.max(0, now - then); final var secondsPassed = millisPassed / 1000; final var ticksPassed = secondsPassed * 20; - revivalData.setKnockoutTicksPassed(revivalData.getKnockoutTicksPassed() + ticksPassed); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(player, PlayerHardcoreRevivalManager.getKnockoutTicksPassed(player) + ticksPassed); } - HardcoreRevival.getManager().updateKnockoutEffects(player); + HardcoreRevivalManager.updateKnockoutEffects(player); } public static void onPlayerLogout(PlayerLogoutEvent event) { Player player = event.getPlayer(); - CompoundTag data = Balm.getHooks().getPersistentData(player); - HardcoreRevivalData revivalData = HardcoreRevival.getRevivalData(player); - revivalData.setLastLogoutAt(player.level().getGameTime()); - Tag tag = revivalData.serialize(); - if (tag != null) { - data.put("HardcoreRevival", tag); - } + PlayerHardcoreRevivalManager.setLastLogoutAt(player, System.currentTimeMillis()); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/RescueHandler.java b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/RescueHandler.java index 13bd663..f7c872b 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/handler/RescueHandler.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/handler/RescueHandler.java @@ -2,8 +2,8 @@ import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.api.event.*; -import net.blay09.mods.hardcorerevival.HardcoreRevival; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; +import net.blay09.mods.hardcorerevival.HardcoreRevivalManager; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.blay09.mods.hardcorerevival.network.RevivalProgressMessage; import net.minecraft.server.level.ServerPlayer; @@ -21,54 +21,52 @@ public static void initialize() { public static void onUseItem(UseItemEvent event) { // Prevent player from using items while they're rescuing - if (HardcoreRevival.getManager().isRescuing(event.getPlayer())) { + if (HardcoreRevivalManager.isRescuing(event.getPlayer())) { event.setCanceled(true); } } public static void onUseBlock(UseBlockEvent event) { // Prevent player from placing blocks while they're rescuing - if (HardcoreRevival.getManager().isRescuing(event.getPlayer())) { + if (HardcoreRevivalManager.isRescuing(event.getPlayer())) { event.setCanceled(true); } } public static void onAttack(PlayerAttackEvent event) { // Stop rescuing if the player does something other than rescuing - HardcoreRevival.getManager().abortRescue(event.getPlayer()); + HardcoreRevivalManager.abortRescue(event.getPlayer()); } public static void onPlayerTick(ServerPlayer player) { // if (event.side == LogicalSide.SERVER && event.phase == TickEvent.Phase.END) { - HardcoreRevivalData revivalData = HardcoreRevival.getRevivalData(player); - Player rescueTarget = revivalData.getRescueTarget(); + Player rescueTarget = PlayerHardcoreRevivalManager.getRescueTarget(player); if (rescueTarget != null) { // Stop rescuing if the target logged out - HardcoreRevivalData rescueTargetData = HardcoreRevival.getRevivalData(rescueTarget); - final int knockoutTicksPassed = rescueTargetData.getKnockoutTicksPassed(); + final int knockoutTicksPassed = PlayerHardcoreRevivalManager.getKnockoutTicksPassed(rescueTarget); final int maxTicksUntilDeath = HardcoreRevivalConfig.getActive().secondsUntilDeath * 20; if (!rescueTarget.isAlive() || (maxTicksUntilDeath > 0 && knockoutTicksPassed >= maxTicksUntilDeath)) { - HardcoreRevival.getManager().abortRescue(player); + HardcoreRevivalManager.abortRescue(player); } else { // Stop rescuing if the player is out of range float dist = player.distanceTo(rescueTarget); if (dist > HardcoreRevivalConfig.getActive().rescueDistance) { - HardcoreRevival.getManager().abortRescue(player); + HardcoreRevivalManager.abortRescue(player); } else { - int rescueTime = revivalData.getRescueTime() + 1; - revivalData.setRescueTime(rescueTime); + int rescueTime = PlayerHardcoreRevivalManager.getRescueTime(player) + 1; + PlayerHardcoreRevivalManager.setRescueTime(player, rescueTime); // Delay death while rescuing - rescueTargetData.setKnockoutTicksPassed(knockoutTicksPassed - 1); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(rescueTarget, knockoutTicksPassed - 1); int maxRescueActionTicks = HardcoreRevivalConfig.getActive().rescueActionTicks; int step = maxRescueActionTicks / 4; if (rescueTime >= maxRescueActionTicks) { - HardcoreRevival.getManager().finishRescue(player); + HardcoreRevivalManager.finishRescue(player); } else if (rescueTime % step == 0) { Balm.getNetworking() .sendTo(player, new RevivalProgressMessage(rescueTarget.getId(), (float) rescueTime / (float) maxRescueActionTicks)); - KnockoutSyncHandler.sendHardcoreRevivalData(rescueTarget, rescueTarget, rescueTargetData, true); + KnockoutSyncHandler.sendHardcoreRevivalData(rescueTarget, rescueTarget, true); } } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/LivingEntityMixin.java b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/LivingEntityMixin.java index b5259a2..c0ca979 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/LivingEntityMixin.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/LivingEntityMixin.java @@ -1,7 +1,8 @@ package net.blay09.mods.hardcorerevival.mixin; -import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -12,7 +13,8 @@ public class LivingEntityMixin { @Inject(method = "canBeSeenAsEnemy()Z", at = @At("HEAD"), cancellable = true) private void canBeSeenAsEnemy(CallbackInfoReturnable cir) { - if (HardcoreRevival.getRevivalData((LivingEntity) (Object) this).isKnockedOut()) { + final var livingEntity = (LivingEntity) (Object) this; + if (livingEntity instanceof Player player && PlayerHardcoreRevivalManager.isKnockedOut(player)) { cir.setReturnValue(false); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/LocalPlayerMixin.java b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/LocalPlayerMixin.java new file mode 100644 index 0000000..71ced38 --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/LocalPlayerMixin.java @@ -0,0 +1,22 @@ +package net.blay09.mods.hardcorerevival.mixin; + +import net.blay09.mods.hardcorerevival.MixinHooks; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.entity.player.Player; +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.CallbackInfoReturnable; + +@Mixin(LocalPlayer.class) +public class LocalPlayerMixin { + @Inject(method = "drop(Z)Z", at = @At("HEAD"), cancellable = true) + public void drop(boolean all, CallbackInfoReturnable cir) { + final var player = (Player) (Object) this; + if (all && MixinHooks.shouldCancelTossAll(player)) { + cir.setReturnValue(false); + } else if (!all && MixinHooks.shouldCancelToss(player, player.getInventory().getSelected())) { + cir.setReturnValue(false); + } + } +} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/PlayerMixin.java b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/PlayerMixin.java index 4fabad2..58334e8 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/PlayerMixin.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/PlayerMixin.java @@ -1,7 +1,6 @@ package net.blay09.mods.hardcorerevival.mixin; import net.blay09.mods.hardcorerevival.MixinHooks; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/ServerPlayNetHandlerMixin.java b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/ServerGamePacketListenerImplMixin.java similarity index 53% rename from common/src/main/java/net/blay09/mods/hardcorerevival/mixin/ServerPlayNetHandlerMixin.java rename to common/src/main/java/net/blay09/mods/hardcorerevival/mixin/ServerGamePacketListenerImplMixin.java index 05d3e5e..8e00b1b 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/ServerPlayNetHandlerMixin.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/mixin/ServerGamePacketListenerImplMixin.java @@ -2,6 +2,7 @@ import net.blay09.mods.hardcorerevival.MixinHooks; import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; import net.minecraft.server.network.ServerGamePacketListenerImpl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -9,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ServerGamePacketListenerImpl.class) -public class ServerPlayNetHandlerMixin { +public class ServerGamePacketListenerImplMixin { @Inject(method = "handleMovePlayer(Lnet/minecraft/network/protocol/game/ServerboundMovePlayerPacket;)V", at = @At("HEAD"), cancellable = true) public void handleMovePlayer(ServerboundMovePlayerPacket packet, CallbackInfo ci) { @@ -20,4 +21,21 @@ public void handleMovePlayer(ServerboundMovePlayerPacket packet, CallbackInfo ci } } + @Inject(method = "handlePlayerAction(Lnet/minecraft/network/protocol/game/ServerboundPlayerActionPacket;)V", at = @At("HEAD"), cancellable = true) + public void handlePlayerAction(ServerboundPlayerActionPacket packet, CallbackInfo ci) { + final var netHandler = (ServerGamePacketListenerImpl) (Object) this; + switch (packet.getAction()) { + case DROP_ALL_ITEMS: + if (MixinHooks.shouldCancelTossAll(netHandler.player)) { + ci.cancel(); + } + break; + case DROP_ITEM: + if (MixinHooks.shouldCancelToss(netHandler.player, netHandler.player.getInventory().getSelected())) { + ci.cancel(); + } + break; + } + } + } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/network/AcceptFateMessage.java b/common/src/main/java/net/blay09/mods/hardcorerevival/network/AcceptFateMessage.java index 9a60ff5..c52362e 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/network/AcceptFateMessage.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/network/AcceptFateMessage.java @@ -1,6 +1,7 @@ package net.blay09.mods.hardcorerevival.network; import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.HardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; @@ -16,7 +17,7 @@ public static void handle(ServerPlayer player, AcceptFateMessage message) { return; } - HardcoreRevival.getManager().notRescuedInTime(player); + HardcoreRevivalManager.notRescuedInTime(player); } @Override diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/network/HardcoreRevivalDataMessage.java b/common/src/main/java/net/blay09/mods/hardcorerevival/network/HardcoreRevivalDataMessage.java index fe32bbb..795868a 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/network/HardcoreRevivalDataMessage.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/network/HardcoreRevivalDataMessage.java @@ -1,7 +1,7 @@ package net.blay09.mods.hardcorerevival.network; import net.blay09.mods.hardcorerevival.HardcoreRevival; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.client.HardcoreRevivalClient; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; @@ -44,11 +44,9 @@ public static HardcoreRevivalDataMessage decode(FriendlyByteBuf buf) { public static void handle(Player player, HardcoreRevivalDataMessage message) { if (player != null) { Entity entity = player.level().getEntity(message.entityId); - if (entity != null) { - HardcoreRevivalData revivalData = entity.getId() == player.getId() ? HardcoreRevival.getClientRevivalData() : HardcoreRevival.getRevivalData( - entity); - revivalData.setKnockedOut(message.knockedOut); - revivalData.setKnockoutTicksPassed(message.knockoutTicksPassed); + if (entity instanceof Player targetEntity) { + PlayerHardcoreRevivalManager.setKnockedOut(targetEntity, message.knockedOut); + PlayerHardcoreRevivalManager.setKnockoutTicksPassed(targetEntity, message.knockoutTicksPassed); HardcoreRevivalClient.setBeingRescued(message.beingRescued); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/network/RescueMessage.java b/common/src/main/java/net/blay09/mods/hardcorerevival/network/RescueMessage.java index 77b365e..425efb4 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/network/RescueMessage.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/network/RescueMessage.java @@ -1,6 +1,8 @@ package net.blay09.mods.hardcorerevival.network; import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.HardcoreRevivalManager; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; @@ -44,14 +46,14 @@ private static boolean isLookingTowards(Player player, Entity candidate) { } public static void handle(ServerPlayer player, RescueMessage message) { - if (player == null || !player.isAlive() || player.isSpectator() || HardcoreRevival.getRevivalData(player).isKnockedOut()) { + if (player == null || !player.isAlive() || player.isSpectator() || PlayerHardcoreRevivalManager.isKnockedOut(player)) { return; } if (message.active) { final double range = HardcoreRevivalConfig.getActive().rescueDistance; List candidates = player.level().getEntitiesOfClass(Player.class, player.getBoundingBox().inflate(range), p -> { - if (p == null || !HardcoreRevival.getRevivalData(p).isKnockedOut()) { + if (p == null || !PlayerHardcoreRevivalManager.isKnockedOut(p)) { return false; } @@ -72,11 +74,11 @@ public static void handle(ServerPlayer player, RescueMessage message) { } } if (target != null) { - HardcoreRevival.getManager().startRescue(player, target); + HardcoreRevivalManager.startRescue(player, target); } } else { - HardcoreRevival.getManager().abortRescue(player); + HardcoreRevivalManager.abortRescue(player); } } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/stats/ModStats.java b/common/src/main/java/net/blay09/mods/hardcorerevival/stats/ModStats.java index 687ae74..fc028bc 100644 --- a/common/src/main/java/net/blay09/mods/hardcorerevival/stats/ModStats.java +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/stats/ModStats.java @@ -8,7 +8,15 @@ public class ModStats { public static final ResourceLocation knockouts = ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "knockouts"); + public static final ResourceLocation timesRescued = ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "times_rescued"); + + public static final ResourceLocation playersRevived = ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "players_revived"); + public static void initialize(BalmStats stats) { stats.registerCustomStat(knockouts); + stats.registerCustomStat(timesRescued); + stats.registerCustomStat(playersRevived); + } + } diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/tag/ModBlockTags.java b/common/src/main/java/net/blay09/mods/hardcorerevival/tag/ModBlockTags.java new file mode 100644 index 0000000..9e237b5 --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/tag/ModBlockTags.java @@ -0,0 +1,13 @@ +package net.blay09.mods.hardcorerevival.tag; + +import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; + +public class ModBlockTags { + public static final TagKey ALLOW_USE_WHILE_KNOCKED_OUT = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "allow_use_while_knocked_out")); + public static final TagKey ALLOW_BREAK_WHILE_KNOCKED_OUT = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "allow_break_while_knocked_out")); +} diff --git a/common/src/main/java/net/blay09/mods/hardcorerevival/tag/ModItemTags.java b/common/src/main/java/net/blay09/mods/hardcorerevival/tag/ModItemTags.java new file mode 100644 index 0000000..9cb8131 --- /dev/null +++ b/common/src/main/java/net/blay09/mods/hardcorerevival/tag/ModItemTags.java @@ -0,0 +1,14 @@ +package net.blay09.mods.hardcorerevival.tag; + +import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; + +public class ModItemTags { + public static final TagKey PASSTHROUGH_DEATH_WHEN_HELD = TagKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "passthrough_death_when_held")); + public static final TagKey ALLOW_ATTACK_WHILE_KNOCKED_OUT = TagKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "allow_attack_while_knocked_out")); + public static final TagKey ALLOW_USE_WHILE_KNOCKED_OUT = TagKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "allow_use_while_knocked_out")); + public static final TagKey ALLOW_TOSS_WHILE_KNOCKED_OUT = TagKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "allow_toss_while_knocked_out")); +} diff --git a/common/src/main/resources/assets/hardcorerevival/lang/en_us.json b/common/src/main/resources/assets/hardcorerevival/lang/en_us.json index f54ef69..87d768b 100644 --- a/common/src/main/resources/assets/hardcorerevival/lang/en_us.json +++ b/common/src/main/resources/assets/hardcorerevival/lang/en_us.json @@ -10,36 +10,49 @@ "death.attack.not_rescued_in_time": "%1$s was not rescued in time", "death.attack.not_rescued_in_time.player": "%1$s was not rescued in time", "stat.hardcorerevival.knockouts": "Knockouts", - "config.hardcorerevival.secondsUntilDeath": "Seconds until Death", - "config.hardcorerevival.secondsUntilDeath.tooltip": "The time in seconds in which a player can still be rescued from death. Set to 0 to disable the timer.", - "config.hardcorerevival.continueTimerWhileOffline": "Continue Timer while Offline", - "config.hardcorerevival.continueTimerWhileOffline.tooltip": "If true, the timer until death continues even if the player logs out.", - "config.hardcorerevival.consecutiveKnockoutThresholdSeconds": "Consecutive Knockout Threshold", - "config.hardcorerevival.consecutiveKnockoutThresholdSeconds.tooltip": "The threshold of seconds that knockout will be treated as a consecutive knockout. See resumeTimerOnConsecutiveKnockout and multiplyTimerOnConsecutiveKnockout.", - "config.hardcorerevival.resumeTimerOnConsecutiveKnockout": "Resume Timer on Consecutive Knockout", - "config.hardcorerevival.resumeTimerOnConsecutiveKnockout.tooltip": "If true, the timer until death resumes from its last time on consecutive knockouts.", - "config.hardcorerevival.multiplyTimerOnConsecutiveKnockout": "Multiply Timer on Consecutive Knockout", - "config.hardcorerevival.multiplyTimerOnConsecutiveKnockout.tooltip": "The multiplier to apply to the time remaining on consecutive knockouts.", - "config.hardcorerevival.rescueDistance": "Max Rescue Distance", - "config.hardcorerevival.rescueDistance.tooltip": "The distance at which a player can rescue another.", - "config.hardcorerevival.rescueActionTicks": "Rescue Action Ticks", - "config.hardcorerevival.rescueActionTicks.tooltip": "The time in ticks it takes to rescue a player. 20 ticks are one second.", - "config.hardcorerevival.rescueRespawnHealth": "Rescue Respawn Health", - "config.hardcorerevival.rescueRespawnHealth.tooltip": "The amount of health to respawn with when a player was rescued, out of 20.", - "config.hardcorerevival.rescueRespawnFoodLevel": "Rescue Respawn Food Level", - "config.hardcorerevival.rescueRespawnFoodLevel.tooltip": "The food level to respawn with when a player was rescued, out of 20.", - "config.hardcorerevival.rescueRespawnEffects": "Rescue Respawn Effects", - "config.hardcorerevival.rescueRespawnEffects.tooltip": "Effects applied to a player when rescued, in the format \"effect|duration|amplifier\"", - "config.hardcorerevival.glowOnKnockout": "Glow on Knockout", - "config.hardcorerevival.glowOnKnockout.tooltip": "If true, knocked out players will glow, making them visible through blocks.", - "config.hardcorerevival.allowCommands": "Allow Commands", - "config.hardcorerevival.allowCommands.tooltip": "If true, knocked out players are still able to run commands. OPs are always able to run commands.", - "config.hardcorerevival.allowUnarmedMelee": "Allow Unarmed Melee", - "config.hardcorerevival.allowUnarmedMelee.tooltip": "If true, knocked out players are still able to punch nearby enemies.", - "config.hardcorerevival.allowBows": "Allow Bows", - "config.hardcorerevival.allowBows.tooltip": "If true, knocked out players are still able to fire bows.", - "config.hardcorerevival.allowPistols": "Allow Pistols", - "config.hardcorerevival.allowPistols.tooltip": "If true, knocked out players are still able to fire pistols from Mr Crayfish's Gun Mod.", + "stat.hardcorerevival.times_rescued": "Times Rescued", + "stat.hardcorerevival.players_revived": "Players Revived", + "hardcorerevival.configuration.title": "Hardcore Revival", + "hardcorerevival.configuration.secondsUntilDeath": "Seconds until Death", + "hardcorerevival.configuration.secondsUntilDeath.tooltip": "The time in seconds in which a player can still be rescued from death. Set to 0 to disable the timer.", + "hardcorerevival.configuration.continueTimerWhileOffline": "Continue Timer while Offline", + "hardcorerevival.configuration.continueTimerWhileOffline.tooltip": "If true, the timer until death continues even if the player logs out.", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds": "Consecutive Knockout Threshold", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds.tooltip": "The threshold of seconds that knockout will be treated as a consecutive knockout. See resumeTimerOnConsecutiveKnockout and multiplyTimerOnConsecutiveKnockout.", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout": "Resume Timer on Consecutive Knockout", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout.tooltip": "If true, the timer until death resumes from its last time on consecutive knockouts.", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout": "Multiply Timer on Consecutive Knockout", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout.tooltip": "The multiplier to apply to the time remaining on consecutive knockouts.", + "hardcorerevival.configuration.rescueDistance": "Max Rescue Distance", + "hardcorerevival.configuration.rescueDistance.tooltip": "The distance at which a player can rescue another.", + "hardcorerevival.configuration.rescueActionTicks": "Rescue Action Ticks", + "hardcorerevival.configuration.rescueActionTicks.tooltip": "The time in ticks it takes to rescue a player. 20 ticks are one second.", + "hardcorerevival.configuration.rescueRespawnHealth": "Rescue Respawn Health", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "The amount of health to respawn with when a player was rescued, out of 20.", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "Rescue Respawn Food Level", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "The food level to respawn with when a player was rescued, out of 20.", + "hardcorerevival.configuration.rescueRespawnEffects": "Rescue Respawn Effects", + "hardcorerevival.configuration.rescueRespawnEffects.tooltip": "Effects applied to a player when rescued, in the format \"effect|duration|amplifier\"", + "hardcorerevival.configuration.glowOnKnockout": "Glow on Knockout", + "hardcorerevival.configuration.glowOnKnockout.tooltip": "If true, knocked out players will glow, making them visible through blocks.", + "hardcorerevival.configuration.allowCommands": "Allow Commands", + "hardcorerevival.configuration.allowCommands.tooltip": "If true, knocked out players are still able to run commands. OPs are always able to run commands.", + "hardcorerevival.configuration.allowUnarmedMelee": "Allow Unarmed Melee", + "hardcorerevival.configuration.allowUnarmedMelee.tooltip": "If true, knocked out players are still able to punch nearby enemies.", + "hardcorerevival.configuration.allowBows": "Allow Bows", + "hardcorerevival.configuration.allowBows.tooltip": "If true, knocked out players are still able to fire bows.", + "hardcorerevival.configuration.allowPistols": "Allow Pistols", + "hardcorerevival.configuration.allowPistols.tooltip": "If true, knocked out players are still able to fire pistols from Mr Crayfish's Gun Mod.", + "hardcorerevival.configuration.disableInLonelyMultiplayer": "Disable in Lonely Multiplayer", + "hardcorerevival.configuration.disableInLonelyMultiplayer.tooltip": "If true, Hardcore Revival will not be active when playing alone in multiplayer.", + "hardcorerevival.configuration.instantDeathSources": "Instant Death Sources", + "hardcorerevival.configuration.instantDeathSources.tooltip": "The damage sources that kill a player instantly, without a K.O. period.", + "hardcorerevival.configuration.instantDeathEntityTypes": "Instant Death Entity Types", + "hardcorerevival.configuration.instantDeathEntityTypes.tooltip": "The source entity types that kill a player instantly, without a K.O. period.", + "hardcorerevival.configuration.disableInSingleplayer": "Disable in Singleplayer", + "hardcorerevival.configuration.disableInSingleplayer.tooltip": "If true, Hardcore Revival will not be active in singleplayer.", + "hardcorerevival.configuration.allowAcceptingFate": "Allow Accepting Fate", + "hardcorerevival.configuration.allowAcceptingFate.tooltip": "Set to false to remove the Accept your Fate button and force players to wait out the timer.", "commands.revive.success.single": "Revived %s", "commands.revive.success.multiple": "Revived %s players", "commands.disabled_when_knocked_out": "You cannot use commands while knocked out." diff --git a/common/src/main/resources/assets/hardcorerevival/lang/fr_fr.json b/common/src/main/resources/assets/hardcorerevival/lang/fr_fr.json index 29ef6cb..1eaa6dc 100644 --- a/common/src/main/resources/assets/hardcorerevival/lang/fr_fr.json +++ b/common/src/main/resources/assets/hardcorerevival/lang/fr_fr.json @@ -10,36 +10,36 @@ "death.attack.not_rescued_in_time": "%1$s n'a pas été réanimé à temps", "death.attack.not_rescued_in_time.player": "%1$s n'a pas été réanimé à temps", "stat.hardcorerevival.knockouts": "Évanouissements", - "config.hardcorerevival.secondsUntilDeath": "Secondes avant la mort", - "config.hardcorerevival.secondsUntilDeath.tooltip": "Le temps en secondes pendant lequel un joueur peut encore être réanimé avant la mort. Réglez sur 0 pour désactiver le minuteur.", - "config.hardcorerevival.continueTimerWhileOffline": "Continuer le minuteur hors ligne", - "config.hardcorerevival.continueTimerWhileOffline.tooltip": "Si vrai, le minuteur avant la mort continue même si le joueur se déconnecte.", - "config.hardcorerevival.consecutiveKnockoutThresholdSeconds": "Seuil d'évanouissements consécutifs", - "config.hardcorerevival.consecutiveKnockoutThresholdSeconds.tooltip": "Le seuil de secondes pour que l'évanouissement soit considéré comme consécutif. Voir resumeTimerOnConsecutiveKnockout et multiplyTimerOnConsecutiveKnockout.", - "config.hardcorerevival.resumeTimerOnConsecutiveKnockout": "Reprendre le minuteur lors d'un évanouissement consécutif", - "config.hardcorerevival.resumeTimerOnConsecutiveKnockout.tooltip": "Si activé, le minuteur avant la mort reprend à son dernier temps lors d'évanouissements consécutifs.", - "config.hardcorerevival.multiplyTimerOnConsecutiveKnockout": "Multiplier le minuteur lors d'un évanouissement consécutif", - "config.hardcorerevival.multiplyTimerOnConsecutiveKnockout.tooltip": "Le multiplicateur à appliquer au temps restant lors d'évanouissements consécutifs.", - "config.hardcorerevival.rescueDistance": "Distance maximale de la réanimation", - "config.hardcorerevival.rescueDistance.tooltip": "La distance à laquelle un joueur peut en réanimer un autre.", - "config.hardcorerevival.rescueActionTicks": "Temps de l'action d'une réanimation", - "config.hardcorerevival.rescueActionTicks.tooltip": "Le temps en ticks nécessaire pour réanimer un joueur. 20 ticks équivalent à une seconde.", - "config.hardcorerevival.rescueRespawnHealth": "Santé à la réapparition après une réanimation", - "config.hardcorerevival.rescueRespawnHealth.tooltip": "La quantité de santé pour réapparaître après avoir été réanimé, sur 20.", - "config.hardcorerevival.rescueRespawnFoodLevel": "Niveau de nourriture à la réapparition après une réanimation", - "config.hardcorerevival.rescueRespawnFoodLevel.tooltip": "Le niveau de nourriture pour réapparaître après avoir été réanimé, sur 20.", - "config.hardcorerevival.rescueRespawnEffects": "Effets à la réapparition après une réanimation", - "config.hardcorerevival.rescueRespawnEffects.tooltip": "Effets appliqués à un joueur lorsqu'il est réanimé, au format \"effet|durée|amplificateur\"", - "config.hardcorerevival.glowOnKnockout": "Briller en cas d'évanouissement", - "config.hardcorerevival.glowOnKnockout.tooltip": "Si activé, les joueurs évanouis brilleront, les rendant visibles à travers les blocs.", - "config.hardcorerevival.allowCommands": "Autoriser les commandes", - "config.hardcorerevival.allowCommands.tooltip": "Si activé, les joueurs évanouis peuvent encore exécuter des commandes. Les OPs peuvent toujours exécuter des commandes.", - "config.hardcorerevival.allowUnarmedMelee": "Autoriser le combat à mains nues", - "config.hardcorerevival.allowUnarmedMelee.tooltip": "Si activé, les joueurs évanouis peuvent encore frapper les ennemis à proximité.", - "config.hardcorerevival.allowBows": "Autoriser les arcs", - "config.hardcorerevival.allowBows.tooltip": "Si activé, les joueurs évanouis peuvent encore tirer des flèches avec un arc.", - "config.hardcorerevival.allowPistols": "Autoriser les pistolets", - "config.hardcorerevival.allowPistols.tooltip": "Si activé, les joueurs évanouis peuvent encore tirer des pistolets du mod de Mr Crayfish.", + "hardcorerevival.configuration.secondsUntilDeath": "Secondes avant la mort", + "hardcorerevival.configuration.secondsUntilDeath.tooltip": "Le temps en secondes pendant lequel un joueur peut encore être réanimé avant la mort. Réglez sur 0 pour désactiver le minuteur.", + "hardcorerevival.configuration.continueTimerWhileOffline": "Continuer le minuteur hors ligne", + "hardcorerevival.configuration.continueTimerWhileOffline.tooltip": "Si vrai, le minuteur avant la mort continue même si le joueur se déconnecte.", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds": "Seuil d'évanouissements consécutifs", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds.tooltip": "Le seuil de secondes pour que l'évanouissement soit considéré comme consécutif. Voir resumeTimerOnConsecutiveKnockout et multiplyTimerOnConsecutiveKnockout.", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout": "Reprendre le minuteur lors d'un évanouissement consécutif", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout.tooltip": "Si activé, le minuteur avant la mort reprend à son dernier temps lors d'évanouissements consécutifs.", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout": "Multiplier le minuteur lors d'un évanouissement consécutif", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout.tooltip": "Le multiplicateur à appliquer au temps restant lors d'évanouissements consécutifs.", + "hardcorerevival.configuration.rescueDistance": "Distance maximale de la réanimation", + "hardcorerevival.configuration.rescueDistance.tooltip": "La distance à laquelle un joueur peut en réanimer un autre.", + "hardcorerevival.configuration.rescueActionTicks": "Temps de l'action d'une réanimation", + "hardcorerevival.configuration.rescueActionTicks.tooltip": "Le temps en ticks nécessaire pour réanimer un joueur. 20 ticks équivalent à une seconde.", + "hardcorerevival.configuration.rescueRespawnHealth": "Santé à la réapparition après une réanimation", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "La quantité de santé pour réapparaître après avoir été réanimé, sur 20.", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "Niveau de nourriture à la réapparition après une réanimation", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "Le niveau de nourriture pour réapparaître après avoir été réanimé, sur 20.", + "hardcorerevival.configuration.rescueRespawnEffects": "Effets à la réapparition après une réanimation", + "hardcorerevival.configuration.rescueRespawnEffects.tooltip": "Effets appliqués à un joueur lorsqu'il est réanimé, au format \"effet|durée|amplificateur\"", + "hardcorerevival.configuration.glowOnKnockout": "Briller en cas d'évanouissement", + "hardcorerevival.configuration.glowOnKnockout.tooltip": "Si activé, les joueurs évanouis brilleront, les rendant visibles à travers les blocs.", + "hardcorerevival.configuration.allowCommands": "Autoriser les commandes", + "hardcorerevival.configuration.allowCommands.tooltip": "Si activé, les joueurs évanouis peuvent encore exécuter des commandes. Les OPs peuvent toujours exécuter des commandes.", + "hardcorerevival.configuration.allowUnarmedMelee": "Autoriser le combat à mains nues", + "hardcorerevival.configuration.allowUnarmedMelee.tooltip": "Si activé, les joueurs évanouis peuvent encore frapper les ennemis à proximité.", + "hardcorerevival.configuration.allowBows": "Autoriser les arcs", + "hardcorerevival.configuration.allowBows.tooltip": "Si activé, les joueurs évanouis peuvent encore tirer des flèches avec un arc.", + "hardcorerevival.configuration.allowPistols": "Autoriser les pistolets", + "hardcorerevival.configuration.allowPistols.tooltip": "Si activé, les joueurs évanouis peuvent encore tirer des pistolets du mod de Mr Crayfish.", "commands.revive.success.single": "Réanimé %s", "commands.revive.success.multiple": "Réanimé %s joueurs", "commands.disabled_when_knocked_out": "Vous ne pouvez pas utiliser de commandes lorsque vous êtes évanoui." diff --git a/common/src/main/resources/assets/hardcorerevival/lang/it_it.json b/common/src/main/resources/assets/hardcorerevival/lang/it_it.json index e355034..2db9adc 100644 --- a/common/src/main/resources/assets/hardcorerevival/lang/it_it.json +++ b/common/src/main/resources/assets/hardcorerevival/lang/it_it.json @@ -9,18 +9,18 @@ "gui.hardcorerevival.rescuing": "Aiutando %s", "death.attack.not_rescued_in_time": "%1$s non è stato salvato in tempo", "death.attack.not_rescued_in_time.player": "%1$s non è stato salvato in tempo", - "config.hardcorerevival.maxDeathTicks": "Death Timer", - "config.hardcorerevival.maxDeathTicks.tooltip": "Il tempo in tick in cui un giocatore può ancora essere salvato dalla morte. 20 tick sono un secondo.", - "config.hardcorerevival.maxRescueDist": "Distanza di rianimazione massima", - "config.hardcorerevival.maxRescueDist.tooltip": "La distanza tra cui i giocatori possono aiutarsi.", - "config.hardcorerevival.rescueTime": "Tempo di salvataggio", - "config.hardcorerevival.rescueTime.tooltip": "Il tempo in tick necessario per salvare un giocatore. 20 tick sono un secondo.", - "config.hardcorerevival.disableDeathTimer": "Disabilità Death Timer", - "config.hardcorerevival.disableDeathTimer.tooltip": "Imposta su vero per disabilitare completamente il timer della morte, il che significa che avrai tempo infinito per salvare gli altri.", - "config.hardcorerevival.rescueRespawnHealth": "Salute dopo la rianimazione", - "config.hardcorerevival.rescueRespawnHealth.tooltip": "La quantità di salute con cui ti alzerai dopo essere stato rianimato, sul totale di 20.", - "config.hardcorerevival.rescueRespawnFoodLevel": "Sazietà dopo la rianimazione", - "config.hardcorerevival.rescueRespawnFoodLevel.tooltip": "La quantità di sazietà con cui ti alzerai dopo essere stato rianimato, sul totale di 20.", + "hardcorerevival.configuration.maxDeathTicks": "Death Timer", + "hardcorerevival.configuration.maxDeathTicks.tooltip": "Il tempo in tick in cui un giocatore può ancora essere salvato dalla morte. 20 tick sono un secondo.", + "hardcorerevival.configuration.maxRescueDist": "Distanza di rianimazione massima", + "hardcorerevival.configuration.maxRescueDist.tooltip": "La distanza tra cui i giocatori possono aiutarsi.", + "hardcorerevival.configuration.rescueTime": "Tempo di salvataggio", + "hardcorerevival.configuration.rescueTime.tooltip": "Il tempo in tick necessario per salvare un giocatore. 20 tick sono un secondo.", + "hardcorerevival.configuration.disableDeathTimer": "Disabilità Death Timer", + "hardcorerevival.configuration.disableDeathTimer.tooltip": "Imposta su vero per disabilitare completamente il timer della morte, il che significa che avrai tempo infinito per salvare gli altri.", + "hardcorerevival.configuration.rescueRespawnHealth": "Salute dopo la rianimazione", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "La quantità di salute con cui ti alzerai dopo essere stato rianimato, sul totale di 20.", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "Sazietà dopo la rianimazione", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "La quantità di sazietà con cui ti alzerai dopo essere stato rianimato, sul totale di 20.", "commands.revive.success.single": "Rianimato %s", "commands.revive.success.multiple": "Rianimati %s giocatori" } diff --git a/common/src/main/resources/assets/hardcorerevival/lang/ko_kr.json b/common/src/main/resources/assets/hardcorerevival/lang/ko_kr.json new file mode 100644 index 0000000..5999453 --- /dev/null +++ b/common/src/main/resources/assets/hardcorerevival/lang/ko_kr.json @@ -0,0 +1,46 @@ +{ + "gui.hardcorerevival.knocked_out": "K.O.", + "gui.hardcorerevival.die": "%1$s 운명을 받아들이기 %1$s", + "gui.hardcorerevival.open_death_screen": "%s 를 눌러 죽기", + "gui.hardcorerevival.hold_to_rescue": "%s 살리기 (홀드)", + "gui.hardcorerevival.rescue_time_left": "살아남기까지 %d 초 남았습니다.", + "gui.hardcorerevival.wait_for_rescue": "구조를 기다리거나 운명을 받아들이세요.", + "gui.hardcorerevival.being_rescued": "구조받는중...", + "gui.hardcorerevival.rescuing": "구조중 %s", + "death.attack.not_rescued_in_time": "%1$s는 제때 구조받지 못했습니다", + "death.attack.not_rescued_in_time.player": "%1$s는 제때 구조받지 못했습니다", + "stat.hardcorerevival.knockouts": "녹아웃", + "hardcorerevival.configuration.secondsUntilDeath": "구출 대기 시간", + "hardcorerevival.configuration.secondsUntilDeath.tooltip": "플레이어가 죽음에서 구출될 수 있는 시간(초). 타이머를 비활성화하려면 0으로 설정하세요.", + "hardcorerevival.configuration.continueTimerWhileOffline": "오프라인 중 타이머 흐름", + "hardcorerevival.configuration.continueTimerWhileOffline.tooltip": "True로 설정하면, 플레이어가 로그아웃 해도 녹아웃 타이머가 흐릅니다.", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds": "연속 녹아웃 한계점", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds.tooltip": "녹아웃이 연속 녹아웃으로 처리되는 시간(초)의 한계점. \"연속 녹아웃에서 타이머 재개\"와 \"연속 녹아웃 타이머 배수\"를 참고하세요.", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout": "연속 녹아웃에서 타이머 재개", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout.tooltip": "True로 설정하면, 연속으로 녹아웃했을때 녹아웃 타이머가 멈췄던 시간에서 다시 흐릅니다.", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout": "연속 녹아웃 타이머 배수", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout.tooltip": "연속 녹아웃 시 남은 시간에 적용할 배수입니다.", + "hardcorerevival.configuration.rescueDistance": "최대 구조 거리", + "hardcorerevival.configuration.rescueDistance.tooltip": "플레이어가 다른 플레이어를 구할 수 있는 거리.", + "hardcorerevival.configuration.rescueActionTicks": "구조 활동 틱", + "hardcorerevival.configuration.rescueActionTicks.tooltip": "플레이어를 구출하는 데 걸리는 시간(틱)입니다. 20틱은 1초입니다.", + "hardcorerevival.configuration.rescueRespawnHealth": "구조 리스폰 체력", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "플레이어가 구출되었을 때 부활할 때의 체력량(기본 최대량 20)입니다.", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "구조 리스폰 허기", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "플레이어가 구출되었을 때 부활할 때의 허기(기본 최대량 20)입니다.", + "hardcorerevival.configuration.rescueRespawnEffects": "구조 리스폰 effect", + "hardcorerevival.configuration.rescueRespawnEffects.tooltip": "구출 시 플레이어에게 적용되는 effect, 형식은 \"effect|duration|amplifier\"입니다.", + "hardcorerevival.configuration.glowOnKnockout": "녹아웃시 발광", + "hardcorerevival.configuration.glowOnKnockout.tooltip": "true로 설정하면, 기절한 플레이어는 빛나서 블록 너머로 보이게 됩니다.", + "hardcorerevival.configuration.allowCommands": "명령어 허용", + "hardcorerevival.configuration.allowCommands.tooltip": "True로 설정하면, 기절한 플레이어는 여전히 명령어를 실행할 수 있습니다. OP는 항상 명령어를 실행할 수 있습니다.", + "hardcorerevival.configuration.allowUnarmedMelee": "비무장 근접 공격 허용", + "hardcorerevival.configuration.allowUnarmedMelee.tooltip": "True로 설정하면, 기절한 플레이어는 여전히 근처의 적을 주먹으로 때릴 수 있습니다.", + "hardcorerevival.configuration.allowBows": "활 허용", + "hardcorerevival.configuration.allowBows.tooltip": "True로 설정하면, 기절한 플레이어는 여전히 활을 쏠 수 있습니다.", + "hardcorerevival.configuration.allowPistols": "권총 허용", + "hardcorerevival.configuration.allowPistols.tooltip": "True로 설정하면, 기절한 플레이어는 여전히 Mr Crayfish's Gun 모드의 권총을 쏠 수 있습니다.", + "commands.revive.success.single": "%s를 살렸습니다", + "commands.revive.success.multiple": "%s를 살렸습니다.", + "commands.disabled_when_knocked_out": "쓰러진 상태에서는 명령어를 사용할 수 없습니다." +} diff --git a/common/src/main/resources/assets/hardcorerevival/lang/nn_no.json b/common/src/main/resources/assets/hardcorerevival/lang/nn_no.json new file mode 100644 index 0000000..a620511 --- /dev/null +++ b/common/src/main/resources/assets/hardcorerevival/lang/nn_no.json @@ -0,0 +1,46 @@ +{ + "gui.hardcorerevival.knocked_out": "Du er slått ut.", + "gui.hardcorerevival.die": "%1$s Godta lagnaden din %1$s", + "gui.hardcorerevival.open_death_screen": "Trykk %s for å døy.", + "gui.hardcorerevival.hold_to_rescue": "Hald inne %s for å redda.", + "gui.hardcorerevival.rescue_time_left": "%d sekund att på å reddast", + "gui.hardcorerevival.wait_for_rescue": "Vent på å bli redda eller godta lagnaden din.", + "gui.hardcorerevival.being_rescued": "Du blir redda...", + "gui.hardcorerevival.rescuing": "Reddar %s", + "death.attack.not_rescued_in_time": "%1$s vart ikkje redda i tide", + "death.attack.not_rescued_in_time.player": "%1$s vart ikkje redda i tide", + "stat.hardcorerevival.knockouts": "Slått ut", + "hardcorerevival.configuration.secondsUntilDeath": "Sekund til døden", + "hardcorerevival.configuration.secondsUntilDeath.tooltip": "Tida i sekund der ein spelar kan bli redda før døden inntreff. Set til 0 for å slå av nedteljinga.", + "hardcorerevival.configuration.continueTimerWhileOffline": "Fortsett nedteljing når fråkopla", + "hardcorerevival.configuration.continueTimerWhileOffline.tooltip": "Om aktivert, held nedteljinga fram sjølv om spelaren loggar ut.", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds": "Terskel for påfølgjande utslåing", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds.tooltip": "Tida i sekund som tel som påfølgjande utslåing. Sjå resumeTimerOnConsecutiveKnockout og multiplyTimerOnConsecutiveKnockout.", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout": "Hald fram nedteljing ved påfølgjande utslåing", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout.tooltip": "Om aktivert, held nedteljinga fram frå førre tidspunkt ved påfølgjande utslåingar.", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout": "Multipliser tid ved påfølgjande utslåing", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout.tooltip": "Multipliseringsfaktor som blir brukt på attverande tid ved påfølgjande utslåingar.", + "hardcorerevival.configuration.rescueDistance": "Maks redningsavstand", + "hardcorerevival.configuration.rescueDistance.tooltip": "Avstanden ein spelar kan redda ein annan på.", + "hardcorerevival.configuration.rescueActionTicks": "Redningshandling i ticks", + "hardcorerevival.configuration.rescueActionTicks.tooltip": "Tid i ticks for å redda ein spelar. 20 ticks = eitt sekund.", + "hardcorerevival.configuration.rescueRespawnHealth": "Helse ved redningsgjenoppstand", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "Kor mykje helse spelaren får ved gjenoppstand etter redning (av 20).", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "Matnivå ved redningsgjenoppstand", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "Matnivået spelaren får ved gjenoppstand etter redning (av 20).", + "hardcorerevival.configuration.rescueRespawnEffects": "Effektar ved redningsgjenoppstand", + "hardcorerevival.configuration.rescueRespawnEffects.tooltip": "Effektar som blir påført ved redning, i formatet \"effekt|varigheit|styrke\"", + "hardcorerevival.configuration.glowOnKnockout": "Glød ved utslåing", + "hardcorerevival.configuration.glowOnKnockout.tooltip": "Om aktivert, vil utslåtte spelarar gløda og vera synlege gjennom blokker.", + "hardcorerevival.configuration.allowCommands": "Tillat kommandoar", + "hardcorerevival.configuration.allowCommands.tooltip": "Om aktivert, kan utslåtte spelarar framleis bruka kommandoar. Administratorar kan alltid bruka kommandoar.", + "hardcorerevival.configuration.allowUnarmedMelee": "Tillat nærkamp utan våpen", + "hardcorerevival.configuration.allowUnarmedMelee.tooltip": "Om aktivert, kan utslåtte spelarar framleis slå nærliggande fiendar.", + "hardcorerevival.configuration.allowBows": "Tillat bruk av bogar", + "hardcorerevival.configuration.allowBows.tooltip": "Om aktivert, kan utslåtte spelarar framleis skyta med boge.", + "hardcorerevival.configuration.allowPistols": "Tillat bruk av pistolar", + "hardcorerevival.configuration.allowPistols.tooltip": "Om aktivert, kan utslåtte spelarar framleis skyta med pistol frå MrCrayfish sin våpenmod.", + "commands.revive.success.single": "Vekte opp %s", + "commands.revive.success.multiple": "Vekte opp %s spelarar", + "commands.disabled_when_knocked_out": "Du kan ikkje bruka kommandoar medan du er utslått." +} diff --git a/common/src/main/resources/assets/hardcorerevival/lang/no_no.json b/common/src/main/resources/assets/hardcorerevival/lang/no_no.json index 097f2d4..cd12f66 100644 --- a/common/src/main/resources/assets/hardcorerevival/lang/no_no.json +++ b/common/src/main/resources/assets/hardcorerevival/lang/no_no.json @@ -1,36 +1,46 @@ { - "gui.hardcorerevival.knocked_out": "Du er slått ut", - "gui.hardcorerevival.die": "%1$s Aksepter din sjebne %1$s", + "gui.hardcorerevival.knocked_out": "Du er slått ut.", + "gui.hardcorerevival.die": "%1$s Godta din skjebne %1$s", "gui.hardcorerevival.open_death_screen": "Trykk %s for å dø.", - "gui.hardcorerevival.hold_to_rescue": "Hold %s for å redde.", + "gui.hardcorerevival.hold_to_rescue": "Hold inne %s for å redde.", "gui.hardcorerevival.rescue_time_left": "%d sekunder igjen på å reddes", - "gui.hardcorerevival.wait_for_rescue": "Vent på redning, eller aksepter din sjebne.", + "gui.hardcorerevival.wait_for_rescue": "Vent på å bli reddet eller godta skjebnen din.", "gui.hardcorerevival.being_rescued": "Du blir reddet...", "gui.hardcorerevival.rescuing": "Redder %s", "death.attack.not_rescued_in_time": "%1$s ble ikke reddet i tide", "death.attack.not_rescued_in_time.player": "%1$s ble ikke reddet i tide", - "config.hardcorerevival.ticksUntilDeath": "Ticks før dødsfall", - "config.hardcorerevival.ticksUntilDeath.tooltip": "Tiden i ticks der en spiller fortsatt kan reddes fra døden. 20 ticks er ett sekund. Sett til 0 for å deaktivere tidtakeren.", - "config.hardcorerevival.continueTimerWhileOffline": "Fortsett nedtelling mens du er frakoblet", - "config.hardcorerevival.continueTimerWhileOffline.tooltip": "Om aktivert, fortsetter nedtellingen mot døden selv om spilleren logger av.", - "config.hardcorerevival.rescueDistance": "Maks redningsavstand", - "config.hardcorerevival.rescueDistance.tooltip": "Maksavstanden som en spiller kan redde en annen på.", - "config.hardcorerevival.rescueActionTicks": "Redningshandling i ticks", - "config.hardcorerevival.rescueActionTicks.tooltip": "Tiden i ticks det vil ta å redde en spiller. 20 ticks er ett sekund.", - "config.hardcorerevival.rescueRespawnHealth": "Helse etter redning", - "config.hardcorerevival.rescueRespawnHealth.tooltip": "Mengden helse man starter med etter å ha blitt reddet, av 20.", - "config.hardcorerevival.rescueRespawnFoodLevel": "Matnivå etter redning", - "config.hardcorerevival.rescueRespawnFoodLevel.tooltip": "Matnivået man starter med etter å ha blitt reddet, av 20.", - "config.hardcorerevival.rescueRespawnEffects": "Effekter etter redning", - "config.hardcorerevival.rescueRespawnEffects.tooltip": "Effekter som gis til en spiller når den reddes, formatert som \"effekt|varighet|nivå\"", - "config.hardcorerevival.glowOnKnockout": "Glød når slått ut", - "config.hardcorerevival.glowOnKnockout.tooltip": "Hvis det er sant, vil utslåtte spillere gløde, noe som gjør dem synlige gjennom blokker.", - "config.hardcorerevival.allowUnarmedMelee": "Tillat ubevæpnet nærkamp", - "config.hardcorerevival.allowUnarmedMelee.tooltip": "Hvis det er sant, kan utslåtte spillere fortsatt slå fiender i nærheten.", - "config.hardcorerevival.allowBows": "Tillat buer", - "config.hardcorerevival.allowBows.tooltip": "Hvis det er sant, kan utslåtte spillere fortsatt skyte med buer.", - "config.hardcorerevival.allowPistols": "Tillat pistoler", - "config.hardcorerevival.allowPistols.tooltip": "Hvis det er sant, kan utslåtte spillere fortsatt avfyre pistoler fra Mr Crayfish's Gun Mod.", - "commands.revive.success.single": "Reddet %s", - "commands.revive.success.multiple": "Reddet %s spillere" + "stat.hardcorerevival.knockouts": "Slått ut", + "hardcorerevival.configuration.secondsUntilDeath": "Sekunder til død", + "hardcorerevival.configuration.secondsUntilDeath.tooltip": "Tiden i sekunder hvor en spiller kan reddes før døden inntreffer. Sett til 0 for å deaktivere nedtellingen.", + "hardcorerevival.configuration.continueTimerWhileOffline": "Fortsett nedtelling når frakoblet", + "hardcorerevival.configuration.continueTimerWhileOffline.tooltip": "Hvis aktivert, fortsetter nedtellingen selv om spilleren logger ut.", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds": "Grense for påfølgende utslåing", + "hardcorerevival.configuration.consecutiveKnockoutThresholdSeconds.tooltip": "Antall sekunder som gjør at utslåing regnes som påfølgende. Se resumeTimerOnConsecutiveKnockout og multiplyTimerOnConsecutiveKnockout.", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout": "Gjenoppta nedtelling ved påfølgende utslåing", + "hardcorerevival.configuration.resumeTimerOnConsecutiveKnockout.tooltip": "Hvis aktivert, gjenopptas nedtellingen fra forrige tidspunkt ved påfølgende utslåing.", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout": "Multipliser tid ved påfølgende utslåing", + "hardcorerevival.configuration.multiplyTimerOnConsecutiveKnockout.tooltip": "Multipliseringsfaktor som brukes på gjenværende tid ved påfølgende utslåing.", + "hardcorerevival.configuration.rescueDistance": "Maks redningsavstand", + "hardcorerevival.configuration.rescueDistance.tooltip": "Avstanden en spiller kan redde en annen på.", + "hardcorerevival.configuration.rescueActionTicks": "Redningstid i ticks", + "hardcorerevival.configuration.rescueActionTicks.tooltip": "Tiden i ticks det tar å redde en spiller. 20 ticks tilsvarer ett sekund.", + "hardcorerevival.configuration.rescueRespawnHealth": "Helse ved gjenoppliving", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "Mengden helse spilleren får etter å ha blitt reddet, av 20.", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "Mettetsnivå ved gjenoppliving", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "Mettetsnivå spilleren får etter å ha blitt reddet, av 20.", + "hardcorerevival.configuration.rescueRespawnEffects": "Effekter ved gjenoppliving", + "hardcorerevival.configuration.rescueRespawnEffects.tooltip": "Effekter som gis ved redning, i formatet \"effekt|varighet|styrke\"", + "hardcorerevival.configuration.glowOnKnockout": "Glød ved utslåing", + "hardcorerevival.configuration.glowOnKnockout.tooltip": "Hvis aktivert, vil utslåtte spillere gløde og være synlige gjennom blokker.", + "hardcorerevival.configuration.allowCommands": "Tillat kommandoer", + "hardcorerevival.configuration.allowCommands.tooltip": "Hvis aktivert, kan utslåtte spillere fortsatt bruke kommandoer. Administratorer kan alltid bruke kommandoer.", + "hardcorerevival.configuration.allowUnarmedMelee": "Tillat nærkamp uten våpen", + "hardcorerevival.configuration.allowUnarmedMelee.tooltip": "Hvis aktivert, kan utslåtte spillere fortsatt slå fiender i nærheten.", + "hardcorerevival.configuration.allowBows": "Tillat buer", + "hardcorerevival.configuration.allowBows.tooltip": "Hvis aktivert, kan utslåtte spillere fortsatt skyte med bue.", + "hardcorerevival.configuration.allowPistols": "Tillat pistoler", + "hardcorerevival.configuration.allowPistols.tooltip": "Hvis aktivert, kan utslåtte spillere fortsatt skyte med pistoler fra MrCrayfish sin våpenmod.", + "commands.revive.success.single": "Vekket opp %s", + "commands.revive.success.multiple": "Vekket opp %s spillere", + "commands.disabled_when_knocked_out": "Du kan ikke bruke kommandoer mens du er utslått." } diff --git a/common/src/main/resources/assets/hardcorerevival/lang/pt_br.json b/common/src/main/resources/assets/hardcorerevival/lang/pt_br.json index 0f3e5bd..9db9c83 100644 --- a/common/src/main/resources/assets/hardcorerevival/lang/pt_br.json +++ b/common/src/main/resources/assets/hardcorerevival/lang/pt_br.json @@ -9,18 +9,18 @@ "gui.hardcorerevival.rescuing": "Resgatando %s", "death.attack.not_rescued_in_time": "%1$s não foi resgatado a tempo", "death.attack.not_rescued_in_time.player": "%1$s não foi resgatado a tempo", - "config.hardcorerevival.maxDeathTicks": "tempo da Morte", - "config.hardcorerevival.maxDeathTicks.tooltip": "O tempo em tiques em que um jogador ainda pode ser resgatado da morte. 20 tiques são um segundo.", - "config.hardcorerevival.maxRescueDist": "Distância máxima de resgate", - "config.hardcorerevival.maxRescueDist.tooltip": "A distância na qual um jogador pode resgatar outro.", - "config.hardcorerevival.rescueTime": "Tempo de resgate", - "config.hardcorerevival.rescueTime.tooltip": "O tempo em tiques que leva para resgatar um jogador. 20 tiques são um segundo.", - "config.hardcorerevival.disableDeathTimer": "Desabilitar tempo da Morte", - "config.hardcorerevival.disableDeathTimer.tooltip": "Defina como true para desabilitar completamente o cronômetro da morte, o que significa que você terá tempo infinito para salvar outras pessoas.", - "config.hardcorerevival.rescueRespawnHealth": "Resgate Respawn Health", - "config.hardcorerevival.rescueRespawnHealth.tooltip": "A quantidade de saúde para reaparecer quando um jogador foi resgatado, de 20.", - "config.hardcorerevival.rescueRespawnFoodLevel": "Nível de Comida de Ressurgimento de Resgate", - "config.hardcorerevival.rescueRespawnFoodLevel.tooltip": "O nível de comida para reaparecer quando um jogador foi resgatado, de 20.", + "hardcorerevival.configuration.maxDeathTicks": "tempo da Morte", + "hardcorerevival.configuration.maxDeathTicks.tooltip": "O tempo em tiques em que um jogador ainda pode ser resgatado da morte. 20 tiques são um segundo.", + "hardcorerevival.configuration.maxRescueDist": "Distância máxima de resgate", + "hardcorerevival.configuration.maxRescueDist.tooltip": "A distância na qual um jogador pode resgatar outro.", + "hardcorerevival.configuration.rescueTime": "Tempo de resgate", + "hardcorerevival.configuration.rescueTime.tooltip": "O tempo em tiques que leva para resgatar um jogador. 20 tiques são um segundo.", + "hardcorerevival.configuration.disableDeathTimer": "Desabilitar tempo da Morte", + "hardcorerevival.configuration.disableDeathTimer.tooltip": "Defina como true para desabilitar completamente o cronômetro da morte, o que significa que você terá tempo infinito para salvar outras pessoas.", + "hardcorerevival.configuration.rescueRespawnHealth": "Resgate Respawn Health", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "A quantidade de saúde para reaparecer quando um jogador foi resgatado, de 20.", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "Nível de Comida de Ressurgimento de Resgate", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "O nível de comida para reaparecer quando um jogador foi resgatado, de 20.", "commands.revive.success.single": "Reviveu %s", "commands.revive.success.multiple": "Reviveu %s jogadores" } diff --git a/common/src/main/resources/assets/hardcorerevival/lang/zh_cn.json b/common/src/main/resources/assets/hardcorerevival/lang/zh_cn.json index 8b92b23..90359cf 100644 --- a/common/src/main/resources/assets/hardcorerevival/lang/zh_cn.json +++ b/common/src/main/resources/assets/hardcorerevival/lang/zh_cn.json @@ -9,18 +9,18 @@ "gui.hardcorerevival.rescuing": "救援 %s", "death.attack.not_rescued_in_time": "%1$s 未及时获救", "death.attack.not_rescued_in_time.player": "%1$s 未及时获救", - "config.hardcorerevival.maxDeathTicks": "死亡计时", - "config.hardcorerevival.maxDeathTicks.tooltip": "一名玩家死亡时可被救起的 tick 时间。20 ticks 等于一秒。", - "config.hardcorerevival.maxRescueDist": "最大救援距离", - "config.hardcorerevival.maxRescueDist.tooltip": "一名玩家可救援其它玩家的距离。", - "config.hardcorerevival.rescueTime": "救援时间", - "config.hardcorerevival.rescueTime.tooltip": "救起一名玩家所需的 tick 时间。20 ticks 等于一秒。", - "config.hardcorerevival.disableDeathTimer": "禁用死亡计时", - "config.hardcorerevival.disableDeathTimer.tooltip": "设置为true将完全禁用死亡计时,这意味着你将有无限的时间来救援他人。", - "config.hardcorerevival.rescueRespawnHealth": "被救起后的生命值", - "config.hardcorerevival.rescueRespawnHealth.tooltip": "玩家被救起后的生命值,不能为20。", - "config.hardcorerevival.rescueRespawnFoodLevel": "被救起后的饱食度", - "config.hardcorerevival.rescueRespawnFoodLevel.tooltip": "玩家被救起后的饱食度,不能为20。", + "hardcorerevival.configuration.maxDeathTicks": "死亡计时", + "hardcorerevival.configuration.maxDeathTicks.tooltip": "一名玩家死亡时可被救起的 tick 时间。20 ticks 等于一秒。", + "hardcorerevival.configuration.maxRescueDist": "最大救援距离", + "hardcorerevival.configuration.maxRescueDist.tooltip": "一名玩家可救援其它玩家的距离。", + "hardcorerevival.configuration.rescueTime": "救援时间", + "hardcorerevival.configuration.rescueTime.tooltip": "救起一名玩家所需的 tick 时间。20 ticks 等于一秒。", + "hardcorerevival.configuration.disableDeathTimer": "禁用死亡计时", + "hardcorerevival.configuration.disableDeathTimer.tooltip": "设置为true将完全禁用死亡计时,这意味着你将有无限的时间来救援他人。", + "hardcorerevival.configuration.rescueRespawnHealth": "被救起后的生命值", + "hardcorerevival.configuration.rescueRespawnHealth.tooltip": "玩家被救起后的生命值,不能为20。", + "hardcorerevival.configuration.rescueRespawnFoodLevel": "被救起后的饱食度", + "hardcorerevival.configuration.rescueRespawnFoodLevel.tooltip": "玩家被救起后的饱食度,不能为20。", "commands.revive.success.single": "复活了 %s", "commands.revive.success.multiple": "复活了 %s 玩家" } diff --git a/common/src/main/resources/hardcorerevival.mixins.json b/common/src/main/resources/hardcorerevival.mixins.json index f0d2cc5..55533ab 100644 --- a/common/src/main/resources/hardcorerevival.mixins.json +++ b/common/src/main/resources/hardcorerevival.mixins.json @@ -7,12 +7,13 @@ "mixins": [ "EntityMixin", "PlayerMixin", - "ServerPlayNetHandlerMixin", + "ServerGamePacketListenerImplMixin", "ServerPlayerAccessor", "LivingEntityMixin", "LivingEntityAccessor" ], "client": [ + "LocalPlayerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/fabric/build.gradle b/fabric/build.gradle index ec56b2c..1d2a554 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -61,7 +61,7 @@ task curseforge(type: net.darkhax.curseforgegradle.TaskPublishCurseForge) { apiToken = project.findProperty("curseforge.api_key") ?: System.getenv("CURSEFORGE_TOKEN") ?: "none" - def mainFile = upload(curseforge_fabric_project_id, file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) + def mainFile = upload(curseforge_project_id, file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) mainFile.changelog = rootProject.file('CHANGELOG.md').text mainFile.addRequirement("fabric-api") mainFile.addRequirement("balm-fabric") diff --git a/fabric/dependencies.gradle b/fabric/dependencies.gradle index 622578b..58cae50 100644 --- a/fabric/dependencies.gradle +++ b/fabric/dependencies.gradle @@ -3,4 +3,5 @@ dependencies { changing = balm_version.contains("SNAPSHOT") } modCompileOnly "com.terraformersmc:modmenu:$modmenu_version" + modCompileOnly "dev.emi:trinkets:3.10.0" } \ No newline at end of file diff --git a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/FabricHardcoreRevival.java b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/FabricHardcoreRevival.java index f9c042a..0f0ebb1 100644 --- a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/FabricHardcoreRevival.java +++ b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/FabricHardcoreRevival.java @@ -2,23 +2,15 @@ import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.api.EmptyLoadContext; -import net.blay09.mods.balm.fabric.provider.FabricBalmProviders; import net.blay09.mods.hardcorerevival.HardcoreRevival; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; +import net.blay09.mods.hardcorerevival.compat.Compat; import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EntityType; public class FabricHardcoreRevival implements ModInitializer { @Override public void onInitialize() { Balm.initialize(HardcoreRevival.MOD_ID, EmptyLoadContext.INSTANCE, HardcoreRevival::initialize); - var providers = ((FabricBalmProviders) Balm.getProviders()); - ResourceLocation identifier = ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "player_data"); - providers.registerProvider(identifier, HardcoreRevivalData.class); - var lookup = EntityApiLookup.get(identifier, HardcoreRevivalData.class, Void.class); - lookup.registerForType((entity, context) -> ((FabricPlayer) entity).getHardcoreRevivalData(), EntityType.PLAYER); + Balm.initializeIfLoaded(Compat.TRINKETS, "net.blay09.mods.hardcorerevival.fabric.compat.TrinketsAddon"); } } diff --git a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/FabricPlayer.java b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/FabricPlayer.java deleted file mode 100644 index 6d4d816..0000000 --- a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/FabricPlayer.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.blay09.mods.hardcorerevival.fabric; - -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; - -public interface FabricPlayer { - HardcoreRevivalData getHardcoreRevivalData(); -} diff --git a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/compat/TrinketsAddon.java b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/compat/TrinketsAddon.java new file mode 100644 index 0000000..187860d --- /dev/null +++ b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/compat/TrinketsAddon.java @@ -0,0 +1,19 @@ +package net.blay09.mods.hardcorerevival.fabric.compat; + +import dev.emi.trinkets.api.TrinketsApi; +import net.blay09.mods.balm.api.Balm; +import net.blay09.mods.hardcorerevival.api.PlayerAboutToKnockOutEvent; +import net.blay09.mods.hardcorerevival.tag.ModItemTags; +import net.minecraft.world.item.Items; + +public class TrinketsAddon { + public TrinketsAddon() { + Balm.getEvents().onEvent(PlayerAboutToKnockOutEvent.class, event -> { + TrinketsApi.getTrinketComponent(event.getPlayer()).ifPresent(trinkets -> { + if (trinkets.isEquipped(itemStack -> itemStack.is(ModItemTags.PASSTHROUGH_DEATH_WHEN_HELD))) { + event.setCanceled(true); + } + }); + }); + } +} diff --git a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/datagen/ModDataGenerator.java b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/datagen/ModDataGenerator.java new file mode 100644 index 0000000..29558ab --- /dev/null +++ b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/datagen/ModDataGenerator.java @@ -0,0 +1,12 @@ +package net.blay09.mods.hardcorerevival.fabric.datagen; + +import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; + +public class ModDataGenerator implements DataGeneratorEntrypoint { + @Override + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + FabricDataGenerator.Pack pack = fabricDataGenerator.createPack(); + pack.addProvider(ModItemTagProvider::new); + } +} diff --git a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/datagen/ModItemTagProvider.java b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/datagen/ModItemTagProvider.java new file mode 100644 index 0000000..1a36486 --- /dev/null +++ b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/datagen/ModItemTagProvider.java @@ -0,0 +1,22 @@ +package net.blay09.mods.hardcorerevival.fabric.datagen; + +import net.blay09.mods.hardcorerevival.tag.ModItemTags; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; + +import java.util.concurrent.CompletableFuture; + +public class ModItemTagProvider extends FabricTagProvider { + public ModItemTagProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, Registries.ITEM, registriesFuture); + } + + @Override + protected void addTags(HolderLookup.Provider lookup) { + getOrCreateTagBuilder(ModItemTags.PASSTHROUGH_DEATH_WHEN_HELD).add(Items.TOTEM_OF_UNDYING); + } +} diff --git a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/mixin/FabricPlayerMixin.java b/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/mixin/FabricPlayerMixin.java deleted file mode 100644 index 4e2edb7..0000000 --- a/fabric/src/main/java/net/blay09/mods/hardcorerevival/fabric/mixin/FabricPlayerMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.blay09.mods.hardcorerevival.fabric.mixin; - -import net.blay09.mods.hardcorerevival.fabric.FabricPlayer; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalDataImpl; -import net.minecraft.world.entity.player.Player; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Player.class) -public class FabricPlayerMixin implements FabricPlayer { - - private HardcoreRevivalData hardcoreRevivalData; - - @Override - public HardcoreRevivalData getHardcoreRevivalData() { - if(hardcoreRevivalData == null) { - hardcoreRevivalData = new HardcoreRevivalDataImpl(); - } - return hardcoreRevivalData; - } - -} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 61ed806..a0584dc 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -25,6 +25,9 @@ "client": [ "net.blay09.mods.hardcorerevival.fabric.client.FabricHardcoreRevivalClient" ], + "fabric-datagen": [ + "net.blay09.mods.hardcorerevival.fabric.datagen.ModDataGenerator" + ], "modmenu": [ "net.blay09.mods.hardcorerevival.fabric.compat.ModMenuIntegration" ] diff --git a/fabric/src/main/resources/hardcorerevival.fabric.mixins.json b/fabric/src/main/resources/hardcorerevival.fabric.mixins.json index e8f4a4a..9c26527 100644 --- a/fabric/src/main/resources/hardcorerevival.fabric.mixins.json +++ b/fabric/src/main/resources/hardcorerevival.fabric.mixins.json @@ -4,7 +4,6 @@ "package": "net.blay09.mods.hardcorerevival.fabric.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ - "FabricPlayerMixin" ], "client": [ ], diff --git a/forge/build.gradle b/forge/build.gradle index 962dc7c..111d6e5 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -99,7 +99,7 @@ task curseforge(type: net.darkhax.curseforgegradle.TaskPublishCurseForge) { apiToken = project.findProperty("curseforge.api_key") ?: System.getenv("CURSEFORGE_TOKEN") ?: "none" - def mainFile = upload(curseforge_forge_project_id, file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) + def mainFile = upload(curseforge_project_id, file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) mainFile.changelog = rootProject.file('CHANGELOG.md').text mainFile.addRequirement("balm") project.minecraft_versions.split(',').toList().each { mainFile.addGameVersion(it) } diff --git a/forge/src/main/java/net/blay09/mods/hardcorerevival/ForgeHardcoreRevival.java b/forge/src/main/java/net/blay09/mods/hardcorerevival/ForgeHardcoreRevival.java index 3d704e9..2e5e315 100644 --- a/forge/src/main/java/net/blay09/mods/hardcorerevival/ForgeHardcoreRevival.java +++ b/forge/src/main/java/net/blay09/mods/hardcorerevival/ForgeHardcoreRevival.java @@ -3,68 +3,18 @@ import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.api.EmptyLoadContext; import net.blay09.mods.balm.api.client.BalmClient; -import net.blay09.mods.balm.forge.provider.ForgeBalmProviders; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalDataImpl; import net.blay09.mods.hardcorerevival.client.HardcoreRevivalClient; -import net.minecraft.client.Minecraft; -import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.capabilities.*; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.Objects; @Mod(HardcoreRevival.MOD_ID) public class ForgeHardcoreRevival { - private final Capability hardcoreRevivalDataCapability = CapabilityManager.get(new CapabilityToken<>() { - }); - public ForgeHardcoreRevival() { Balm.initialize(HardcoreRevival.MOD_ID, EmptyLoadContext.INSTANCE, HardcoreRevival::initialize); - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> BalmClient.initialize(HardcoreRevival.MOD_ID, EmptyLoadContext.INSTANCE, HardcoreRevivalClient::initialize)); - - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::registerCapabilities); - MinecraftForge.EVENT_BUS.addGenericListener(Entity.class, this::attachEntityCapabilities); - - ForgeBalmProviders providers = (ForgeBalmProviders) Balm.getProviders(); - providers.register(HardcoreRevivalData.class, new CapabilityToken<>() { - }); - } - - private void registerCapabilities(RegisterCapabilitiesEvent event) { - event.register(HardcoreRevivalData.class); + DistExecutor.runWhenOn(Dist.CLIENT, + () -> () -> BalmClient.initialize(HardcoreRevival.MOD_ID, EmptyLoadContext.INSTANCE, HardcoreRevivalClient::initialize)); } - private void attachEntityCapabilities(AttachCapabilitiesEvent event) { - if (event.getObject() instanceof Player) { - event.addCapability(ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, "entity_data"), new ICapabilityProvider() { - private LazyOptional revival; - - private LazyOptional getRevivalCapabilityInstance() { - if (revival == null) { - revival = LazyOptional.of(HardcoreRevivalDataImpl::new); - } - - return revival; - } - - @Override - public LazyOptional getCapability(Capability cap, @Nullable Direction facing) { - return hardcoreRevivalDataCapability.orEmpty(cap, getRevivalCapabilityInstance()); - } - }); - } - } } diff --git a/forge/src/main/java/net/blay09/mods/hardcorerevival/compat/MrCrayfishsGunModAddon.java b/forge/src/main/java/net/blay09/mods/hardcorerevival/compat/MrCrayfishsGunModAddon.java index 4ccba17..e475c62 100644 --- a/forge/src/main/java/net/blay09/mods/hardcorerevival/compat/MrCrayfishsGunModAddon.java +++ b/forge/src/main/java/net/blay09/mods/hardcorerevival/compat/MrCrayfishsGunModAddon.java @@ -2,7 +2,7 @@ import com.mrcrayfish.guns.event.GunFireEvent; import net.blay09.mods.balm.api.Balm; -import net.blay09.mods.hardcorerevival.HardcoreRevival; +import net.blay09.mods.hardcorerevival.PlayerHardcoreRevivalManager; import net.blay09.mods.hardcorerevival.config.HardcoreRevivalConfig; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.MinecraftForge; @@ -19,7 +19,7 @@ public MrCrayfishsGunModAddon() { @SubscribeEvent public void onGunFirePre(GunFireEvent.Pre event) { - if (HardcoreRevival.getRevivalData(event.getEntity()).isKnockedOut()) { + if (PlayerHardcoreRevivalManager.isKnockedOut(event.getEntity())) { ResourceLocation mainHandItemKey = Balm.getRegistries().getKey(event.getEntity().getMainHandItem().getItem()); boolean isFiringPistol = Objects.equals(mainHandItemKey, PISTOL); if (isFiringPistol && HardcoreRevivalConfig.getActive().allowPistols) { diff --git a/gradle.properties b/gradle.properties index 50e6fda..6a19434 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ mod_id = hardcorerevival mod_name = Hardcore Revival mod_main=HardcoreRevival description=Help your friends back up after they die (if you can make it in time). -version = 21.1.1 +version = 21.1.11 group = net.blay09.mods homepage=https://mods.twelveiterations.com/mc/hardcore-revival sources=https://github.com/TwelveIterationMods/HardcoreRevival @@ -12,21 +12,20 @@ license=All Rights Reserved # Publishing curseforge_release_type = release -curseforge_forge_project_id = 274036 -curseforge_fabric_project_id = 554587 +curseforge_project_id = 274036 modrinth_release_type = release modrinth_project_id = HqKoXaXz # Minecraft minecraft_version = 1.21.1 minimum_minecraft_version = 1.21 -minecraft_versions = 1.21,1.21.1 +minecraft_versions = 1.21.1 minecraft_version_range = [1.21,) pack_format_number = 18 java_version = 21 # Balm -balm_version = 21.0.14-SNAPSHOT +balm_version = 21.0.55+1.21.1 balm_version_range = [21.0.0,) # Forge @@ -52,7 +51,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false mod_author = BlayTheNinth credits = BlayTheNinth -kuma_version = [21.0,22) +kuma_version = [21.0,21.2) neo_form_version = 1.21.1-20240808.144430 parchment_minecraft = 1.21 parchment_version = 2024.06.23 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0d18421..e48eca5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 223276f..08b015b 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -60,7 +60,7 @@ task curseforge(type: net.darkhax.curseforgegradle.TaskPublishCurseForge) { apiToken = project.findProperty("curseforge.api_key") ?: System.getenv("CURSEFORGE_TOKEN") ?: "none" - def mainFile = upload(curseforge_forge_project_id, file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) + def mainFile = upload(curseforge_project_id, file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) mainFile.changelog = rootProject.file('CHANGELOG.md').text mainFile.addRequirement("balm") project.minecraft_versions.split(',').toList().each { mainFile.addGameVersion(it) } diff --git a/neoforge/dependencies.gradle b/neoforge/dependencies.gradle index bf92cd4..ee548fa 100644 --- a/neoforge/dependencies.gradle +++ b/neoforge/dependencies.gradle @@ -2,4 +2,5 @@ dependencies { implementation("net.blay09.mods:balm-neoforge:${balm_version}") { changing = balm_version.contains("SNAPSHOT") } + compileOnly("top.theillusivec4.curios:curios-neoforge:9.2.2+1.21.1:api") } \ No newline at end of file diff --git a/neoforge/src/main/java/net/blay09/mods/hardcorerevival/NeoForgeHardcoreRevival.java b/neoforge/src/main/java/net/blay09/mods/hardcorerevival/NeoForgeHardcoreRevival.java index 2826595..b1bdf08 100644 --- a/neoforge/src/main/java/net/blay09/mods/hardcorerevival/NeoForgeHardcoreRevival.java +++ b/neoforge/src/main/java/net/blay09/mods/hardcorerevival/NeoForgeHardcoreRevival.java @@ -2,33 +2,18 @@ import net.blay09.mods.balm.api.Balm; import net.blay09.mods.balm.neoforge.NeoForgeLoadContext; -import net.blay09.mods.balm.neoforge.provider.NeoForgeBalmProviders; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalData; -import net.blay09.mods.hardcorerevival.capability.HardcoreRevivalDataImpl; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EntityType; +import net.blay09.mods.hardcorerevival.compat.Compat; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.capabilities.EntityCapability; -import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; @Mod(HardcoreRevival.MOD_ID) public class NeoForgeHardcoreRevival { - private final EntityCapability hardcoreRevivalDataCapability = EntityCapability.createVoid(ResourceLocation.fromNamespaceAndPath(HardcoreRevival.MOD_ID, - "entity_data"), HardcoreRevivalData.class); - public NeoForgeHardcoreRevival(IEventBus eventBus) { final var context = new NeoForgeLoadContext(eventBus); Balm.initialize(HardcoreRevival.MOD_ID, context, HardcoreRevival::initialize); - eventBus.addListener(this::registerCapabilities); - - NeoForgeBalmProviders providers = (NeoForgeBalmProviders) Balm.getProviders(); - providers.registerEntityProvider(HardcoreRevivalData.class, hardcoreRevivalDataCapability); + Balm.initializeIfLoaded(Compat.CURIOS, "net.blay09.mods.hardcorerevival.neoforge.compat.CuriosAddon"); } - private void registerCapabilities(RegisterCapabilitiesEvent event) { - event.registerEntity(hardcoreRevivalDataCapability, EntityType.PLAYER, (player, context) -> new HardcoreRevivalDataImpl()); - } } diff --git a/neoforge/src/main/java/net/blay09/mods/hardcorerevival/neoforge/compat/CuriosAddon.java b/neoforge/src/main/java/net/blay09/mods/hardcorerevival/neoforge/compat/CuriosAddon.java new file mode 100644 index 0000000..2d45c5d --- /dev/null +++ b/neoforge/src/main/java/net/blay09/mods/hardcorerevival/neoforge/compat/CuriosAddon.java @@ -0,0 +1,19 @@ +package net.blay09.mods.hardcorerevival.neoforge.compat; + +import net.blay09.mods.balm.api.Balm; +import net.blay09.mods.hardcorerevival.api.PlayerAboutToKnockOutEvent; +import net.blay09.mods.hardcorerevival.tag.ModItemTags; +import net.minecraft.world.item.Items; +import top.theillusivec4.curios.api.CuriosApi; + +public class CuriosAddon { + public CuriosAddon() { + Balm.getEvents().onEvent(PlayerAboutToKnockOutEvent.class, event -> { + CuriosApi.getCuriosInventory(event.getPlayer()).ifPresent(trinkets -> { + if (trinkets.isEquipped(itemStack -> itemStack.is(ModItemTags.PASSTHROUGH_DEATH_WHEN_HELD))) { + event.setCanceled(true); + } + }); + }); + } +} diff --git a/repositories.gradle b/repositories.gradle index 0fa21f4..382bdd7 100644 --- a/repositories.gradle +++ b/repositories.gradle @@ -65,4 +65,18 @@ repositories { includeGroup "de.siphalor" } } + + maven { + url = 'https://maven.ladysnake.org/releases' + content { + includeGroup "org.ladysnake.cardinal-components-api" + } + } + + maven { + url = "https://maven.theillusivec4.top/" + content { + includeGroup "top.theillusivec4.curios" + } + } } \ No newline at end of file