Added enchantment compatibility for accessories#1569
Added enchantment compatibility for accessories#1569Foxyas wants to merge 10 commits intoLtxProgrammer:0.15-featuresfrom
Conversation
added 5 functions; one to tell if a accessory should be considered by X enchantment. (example: mending, protection, thorns) as well a simpler boolean function that just allow a accessory to be affect by mending, one to tell if a accessory should do the "doPostHurtEffects", and one to tell if a accessory should do the "doPostDamageEffects".
|
I HOPE that i didn't break any code style thing.. |
made it use the @WrapOperation instead of @reDIrect
added quick band-aid fix for spamming logs LtxProgrammer#1570 it don't fix the issue. just ignore more than 20 logs
| return facility; | ||
| } catch (Exception e) { | ||
| Changed.LOGGER.error("Failed to load facility from disk ", e); | ||
| if (loggedFacilityTimes < 20) { |
There was a problem hiding this comment.
Band aid fix, i will remove it
LtxProgrammer
left a comment
There was a problem hiding this comment.
See review comments. Also I'd like to be the one to setup the mixins.
| /** | ||
| * Allows the Accessory be affected by mending enchantment | ||
| * This is a split method from the AccessoryItem$isConsideredByEnchantment for better class organization | ||
| * The main default value is false | ||
| * @param slotType The Accessory Slot Type | ||
| * @param itemStack The Accessory ItemStack | ||
| * @return false if not affected by mending | ||
| */ | ||
| default boolean isAffectedByMending(AccessorySlotType slotType, ItemStack itemStack) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
I don't think splitting this function out is necessary. With the exception of the Thunder Science vest, no accessories in Changed are planned to be affected by mending.
There was a problem hiding this comment.
alright. i only split such method because it looks cleaner :p
| /** | ||
| * Allow the Accessory to be Considered by an Enchantment | ||
| * It Affects directly the Enchantment$getSlotItems where it will make the method considerate the item and it equivalentSlot from the slot type | ||
| * The main default value is false | ||
| * @param enchantment The Enchantment to be considered | ||
| * @param itemStack The Accessory ItemStack | ||
| * @param slotType The Accessory Slot Type | ||
| * @param pEntity The User | ||
| * @return false if the enchantment should not be considered | ||
| */ | ||
| default boolean isConsideredByEnchantment(Enchantment enchantment, ItemStack itemStack, AccessorySlotType slotType, LivingEntity pEntity) { | ||
| if (enchantment == Enchantments.MENDING) { | ||
| return this.isAffectedByMending(slotType, itemStack); | ||
| } | ||
|
|
||
| return false; | ||
| } |
There was a problem hiding this comment.
I worry about the possibility of modded enchantments relying on the accessory being present in the equivalentSlot field. I suppose if it is up to the accessory item to specify which enchantments it will support in getRandomItemWith(), then this is fine.
| /** | ||
| * It Affects directly the Entity$getAllSlots where it will make the method considerate the item and it equivalentSlot from the slot type | ||
| * This make the item be affected by Post Damage/Hurt Effects use with it caution | ||
| * The main default value is false | ||
| * @param itemStack The Accessory ItemStack | ||
| * @param slotType The Accessory Slot Type | ||
| * @param livingEntity The User | ||
| * @return false if the enchantment should not be considered | ||
| */ | ||
| default boolean isConsideredBySlots(ItemStack itemStack, AccessorySlotType slotType, LivingEntity livingEntity) { | ||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * It Affects directly the EnchantmentHelper$doPostDamageEffects where it will make the method considerate the item and it equivalentSlot from the slot type | ||
| * It is here just for precision, example ("claw gloves" which would be affected by sharpness but not thorns) | ||
| * The main default value is false | ||
| * @param itemStack The Accessory ItemStack | ||
| * @param slotType The Accessory Slot Type | ||
| * @param livingEntity The User | ||
| * @return false if the enchantment should not be considered | ||
| */ | ||
| default boolean isConsideredIntoPostDamageEffects(ItemStack itemStack, AccessorySlotType slotType, LivingEntity livingEntity) { | ||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * It Affects directly the EnchantmentHelper$doPostHurtEffects where it will make the method considerate the item and it equivalentSlot from the slot type | ||
| * It is here just for precision, example ("Chain Vest" which would be affected by protection but not from bane of arthropods) | ||
| * The main default value is false | ||
| * @param itemStack The Accessory ItemStack | ||
| * @param slotType The Accessory Slot Type | ||
| * @param livingEntity The User | ||
| * @return false if the enchantment should not be considered | ||
| */ | ||
| default boolean isConsideredIntoPostHurtEffects(ItemStack itemStack, AccessorySlotType slotType, LivingEntity livingEntity) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
I think these three functions are redundant. It would be up to the item to specify which enchantments it supports using isConsideredByEnchantment(). Both examples you provide can be handled in that way.
There was a problem hiding this comment.
okay so should accessories just be always considered into "getAllSlots"?
There was a problem hiding this comment.
I would implement this another, simpler way. Depends on the removal of the doPostHurt and doPostDamage specifiers in AccessoryItem.
There was a problem hiding this comment.
I would implement this another, simpler way. Depends on the removal of the doPostHurt and doPostDamage specifiers in AccessoryItem.
we could make accessories always be considered into get all slots.
it would make them more similar to how normal items are considerated too
|
how about a mixin into Enchantment$doPostAttack and Enchantment$doPostHurt to considerate the accessory slots too? |
|
btw both methods only work if the Entity$getAllSlots return the accessories slots items too |
|
@LtxProgrammer how about this? |
| AccessorySlots.getForEntity(attacker).ifPresent((slots) -> | ||
| slots.forEachSlot((slotType, itemStack) -> { | ||
| if (itemStack.isEmpty()) return; | ||
| if (!(itemStack.getItem() instanceof AccessoryItem accessoryItem)) return; | ||
| if (!accessoryItem.isConsideredByEnchantment(AccessorySlotContext.of(attacker, slotType), self(), ExecutionContext.POST_HURT)) { | ||
| ci.cancel(); //Cancel behavior if the accessory item don't support it | ||
| } | ||
| }) | ||
| ); |
There was a problem hiding this comment.
This mixin will not work as intended:
- Injecting at the
HEADofEnchantment.doPostHurt()will not apply to enchantments that override it (e.g.ThornsEnchantment.doPostHurt()). - The entire
doPostHurt()effect is canceled if the player is wearing an accessory that denies that enchantment, despite wearing another item that has it. (e.g. Thorns on a chestplate fails to work when wearing benign shorts). This is becausedoPostHurt()is called per enchantment per item. This mixin code will check every accessory slot without knowing which itemdoPostHurt()has been called for.
This comment can also be applied to accessoriesEnchantmentDetectionPostAttack()
| Map<EquipmentSlot, ItemStack> returnValue = cir.getReturnValue(); | ||
| Map<EquipmentSlot, ItemStack> newReturnValue = new HashMap<>(); | ||
| if (returnValue != null) { | ||
| newReturnValue.put(slotType.getEquivalentSlot(), itemStack); |
There was a problem hiding this comment.
This function will override the enchantment effects of any armor item present in the accessory's equivalent slot, should that accessory item return true for consideration.
| returnValue.forEach(defaultStacks::add); | ||
| stacks.addAll(defaultStacks); | ||
| cir.setReturnValue(stacks); |
There was a problem hiding this comment.
This return condition will cause entities that have null default slots but present accessories to ignore said accessories. It is also very inefficient to use two lists like this. defaultStacks is completely redundant, as List::add can be called on stacks. Furthermore, the result of iterating each accessory slot will be completely ignored on a check that can be done earlier in the function.
|
I have implemented these changes locally. I will close this PR and push the changes. |
Signed-off-by: LtxPgm <ltxprogrammer@outlook.com>
|
i just got into my pc now, and alright |
|
well, now that i think about it. i'm evolving in dev skills abit too fast kk. |
It's from mixin extras. It lets you capture variables present in the context of your mixin function. |
added 5 functions;
one to tell if a accessory should be considered by X enchantment. (example: mending, protection, thorns) as well a simpler boolean function that just allow a accessory to be affect by mending,
one to tell if a accessory should do the "doPostHurtEffects",
and one to tell if a accessory should do the "doPostDamageEffects".
the accessory need to specify if it's affected by do Post Damage/Hurt feature, or else it will just do the normal enchantment.
example:
mending -> don't need to be specified if is affected by any "doPost" because it code is on the experience orb which only get a random item with the enchantment from the player that gonna get the experience
just for example i made the exoskeleton be compatible with thorns
idk if you will like such change soo is there just as a example of use
In short term -> Added suggestion from #1540