Consider a more elegant approach to resolution of the target entity from the ray trace port in classes ProjectileModifierEventHandler
athrane opened this issue ยท 0 comments
Could the code from class ProjectileModifierEventHandler
below be improved?
Possibilities:
- the target resolution moved to an operator or helper function?
- the invoker resolution moved to an operator or helper function?
The same issue is also present in class ReceiveAggroBook
.
Code from ProjectileModifierEventHandler
:
/**
* Create meteor operator.
*
* The reason for not using the no-arg constructor for {@linkplain ShootMeteor2}
* is that it by default gets the target entity as living entity #2 from the
* ports.
*
* But the event handler currently only sets the invoker (in the living entity
* #1 port) and the ray race result (in the ray trace result #1 port) from the
* event.
*
* In order for {@linkplain ShootMeteor2} to resolve the target entity from the
* ray trace result then its constructor is invoked with adapted functions.
*/
static Supplier<Operator2> splMeteorOp = () -> {
Function<Ports, LivingEntity> fnGetInvoker = getFnGetLivingEntity1();
Function<Ports, LivingEntity> fnGetTarget = p -> {
RayTraceResult result = p.getRayTraceResult1();
EntityRayTraceResult entityResult = (EntityRayTraceResult) result;
return (LivingEntity) entityResult.getEntity();
};
return new Sequence2(new IsLivingEntityHitInRaytraceResult2(), new ShootMeteor2(fnGetInvoker, fnGetTarget));
};
and:
/**
* Execute meteor operator.
*
* @param event projectile impact event.
*/
static void shootMeteor(ProjectileImpactEvent event) {
// exit if invoker couldn't be resolved
Optional<LivingEntity> optInvoker = resolveInvoker(event);
if (!optInvoker.isPresent())
return;
// create ports
Ports ports = getInstance();
ports.setRayTraceResult1(event.getRayTraceResult());
ports.setLivingEntity1(optInvoker.get());
// execute
run(ports, METEOR_OPERATOR);
}