Skip to content

Conflict Group

alexcrea edited this page Oct 31, 2024 · 6 revisions

Conflict Group

Custom Anvil represent vanilla enchantment restriction by 1 concept called here "Conflict Group" sometimes just called "conflict".

General structure of a conflict group

Conflict groups contain:

  • A list of enchantment (will be called "conflict enchantments". Alternatively called "enchantments" in the config file).
  • A list of material group that will not be affected by the conflict (will be called "conflict material groups". Alternatively called "notAffectedGroups" in the config file).
  • The number of enchantments in the previously mentioned enchantment list an item need to contain before the conflict is considered active (will be called "maxBeforeConflict". Alternatively called "maxEnchantmentBeforeConflict" in the config file)

How do it work

Let assume we have a conflict, and we try to combine another item.
We call "conflicting enchantment" the list of enchantment the item contain that also contained in the conflict enchantments.

If the item material is contained, one of the conflict material groups. Then the conflict will do nothing.

Else, If the item contains more than maxBeforeConflict conflicting enchantment, then these enchantments can't have their level increased, and no new enchantment contained in the conflict enchantments can be added.

Else, The item can have new enchantments. Unless adding this enchantment would make the conflicting enchantment count more than maxBeforeConflict.

Creating and Registering a Conflict Group

Here is an example of you could create a material group

@EventHandler
public void onConfigReady(CAConfigReadyEvent event){
    // Create Material Group (see material group doc)
    // ...

    // Create Conflicts
    ConflictBuilder conflictExample = new ConflictBuilder("conflict_example"); // This is an example that mean nothing.
    conflictExample
            .addEnchantment("sharpness") // Add sharpness by its name
            .addEnchantment(NamespacedKey.minecraft("mending")) // Add mending by its key
            .addEnchantment(EnchantmentApi.getByName("unbreaking")); // Add unbreaking enchantment as Custom Anvil enchantment. assume not null (but nullable add may be available in one of the next version)

    conflictExample
            .addExcludedGroup("axes") // Add exclude group by name
            .addExcludedGroup(MaterialGroupApi.getGroup("bow")); // Add exclude group by instance. assume not null (but nullable add may be available in one of the next version)

    // Allow only 2 of the previous enchantment to be present at the same time on an item
    conflictExample.setMaxBeforeConflict(2);

    // Register group
    conflictExample.registerIfAbsent(); 
    //or you can use ConflictAPI.addConflict(conflictExample);

}

Please note: required enchantment and material group need to be registered/added before calling ConflictAPI.addConflict.

Representing vanilla restriction

To represent vanilla restrictions, Custom Anvil use 2 type of conflict.

Material Restriction conflict

A material restriction conflict goal is to restrict what item an enchantment can be applied to.
For example, we want sharpness to be applied only to swords and axes.

Properties of these groups are:

  • Only one conflict enchantment
  • Conflict material groups are the group of materials allowed to have the enchantment
  • maxBeforeConflict set to 0

Here is an example of how a material restriction conflict can be created

ConflictBuilder sharpnessRestriction = new ConflictBuilder("sharpness_restriction")
        .addEnchantment("sharpness")
        .addExcludedGroup("sword")
        .addExcludedGroup("axes")
        .setMaxBeforeConflict(0);

Enchantment conflict

An enchantment conflict is created for incompatible enchantment.
For example, we would create an enchantment conflict for the incompatibility with sharpness, smite and bane of astropode.

Properties of these groups are:

  • Conflict enchantments are all the incompatible enchantments
  • Conflict material groups is empty
  • maxBeforeConflict set to 1

Here is an example of how an echantment conflict can be created

// badly named conflict but that how it is named in cutom anvil default config
ConflictBuilder swordEnchantmentConflict = new ConflictBuilder("sword_enchant_conflict")
        .addEnchantment("sharpness")
        .addEnchantment("smite")
        .addEnchantment("bane_of_arthropods")
        .setMaxBeforeConflict(1);

Why this system ?

I created Custom Anvil with this system in my head as it could generalize restriction and I had to think of a system to customize restriction like this as my goal was to be able to replicate how vanilla minecraft handle it. May not be the best system that exist, but it does the work.
This system allow simple edit of vanilla conflict. For example:

  • If you like to have 2 protection type at the same time, set maxBeforeConflict (maxEnchantmentBeforeConflict) to 2.
  • If you like sharpness to be able to be placed on axes. Replace group melee_weapons to sword from restriction_sharpness. Almost any setting someone want to do can be done with this system.

Can I not use this system/Also use another conflict system

Yes, you can ! Just implement AdditionalTestEnchantment to your custom anvil enchantment and implement the interface functions.
Please note that server admin should/will be able to add conflict group via custom anvil if they want to.

Additional Notes:

You can also get by name and remove conflict using the ConflictAPI facade.

Current method registerIfAbsent will soon also register if the conflict was previously deleted. Current implementation of registerIfAbsent will be replaced by registerIfNew