Skip to content

Commit

Permalink
Add bounce on impact projectile item #952
Browse files Browse the repository at this point in the history
  • Loading branch information
athrane committed Sep 23, 2020
1 parent 9462895 commit 0f9aa17
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/main/java/bassebombecraft/config/ModConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
import bassebombecraft.item.composite.projectile.formation.modifier.InaccuracyProjectileFormationModifierItem;
import bassebombecraft.item.composite.projectile.formation.modifier.OscillatingRotation180DProjectileFormationModifierItem;
import bassebombecraft.item.composite.projectile.formation.modifier.RandomProjectileFormationModifierItem;
import bassebombecraft.item.composite.projectile.modifier.BounceProjectileModifierItem;
import bassebombecraft.item.composite.projectile.modifier.CharmProjectileModifierItem;
import bassebombecraft.item.composite.projectile.modifier.DecoyProjectileModifierItem;
import bassebombecraft.item.composite.projectile.modifier.DigMobHoleProjectileModifierItem;
Expand Down Expand Up @@ -466,6 +467,7 @@ public class ModConfiguration {
public static ItemConfig spawnCobwebProjectileModifierItem;
public static ItemConfig spawnAnvilProjectileModifierItem;
public static ItemConfig receiveAggroProjectileModifierItem;
public static ItemConfig bounceProjectileModifierItem;

// Actions..

Expand Down Expand Up @@ -2203,6 +2205,17 @@ static void setupCompositeItemsConfig() {
"A mythical image of the modification of a projectile. If a creature is hit then all mobs in the vicinity will aggro the creature.",
25);
COMMON_BUILDER.pop();

/**
* Configuration for the {@linkplain BounceProjectileModifierItem} item.
*/
name = BounceProjectileModifierItem.NAME;
COMMON_BUILDER.comment(name + " settings").push(name);
bounceProjectileModifierItem = getInstance(COMMON_BUILDER, name,
"A mythical image of the modification of a projectile. If a block is hit then the project bounce of the block in some other direction.",
25);
COMMON_BUILDER.pop();

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import bassebombecraft.item.composite.projectile.formation.modifier.InaccuracyProjectileFormationModifierItem;
import bassebombecraft.item.composite.projectile.formation.modifier.OscillatingRotation180DProjectileFormationModifierItem;
import bassebombecraft.item.composite.projectile.formation.modifier.RandomProjectileFormationModifierItem;
import bassebombecraft.item.composite.projectile.modifier.BounceProjectileModifierItem;
import bassebombecraft.item.composite.projectile.modifier.CharmProjectileModifierItem;
import bassebombecraft.item.composite.projectile.modifier.DecoyProjectileModifierItem;
import bassebombecraft.item.composite.projectile.modifier.DigMobHoleProjectileModifierItem;
Expand Down Expand Up @@ -200,7 +201,8 @@ BUILD_MINE_BOOK, new BuildAbyssBook(), new BuildSmallHoleBook(), new NaturalizeB
new MeteorProjectileModifierItem(), new DecoyProjectileModifierItem(),
new ExplodeMobWhenKilledProjectileModifierItem(), new DigMobHoleProjectileModifierItem(),
new ExplodeOnImpactProjectileModifierItem(), new SpawnCobwebProjectileModifierItem(),
new SpawnAnvilProjectileModifierItem(), new ReceiveAggroProjectileModifierItem() };
new SpawnAnvilProjectileModifierItem(), new ReceiveAggroProjectileModifierItem(),
new BounceProjectileModifierItem() };

/**
* Handle {@linkplain RegistryEvent.Register<Item>} event to register items with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import bassebombecraft.operator.entity.Explode2;
import bassebombecraft.operator.entity.ShootMeteor2;
import bassebombecraft.operator.entity.potion.effect.AddEffect2;
import bassebombecraft.operator.entity.raytraceresult.Bounce2;
import bassebombecraft.operator.entity.raytraceresult.Charm2;
import bassebombecraft.operator.entity.raytraceresult.DigMobHole2;
import bassebombecraft.operator.entity.raytraceresult.ExplodeOnImpact2;
Expand Down Expand Up @@ -176,6 +177,11 @@ public class ProjectileModifierEventHandler {
*/
static final Operator2 RECEIVE_AGGGRO_OPERATOR = splReceiveAggroOp.get();

