Jump to content

ZigTheHedge

Members
  • Posts

    57
  • Joined

  • Last visited

Posts posted by ZigTheHedge

  1. Hey, guys.

    I'm trying to play a sound in a mod, which is client-only.

    It works fine with single-player saves, but when trying to use in on a real multiplayer server (without installing the mod on server of course), I'm getting a crash:

    Quote

    java.lang.NullPointerException: Registry Object not present: trovogration:cooldown_end
        at java.util.Objects.requireNonNull(Objects.java:334) ~[?:?] {re:mixin}
        at net.minecraftforge.registries.RegistryObject.get(RegistryObject.java:320) ~[forge-1.18.2-40.1.92-universal.jar%23301!/:?] {re:mixin,xf:fml:forge:registry_object_binary_compat,re:classloading,xf:fml:forge:registry_object_binary_compat}

    Here's the code:

    Registration:

    public class Sounds {
        public static final DeferredRegister<SoundEvent> SOUNDS = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, TrovoGration.MOD_ID);
        public static final RegistryObject<SoundEvent> SOUND_ACTION_NEGATIVE = SOUNDS.register("negative_action", () -> new SoundEvent(new ResourceLocation(TrovoGration.MOD_ID,"negative_action")));
        public static final RegistryObject<SoundEvent> SOUND_ACTION_POSITIVE = SOUNDS.register("positive_action", () -> new SoundEvent(new ResourceLocation(TrovoGration.MOD_ID,"positive_action")));
        public static final RegistryObject<SoundEvent> SOUND_COOLDOWN_START = SOUNDS.register("cooldown_start", () -> new SoundEvent(new ResourceLocation(TrovoGration.MOD_ID,"cooldown_start")));
        public static final RegistryObject<SoundEvent> SOUND_COOLDOWN_END = SOUNDS.register("cooldown_end", () -> new SoundEvent(new ResourceLocation(TrovoGration.MOD_ID,"cooldown_end")));
    }

    Main class constructor:

        public TrovoGration(){
            Sounds.SOUNDS.register(FMLJavaModLoadingContext.get().getModEventBus());
        }

    Play code:

    LocalPlayer player ... ;
    player.playSound(Sounds.SOUND_ACTION_NEGATIVE.get(), 0.7f, 1.0f);

    sounds.json:

    {
      "positive_action": {
    	"category": "record",
        "subtitle": "trovogration.subtitle.positive_action",
        "sounds": [ "trovogration:positive_action" ]
      },
      "negative_action": {
    	"category": "record",
        "subtitle": "trovogration.subtitle.negative_action",
        "sounds": [ "trovogration:negative_action" ]
      },
      "cooldown_start": {
    	"category": "record",
        "subtitle": "trovogration.subtitle.cooldown_start",
        "sounds": [ "trovogration:cooldown_start" ]
      },
      "cooldown_end": {
    	"category": "record",
        "subtitle": "trovogration.subtitle.cooldown_end",
        "sounds": [ "trovogration:cooldown_end" ]
      }  
    }

    Help!!

  2. Hey guys!

    I'm porting one of my mods from 1.14.4 to 1.18.2 and got stuck with Capabilities. To ensure that I'm not making a mistake elsewhere, I've started a completely new project just for testing and faced the same issue: I cannot copy capability data to new Player instance on PlayerEvent.Clone on Player's death.

    My capability class SpiritCapability:
     

    public class SpiritCapability {
    
        public final ArrayList<DeathEventData> deaths = new ArrayList<>();
    
        public void addDeath(DeathEventType reason, long tod) {
            deaths.add(new DeathEventData(reason, tod));
        }
    
        public void copyFrom(SpiritCapability source) {
            deaths.clear();
            deaths.addAll(source.deaths);
        }
    
        public void saveNBTData(CompoundTag compound) {
            compound.putInt("deathCount", deaths.size());
            for (int i = 0; i < deaths.size(); i++) {
                compound.put("dth_" + i, deaths.get(i).getTag());
            }
        }
    
        public void loadNBTData(CompoundTag compound) {
            deaths.clear();
            int deathCount = compound.getInt("deathCount");
            for (int i = 0; i < deathCount; i++) {
                CompoundTag death = compound.getCompound("dth_" + i);
                deaths.add(new DeathEventData(death));
            }
        }
    }

    Capability Provider class SpiritCapabilityProvider:
     

    public class SpiritCapabilityProvider implements ICapabilityProvider, INBTSerializable<CompoundTag> {
    
        public static Capability<SpiritCapability> SPIRIT_CAP = CapabilityManager.get(new CapabilityToken<>(){});
        private SpiritCapability spiritCapability = null;
        private final LazyOptional<SpiritCapability> opt = LazyOptional.of(this::createCap);
    
        @Nonnull
        private SpiritCapability createCap() {
            if (spiritCapability == null) {
                spiritCapability = new SpiritCapability();
            }
            return spiritCapability;
        }
    
        @NotNull
        @Override
        public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
            return getCapability(cap);
        }
    
        @NotNull
        @Override
        public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap) {
            if(cap == SPIRIT_CAP)
                return opt.cast();
            else
                return LazyOptional.empty();
        }
    
        @Override
        public CompoundTag serializeNBT() {
            CompoundTag nbt = new CompoundTag();
            createCap().saveNBTData(nbt);
            return nbt;
        }
    
        @Override
        public void deserializeNBT(CompoundTag nbt) {
            createCap().loadNBTData(nbt);
        }
    }

    Capability events:

    public class SpiritCapabilityEvents {
    
        @SubscribeEvent
        public void onAttachCapabilitiesPlayer(AttachCapabilitiesEvent<Entity> event){
            if (event.getObject() instanceof Player) {
                if (!event.getObject().getCapability(SpiritCapabilityProvider.SPIRIT_CAP).isPresent()) {
                    event.addCapability(new ResourceLocation(SinsOfDeath.MODID, "spiritcap"), new SpiritCapabilityProvider());
                }
            }
        }
    
        @SubscribeEvent
        public void onPlayerCloned(PlayerEvent.Clone event) {
            if(event.getOriginal().level.isClientSide)
                return;
    
            if(event.isWasDeath()) {
                LazyOptional<SpiritCapability> loNewCap = event.getPlayer().getCapability(SpiritCapabilityProvider.SPIRIT_CAP);
                // loOldCap is never present!
                LazyOptional<SpiritCapability> loOldCap = event.getOriginal().getCapability(SpiritCapabilityProvider.SPIRIT_CAP);
                loNewCap.ifPresent( newCap -> {
                    loOldCap.ifPresent( oldCap -> {
                        newCap.copyFrom(oldCap);
                    });
                });
            }
        }
    }

    Main class:

    @Mod(SinsOfDeath.MODID)
    public class SinsOfDeath
    {
        // Directly reference a slf4j logger
        public static final String MODID = "sinsofdeath";
        private static final Logger LOGGER = LogUtils.getLogger();
    
        public SinsOfDeath()
        {
            // Register the setup method for modloading
            FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
            FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onRegisterCapabilities);
    
        }
    
        private void setup(final FMLCommonSetupEvent event)
        {
            MinecraftForge.EVENT_BUS.register(new DeathEvent());
            MinecraftForge.EVENT_BUS.register(new CommandEvent());
            MinecraftForge.EVENT_BUS.register(new SpiritCapabilityEvents());
            Networking.registerMessages();
        }
    
        public void onRegisterCapabilities(RegisterCapabilitiesEvent event) {
            event.register(SpiritCapability.class);
        }
    }

    When setting capability data, I use the following code server-side:

    // ep is ServerPlayer 
    ...
    ep.getCapability(SpiritCapabilityProvider.SPIRIT_CAP).ifPresent(spiritDeath -> {
        spiritDeath.addDeath(finalDt, ep.deathTime);
    });
    ...

    Am I forgetting something?

  3. Okay. Solved. If anyone is interested:

    First of all, I had to use "relocate" in shadowJar to shadow both packages like this:

    shadowJar {
        configurations = [project.configurations.embed]
        relocate 'org.glassfish', 'shaded.glassfish'
        relocate 'javax.websocket', 'shaded.websocket'
        classifier = ''
    }

    After that, pay close attention at your META-INF. In my case there was a direct reference to unshadowed package service called "javax.websocket.ContainerProvider", containing unshadowed path to class... So, just find a way to replace this file with one, that is referencing your shadowed configuration. In my case, file is called "shaded.websocket.ContainerProvider".

  4. Hey, guys!

    I'm trying to add javax.websocket in my mod. In dev environment everything is smooth, but when I build my mod and add it to modpack, I'm getting java.lang.NoClassDefFoundError.

    Here's my build.gradle:

    buildscript {
        repositories {
            maven { url = 'https://maven.minecraftforge.net' }
            mavenCentral()
            repositories {
                maven {
                    url "https://plugins.gradle.org/m2/"
    
                }
            }
        }
        dependencies {
            classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '4.1.+', changing: true
            classpath "com.github.jengelman.gradle.plugins:shadow:4.0.4"
        }
    }
    apply plugin: 'net.minecraftforge.gradle'
    // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
    apply plugin: 'eclipse'
    apply plugin: 'maven-publish'
    apply plugin: 'com.github.johnrengelman.shadow'
    
    version = '1.16.5-1.0.0'
    group = 'com.cwelth.omd' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
    archivesBaseName = 'omd'
    
    java.toolchain.languageVersion = JavaLanguageVersion.of(8) // Mojang ships Java 8 to end users, so your mod should target Java 8.
    
    println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
    minecraft {
        mappings channel: 'official', version: '1.16.5'
    
        runs {
            client {
                workingDirectory project.file('run')
                property 'forge.logging.markers', 'REGISTRIES'
                property 'forge.logging.console.level', 'debug'
    
                mods {
                    examplemod {
                        source sourceSets.main
                    }
                }
            }
    
            server {
                workingDirectory project.file('run')
                property 'forge.logging.markers', 'REGISTRIES'
                property 'forge.logging.console.level', 'debug'
    
                mods {
                    examplemod {
                        source sourceSets.main
                    }
                }
            }
    
            data {
                workingDirectory project.file('run')
                property 'forge.logging.markers', 'REGISTRIES'
                property 'forge.logging.console.level', 'debug'
    
                args '--mod', 'examplemod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
    
                mods {
                    examplemod {
                        source sourceSets.main
                    }
                }
            }
        }
    }
    
    // Include resources generated by data generators.
    sourceSets.main.resources { srcDir 'src/generated/resources' }
    
    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            url = 'https://mvnrepository.com/artifact/javax'
        }
        maven {
            url = 'https://mvnrepository.com/artifact/org.glassfish.tyrus.bundles'
        }
        flatDir {
            dirs 'libs\\'
        }
    }
    
    configurations {
        embed
        compileOnly.extendsFrom(embed)
    }
    
    shadowJar {
        configurations = [project.configurations.embed]
    }
    reobf {
        shadowJar {
            dependsOn tasks.createMcpToSrg
            mappings = tasks.createMcpToSrg.outputs.files.singleFile
        }
    }
    artifacts {
        archives tasks.shadowJar
    }
    
    dependencies {
        minecraft 'net.minecraftforge:forge:1.16.5-36.1.30'
    
        /*
        compile 'javax.websocket:javax.websocket-client-api:1.1'
        compile 'org.glassfish.tyrus.bundles:tyrus-standalone-client:1.9'
        */
    
        embed 'javax.websocket:javax.websocket-client-api:1.1'
        embed 'org.glassfish.tyrus.bundles:tyrus-standalone-client:1.9'
    
    }
    
    // Example for how to get properties into the manifest for reading by the runtime..
    jar {
        manifest {
            attributes([
                "Specification-Title": "examplemod",
                "Specification-Vendor": "examplemodsareus",
                "Specification-Version": "1", // We are version 1 of ourselves
                "Implementation-Title": project.name,
                "Implementation-Version": "${version}",
                "Implementation-Vendor" :"examplemodsareus",
                "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
            ])
        }
    }
    
    jar.finalizedBy('reobfJar') 
    
    publishing {
        publications {
            mavenJava(MavenPublication) {
                artifact jar
            }
        }
        repositories {
            maven {
                url "file:///${project.projectDir}/mcmodsrepo"
            }
        }
    }

    And I can see that needed packages are in my compiled jar:

    image.thumb.png.1cb7058fce57cf914a45e26b1a94e3e6.png

  5. I'm making a block which contains three different parts. Each of the parts can use one of five possible textures, leading to 125 blocks in total (due to flattening). I could make three states in block (one state per part) and just 15 models and use multipart blockstate to combine the final block, but parts can use different geometry themselves, increasing the number of possible states combination drastically.

    In 1.12.2 there was a way to specify texture in blockstate, and now, when forge blockstate format is gone, I cannot find a way to efficiently solve this task.

  6. Hey, guys and gals!

     

    In times of 1.12.2 there was a possibility to put normal obfuscated mod jar file in ./libs directory to make its classes accessible within dev environment. In recent versions however, that doesn't work. Yes, I know that I can (and probably should) use maven dependencies to load deobf versions of needed mods, but what to do if I want to use mod, whose maven repository doesn't exist?

    I've tried to use "compile fileTree(include: ['*.jar'], dir: 'libs')" which allows IDEA to see the internals of jars inside "libs" directory, but I cannot run the mod due to obfuscated names in jars, the same with local "flatDir" repo. Is it possible now at all?

     

  7. Well, I'm struggling with getActualState absence... I have a block, which should act pretty much like fences do. It changes it's model (via BlockState) according to neighbors. I overrode updateNeighbors to set BlockStates to correct values when block is placed nearby, but this method doesn't get called when something destroys the block. What mechanic should I use to change the BlockState when nearby block is destroyed?

    Forge: 28.1.104

  8. Well, it seems that normals doesn't get rotated with the model itself when I use GlStateManager.rotate.

    I have a JSON model. One part of it is static, and two parts are dynamic. Dynamic parts are rendered using TESR. If the facing of model placed in world is NORTH (default) - everything is rendering as it should, but when model gets rotated, static part is rendered fine and TESR part looks like normals of dynamic parts are still pointing to the NORTH direction. Here are the screenshots:

    2019-09-13_11_10_56.png.306d2de0c76d72d3119230f3c039d045.png

    Model facing SOUTH

     

    2019-09-13_11_10_47.png.1dd581ec777980df9064b52a3f348c4f.png

    Model facing NORTH

     

    TESR rendering part:

    @Override
    public void render(CounterTE te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) {
        GlStateManager.pushAttrib();
        GlStateManager.pushMatrix();
    
    
        GlStateManager.translate(x, y, z);
        GlStateManager.disableRescaleNormal();
    
        renderDoor(te, partialTicks);
    
        GlStateManager.popMatrix();
        GlStateManager.popAttrib();
    }
    
    public void renderDoor(CounterTE te, float partialTicks) {
        GlStateManager.pushMatrix();
        RenderHelper.disableStandardItemLighting();
    
        this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
        if (Minecraft.isAmbientOcclusionEnabled()) {
            GlStateManager.shadeModel(GL11.GL_SMOOTH);
        } else {
            GlStateManager.shadeModel(GL11.GL_FLAT);
        }
    
        World world = te.getWorld();
        //Rotate renderer to match FACING
        
        GlStateManager.translate(.5F, 0, .5F);
        if(world.getBlockState(te.getPos()).getValue(CommonBlock.FACING) == EnumFacing.NORTH)GlStateManager.rotate(0, 0, 1, 0);
        if(world.getBlockState(te.getPos()).getValue(CommonBlock.FACING) == EnumFacing.EAST)GlStateManager.rotate(270, 0, 1, 0);
        if(world.getBlockState(te.getPos()).getValue(CommonBlock.FACING) == EnumFacing.SOUTH)GlStateManager.rotate(180, 0, 1, 0);
        if(world.getBlockState(te.getPos()).getValue(CommonBlock.FACING) == EnumFacing.WEST)GlStateManager.rotate(90, 0, 1, 0);
        GlStateManager.translate(-.5F, 0, -.5F);
    
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder bufferBuilder = tessellator.getBuffer();
        bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
        
        IBlockState stateLeft = NMFBlocks.counter.getDefaultState().withProperty(Counter.ASKFOR_LEFTDOOR, true);
        IBlockState stateRight = NMFBlocks.counter.getDefaultState().withProperty(Counter.ASKFOR_RIGHTDOOR, true);
        BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
    
        IBakedModel modelLeft = dispatcher.getModelForState(stateLeft);
        IBakedModel modelRight = dispatcher.getModelForState(stateRight);
    
        GlStateManager.pushMatrix();
        //Render LEFT door
        GlStateManager.translate(0.96875F, 0, 0.15625F);
    
        if(te.getMovingDelta() != 0)
            GlStateManager.rotate(-(te.getOpenProgress() + partialTicks * ((te.getMovingDelta() > 0) ? 1 : -1)), 0, 1, 0);
        else
            GlStateManager.rotate(-te.getOpenProgress(), 0, 1, 0);
        GlStateManager.translate(-0.96875F, 0, -0.15625F);
    
        GlStateManager.translate(-te.getPos().getX(), -te.getPos().getY(), -te.getPos().getZ());
    
        dispatcher.getBlockModelRenderer().renderModel(world, modelLeft, stateLeft, te.getPos(), bufferBuilder, true);
        tessellator.draw();
    
        GlStateManager.translate(te.getPos().getX(), te.getPos().getY(), te.getPos().getZ());
        GlStateManager.popMatrix();
    
        GlStateManager.pushMatrix();
        //Render RIGHT door
        bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
    
        GlStateManager.translate(0.03125F, 0, 0.15625F);
        if(te.getMovingDelta() != 0)
            GlStateManager.rotate(te.getOpenProgress() + partialTicks * ((te.getMovingDelta() > 0) ? 1 : -1), 0, 1, 0);
        else
            GlStateManager.rotate(te.getOpenProgress(), 0, 1, 0);
        GlStateManager.translate(-0.03125F, 0, -0.15625F);
    
        GlStateManager.translate(-te.getPos().getX(), -te.getPos().getY(), -te.getPos().getZ());
    
        dispatcher.getBlockModelRenderer().renderModel(world, modelRight, stateRight, te.getPos(), bufferBuilder, true);
        bufferBuilder.putNormal(0F, 1F, 0F);
        tessellator.draw();
    
        GlStateManager.translate(te.getPos().getX(), te.getPos().getY(), te.getPos().getZ());
        GlStateManager.popMatrix();
    
        RenderHelper.enableStandardItemLighting();
        GlStateManager.popMatrix();
    }
    

     

    TESR is necessary because of block inventory rendering. That's actually the only reason why I don't use ASM animation...

     

  9. That's definitely the problem with IDEA and gradle 4.8.1 because I have the very same issue every damned time I'm cloning my old project from github into new dev environment. But usually I'm able to fix it by rerunning setupDecompWorkspace and genIntelliJRuns with IDEA closed. That issue has nothing to do with file names and locations because they ARE correct. You can try to run runClient task from gradle directly to see that everything is loading properly. I'm not experienced in gradle or IDEA internals, so I cannot point to exact problematic place...

     

    • Like 1
  10. @Mod.EventBusSubscriber(Side.CLIENT)
    public class ClientProxy extends CommonProxy {
      ...
        @Override
        public void preInit(FMLPreInitializationEvent e) {
            OBJLoader.INSTANCE.addDomain(MODID);
            super.preInit(e);
        }
      ...
    }

    Something like this.

     

    And don't forget to create blockstate json for your item (it should point to .obj file in "defaults" section):

    {
      "forge_marker": 1,
      "defaults":
      {
        "model": "modid:knight_helmet.obj"
      },
      "variants":
      {
        "inventory":[{
          "transform": "forge:default-item"
        }]
      }
    }

    Something like that.

     

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.