Skip to content

Commit

Permalink
feat(infinity-sword): add special abilities for Infinity Sword
Browse files Browse the repository at this point in the history
- Add onLeftClickEntity method to handle special attacks
- Implement sweepAttack functionality for the sword
- Add conditions for dealing damage to Ender Dragon and players with Infinity Armor
- Remove useOn method from NeutronGearItem
  • Loading branch information
cnlimiter committed Jan 6, 2025
1 parent c067c90 commit 824ef95
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,39 @@ public NeutronGearItem() {
super(ModRarities.RARE, "neutron_gear", true);
}

@Override
public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {
var level = pContext.getLevel();
var blockpos = pContext.getClickedPos();
var blockstate = level.getBlockState(blockpos);
var tile = pContext.getLevel().getBlockEntity(pContext.getClickedPos());
var player = pContext.getPlayer();
var itemInHand = pContext.getItemInHand();

if (tile instanceof BaseNeutronCollectorTile collectorTile && player != null && player.isCrouching()) {
switch (collectorTile.getTier()) {
case DEFAULT -> {
collectorTile.setTier(CollectorTier.DENSE);
level.setBlockAndUpdate(blockpos, ModBlocks.dense_neutron_collector.get().withPropertiesOf(blockstate));
level.playSound(player, blockpos, SoundEvents.PLAYER_LEVELUP, SoundSource.PLAYERS);
itemInHand.shrink(1);
player.getCooldowns().addCooldown(this, 20);
return InteractionResult.CONSUME;
}
case DENSE -> {
collectorTile.setTier(CollectorTier.DENSER);
level.setBlockAndUpdate(blockpos, ModBlocks.denser_neutron_collector.get().withPropertiesOf(blockstate));
level.playSound(player, blockpos, SoundEvents.PLAYER_LEVELUP, SoundSource.PLAYERS);
itemInHand.shrink(1);
player.getCooldowns().addCooldown(this, 20);
return InteractionResult.CONSUME;
}
default -> {
return InteractionResult.PASS;
}
}
} else {
return super.useOn(pContext);
}
}
// @Override
// public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {
// var level = pContext.getLevel();
// var blockpos = pContext.getClickedPos();
// var blockstate = level.getBlockState(blockpos);
// var tile = pContext.getLevel().getBlockEntity(pContext.getClickedPos());
// var player = pContext.getPlayer();
// var itemInHand = pContext.getItemInHand();
//
// if (tile instanceof BaseNeutronCollectorTile collectorTile && player != null && player.isCrouching()) {
// switch (collectorTile.getTier()) {
// case DEFAULT -> {
// collectorTile.setTier(CollectorTier.DENSE);
// level.setBlockAndUpdate(blockpos, ModBlocks.dense_neutron_collector.get().withPropertiesOf(blockstate));
// level.playSound(player, blockpos, SoundEvents.PLAYER_LEVELUP, SoundSource.PLAYERS);
// itemInHand.shrink(1);
// player.getCooldowns().addCooldown(this, 20);
// return InteractionResult.CONSUME;
// }
// case DENSE -> {
// collectorTile.setTier(CollectorTier.DENSER);
// level.setBlockAndUpdate(blockpos, ModBlocks.denser_neutron_collector.get().withPropertiesOf(blockstate));
// level.playSound(player, blockpos, SoundEvents.PLAYER_LEVELUP, SoundSource.PLAYERS);
// itemInHand.shrink(1);
// player.getCooldowns().addCooldown(this, 20);
// return InteractionResult.CONSUME;
// }
// default -> {
// return InteractionResult.PASS;
// }
// }
// } else {
// return super.useOn(pContext);
// }
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,39 @@ public InfinitySwordItem() {
.fireResistant());
}

@Override
public boolean onLeftClickEntity(ItemStack stack, Player player, Entity victim) {
var level = player.level();
var endlessDamage = ModConfig.isSwordAttackEndless.get();
if (!level.isClientSide) {
ToolUtils.sweepAttack(level, player, victim);//横扫
if (victim instanceof EnderDragon dragon ) {
victim.setInvulnerable(false);//取消无敌
dragon.hurt(dragon.head, player.damageSources().source(ModDamageTypes.INFINITY, player, victim), endlessDamage ? Float.MAX_VALUE : ModToolTiers.INFINITY_SWORD.getAttackDamageBonus());
} else if (victim instanceof Player pvp) {
if (ToolUtils.isInfinite(pvp)) {
// 玩家身着无尽甲则只造成爆炸伤害
pvp.level().explode(player, pvp.getBlockX(), pvp.getBlockY(), pvp.getBlockZ(), 25.0f, Level.ExplosionInteraction.MOB);
return true;//直接返回
} else {
victim.setInvulnerable(false);
victim.hurt(player.damageSources().source(ModDamageTypes.INFINITY, player, victim), endlessDamage ? Float.MAX_VALUE : ModToolTiers.INFINITY_SWORD.getAttackDamageBonus());
}

} else {
victim.setInvulnerable(false);
victim.hurt(player.damageSources().source(ModDamageTypes.INFINITY, player, victim), endlessDamage ? Float.MAX_VALUE : ModToolTiers.INFINITY_SWORD.getAttackDamageBonus());
}

if (endlessDamage) {
if (victim.isAlive()) {
victim.remove(Entity.RemovalReason.DISCARDED);//修正死亡
}
}
}
return true;
}

@Override
public boolean hurtEnemy(@NotNull ItemStack stack, @NotNull LivingEntity victim, LivingEntity livingEntity) {
var level = livingEntity.level();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,12 @@ public static void infinityTraceArrowDamage(@NotNull EntityHitResult result, Arr
* @param livingEntity 玩家
* @param victim 被攻击者
*/
public static void sweepAttack(Level level, LivingEntity livingEntity, LivingEntity victim) {
public static void sweepAttack(Level level, LivingEntity livingEntity, Entity victim) {
if (livingEntity instanceof Player player) {
for (LivingEntity livingentity : level.getEntitiesOfClass(LivingEntity.class, player.getItemInHand(InteractionHand.MAIN_HAND).getSweepHitBox(player, victim))) {
double entityReachSq = Mth.square(player.getEntityReach()); // Use entity reach instead of constant 9.0. Vanilla uses bottom center-to-center checks here, so don't update this to use canReach, since it uses closest-corner checks.
if (!player.isAlliedTo(livingentity) && (!(livingentity instanceof ArmorStand) || !((ArmorStand) livingentity).isMarker()) && player.distanceToSqr(livingentity) < entityReachSq) {
livingentity.knockback(0.6F, Mth.sin(player.getYRot() * ((float) Math.PI / 180F)), -Mth.cos(player.getYRot() * ((float) Math.PI / 180F)));
victim.setHealth(0);
victim.die(player.damageSources().source(ModDamageTypes.INFINITY, player, victim));
}
}
level.playSound(null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, livingEntity.getSoundSource(), 1.0F, 1.0F);
Expand Down

0 comments on commit 824ef95

Please sign in to comment.