Crystal-Nest / soul-fire-d

Let Soul Fire burn!
https://modrinth.com/mod/soul-fire-d
GNU General Public License v3.0
5 stars 2 forks source link

My game crashed #34

Closed jojofenin99 closed 5 months ago

jojofenin99 commented 9 months ago

My games crashes with no crash report i got soulfired along with a bunch of other mods here is the log: 2023-11-19-1.log

Crystal-Spider commented 9 months ago

So, unfortunately this seems to be an unavoidable compatibility issue with Soul Fire'd and Danger Close.
Basically, we both try to change the default behavior for when campfires hurt entities, and this causes a collision that makes the game crash.

Unfortunately, the link for their source gives a 404 Not Found error, so I can't look too much into this and find a way to solve it.
You can try to ask Danger Close modder for better help, I can't do much on my own.

Crystal-Spider commented 9 months ago

Also, as a side note, I wonder what's the point of changing the campfire behavior when already by standing on it you take damage. Is it just so that one takes damage even by standing nearby? That's not really how a campfire works, that's why it has a wooden structure at its base to prevent the flames from expanding outwards.

jason13official commented 9 months ago

Hey! I'm the author of Danger Close, I used an Overwrite instead of a Redirect, how could I improve my compatibility with your mod? I can upload the source soon just dealing with a lot IRL. And I did this to disable the block causing damage so everything could be focused around the player ticking event, and use the setSecondsOnFire method as well.

Crystal-Spider commented 9 months ago

Hi @jason13official ! Thank you for reaching out! I should've thought about tagging you earlier though ahah
Anyway, I don't think I actually need your full source, with what you said I think I need just your campfire mixin and the logic for the player ticking event. Maybe we can find a solution by tweaking something in there.

Thank you again!

jason13official commented 9 months ago

Campfire Mixin

@Mixin(CampfireBlock.class)
public class CampfireBlockMixin {

    /** @reason Disabled damage standing inside block.
     * @author GGWP Jason*/
    @Overwrite
    public void entityInside(BlockState p_51269_, Level p_51270_, BlockPos p_51271_, Entity p_51272_) {
//        if (p_51269_.getValue(LIT) && p_51272_ instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity)p_51272_)) {
//            p_51272_.hurt(p_51270_.damageSources().inFire(), (float)this.fireDamage);
//        }
//        super.entityInside(p_51269_, p_51270_, p_51271_, p_51272_);
        // ORIGINAL CODE ABOVE
    }
}

Player Ticking Handler

    public static void livingTickEvent(LivingEvent.LivingTickEvent event) {
        if (Config.ENABLE_DANGER_CLOSE.get()) {

            LivingEntity entity = event.getEntity();
            Level level = entity.level(); // >= 1.20
            // Level level = entity.level; // <= 1.19.4
            BlockPos pos = entity.blockPosition();
            List<Mob> nearby = level.getNearbyEntities(Mob.class, TargetingConditions.DEFAULT, entity, entity.getBoundingBox());
            List<String> nearby_names = new ArrayList<>();

            for (Mob mob : nearby) {
                if (mob.isOnFire()) {
                    entity.setSecondsOnFire(2);
                }
                nearby_names.add(mob.getName().getString());
            }

            if ( Config.ENABLE_TORCH_BURN_DAMAGE.get() &&
                    (level.getBlockState(pos).getTags().anyMatch(blockTagKey -> blockTagKey == Tags.Blocks.TORCH_BURN_DANGER) ||
                    level.getBlockState(pos.below()).getTags().anyMatch(blockTagKey -> blockTagKey == Tags.Blocks.TORCH_BURN_DANGER))) {
                entity.setSecondsOnFire(2);
            }

            if ( Config.ENABLE_CAMPFIRE_BURN_DAMAGE.get() &&
                    ((level.getBlockState(pos).getTags().anyMatch(blockTagKey -> blockTagKey == Tags.Blocks.CAMPFIRE_BURN_DANGER) && (level.getBlockState(pos).getValue(LIT) == true)) ||
                    (level.getBlockState(pos.below()).getTags().anyMatch(blockTagKey -> blockTagKey == Tags.Blocks.CAMPFIRE_BURN_DANGER) && (level.getBlockState(pos.below()).getValue(LIT) == true)))) {
                entity.setSecondsOnFire(2);
            }

            if ( Config.ENABLE_STONECUTTER_DAMAGE.get() &&
                    (level.getBlockState(pos).getTags().anyMatch(blockTagKey -> blockTagKey == Tags.Blocks.CUTTING_DANGER) ||
                    level.getBlockState(pos.below()).getTags().anyMatch(blockTagKey -> blockTagKey == Tags.Blocks.CUTTING_DANGER))) {
                entity.addEffect(new MobEffectInstance(MobEffects.HARM, 2, 0, false, false));
            }

            if ( Config.ENABLE_BLAZE_DAMAGE.get() && nearby_names.contains("Blaze")) {
                entity.setSecondsOnFire(2);
            }

            if ( Config.ENABLE_MAGMA_SLIME_DAMAGE.get() && nearby_names.contains("Magma Cube")) {
                entity.setSecondsOnFire(2);
            }

            if ( Config.ENABLE_MAGMA_BLOCK_DAMAGE.get() && (level.getBlockState(pos).is(Blocks.MAGMA_BLOCK) || level.getBlockState(pos.below()).is(Blocks.MAGMA_BLOCK))) {
                entity.setSecondsOnFire(2);
            }
        }
    }

