Robotic Parts

Robotic Parts

1M Downloads

[Compatibility] Increasing tolerance doesn't seem to work

clubpetey opened this issue ยท 5 comments

commented

I'm integrating this mod with GeneticsReborn, below the code I'm using to change the max tolerance for a given player:

	IAttributeInstance attr = elb.getAttributeMap().getAttributeInstanceByName("cyberware.tolerance");
	if (attr == null) return;
	
	if (add) attr.setBaseValue(attr.getBaseValue() + 25);

However, this doesn't seem to work. the RoboDoc still shows a tolerance of 100, and the players still get damage after 75 points of use. I'm not sure if this is a bug, or maybe I'm not changing the tolerance value correctly. More information can be found at the bottom of this ticket:
TheUnderTaker11/GeneticsReborn#108

commented

What versions are involved here?

commented

An attribute is provided by a mod with a base value.
AttributeModifiers are used by other mods to adjust this base value.
Beware that lots of entities are loaded permanently on a server, so you want to minimize CPU load attached to it by:

  • reducing collection lookups like getAttributeInstanceByName()
  • reducing attributes update
    => typically you could only apply your modifier every few seconds with something like:
if (entityLivingBase.ticksExisted % 100 != 0) return;
  • reduce object creation, notably attribute modifiers
    => only create it once, storing it in a static

Here's a rough example, inspired by the Claws cyberware:

private static final UUID uuidCyberGenModifierAttribute = UUID.fromString("<create your own UUID and insert it here>");
private static final HashMultimap<String, AttributeModifier> multimapCyberGenModifierAttribute;
    
static {
    multimapCyberGenModifierAttribute= HashMultimap.create();
    multimapCyberGenModifierAttribute.put(CyberwareAPI.TOLERANCE_ATTR.getName(), new AttributeModifier(uuidCyberGenModifierAttribute, "CyberGen tolerance upgrade", 25.0F, 0));
}
...
if (entityLivingBase.ticksExisted % 100 != 0) return;

if (hasClaws) {
    entityLivingBase.getAttributeMap().applyAttributeModifiers(multimapCyberGenModifierAttribute);
} else {
    entityLivingBase.getAttributeMap().removeAttributeModifiers(multimapCyberGenModifierAttribute);
}
commented

Thanks for the sample, This makes more sense now. I am a bit confused as to the need of the constant tick processing of the modifier. It seems to suggest that on some periodic basis the attribute's value is reset and modifiers must be re-applied.

This seems counter-intuitive to the desire to reduce updates. If for example I want to just permanently increase the attribute by 10, can I not just set the attribute once when the player joins the server and never again? (Ignoring death cloning).

commented

I came to the same conclusion... so I went with every 5 seconds like your example. Thanks for the hints.

commented

Yes, in theory you could apply the effect based on events instead of periodically.
Practically, there's quite a few mods out there with their own 'limitations', that'll break your mod effects directly or not. For example, on player death and when changing dimensions, there's recurrent issues with loss of attribute modifiers, potion effects or extended inventories.
As a preventive measure, it's tempting to reapply your changes periodically in the entity update event to recover your changes. My advise is to only do it infrequently, not every tick, if you consider you need this recovery logic.