Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Mixin tutorials


Tret
 Share

Recommended Posts

Dear Forge Community,

 

I have an idea for a mod which implementation is a bit invasive and I have only c++ experience yet so I've came here to ask this question. (I know I should not program MC mods without java experience but in my opinion the seek for knowledge should not be refused under any circumstances and I'm turning to you guys hoping you would not reject it either.)

 

The base idea is to implement heat and heat exchange and add this mechanic to the vanilla blocks of minecraft. My idea is to only calculate a blocks init heat if It's heat transfer rate is far enough from 0 in any direction. This would allow me to calculate efficiently and would not require me to store a new unsigned short for every block. Also I'm planning to use air as a block group with same heat unit at init. At least yet.

 

The question is. I need to mixin into the chunk generation in order to catch the event block generated event and inject my code before return but I can not find any good documentation about this topic and I also can not find the block generated event function which I need to overwrite. Can you help me out with this?

Every help is appreciated since I'm learning modding and java.

 

Edit: typo

Edited by Tret
Link to comment
Share on other sites

6 hours ago, Tret said:

(I know I should not program MC mods without java experience but in my opinion the seek for knowledge should not be refused under any circumstances and I'm turning to you guys hoping you would not reject it either.)

basic java is required for modding minecraft 

Also coremodding/mixin is not supported on this Forum, if you have a real case to use mixin, refer to the Forge Discord into the channel non-api-modding

Link to comment
Share on other sites

So in theory if I had an event that is triggered when a block's neighbor changes I can determine the heat transfer rate at a given tick for the block and with this way I can spare lot's of calculations. So I would need an event that triggers when a block is placed but not just for my blocks, for every block there is in minecraft. I'm searching for that function so I can implement my mechanic in it.

Link to comment
Share on other sites

The problem is, this is a constructor and mixin can not modify constructors. Subscribing to the event would still not work as I need to apply my mechanic to every block there is in Minecraft. Subscribing only applies my mechanic to my blocks or am I wrong here?

Link to comment
Share on other sites

Is this as easy as this: https://mcforge.readthedocs.io/en/latest/datastorage/capabilities/#attaching-capabilities

Or do I need to create my own capability?

 

Also considering I need to store the BlockPos too as a key my storage size would almost go triple the size as opposed if I try to add my value as a block property. Is there a way to avoid this?

Link to comment
Share on other sites

11 minutes ago, Tret said:

that's exactly what D7 told you

 

11 minutes ago, Tret said:

Or do I need to create my own capability?

read the doc, you also can look at the Forge Community Wiki

 

11 minutes ago, Tret said:

Also considering I need to store the BlockPos too as a key my storage size would almost go triple the size as opposed if I try to add my value as a block property. Is there a way to avoid this?

what, create a Map<BlockPos, your Property>, the BlockPos is the Key and your Property is the value

Edited by Luis_ST
Link to comment
Share on other sites

Yeah but a BlockPos contains a lot of information. For example 3 ints for the 3D space. Id of the world which could be an unsigned short but it is still 31bit of information. If java is smart enough maybe it will use references instead of copy constructors but is it smart enough for that or should I dig into java symbols for getting a value by reference?

Link to comment
Share on other sites

4 minutes ago, Tret said:

Yeah but a BlockPos contains a lot of information. For example 3 ints for the 3D space. Id of the world which could be an unsigned short but it is still 31bit of information.

then create your own BlockPos, with the Data which is relevant for you

but iirc the BlockPos is an extension of Vec3 which use 3 Integer there no more Data

Link to comment
Share on other sites

You can write your own record that stores just the position within the chunk. That's two 4-bit numbers (0-15 for x and z) and the y position (pre 1.18 this is just a byte, 0-255). So for pre 1.18 you need a record with two bytes in it.

For 1.18 you'll have to be more sophisticated, because the build height has been increased.

Link to comment
Share on other sites

I've been digging for some capabilities knowledge and I can see a lot of people using capabilities and nbt tags to add custom properties to block entities. Should I stick with the custom storage or would the capability system be a better way to implement my mechanic?

So far I have these prototype codes:
 

public class HeatCapability implements IHeat{
    @Override
    public void setHeat(double heat) {

    }

    @Override
    public double getHeat() {
        return 0;
    }

    @Override
    public double ExchangeRate() {
        return 0;
    }

    @Override
    public double HeatCapacity() {
        return 0;
    }

    @Override
    public double ExchangeFactor() {
        return 0;
    }

    @Override
    public void write(DataOutput pOutput) throws IOException {

    }

    @Override
    public byte getId() {
        return 0;
    }

    @Override
    public TagType<?> getType() {
        return null;
    }

    @Override
    public Tag copy() {
        return null;
    }

    @Override
    public void accept(TagVisitor pVisitor) {

    }
}
public class HeatStorage implements ICapabilitySerializable<CompoundTag> {
    @CapabilityInject(IHeat.class)
    public static final Capability<IHeat> HEAT_CAPABILITY = null;
    public static final LazyOptional<IHeat> instance = LazyOptional.of(HEAT_CAPABILITY::getDefaultInstance);

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
        return cap == HEAT_CAPABILITY? (LazyOptional<T>) instance : LazyOptional.empty();
    }

    @Override
    public CompoundTag serializeNBT() {
        CompoundTag nbt = new CompoundTag();
        nbt.putDouble("Heat", instance.resolve().get().getHeat());
        return nbt;
    }

    @Override
    public void deserializeNBT(CompoundTag nbt) {
        instance.resolve().get().setHeat(nbt.getDouble("Heat"));
    }
}
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • Amplifier is like the strength of the effect, for example movement speed boost with amplifier 0 will be Speed I, and 1 will be Speed II, 2 will be Speed III. Effect is just an...effect type, EffectInstance contains all information for the actual effect being applied to the entity (duration, amplifier...etc). For example there's only an effect type "Speed", but for an EffectInstance it could be: "Level 2 Speed for 10 seconds" "Level 4 Speed for 2 seconds"...   The first method applyEffectTick is called when a effect is impacting the entity, the first arg is the entity that has the effect/is affected by the effect, and amplifier is the strength of the effect. The second method isDurationEFfectTick is to check whether the effect should impact/affect the entity this tick (the effects usually don't trigger every tick!), if true, then the first method is called.  
    • Hi, I have enchantment named "Stun" that can be applied to weapon and that has 3 levels: Level 1 - 10% chance to stun mob for 1 sec Level 2 - 20% chance to stun mob for 2 secs Level 3 - 30% chance to stun mob for 3 secs Plan is to apply MobEffect named StunnedMobEffect on doPostAttack in enchantment. StunnedMobEffect should have variable duration based on the level of enchantment that was applied on weapon. I am trying to find an example on how to do the following: How can I set duration of effect dynamically? How can I track whether duration has expired? I have found these two methods that can be overriden:   public void applyEffectTick(LivingEntity pLivingEntity, int pAmplifier) { public boolean isDurationEffectTick(int pDuration, int pAmplifier) { But looking at the source code of MobEffect class, I can't figure out what pAmplifier is? Any hints / samples on this would be appreciated.          
    • 2022-01-22 07:41:00,800 main WARN Advanced terminal features are not available in this environment [07:41:00] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher running: args [--gameDir, ., --launchTarget, fmlserver, --fml.forgeVersion, 36.2.23, --fml.mcpVersion, 20210115.111550, --fml.mcVersion, 1.16.5, --fml.forgeGroup, net.minecraftforge, nogui] [07:41:00] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher 8.0.9+86+master.3cf110c starting: java version 17.0.2 by Oracle Corporation Exception in thread "main" java.lang.IllegalAccessError: class cpw.mods.modlauncher.SecureJarHandler (in unnamed module @0x7ff95560) cannot access class sun.security.util.ManifestEntryVerifier (in module java.base) because module java.base does not export sun.security.util to unnamed module @0x7ff95560         at cpw.mods.modlauncher.SecureJarHandler.lambda$static$1(SecureJarHandler.java:41)         at cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck(LamdbaExceptionUtils.java:95)         at cpw.mods.modlauncher.SecureJarHandler.<clinit>(SecureJarHandler.java:41)         at cpw.mods.modlauncher.Launcher.lambda$new$6(Launcher.java:55)         at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)         at cpw.mods.modlauncher.api.TypesafeMap.computeIfAbsent(TypesafeMap.java:52)         at cpw.mods.modlauncher.api.TypesafeMap.computeIfAbsent(TypesafeMap.java:47)         at cpw.mods.modlauncher.Environment.computePropertyIfAbsent(Environment.java:62)         at cpw.mods.modlauncher.Launcher.<init>(Launcher.java:55)         at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)         at net.minecraftforge.server.ServerMain$Runner.runLauncher(ServerMain.java:63)         at net.minecraftforge.server.ServerMain$Runner.access$100(ServerMain.java:60)         at net.minecraftforge.server.ServerMain.main(ServerMain.java:57) i have the same how do i fix it  
    • Hi, I'm facing an issue that a custom datapack is always loaded before the mod's datapack. Means the users/players are not able to override mod's configurations/data at all. I've tried to alternate the order of datapack by using the /datapack commands, however the actual loading order does not change at all. (I can confirm that both datapacks are working as usual by disabling one of them at a time, the correspond data is loaded correctly), is it the mod's problem or...? Thanks.
    • I'm trying to play a custom modpack with a few dozen mods, but when I try to create a world it hits 100% and then crashes and I can't figure out why. Here's the crash log:  
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.