Skip to content

Commit 8364ff2

Browse files
committed
feat: rework impaler by removing shooter self damage, reducing move penalty, reducing reload time, decreasing max velocity and allowing the projectile to launch without full charge
1 parent c6e9e9c commit 8364ff2

File tree

7 files changed

+75
-95
lines changed

7 files changed

+75
-95
lines changed

src/main/java/com/github/elenterius/biomancy/client/gui/ScreenOverlays.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import com.github.elenterius.biomancy.item.KnowledgeReader;
1414
import com.github.elenterius.biomancy.item.injector.InjectorItem;
1515
import com.github.elenterius.biomancy.item.weapon.gun.Gun;
16-
import com.github.elenterius.biomancy.item.weapon.gun.GunProperties;
1716
import com.github.elenterius.biomancy.styles.TextStyles;
1817
import com.github.elenterius.biomancy.util.ComponentUtil;
1918
import com.mojang.blaze3d.platform.GlStateManager;
@@ -290,14 +289,25 @@ static void renderReloadIndicator(GuiGraphics guiGraphics, int screenWidth, int
290289
else {
291290
long elapsedTimeFromShot = player.clientLevel.getGameTime() - gun.getShootTimestamp(stack);
292291

293-
if (gun.getShootBehavior() != GunProperties.ShootBehavior.INSTANT) {
294-
int delayBetweenShots = Math.max(gun.getDelayBetweenShots(stack), 1);
295-
int ticksUsingItem = player.getTicksUsingItem();
296-
if (ticksUsingItem >= 0) {
297-
float pct = ticksUsingItem / (float) delayBetweenShots;
298-
float chargeProgress = Mth.clamp(pct - Mth.floor(pct), 0f, 1f);
299-
GuiRenderUtil.drawSquareProgressBar(guiGraphics, screenWidth / 2, screenHeight / 2, zDepth, 10, chargeProgress);
292+
switch (gun.getShootBehavior()) {
293+
case ON_FULL_CHARGE -> {
294+
int delayBetweenShots = Math.max(gun.getDelayBetweenShots(stack), 1);
295+
int ticksUsingItem = player.getTicksUsingItem();
296+
if (ticksUsingItem >= 0) {
297+
float pct = ticksUsingItem / (float) delayBetweenShots;
298+
float chargeProgress = Mth.clamp(pct - Mth.floor(pct), 0f, 1f);
299+
GuiRenderUtil.drawSquareProgressBar(guiGraphics, screenWidth / 2, screenHeight / 2, zDepth, 10, chargeProgress);
300+
}
300301
}
302+
case ON_RELEASE_INSTANT, ON_RELEASE_WITH_FULL_CHARGE -> {
303+
if (player.isUsingItem()) {
304+
int delayBetweenShots = Math.max(gun.getDelayBetweenShots(stack), 1);
305+
float elapsedDuration = (float) stack.getUseDuration() - ((float) player.getUseItemRemainingTicks());
306+
float chargePercentage = Mth.clamp(elapsedDuration / delayBetweenShots, 0f, 1f);
307+
GuiRenderUtil.drawSquareProgressBar(guiGraphics, screenWidth / 2, screenHeight / 2, zDepth, 10, chargePercentage);
308+
}
309+
}
310+
default -> {}
301311
}
302312

303313
renderAttackIndicator(guiGraphics, screenWidth, screenHeight, zDepth, player, elapsedTimeFromShot, gun.getDelayBetweenShots(stack));

src/main/java/com/github/elenterius/biomancy/entity/projectile/BaseProjectile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ protected void onHit(HitResult result) {
150150
}
151151

152152
protected void spawnParticle(double x, double y, double z) {
153-
level().addParticle(getParticle(), x, y + 0.5d, z, 0, 0, 0);
153+
level().addParticle(getParticle(), x, y + getBbHeight() * 0.5f, z, 0, 0, 0);
154154
}
155155

156156
protected ParticleOptions getParticle() {

src/main/java/com/github/elenterius/biomancy/entity/projectile/ImpalerProjectile.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ protected void positionRider(Entity passenger, MoveFunction mover) {
159159

160160
@Override
161161
public float getGravity() {
162-
return Math.max(getDeltaMovement().length() <= 0.25d ? 0.05f : 0.001f, getPassengers().size() * 0.02f);
162+
double speed = getDeltaMovement().length();
163+
return Math.max(speed < 1d ? 0.05f : 0.001f, getPassengers().size() * 0.02f);
163164
}
164165

165166
@Override
@@ -244,8 +245,6 @@ protected void onHitBlock(BlockHitResult result) {
244245

245246
/////////////
246247

247-
System.out.println(level().isClientSide);
248-
249248
if (!tryToDestroyBlock(blockState, blockPos)) {
250249
blockState.onProjectileHit(level(), blockState, result, this);
251250

src/main/java/com/github/elenterius/biomancy/init/ModProjectiles.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
public final class ModProjectiles {
2121

2222
public static final List<ConfiguredProjectile<? extends BaseProjectile>> PRECONFIGURED_PROJECTILES = new ArrayList<>();
23-
public static final ConfiguredProjectile<ToothProjectile> TOOTH = create("Sharp Tooth", 1.75f, 5f, 0, 0.92f, ToothProjectile::new);
24-
public static final ConfiguredProjectile<ImpalerProjectile> IMPALER_PROJECTILE = create("Impaler Projectile", 3f, 24f, 0, 0.99f, ModSoundEvents.IMPALER_SHOOT.get(), ImpalerProjectile::new);
23+
24+
public static final ConfiguredProjectile<ImpalerProjectile> IMPALER_PROJECTILE = create("Impaler Projectile", 2.85f, 24f, 0, 0.99f, ModSoundEvents.IMPALER_SHOOT.get(), ImpalerProjectile::new);
2525
public static final ConfiguredProjectile<AcidBlobProjectile> ACID_BLOB = create("Acid Blob", 1.5f, 2, 0, 0.9f, ModSoundEvents.ACID_BLOB_SHOOT.get(), (level, x, y, z) -> new AcidBlobProjectile(level, x, y, z, false));
2626
public static final ConfiguredProjectile<AcidBlobProjectile> FALLING_ACID_BLOB = create("Falling Acid Blob", 0.1f, 2, 0, 0.9f, ModSoundEvents.ACID_BLOB_FALL.get(), AcidBlobProjectile::new);
2727
public static final ConfiguredProjectile<AcidSpitProjectile> GASTRIC_SPIT = create("Gastric Acid Spit", 1.5f, 1, 0, 0.25f, ModSoundEvents.ACID_SPIT.get(), AcidSpitProjectile::new);

src/main/java/com/github/elenterius/biomancy/item/weapon/gun/GunItem.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,19 +179,23 @@ public void onUseTick(Level level, LivingEntity shooter, ItemStack stack, int re
179179

180180
@Override
181181
public void releaseUsing(ItemStack stack, Level level, LivingEntity shooter, int remainingUseDuration) {
182+
182183
if (level instanceof ServerLevel serverLevel && gunProperties.shootBehavior().isOnRelease()) {
183184
int elapsedTime = getUseDuration(stack) - remainingUseDuration;
184185
int delayBetweenShots = getDelayBetweenShots(stack);
185186

186-
boolean mayShoot = switch (gunProperties.shootBehavior()) {
187-
case ON_RELEASE_INSTANT -> true;
188-
case ON_RELEASE_WITH_FULL_CHARGE -> elapsedTime >= delayBetweenShots;
189-
default -> false;
190-
};
191-
192-
if (mayShoot && serverLevel.getGameTime() - getShootTimestamp(stack) < delayBetweenShots) {
193-
shoot(serverLevel, shooter, shooter.getUsedItemHand(), stack);
194-
stack.getOrCreateTag().putLong(SHOOT_TIMESTAMP_KEY, serverLevel.getGameTime());
187+
switch (gunProperties.shootBehavior()) {
188+
case ON_RELEASE_INSTANT -> {
189+
shoot(serverLevel, shooter, shooter.getUsedItemHand(), stack);
190+
stack.getOrCreateTag().putLong(SHOOT_TIMESTAMP_KEY, serverLevel.getGameTime());
191+
}
192+
case ON_RELEASE_WITH_FULL_CHARGE -> {
193+
if (elapsedTime >= delayBetweenShots && serverLevel.getGameTime() - getShootTimestamp(stack) < delayBetweenShots) {
194+
shoot(serverLevel, shooter, shooter.getUsedItemHand(), stack);
195+
stack.getOrCreateTag().putLong(SHOOT_TIMESTAMP_KEY, serverLevel.getGameTime());
196+
}
197+
}
198+
default -> {}
195199
}
196200
}
197201

src/main/java/com/github/elenterius/biomancy/item/weapon/gun/ImpalerItem.java

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import net.minecraft.server.level.ServerPlayer;
2525
import net.minecraft.util.Mth;
2626
import net.minecraft.world.InteractionHand;
27-
import net.minecraft.world.damagesource.DamageSource;
2827
import net.minecraft.world.entity.Entity;
2928
import net.minecraft.world.entity.EquipmentSlot;
3029
import net.minecraft.world.entity.HumanoidArm;
@@ -57,6 +56,8 @@
5756

5857
public class ImpalerItem extends LivingGunItem implements ItemTooltipStyleProvider, GeoItem {
5958

59+
public static final float CHARGE_DURATION = 1.79f + 0.17f; //based on animation length of "charging_shot" + "holding_shot"
60+
6061
protected static final UUID BASE_MOVEMENT_SPEED_UUID = UUID.fromString("efc325ad-c747-4c0e-80c2-f3f0f4261e91");
6162

6263
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
@@ -66,15 +67,15 @@ public class ImpalerItem extends LivingGunItem implements ItemTooltipStyleProvid
6667
public ImpalerItem(int maxNutrients, Properties properties) {
6768
super(maxNutrients, properties,
6869
GunProperties.builder()
69-
.shootBehavior(GunProperties.ShootBehavior.ON_FULL_CHARGE)
70-
.timeBetweenShots(2 * 20)
71-
.maxAmmo(1).reloadDuration(10 * 20).autoReload()
70+
.shootBehavior(GunProperties.ShootBehavior.ON_RELEASE_INSTANT)
71+
.timeBetweenShots(Mth.ceil(CHARGE_DURATION * 20f))
72+
.maxAmmo(1).reloadDuration(3 * 20).autoReload()
7273
.build(),
7374
ModProjectiles.IMPALER_PROJECTILE);
7475

7576
ImmutableMultimap.Builder<Attribute, AttributeModifier> builder = ImmutableMultimap.builder();
7677
builder.put(Attributes.ATTACK_SPEED, new AttributeModifier(BASE_ATTACK_SPEED_UUID, "Weapon modifier", -3.5f, AttributeModifier.Operation.ADDITION));
77-
builder.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(BASE_MOVEMENT_SPEED_UUID, "Weapon modifier", -0.25f, AttributeModifier.Operation.MULTIPLY_BASE));
78+
builder.put(Attributes.MOVEMENT_SPEED, new AttributeModifier(BASE_MOVEMENT_SPEED_UUID, "Weapon modifier", -0.125f, AttributeModifier.Operation.MULTIPLY_BASE));
7879
defaultModifiers = builder.build();
7980

8081
GeoItem.registerSyncedAnimatable(this);
@@ -126,8 +127,12 @@ public float modifyProjectileDamage(float baseDamage, ItemStack stack) {
126127

127128
@Override
128129
public void shoot(ServerLevel level, LivingEntity shooter, InteractionHand usedHand, ItemStack projectileWeapon) {
130+
float elapsedDuration = (float) projectileWeapon.getUseDuration() - ((float) shooter.getUseItemRemainingTicks());
131+
float maxChargeDuration = getDelayBetweenShots(projectileWeapon);
132+
float chargePercentage = Mth.clamp(elapsedDuration / maxChargeDuration, 0.1f, 1f);
133+
129134
boolean success = configuredProjectile.shoot(level, shooter,
130-
baseVelocity -> modifyProjectileVelocity(baseVelocity, projectileWeapon),
135+
baseVelocity -> modifyProjectileVelocity(baseVelocity * chargePercentage, projectileWeapon),
131136
baseDamage -> modifyProjectileDamage(baseDamage, projectileWeapon),
132137
baseKnockBack -> modifyProjectileKnockBack(baseKnockBack, projectileWeapon),
133138
baseInaccuracy -> modifyProjectileInaccuracy(baseInaccuracy, projectileWeapon),
@@ -149,14 +154,15 @@ public void shoot(ServerLevel level, LivingEntity shooter, InteractionHand usedH
149154
boolean isAnchored = shooter.onGround() && shooter.isCrouching();
150155
double reduction = isAnchored ? 0.25d : 0.5d;
151156

152-
float velocity = configuredProjectile.velocity(); //TODO: get final velocity e.g. velocity * chargePercentage
157+
float velocity = modifyProjectileVelocity(configuredProjectile.velocity() * chargePercentage, projectileWeapon);
153158

154159
Vec3 recoil = shooter.getLookAngle().normalize().scale(-1d).scale(velocity * reduction);
155160
shooter.push(recoil.x, recoil.y, recoil.z); //sets hasImpulse to true
156161
shooter.fallDistance = 0f;
157162

158-
DamageSource damageSource = level.damageSources().explosion(shooter, shooter);
159-
shooter.hurt(damageSource, velocity * 0.5f);
163+
// "self" damage
164+
//DamageSource damageSource = level.damageSources().explosion(shooter, shooter);
165+
//shooter.hurt(damageSource, velocity * 0.5f);
160166

161167
if (!shooter.hurtMarked && shooter instanceof ServerPlayer serverPlayer) {
162168
// Important:
@@ -212,7 +218,7 @@ private static boolean isHandPartOfArm(LocalPlayer player, HumanoidArm arm, Inte
212218
private static void applyArmTransform(PoseStack poseStack, HumanoidArm arm, float progress, float ticks) {
213219
float direction = arm == HumanoidArm.RIGHT ? 1f : -1f;
214220
float invProgress = 1f - progress;
215-
// float yOffset = 0.1f * -0.6f;
221+
//float yOffset = 0.1f * -0.6f;
216222
poseStack.mulPose(Axis.YP.rotationDegrees(10f * invProgress + direction * Mth.cos(ticks * 0.09f) * 1f));
217223
poseStack.mulPose(Axis.XP.rotationDegrees(-15f * invProgress + direction * Mth.sin(ticks * 0.067f) * 1f));
218224
poseStack.translate(0.56f * direction, -0.52f, -0.72f); //align item to "item holding position of hand" on screen
@@ -236,7 +242,8 @@ public HumanoidModel.ArmPose getArmPose(LivingEntity entityLiving, InteractionHa
236242
public boolean applyForgeHandTransform(PoseStack poseStack, LocalPlayer player, HumanoidArm arm, ItemStack itemInHand, float partialTick, float equipProcess, float swingProcess) {
237243
if (player.isUsingItem() && player.getUseItemRemainingTicks() > 0 && isHandPartOfArm(player, arm, player.getUsedItemHand())) {
238244
float elapsedDuration = (float) itemInHand.getUseDuration() - ((float) player.getUseItemRemainingTicks() - partialTick + 1f);
239-
float aimProgress = elapsedDuration / 2.5f;
245+
float maxChargeDuration = getDelayBetweenShots(itemInHand);
246+
float aimProgress = elapsedDuration / maxChargeDuration;
240247
if (aimProgress > 1f) {
241248
aimProgress = 1f;
242249
}
@@ -275,9 +282,8 @@ protected static final class Animations {
275282
private static final List<TriggerableAnimation> TRIGGERABLE_ANIMATIONS = new ArrayList<>();
276283

277284
static final TriggerableAnimation SHOOT = register(MAIN_CONTROLLER, "shoot", RawAnimation.begin().thenPlay("barrel_recoil"));
278-
static final RawAnimation CHARGE_UP_SHOT = RawAnimation.begin().thenPlay("charging_shot");
279-
static final RawAnimation NO_PROJECTILE = RawAnimation.begin().thenPlay("no_projectile");
280-
static final RawAnimation GROW_PROJECTILE = RawAnimation.begin().thenPlay("grow_projectile");
285+
static final RawAnimation CHARGE_UP_SHOT = RawAnimation.begin().thenPlay("charging_shot").thenPlay("holding_shot");
286+
static final RawAnimation DEFAULT_STATE = RawAnimation.begin().thenPlay("default_state");
281287

282288
private Animations() {}
283289

@@ -286,30 +292,15 @@ static void registerControllers(ImpalerItem animatable, AnimatableManager.Contro
286292
registerTriggerableAnimations(mainController);
287293
controllers.add(mainController);
288294

289-
controllers.add(new AnimationController<>(animatable, "charge_up", state -> {
295+
controllers.add(new AnimationController<>(animatable, "charging", state -> {
290296
ImpalerItem impalerItem = state.getAnimatable();
291297
ItemStack stack = state.getData(DataTickets.ITEMSTACK);
292298

293299
if (impalerItem.getGunState(stack) == GunState.SHOOTING_OR_CHARGING) {
294300
return state.setAndContinue(CHARGE_UP_SHOT);
295301
}
296302

297-
return PlayState.STOP;
298-
}));
299-
300-
controllers.add(new AnimationController<>(animatable, "projectile", state -> {
301-
ImpalerItem impalerItem = state.getAnimatable();
302-
ItemStack stack = state.getData(DataTickets.ITEMSTACK);
303-
304-
if (impalerItem.getGunState(stack) == GunState.RELOADING) {
305-
return state.setAndContinue(GROW_PROJECTILE);
306-
}
307-
308-
if (!impalerItem.hasAmmo(stack)) {
309-
return state.setAndContinue(NO_PROJECTILE);
310-
}
311-
312-
return PlayState.STOP; //show projectile
303+
return state.setAndContinue(DEFAULT_STATE);
313304
}));
314305
}
315306

src/main/resources/assets/biomancy/models/item/impaler_display.json

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,24 @@
2222
"rotation": [
2323
-1,
2424
0,
25-
-180
25+
0
2626
],
2727
"translation": [
2828
1.5,
2929
-2,
3030
1.25
31+
],
32+
"scale": [
33+
-1,
34+
1,
35+
1
3136
]
3237
},
3338
"firstperson_righthand": {
3439
"rotation": [
35-
3.07,
36-
2.51,
37-
-4.06
40+
3.0700000000001637,
41+
2.5100000000002183,
42+
-4.059999999999945
3843
],
3944
"translation": [
4045
-3.37,
@@ -49,50 +54,21 @@
4954
},
5055
"firstperson_lefthand": {
5156
"rotation": [
52-
12.11999999999989,
53-
9,
54-
-0.19000000000005457
57+
3.0700000000001637,
58+
2.5100000000002183,
59+
-4.059999999999945
5560
],
5661
"translation": [
57-
-3.12,
58-
2.7,
59-
1.13
60-
],
61-
"scale": [
62-
0.68,
63-
0.68,
64-
0.68
65-
]
66-
},
67-
"ground": {
68-
"translation": [
69-
0,
70-
2,
71-
0
62+
-3.37,
63+
4.7,
64+
3.38
7265
],
7366
"scale": [
74-
0.5,
67+
-0.5,
7568
0.5,
7669
0.5
7770
]
7871
},
79-
"gui": {
80-
"rotation": [
81-
30,
82-
-135,
83-
0
84-
],
85-
"translation": [
86-
0.5,
87-
-3,
88-
0
89-
],
90-
"scale": [
91-
0.8,
92-
0.8,
93-
0.8
94-
]
95-
},
9672
"head": {
9773
"translation": [
9874
8.75,
@@ -101,4 +77,4 @@
10177
]
10278
}
10379
}
104-
}
80+
}

0 commit comments

Comments
 (0)