/**
* Bounce on impact operator.
*/
static final Operator2 BOUNCE_ON_IMPACT_OPERATOR = new Bounce2();

@SubscribeEvent
static public void handleProjectileImpactEvent(ProjectileImpactEvent event) {
try {
Expand Down Expand Up @@ -234,6 +240,10 @@ static public void handleProjectileImpactEvent(ProjectileImpactEvent event) {
if (tags.contains(ReceiveAggro2.NAME))
receiveAggro(event);

// handle: bounce projectile
if (tags.contains(Bounce2.NAME))
bounceOnImpact(event);

} catch (Exception e) {
getBassebombeCraft().reportAndLogException(e);
}
Expand Down Expand Up @@ -426,4 +436,19 @@ static void receiveAggro(ProjectileImpactEvent event) {
run(ports, RECEIVE_AGGGRO_OPERATOR);
}

/**
* Execute bounce projectile on impact operator.
*
* @param event projectile impact event.
*/
static void bounceOnImpact(ProjectileImpactEvent event) {
Ports ports = getInstance();
ports.setRayTraceResult1(event.getRayTraceResult());
ports.setEntity1(event.getEntity());
run(ports, BOUNCE_ON_IMPACT_OPERATOR);

// cancel event to avoid removal of projectile
event.setCanceled(true);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package bassebombecraft.item.composite.projectile.modifier;

import static bassebombecraft.config.ModConfiguration.bounceProjectileModifierItem;
import static bassebombecraft.operator.DefaultPorts.getFnGetEntities1;

import java.util.function.Function;
import java.util.function.Supplier;

import bassebombecraft.event.projectile.ProjectileModifierEventHandler;
import bassebombecraft.item.composite.GenericCompositeNullItem;
import bassebombecraft.operator.Operator2;
import bassebombecraft.operator.Ports;
import bassebombecraft.operator.entity.raytraceresult.Bounce2;
import bassebombecraft.operator.projectile.modifier.TagProjectileWithProjectileModifier;
import net.minecraft.entity.Entity;

/**
* Bounce on impact projectile modifier item.
*
* The tagged projectile is processed in
* {@linkplain ProjectileModifierEventHandler} where the {@linkplain Bounce2}
* operator is executed.
*/
public class BounceProjectileModifierItem extends GenericCompositeNullItem {

/**
* Item identifier.
*/
public static final String NAME = BounceProjectileModifierItem.class.getSimpleName();

/**
* Create operators.
*/
static Supplier<Operator2> splOp = () -> {
Function<Ports, Entity[]> fnGetProjectiles = getFnGetEntities1();
Function<Ports, String> fnGetTag = p -> Bounce2.NAME;
return new TagProjectileWithProjectileModifier(fnGetProjectiles, fnGetTag);
};

/**
* Constructor.
*/
public BounceProjectileModifierItem() {
super(NAME, bounceProjectileModifierItem);
}

@Override
public Operator2 createOperator() {
return splOp.get();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package bassebombecraft.operator.entity.raytraceresult;

import static bassebombecraft.entity.projectile.ProjectileUtils.isBlockHit;
import static bassebombecraft.entity.projectile.ProjectileUtils.isNothingHit;
import static bassebombecraft.entity.projectile.ProjectileUtils.isTypeBlockRayTraceResult;
import static bassebombecraft.operator.DefaultPorts.getFnGetEntity1;
import static bassebombecraft.operator.DefaultPorts.getFnGetRayTraceResult1;

import java.util.function.Function;

import bassebombecraft.operator.Operator2;
import bassebombecraft.operator.Ports;
import net.minecraft.entity.Entity;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;

/**
* Implementation of the {@linkplain Operator2} interface which bounces
* projectile on impact on block.
*/
public class Bounce2 implements Operator2 {

/**
* Operator identifier.
*/
public static final String NAME = Bounce2.class.getSimpleName();

/**
* Null entity for block explosions.
*/
static final Entity NULL_ENTITY = null;

/**
* Function to get ray trace result.
*/
Function<Ports, RayTraceResult> fnGetRayTraceResult;

/**
* Function to get projectile entity.
*/
Function<Ports, Entity> fnGetProjectile;

/**
* Constructor.
*
* @param splRayTraceResult function to get ray trace result.
* @param fnGetProjectile function to get projectile entity.
*/
public Bounce2(Function<Ports, RayTraceResult> fnGetRayTraceResult,
Function<Ports, Entity> fnGetProjectile) {
this.fnGetRayTraceResult = fnGetRayTraceResult;
this.fnGetProjectile = fnGetProjectile;
}

/**
* Constructor.
*
* Instance is configured with ray tracing result #1 from ports.
*
* Instance is configured with entity #1 as projectile from ports.
*/
public Bounce2() {
this(getFnGetRayTraceResult1(), getFnGetEntity1());
}

@Override
public Ports run(Ports ports) {

// get ray trace result
RayTraceResult result = fnGetRayTraceResult.apply(ports);
if (result == null)
return ports;

// get projectile
Entity projectile = fnGetProjectile.apply(ports);
if (projectile == null)
return ports;

// get motion vector
Vec3d motionVector = projectile.getMotion();
if (motionVector == null)
return ports;

// exit if nothing was hit
if (isNothingHit(result))
return ports;

// bounce projectile motion
if (isBlockHit(result)) {

// exit if result isn't block ray trace result
if (!isTypeBlockRayTraceResult(result))
return ports;

// type cast
BlockRayTraceResult blockResult = (BlockRayTraceResult) result;

// get impact info
Direction impactFace = blockResult.getFace();
Axis impactAxis = impactFace.getAxis();

// calculate bounced motion vector
Vec3d bouncedVector = bounceMotionVector(impactAxis, motionVector);

// set bounced motion
projectile.setMotion(bouncedVector);
}

return ports;
}

/**
* Calculate bounced motion vector.
*
* @param impactAxis impact axis.
* @param motionVector motion vector.
*
* @return bounced motion vector
*/
Vec3d bounceMotionVector(Axis impactAxis, Vec3d motionVector) {
switch(impactAxis) {
case X:
return motionVector.mul(-1, 1, 1);
case Y:
return motionVector.mul(1, -1, 1);
case Z:
return motionVector.mul(1, 1, -1);
}
return motionVector;
}

}
1 change: 1 addition & 0 deletions src/main/resources/assets/bassebombecraft/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
"item.bassebombecraft.spawncobwebprojectilemodifieritem": "Projectile Modifier: Spawn Cobweb",
"item.bassebombecraft.spawnanvilprojectilemodifieritem": "Projectile Modifier: Spawn Anvil",
"item.bassebombecraft.receiveaggroprojectilemodifieritem": "Projectile Modifier: Receive Mob Aggro",
"item.bassebombecraft.bounceprojectilemodifieritem": "Projectile Modifier: Bounce On Impact",

"_comment": "effects",
"effect.bassebombecraft.amplifiereffect": "Amplify effects",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"parent": "item/handheld",
"textures": {
"layer0": "bassebombecraft:item/bounceprojectilemodifieritem"
},
"display": {
"thirdperson_righthand": {
"rotation": [ 0, -15, 0 ],
"translation": [ 0, 0, 0 ],
"scale": [ 0.5, 0.5, 0.5 ]
},
"thirdperson_lefthand": {
"rotation": [ 0, -15, 0 ],
"translation": [ 0, 0, 0 ],
"scale": [ 0.5, 0.5, 0.5 ]
},
"firstperson_righthand": {
"rotation": [ 0, -90, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 0.5, 0.5, 0.5 ]
},
"firstperson_lefthand": {
"rotation": [ 0, 90, -25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 0.5, 0.5, 0.5 ]
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 0f9aa17

Please sign in to comment.