I hope this helps πŸ™ and thank you for being kind

Crystal-Spider commented 9 months ago

Quick question: what happens if either ENABLE_CAMPFIRE_BURN_DAMAGE or ENABLE_DANGER_CLOSE config options are set to false? It seems to me that this way campfires won't deal any damage to entities at all, reverting a Vanilla feature, is that correct?


Now, to solve our specific issue I think this will suffice:

@Inject(method = "entityInside", at = @At(value = "HEAD"), cancellable = true)
public void onEntityInside(BlockState state, Level world, BlockPos pos, Entity entity, CallbackInfoReturnable<Void> cir) {
  cir.cancel();
}

This way, instead of overwriting the original method, you basically just add a return; statement at the very start of it.
I think this should solve the compatibility issue without changing the inner workings of your mod.


This being said, the above solution will only avoid crashes but it won't actually make our mods 100% compatible.
This is because I use a ResourceLocation to keep track of the actual fire an entity is burning from, but of course to keep track of it I need methods that set it. Unfortunately calling directly the Entity#setSecondsOnFire(int) method doesn't do it.
With my API you would need to call FireManager#setOnFire(Entity, int, ResourceLocation) to make it 100% compatible. For example:

public static void livingTickEvent(LivingEvent.LivingTickEvent event) {
  if (Config.ENABLE_DANGER_CLOSE.get()) {
    LivingEntity entity = event.getEntity();
    Level level = entity.level(); // >= 1.20
    // Level level = entity.level; // <= 1.19.4
    BlockPos pos = entity.blockPosition();
    List<Mob> nearby = level.getNearbyEntities(Mob.class, TargetingConditions.DEFAULT, entity, entity.getBoundingBox());
    List<String> nearby_names = new ArrayList<>();

    for (Mob mob : nearby) {
      if (mob.isOnFire()) {
        FireManager.setOnFire(entity, 2, ((FireTyped) mob).getFireType());
        // entity.setSecondsOnFire(2);
      }
      nearby_names.add(mob.getName().getString());
    }

    if ( Config.ENABLE_TORCH_BURN_DAMAGE.get() && /** other conditions... */) {
      // Torches don't have an explicit Fire Type, so you need to check which kind of torch it is.
      FireManager.setOnFire(entity, 2, level.getBlockState(pos).getBlock() == Blocks.SOUL_TORCH ? FireManager.SOUL_FIRE_TYPE : FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_CAMPFIRE_BURN_DAMAGE.get() && /** other conditions... */) {
      FireManager.setOnFire(entity, 2, ((FireTyped) level.getBlockState(pos).getBlock()).getFireType());
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_STONECUTTER_DAMAGE.get() && /** other conditions... */) {
      entity.addEffect(new MobEffectInstance(MobEffects.HARM, 2, 0, false, false));
    }

    if ( Config.ENABLE_BLAZE_DAMAGE.get() && nearby_names.contains("Blaze")) {
      FireManager.setOnFire(entity, 2, FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_MAGMA_SLIME_DAMAGE.get() && nearby_names.contains("Magma Cube")) {
      FireManager.setOnFire(entity, 2, FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_MAGMA_BLOCK_DAMAGE.get() && (level.getBlockState(pos).is(Blocks.MAGMA_BLOCK) || level.getBlockState(pos.below()).is(Blocks.MAGMA_BLOCK))) {
      FireManager.setOnFire(entity, 2, FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }
  }
}

Now, I also don't want to force you to depend on my mod when it's not actually needed. So what I think is best is if you actually add my mod as an optional dependency (you can check how here and ask me if you have any doubt).
Then, at runtime, you just check if the mod is loaded and, if so, call FireManager#setOnFire(Entity, int, ResourceLocation), otherwise fall back to Entity#setSecondsOnFire(int).
To do this without crashes you need to:

  1. Create a new package (I usually call my packages for optional dependencies optional).
  2. Under the new package, you create a new class (for example called SoulFired).
  3. In SoulFired you add nothing but a single static method that wraps FireManager#setOnFire(Entity, int, ResourceLocation).
  4. (Optional, but handy) In your handler class for the entity tick event you add a method to avoid duplicating the check of whether Soul Fire'd is loaded and either call your SoulFired static method or Entity#setSecondsOnFire(int).
  5. You use the above mentioned method in place of the previous calls to set the entity on fire.

Putting these 5 steps together you get the following.

// SoulFired class under the optional package
package your.path.optional;

import crystalspider.soulfired.api.FireManager;
import net.minecraft.world.entity.Entity;

/**
 * Proxy for Soul Fire'd mod.
 */
public final class SoulFired {
  /**
   * Sets on fire the given entity, for the given seconds, with the correct Fire Type.
   * 
   * @param entity
   * @param seconds
   * @param fireType
   */
  public static void setOnFire(Entity entity, int seconds, ResourceLocation fireType) {
    FireManager.setOnFire(entity, seconds, fireType);
  }
}
// Inside your event handler class

/**
   * Whether Soul Fire'd mod is installed at runtime.
   * I think this could be a simple assignment rather than a Supplier, but I'm not 100% sure.
   */
private static final Supplier<Boolean> isSoulfiredInstalled = () -> ModList.get().isLoaded("soulfired");

public static void livingTickEvent(LivingEvent.LivingTickEvent event) {
  if (Config.ENABLE_DANGER_CLOSE.get()) {
    LivingEntity entity = event.getEntity();
    Level level = entity.level(); // >= 1.20
    // Level level = entity.level; // <= 1.19.4
    BlockPos pos = entity.blockPosition();
    List<Mob> nearby = level.getNearbyEntities(Mob.class, TargetingConditions.DEFAULT, entity, entity.getBoundingBox());
    List<String> nearby_names = new ArrayList<>();

    for (Mob mob : nearby) {
      if (mob.isOnFire()) {
        setOnFire(entity, ((FireTyped) mob).getFireType());
        // FireManager.setOnFire(entity, 2, ((FireTyped) mob).getFireType());
        // entity.setSecondsOnFire(2);
      }
      nearby_names.add(mob.getName().getString());
    }

    if ( Config.ENABLE_TORCH_BURN_DAMAGE.get() && /** other conditions... */) {
      // Torches don't have an explicit Fire Type, so you need to check which kind of torch it is.
       setOnFire(entity, level.getBlockState(pos).getBlock() == Blocks.SOUL_TORCH ? FireManager.SOUL_FIRE_TYPE : FireManager.DEFAULT_FIRE_TYPE);
      // FireManager.setOnFire(entity, 2, level.getBlockState(pos).getBlock() == Blocks.SOUL_TORCH ? FireManager.SOUL_FIRE_TYPE : FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_CAMPFIRE_BURN_DAMAGE.get() && /** other conditions... */) {
      setOnFire(entity, ((FireTyped) level.getBlockState(pos).getBlock()).getFireType());
      // FireManager.setOnFire(entity, 2, ((FireTyped) level.getBlockState(pos).getBlock()).getFireType());
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_STONECUTTER_DAMAGE.get() && /** other conditions... */) {
      entity.addEffect(new MobEffectInstance(MobEffects.HARM, 2, 0, false, false));
    }

    if ( Config.ENABLE_BLAZE_DAMAGE.get() && nearby_names.contains("Blaze")) {
      setOnFire(entity, FireManager.DEFAULT_FIRE_TYPE);
      // FireManager.setOnFire(entity, 2, FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_MAGMA_SLIME_DAMAGE.get() && nearby_names.contains("Magma Cube")) {
      setOnFire(entity, FireManager.DEFAULT_FIRE_TYPE);
      // FireManager.setOnFire(entity, 2, FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }

    if ( Config.ENABLE_MAGMA_BLOCK_DAMAGE.get() && (level.getBlockState(pos).is(Blocks.MAGMA_BLOCK) || level.getBlockState(pos.below()).is(Blocks.MAGMA_BLOCK))) {
      setOnFire(entity, FireManager.DEFAULT_FIRE_TYPE);
      // FireManager.setOnFire(entity, 2, FireManager.DEFAULT_FIRE_TYPE);
      // entity.setSecondsOnFire(2);
    }
  }
}

private static void setOnFire(Entity entity, ResourceLocation fireType) {
  if (isSoulfiredInstalled.get()) {
    SoulFired.setOnFire(entity, 2, fireType);
  } else {
    entity.setSecondsOnFire(2);
  }
}

I think this is all. If in other places you set entities on fire, the same process applies.
If there's any mistake/error in what I've written, I'm sorry but I wrote all the code in the GitHub comment section and didn't use an editor because I was outside and could use only my phone ahah

Let me know, thank you!

jason13official commented 8 months ago

Hey I'm not sure what I did wrong but I couldn't get a fix for this :/ I took some time to cleanup my code, and I've uploaded a repository DangerClose with branches for 1.19.2 Forge and 1.20.4 NeoForge. If you have any time to check them out I would appreciate it :/ I'm sorry for the inconvenience

Crystal-Spider commented 8 months ago

I created a PR for your project, branch 1.19.2-forge.
I tested it and it seems to be working fine with or without Soul Fire'd installed, but just to be sure I think it's better if you test both cases too.
Once it's all tested out, let me know if you can merge the PR and apply the same changes for the 1.20.4-neoforge branch yourself.

Let me know if there's anything else!

jason13official commented 8 months ago

I've merged your pull request into the 1.19.2-forge branch, then I did the following:

  1. download the repository as a .zip
  2. build the mod from the downloaded zip file

When I add this mod to a CurseForge profile with Soul Fire'd installed on Minecraft 1.19.2 Forge, I get Exit Code: 1 and the following error log in latest.log

[14:18:00] [pool-3-thread-1/FATAL]: Mixin apply failed mixins.dangerclose.json:MagmaBlockMixin -> net.minecraft.world.level.block.MagmaBlock: org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException Critical injection failure: @Inject annotation on onStepOn could not find any targets matching 'stepOn' in net.minecraft.world.level.block.MagmaBlock. No refMap loaded. [PREINJECT Applicator Phase -> mixins.dangerclose.json:MagmaBlockMixin -> Prepare Injections ->  -> handler$zzl000$onStepOn(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/entity/Entity;Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfo;)V -> Parse]
org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException: Critical injection failure: @Inject annotation on onStepOn could not find any targets matching 'stepOn' in net.minecraft.world.level.block.MagmaBlock. No refMap loaded. [PREINJECT Applicator Phase -> mixins.dangerclose.json:MagmaBlockMixin -> Prepare Injections ->  -> handler$zzl000$onStepOn(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/entity/Entity;Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfo;)V -> Parse]
    at org.spongepowered.asm.mixin.injection.struct.InjectionInfo.validateTargets(InjectionInfo.java:656) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.injection.struct.InjectionInfo.findTargets(InjectionInfo.java:587) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.injection.struct.InjectionInfo.readAnnotation(InjectionInfo.java:330) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.injection.struct.InjectionInfo.<init>(InjectionInfo.java:316) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.injection.struct.InjectionInfo.<init>(InjectionInfo.java:308) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.injection.struct.CallbackInjectionInfo.<init>(CallbackInjectionInfo.java:46) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[?:?]
    at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
    at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[?:?]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[?:?]
    at org.spongepowered.asm.mixin.injection.struct.InjectionInfo$InjectorEntry.create(InjectionInfo.java:149) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.injection.struct.InjectionInfo.parse(InjectionInfo.java:708) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.MixinTargetContext.prepareInjections(MixinTargetContext.java:1311) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.MixinApplicatorStandard.prepareInjections(MixinApplicatorStandard.java:1042) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.MixinApplicatorStandard.applyMixin(MixinApplicatorStandard.java:393) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.MixinApplicatorStandard.apply(MixinApplicatorStandard.java:325) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.TargetClassContext.apply(TargetClassContext.java:383) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.TargetClassContext.applyMixins(TargetClassContext.java:365) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.MixinProcessor.applyMixins(MixinProcessor.java:363) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.mixin.transformer.MixinTransformer.transformClass(MixinTransformer.java:250) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.service.modlauncher.MixinTransformationHandler.processClass(MixinTransformationHandler.java:131) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at org.spongepowered.asm.launch.MixinLaunchPluginLegacy.processClass(MixinLaunchPluginLegacy.java:131) ~[mixin-0.8.5.jar:0.8.5+Jenkins-b310.git-155314e6e91465dad727e621a569906a410cd6f4]
    at cpw.mods.modlauncher.serviceapi.ILaunchPluginService.processClassWithFlags(ILaunchPluginService.java:156) ~[modlauncher-10.0.8.jar:10.0.8+10.0.8+main.0ef7e830]
    at cpw.mods.modlauncher.LaunchPluginHandler.offerClassNodeToPlugins(LaunchPluginHandler.java:88) ~[modlauncher-10.0.8.jar:?]
    at cpw.mods.modlauncher.ClassTransformer.transform(ClassTransformer.java:120) ~[modlauncher-10.0.8.jar:?]
    at cpw.mods.modlauncher.TransformingClassLoader.maybeTransformClassBytes(TransformingClassLoader.java:50) ~[modlauncher-10.0.8.jar:?]
    at cpw.mods.cl.ModuleClassLoader.readerToClass(ModuleClassLoader.java:113) ~[securejarhandler-2.1.4.jar:?]
    at cpw.mods.cl.ModuleClassLoader.lambda$findClass$15(ModuleClassLoader.java:219) ~[securejarhandler-2.1.4.jar:?]
    at cpw.mods.cl.ModuleClassLoader.loadFromModule(ModuleClassLoader.java:229) ~[securejarhandler-2.1.4.jar:?]
    at cpw.mods.cl.ModuleClassLoader.findClass(ModuleClassLoader.java:219) ~[securejarhandler-2.1.4.jar:?]
    at cpw.mods.cl.ModuleClassLoader.loadClass(ModuleClassLoader.java:135) ~[securejarhandler-2.1.4.jar:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[?:?]
    at net.minecraft.world.level.levelgen.carver.CarverDebugSettings.<clinit>(CarverDebugSettings.java:9) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.world.level.levelgen.carver.CarverConfiguration.m_224838_(CarverConfiguration.java:20) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at com.mojang.serialization.codecs.RecordCodecBuilder.mapCodec(RecordCodecBuilder.java:76) ~[datafixerupper-5.0.28.jar%23126!/:?]
    at net.minecraft.world.level.levelgen.carver.CarverConfiguration.<clinit>(CarverConfiguration.java:16) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.world.level.levelgen.carver.WorldCarver.<clinit>(WorldCarver.java:32) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.data.worldgen.Carvers.<clinit>(Carvers.java:21) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.data.BuiltinRegistries.m_236012_(BuiltinRegistries.java:53) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.data.BuiltinRegistries.m_236009_(BuiltinRegistries.java:87) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.data.BuiltinRegistries.m_236004_(BuiltinRegistries.java:114) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[?:?]
    at net.minecraft.data.BuiltinRegistries.<clinit>(BuiltinRegistries.java:113) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.core.Registry.<clinit>(Registry.java:665) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.server.Bootstrap.m_135870_(Bootstrap.java:43) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at net.minecraft.client.main.Main.lambda$run$0(Main.java:145) ~[client-1.19.2-20220805.130853-srg.jar%23155!/:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
    at java.lang.Thread.run(Thread.java:833) [?:?]
Crystal-Spider commented 8 months ago

That's weird, it seems like it can't read the mixin refmap, but I can't figure out why. I will look more into it tomorrow!

Crystal-Spider commented 8 months ago

Okay, I opened another PR, it should be working now!

Crystal-Spider commented 6 months ago

@jason13official do you happen to have any update on this?

jason13official commented 5 months ago

sorry! I've been bogged down, I'm porting danger close to a multi-loader environment soon and I'll be sure to update you once I have this fixed. again, I apologize for the late, late reply

Crystal-Spider commented 5 months ago

Don't worry, great to hear from you!
I understand the struggle, I'm migrating to a multi-loader too and organizing better the DevOps behind it all, and it's neither fast nor easy ahah

I hope that my latest PR hasn't gone lost in the process, I get 404 when I click on the link (but maybe the repo has been moved and it's normal, I don't know).

jason13official commented 5 months ago

never to fear, I have janky solutions to hear (i was trash with git and deleted the repository like a dumbo)

I have danger close and soulfire'd working together all nice on 1.20.1,

    @Overwrite
    public void entityInside(BlockState $$0, Level $$1, BlockPos $$2, Entity $$3) {
        if ($$0.getValue(CampfireBlock.LIT) && $$3 instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity)$$3)) {
            if (CommonServices.PLATFORM.isModLoaded("soulfired")){
                $$3.hurt($$1.damageSources().inFire(), (float) fireDamage);
            }
        }
    }

I absolutely know this is not the safest / most compatible method to go about this, but it works and I am so very exhausted https://github.com/jason13official/DangerClose-1.20.1/blob/master/common/src/main/java/net/jason13/dangerclose/mixin/CommonCampfireBlockMixin.java This should be released soon I'm just waiting on my client to approve it and they'll upload it.

I'm sorry for messing up github :/ it's been a whirlwind trying to learn everything all at once

jason13official commented 5 months ago

basically just leaving in the method that you're re-directing, otherwise the method returns void? is my basic explanation 😭

jason13official commented 5 months ago

still working on this don't worry (sorry for spam)

Crystal-Spider commented 5 months ago

I think that code works for avoiding crashes. However, I don't think it suffices when it comes to setting entities on the correct kind of fire.

As I said in one of my earliest suggestions, I think it might be better to just cancel the method instead of overwriting it.

Now, to solve our specific issue I think this will suffice:

@Inject(method = "entityInside", at = @At(value = "HEAD"), cancellable = true)
public void onEntityInside(BlockState state, Level world, BlockPos pos, Entity entity, CallbackInfoReturnable<Void> cir) {
  cir.cancel();
}

This way, instead of overwriting the original method, you basically just add a return; statement at the very start of it. I think this should solve the compatibility issue without changing the inner workings of your mod.

When it comes to setting the entity on fire, it's now a bit trickier since you've moved to a multi-loader. I guess the part that actually handles it has now been moved to the common part.
The gist of it is that it's still needed to do something like this.
However, you can't just call SoulFire'd from the common part, as SoulFire'd does not (yet) have a common API. The first idea to overcome this that comes to mind is to declare in the IPlatformHelper a new setOnFire method. This method will be implemented in each loader-specific PlatformHelper and will be called in the common part when handling the event.

  // Inside the common IPlatformHelper
  void setOnFire(Entity entity, ResourceLocation fireType);
  // Inside a loader-specific PlatformHelper
  // Import the SoulFire'd loader-specific version and implement the method
  void setOnFire(Entity entity, ResourceLocation fireType);{
    if (isModLoaded("soulfired")) {
      SoulFired.setOnFire(entity, 2, fireType);
    } else {
      entity.setSecondsOnFire(2);
    }
  }

And then you can call this new method in the common event handling part.

Let me know if my explanation was clear enough or if I overlooked something!

jason13official commented 5 months ago

I've tested soulfire'd by itself and with dangerclose installed with the last commit I pushed. This version seems to work as expected , the campfires seem to work the same either way now. I mixed into the FireManager class for a test and the method damageInFire(Entity, Identifier) was still being called without issue (all I did was a basic inject into the head and a standard print to console to confirm). I had to move the event handling to the loader specific entrypoints, and removed my Mob/Player mixins from the mixin config but haven't deleted the files yet

EDIT: made the repo public https://github.com/jason13official/DangerClose-1.20.1

Crystal-Spider commented 5 months ago

Do soul fire torches set on soul fire? And, once you're on soul fire (for any reason), do normal torches (or blazes/magma blocks/etc.) set you back on normal fire?

If an entity is on soul fire, does being close to it set the player on soul fire too or on normal fire (and vice versa, if the entity is on normal fire, does the player revert from soul fire to normal fire)?

jason13official commented 5 months ago

no ;-; I'm going to keep working on this and implement what you suggested soon just short on time

jason13official commented 5 months ago

Okay! I'm at the last step, I've just pushed to the repository I created again with what you said implemented in both forge and fabric. Now, I'm facing a hilarious issue and I'm sure I might just be overlooking something, but I'd appreciate you taking a look. The campfires are giving the opposite of the correct fire, and I'm really clueless as to why.

βœ… soul fire torches set on soul fire βœ…once you're on soul fire, normal torches(magma block/blaze/etc.) set you back on normal fire ❌If an entity is on soul fire, does being close to it set the player on soul fire too ( I have no idea how to check what kind of fire is on the entity)

jason13official commented 5 months ago

sorry I see casting to FireTyped in your suggested fix now my apologies, I still need help with the campfire issue though xdxd

Crystal-Spider commented 5 months ago

I will take a look first thing tomorrow morning!
If needed, you can cast a CampfireBlock to FireTyped too.

P.S. use FireManager.SOUL_FIRE_TYPE and FireManager.DEFAULT_FIRE_TYPE instead of passing the raw ResourceLocation when calling FireManager.setOnFire, so that if they ever change, your mod will be unaffected.

jason13official commented 5 months ago

I'm still not used to posting here but I think I've got it solid now fixed 2

jason13official commented 5 months ago

P.S. use FireManager.SOUL_FIRE_TYPE and FireManager.DEFAULT_FIRE_TYPE

I got you!

Crystal-Spider commented 5 months ago

Cool! Did you manage to make everything work? Is there something I should still take a look?

jason13official commented 5 months ago

I think it's all good! It should be uploaded soon / later today** (I'm in Eastern Standard / GMT-05:00)

Crystal-Spider commented 5 months ago

Great! If you don't mind, could you make a test with BYG installed too?
BYG is compatible with Soul Fire'd and its campfires have a fire ID. I guess it's possible to make Danger Close detect BYG campfires too, and everything should work perfectly.

jason13official commented 5 months ago

Biomes You'll Go, right?

jason13official commented 5 months ago

Any chance you plan on a 1.20 port? πŸ‘‰πŸ‘ˆ

Crystal-Spider commented 5 months ago

Oh, I didn't realize that BYG is stuck at 1.19.4.
Unfortunately, that mod is not one of mine, so I can't do anything about a port.

So, if you plan on backporting to 1.19.4, you can test it, otherwise nevermind.

jason13official commented 5 months ago

Sorry I meant Soul Fire'd specifically, is there any chance of a 1.20 port?

Crystal-Spider commented 5 months ago

It's already available for 1.20!
IMG_20240331_171308

jason13official commented 5 months ago

Does 1.20.1 work for 1.20.0 specifically? Sorry if it's a dumb question, I was looking on CurseForge under the versions available

EDIT: Mainly asking because Soul Fire'd doesn't appear in the CurseForge launcher when searching on MC 1.20, only for 1.20.1+ and 1.19.4-

Crystal-Spider commented 5 months ago

Oh I'm sorry, I'm an idiot, you meant 1.20 specifically, not 1.20.x.
Then no, it's a version I dropped support for.

jason13official commented 5 months ago

No worries, thank you for the answer. I'll have DangerClose 1.20.1/1.20.2/1.20.4 released today/tomrrow, I had to fix a few issues specific to my mod that I didn't catch yesterday. After it's uploaded, should I comment here to notify you so we can close this issue?

Crystal-Spider commented 5 months ago

Yes, thank you very much!

jason13official commented 5 months ago

DangerClose on Minecraft versions 1.20.1, 1.20.2, and 1.20.4 have been uploaded (mod version 3.0.0), fixing the compatibility issue for this ticket (1.20.1) specifically! I'll have updates at a (much) later point for versions 1.19.4 and lower, unless an issue gets reported on either of our ends before I get to it

Thank you very very much for your help!! This has been a huge learning experience for me, and I appreciate the patience you have for others.

Crystal-Spider commented 5 months ago

No problem, thank you for your kind words, and thank you for taking the time to add compatibility!