[Suggestion/PR Discussion] Conversion of Tesla Coils to using an ITeslaEntity Capability
Thutmose opened this issue ยท 7 comments
Current Tesla Coil Behaviour:
-
Get a list of all nearby entities, within radius + radius/2 (targetsAll)
-
Filter targetsAll for all nearby living entities within radius (targets)
-
Select a random member of targets, and hits it for damage
-
Then foreach in targetsAll, if it is an ITeslaEntity, call onHit, otherwise if LivingEntity, try to apply the effect of the TC_FIELD to it
Proposed Tesla Coil Behaviour:
1. Convert ITeslaEntity to a capability, add an additional method to it
Currently ITeslaEntity, contains a single method, void onHit(TileEntity teslaCoil, boolean lowPower)
, which the flourescent tubes use to pull energy from the coil and glow.
I propose that onHit
be changed to onNear
, or similar, as it actually applies from distance, not for them actual arc hit, this method can have default behaviour identical to these lines here:
Next, I propose an onHit
method which is called if the arc actually hits the entity, like in (3) in the current behaviour, the effect of the default for this method can be identical to these lines here:
2. Apply this capability to all LivingEntity by default, with a lowest priority event listener
By using lowest priority event listener, this allows doing a check to see if someone else has added a capability handler for this first, before applying the default settings.
If the ITeslaEntity uses the proposed defaults above, then it will behave exactly like the current behaviour for LivingEntitites, and the Flourescent Tube can have a custom implementation as it currently does in the existing onHit
Behaviour after the proposed changes:
- Get a list of all nearby entities, within radius + radius/2 (targetsAll)
- Filter targetsAll to only contain entities which posses the ITeslaEntity capability
- Filter targetsAll for living entities within radius (targets)
- Select a random member of targets, and call the new
onHit
for it - For the remainder in targetsAll, call
onNear
Additional Things to discuss:
- Where should this capability be held? should it be where the sky hooks capability currently is?
- What arguments should be handed to the new
onHit
method, should any adjustments be made to the arguments foronNear
? - Should any other methods be added?
I'm not super sure if I like the idea of applying that capability to all living entities. Beyond that, this seems like a good approach.
hmm, could have an API method which returns an ITeslaEntity when handed an entity, and have that do a capability check, if present, return that, otherwise, return a defaulted case of the capability? that way it doesn't need to be attached to the living entities, except for ones which have custom behaviour?
ie something like:
public static ITeslaEntity getITeslaEntity(Entity in)
{
return in.getCapability(ITESLACAP).orElse(in instanceof LivingEntity? new DefaultTeslaEntity(in): null);
}
then do a null check after this to see if any effects to apply? or have the DefaultTeslaEntity able to handle non-living entities as well?
Why handle all this in some obscure default implementation of the capability?
The capability should have a void onHit()
and boolean shouldTakeDamage()
.
Then you get the capability from the target entity using entity.getCapability()
. That returns an optional. If it's present, you respect shouldTakeDamage()
. If it's not present, you just inflict damage. That way, a tesla-immune entity can prevent taking damage. Easy.
the concern is if your entity wants to do something on the standard hit, rather than on just being nearby.
currently "onHit" is more of an "onNearby", and it gets triggered regardless of if one of the arcs actually hits the entity
Having the damage dealt in a custom method call when the mob is actually hit would allow for more easily handling cases where the streamer hits the target, can be used for things like adjusting energy stored in worn items, etc as well as dealing the damage
Okay, do an onNear
, onHit
and shouldTakeDamage
then. But handling the actual damage application in a default capability implementation that needs to be applied to every Entity is a massive waste of resources.
There is zero precedent or usecase for it, over having the damaging be handled by the coil itself.
having shouldTakeDamage
would remove the utility of handing the damage in onHit
, so shouldTakeDamage
would remove the need for a default implementation
Yes, that is exactly what I'm saying.
I don't want a default implementation that gets attached to everything. So if there is no capability, the entity takes damage, and if there is one shouldTakeDamage
is called before applying damage. You can cancel it in there if you want, and then run custom damage logic in onHit