From 84000f31fdd1a938328ed0fada4317cbddadb292 Mon Sep 17 00:00:00 2001 From: TechnoDraconic Date: Mon, 2 Feb 2026 09:29:16 -0800 Subject: [PATCH] Added oxygen damage and an oxygen damage source --- .../aphelion/core/init/ModDamageSources.java | 19 ++++++++++ .../mixins/common/LivingEntityMixin.java | 29 ++++++++++++++ .../aphelion/systems/OxygenService.java | 38 +++++++++++++++++++ src/main/resources/aphelion.mixins.json | 1 + .../data/aphelion/damage_type/oxygen.json | 7 ++++ .../tags/damage_type/no_knockback.json | 6 +++ 6 files changed, 100 insertions(+) create mode 100644 src/main/java/net/xevianlight/aphelion/core/init/ModDamageSources.java create mode 100644 src/main/java/net/xevianlight/aphelion/mixins/common/LivingEntityMixin.java create mode 100644 src/main/java/net/xevianlight/aphelion/systems/OxygenService.java create mode 100644 src/main/resources/data/aphelion/damage_type/oxygen.json create mode 100644 src/main/resources/data/minecraft/tags/damage_type/no_knockback.json diff --git a/src/main/java/net/xevianlight/aphelion/core/init/ModDamageSources.java b/src/main/java/net/xevianlight/aphelion/core/init/ModDamageSources.java new file mode 100644 index 0000000..9d8b1dc --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/core/init/ModDamageSources.java @@ -0,0 +1,19 @@ +package net.xevianlight.aphelion.core.init; + +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.DamageType; +import net.minecraft.world.level.Level; +import net.xevianlight.aphelion.Aphelion; + +public class ModDamageSources { + + // Relatively sure this is right + public static final ResourceKey OXYGEN = ResourceKey.create(Registries.DAMAGE_TYPE, ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "oxygen")); + + public static DamageSource create(Level level, ResourceKey key) { + return new DamageSource(level.registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(key)); + } +} diff --git a/src/main/java/net/xevianlight/aphelion/mixins/common/LivingEntityMixin.java b/src/main/java/net/xevianlight/aphelion/mixins/common/LivingEntityMixin.java new file mode 100644 index 0000000..3d2cd63 --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/mixins/common/LivingEntityMixin.java @@ -0,0 +1,29 @@ +package net.xevianlight.aphelion.mixins.common; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.level.Level; +import net.xevianlight.aphelion.systems.OxygenService; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +// +@Mixin(LivingEntity.class) +public abstract class LivingEntityMixin extends Entity { + + public LivingEntityMixin(EntityType type, Level level) { super(type, level); } + + @Inject(method= "tick", at = @At("TAIL")) + public void aphelion$tick(CallbackInfo ci) { + if ((level() instanceof ServerLevel level)) { + LivingEntity entity = (LivingEntity) (Object) this; + + // Oxygen system + OxygenService.entityTick(level, entity); + } + } +} diff --git a/src/main/java/net/xevianlight/aphelion/systems/OxygenService.java b/src/main/java/net/xevianlight/aphelion/systems/OxygenService.java new file mode 100644 index 0000000..9a4611b --- /dev/null +++ b/src/main/java/net/xevianlight/aphelion/systems/OxygenService.java @@ -0,0 +1,38 @@ +package net.xevianlight.aphelion.systems; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.level.Level; +import net.xevianlight.aphelion.Aphelion; +import net.xevianlight.aphelion.core.init.ModDamageSources; +import net.xevianlight.aphelion.core.saveddata.EnvironmentSavedData; + +public class OxygenService { + public static boolean hasOxygen(Level level, BlockPos pos) { + if (level.isClientSide) { + // We can't pull oxygen data from the client side, so just, uhh, don't! + Aphelion.LOGGER.warn("Tried to get server oxygen data from client side!"); + return false; + } + boolean positionHasOxygen = EnvironmentSavedData.get((ServerLevel) level).hasOxygen(level, pos); + + return positionHasOxygen; + } + + public static boolean hasOxygen(Entity entity) { + // Not sure if this is at the entity's feet, head, or the middle... research later + BlockPos entityBlockPos = BlockPos.containing(entity.getX(), entity.getY(), entity.getZ()); + return hasOxygen(entity.level(), entityBlockPos); + } + + public static int OXYGEN_DAMAGE_TICK_AMT = 2; + public static int OXYGEN_DAMAGE_TICK_FREQ = 20; + /// Called by LivingEntity.entityTick mixin + public static void entityTick(ServerLevel level, LivingEntity entity) { + if (entity.tickCount % OXYGEN_DAMAGE_TICK_FREQ != 0) return; + if (hasOxygen(entity)) return; + entity.hurt(ModDamageSources.create(level, ModDamageSources.OXYGEN), OXYGEN_DAMAGE_TICK_AMT); + } +} diff --git a/src/main/resources/aphelion.mixins.json b/src/main/resources/aphelion.mixins.json index 37514cb..29e0967 100644 --- a/src/main/resources/aphelion.mixins.json +++ b/src/main/resources/aphelion.mixins.json @@ -4,6 +4,7 @@ "package": "net.xevianlight.aphelion.mixins", "compatibilityLevel": "JAVA_21", "mixins": [ + "common.LivingEntityMixin" ], "client": [ "common.ClientLevelMixin", diff --git a/src/main/resources/data/aphelion/damage_type/oxygen.json b/src/main/resources/data/aphelion/damage_type/oxygen.json new file mode 100644 index 0000000..d5745f5 --- /dev/null +++ b/src/main/resources/data/aphelion/damage_type/oxygen.json @@ -0,0 +1,7 @@ +{ + "message_id": "%1$s remembers' your §bOxygens", + "scaling": "never", + "exhaustion": 0, + "effects": "drowning", + "death_message_type": "default" +} \ No newline at end of file diff --git a/src/main/resources/data/minecraft/tags/damage_type/no_knockback.json b/src/main/resources/data/minecraft/tags/damage_type/no_knockback.json new file mode 100644 index 0000000..ac29ecb --- /dev/null +++ b/src/main/resources/data/minecraft/tags/damage_type/no_knockback.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "aphelion:oxygen" + ] +} \ No newline at end of file