更新版本为1.0.7
1. 添加便捷填充交互方法和相关提示 2. 添加了相关大炮发射事件
This commit is contained in:
parent
e3ba40f8ff
commit
b0f0c05e0b
|
|
@ -1,2 +1,2 @@
|
|||
// 1.20.1 2025-11-22T19:25:06.9619789 Languages: zh_tw
|
||||
094e7efc852fc45d55f97c0976bf2453de88e219 assets/blasttravelreborn/lang/zh_tw.json
|
||||
// 1.20.1 2025-11-30T14:45:33.9013121 Languages: zh_tw
|
||||
44b757dcddc2167ba3ed8fc339cee79e846f1584 assets/blasttravelreborn/lang/zh_tw.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.20.1 2025-11-22T19:25:06.9619789 Languages: zh_cn
|
||||
03cccc87a6370bef5c6b95b1d76cd9d22547b86c assets/blasttravelreborn/lang/zh_cn.json
|
||||
// 1.20.1 2025-11-30T14:45:33.8955012 Languages: zh_cn
|
||||
e74f7223f158133b80d3a926aface528b4bf7e2b assets/blasttravelreborn/lang/zh_cn.json
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
// 1.20.1 2025-11-22T19:25:06.9619789 Languages: en_us
|
||||
c3f0d412d3d39f47d1dd4065782d0984a17ed4e7 assets/blasttravelreborn/lang/en_us.json
|
||||
// 1.20.1 2025-11-30T14:45:33.8997715 Languages: en_us
|
||||
e8f3919eb4dcc1d7cf4176f3258bc19c6cf7a0b2 assets/blasttravelreborn/lang/en_us.json
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
{
|
||||
"container.blasttravelreborn.cannon_container_menu": "Cannon",
|
||||
"death.attack.blasttravelreborn.cannon": "%s was knocked out by a flying %s",
|
||||
"dialog.blasttravelreborn.add_behavior_item": "Added %s",
|
||||
"dialog.blasttravelreborn.add_gunpowder_item": "Added Gunpowder",
|
||||
"dialog.blasttravelreborn.add_lock_chain_item": "Cannon Locked",
|
||||
"dialog.blasttravelreborn.fire": "Fire",
|
||||
"dialog.blasttravelreborn.full_cannon": "Cannon is full!",
|
||||
"dialog.blasttravelreborn.no_gunpowder": "Cannon has no gunpowder!",
|
||||
"dialog.blasttravelreborn.remove_lock_chain_item": "Cannon Unlocked",
|
||||
"entity.blasttravelreborn.cannon": "Cannon",
|
||||
"item.blasttravelreborn.cannon": "Cannon",
|
||||
"mount.blasttravelreborn.cannon.onboard": "Press %s to Exit, or %s to Fire"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
{
|
||||
"container.blasttravelreborn.cannon_container_menu": "大炮实体",
|
||||
"death.attack.blasttravelreborn.cannon": "%s被飞行的%s击倒了",
|
||||
"dialog.blasttravelreborn.add_behavior_item": "填充%s (当前/最大): %d / %d",
|
||||
"dialog.blasttravelreborn.add_gunpowder_item": "填充火药 (当前/最大): %d / %d",
|
||||
"dialog.blasttravelreborn.add_lock_chain_item": "添加大炮锁链",
|
||||
"dialog.blasttravelreborn.fire": "发射",
|
||||
"dialog.blasttravelreborn.full_cannon": "大炮已装满!",
|
||||
"dialog.blasttravelreborn.no_gunpowder": "大炮没有火药了!",
|
||||
"dialog.blasttravelreborn.remove_lock_chain_item": "移除大炮锁链",
|
||||
"entity.blasttravelreborn.cannon": "大炮",
|
||||
"item.blasttravelreborn.cannon": "大炮",
|
||||
"mount.blasttravelreborn.cannon.onboard": "按%s离开,或按%s发射"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
{
|
||||
"container.blasttravelreborn.cannon_container_menu": "大砲實體",
|
||||
"death.attack.blasttravelreborn.cannon": "%s被飛行的%s擊倒了",
|
||||
"dialog.blasttravelreborn.add_behavior_item": "填充%s (當前/最大): %d / %d",
|
||||
"dialog.blasttravelreborn.add_gunpowder_item": "填充火藥 (當前/最大): %d / %d",
|
||||
"dialog.blasttravelreborn.add_lock_chain_item": "添加大砲鎖鏈",
|
||||
"dialog.blasttravelreborn.fire": "發射",
|
||||
"dialog.blasttravelreborn.full_cannon": "大砲已裝滿!",
|
||||
"dialog.blasttravelreborn.no_gunpowder": "大砲沒有火藥了!",
|
||||
"dialog.blasttravelreborn.remove_lock_chain_item": "移除大砲鎖鏈",
|
||||
"entity.blasttravelreborn.cannon": "大砲",
|
||||
"item.blasttravelreborn.cannon": "大砲",
|
||||
"mount.blasttravelreborn.cannon.onboard": "按%s離開,或按%s發射"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package com.leisuretimedock.blasttravelreborn.api.events;
|
||||
|
||||
import com.leisuretimedock.blasttravelreborn.content.entity.CannonEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.event.IModBusEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class CannonFireEvent extends Event implements IModBusEvent {
|
||||
private final CannonEntity cannonEntity;
|
||||
@Nullable
|
||||
private final Player firePlayer;
|
||||
@Nullable
|
||||
private final ItemStack fireStack;
|
||||
public CannonFireEvent(CannonEntity cannonEntity, @Nullable Player firePlayer, @Nullable ItemStack fireStack) {
|
||||
this.cannonEntity = cannonEntity;
|
||||
this.firePlayer = firePlayer;
|
||||
this.fireStack = fireStack;
|
||||
}
|
||||
|
||||
public CannonEntity getCannonEntity() {
|
||||
return cannonEntity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Player getFirePlayer() {
|
||||
return firePlayer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getFireStack() {
|
||||
return fireStack;
|
||||
}
|
||||
|
||||
@Cancelable
|
||||
public static class Pre extends CannonFireEvent {
|
||||
|
||||
public Pre(CannonEntity cannonEntity, Player firePlayer, ItemStack fireStack) {
|
||||
super(cannonEntity, firePlayer, fireStack);
|
||||
}
|
||||
}
|
||||
public static class Post extends CannonFireEvent {
|
||||
private final Vec3 firePos;
|
||||
private final Vec3 fireVel;
|
||||
public Post(CannonEntity cannonEntity, Player firePlayer, ItemStack fireStack, Vec3 firePos, Vec3 fireVel) {
|
||||
super(cannonEntity, firePlayer, fireStack);
|
||||
this.firePos = firePos;
|
||||
this.fireVel = fireVel;
|
||||
}
|
||||
public Vec3 getFirePos() {
|
||||
return firePos;
|
||||
}
|
||||
|
||||
public Vec3 getFireVel() {
|
||||
return fireVel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.leisuretimedock.blasttravelreborn.api.events;
|
||||
|
||||
import com.leisuretimedock.blasttravelreborn.util.PlayerEntityDuck;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.event.IModBusEvent;
|
||||
|
||||
public class PlayerCannonFlightTickEvent extends Event implements IModBusEvent {
|
||||
|
||||
private final Entity player;
|
||||
private final Vec3 velocity;
|
||||
private final Vec3 pos;
|
||||
private final long flightTick;
|
||||
|
||||
public PlayerCannonFlightTickEvent(Entity player, Vec3 velocity, Vec3 pos, long flightTick) {
|
||||
this.player = player;
|
||||
this.velocity = velocity;
|
||||
this.pos = pos;
|
||||
this.flightTick = flightTick;
|
||||
}
|
||||
public void cancelFlightState() {
|
||||
if(player instanceof PlayerEntityDuck playerDuck) {
|
||||
playerDuck.blasttravel$setCannonFlight(false);
|
||||
}
|
||||
}
|
||||
|
||||
public Vec3 getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
public Vec3 getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public Entity getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public long getFlightTick() {
|
||||
return flightTick;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.leisuretimedock.blasttravelreborn.content.entity;
|
||||
|
||||
import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
|
||||
import com.leisuretimedock.blasttravelreborn.api.events.CannonFireEvent;
|
||||
import com.leisuretimedock.blasttravelreborn.content.BTRParticleTypes;
|
||||
import com.leisuretimedock.blasttravelreborn.content.entity.cannon.CannonBehavior;
|
||||
import com.leisuretimedock.blasttravelreborn.content.entity.cannon.ConcretePowderCannonBehavior;
|
||||
|
|
@ -14,6 +15,7 @@ import com.leisuretimedock.blasttravelreborn.util.PlayerEntityDuck;
|
|||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
|
@ -39,8 +41,6 @@ import net.minecraft.world.level.block.Blocks;
|
|||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.network.NetworkDirection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -50,6 +50,11 @@ public class CannonEntity extends Entity {
|
|||
public static final Component UI_TITLE = Component.translatable("container.blasttravelreborn.cannon_container_menu");
|
||||
public static final Component NO_GUNPOWDER_DIALOG = Component.translatable("dialog.blasttravelreborn.no_gunpowder").withStyle(ChatFormatting.RED);
|
||||
public static final Component FULL_CANNON_DIALOG = Component.translatable("dialog.blasttravelreborn.full_cannon").withStyle(ChatFormatting.RED);
|
||||
public static final String ADD_GUNPOWDER_DIALOG = "dialog.blasttravelreborn.add_gunpowder_item";
|
||||
public static final String ADD_BEHAVIOR_DIALOG = "dialog.blasttravelreborn.add_behavior_item";
|
||||
public static final String ADD_LOCK_CHAIN_DIALOG = "dialog.blasttravelreborn.add_lock_chain_item";
|
||||
public static final String REMOVE_LOCK_CHAIN_DIALOG = "dialog.blasttravelreborn.remove_lock_chain_item";
|
||||
public static final Component FIRE = Component.translatable("dialog.blasttravelreborn.fire").withStyle(ChatFormatting.RED);
|
||||
|
||||
public static final CannonBehavior NONE = new CannonBehavior(Items.AIR, stack -> false).register();
|
||||
public static final CannonBehavior GOLDEN = new CannonBehavior(Items.GOLD_BLOCK, BlastTravelReborn.id("textures/entity/cannon/golden.png")).register();
|
||||
|
|
@ -212,6 +217,7 @@ public class CannonEntity extends Entity {
|
|||
handlerBehaviorItem(player, stack);
|
||||
return true;
|
||||
} else if (stack.is(Items.FLINT_AND_STEEL)) {
|
||||
player.displayClientMessage(FIRE, true);
|
||||
fireServer();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -231,7 +237,7 @@ public class CannonEntity extends Entity {
|
|||
// 设置新的火药到炮中
|
||||
ItemStack newGunpowder = stack.copy();
|
||||
newGunpowder.setCount(currentGunpowder.getCount() + 1); // 只放一个火药
|
||||
((ServerPlayer) player).sendSystemMessage(Component.literal(String.format("%d / %d", currentGunpowder.getCount() + 1, currentGunpowder.getMaxStackSize())), true);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(ADD_GUNPOWDER_DIALOG, Math.min(currentGunpowder.getCount() + 1, currentGunpowder.getMaxStackSize()), currentGunpowder.getMaxStackSize()), true);
|
||||
inventory.setItem(0, newGunpowder);
|
||||
|
||||
if (!player.isCreative()) {
|
||||
|
|
@ -252,6 +258,7 @@ public class CannonEntity extends Entity {
|
|||
if (!player.isCreative()) {
|
||||
stack.shrink(1);
|
||||
}
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(ADD_LOCK_CHAIN_DIALOG).withStyle(ChatFormatting.GREEN), true);
|
||||
level().playSound(null, this.blockPosition(), SoundEvents.CHAIN_PLACE, SoundSource.BLOCKS, 1.0f, 1.0f);
|
||||
} else {
|
||||
inventory.setItem(1, ItemStack.EMPTY);
|
||||
|
|
@ -260,6 +267,7 @@ public class CannonEntity extends Entity {
|
|||
player.drop(currentChain, false);
|
||||
}
|
||||
}
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(REMOVE_LOCK_CHAIN_DIALOG).withStyle(ChatFormatting.RED), true);
|
||||
level().playSound(null, this.blockPosition(), SoundEvents.CHAIN_FALL, SoundSource.BLOCKS, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
|
@ -285,7 +293,7 @@ public class CannonEntity extends Entity {
|
|||
}
|
||||
ItemStack stack1 = stack.copy();
|
||||
stack1.setCount(currentBehaviorItem.getCount() + 1);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.literal(String.format("%d / %d", currentBehaviorItem.getCount() + 1, currentBehaviorItem.getMaxStackSize())), true);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(ADD_BEHAVIOR_DIALOG, I18n.get(currentBehaviorItem.getDescriptionId()),Math.min(currentBehaviorItem.getCount() + 1, currentBehaviorItem.getMaxStackSize()), currentBehaviorItem.getMaxStackSize()), true);
|
||||
inventory.setItem(2, stack1);
|
||||
|
||||
if (!player.isCreative()) {
|
||||
|
|
@ -300,6 +308,7 @@ public class CannonEntity extends Entity {
|
|||
ItemStack copied = stack.copy();
|
||||
copied.setCount(1);
|
||||
inventory.setItem(2, copied);
|
||||
((ServerPlayer) player).sendSystemMessage(Component.translatable(ADD_BEHAVIOR_DIALOG, I18n.get(stack.getDescriptionId()), 1, stack.getMaxStackSize()), true);
|
||||
if (!player.isCreative()) {
|
||||
stack.shrink(1);
|
||||
}
|
||||
|
|
@ -391,50 +400,32 @@ public class CannonEntity extends Entity {
|
|||
if (this.level() instanceof ServerLevel world) {
|
||||
var gunpowder = this.inventory.getItem(0);
|
||||
if (gunpowder.is(Items.GUNPOWDER) && gunpowder.getCount() > 0) {
|
||||
CannonFireEvent.Pre pre;
|
||||
Player firedPlayer = null;
|
||||
var behaviorStack = this.getBehaviorStack();
|
||||
var vel = getDeltaMovement().add(getLookAngle().scale(Math.sqrt(gunpowder.getCount()) * 0.6));
|
||||
this.getBehavior().onFired(this, behaviorStack, vel);
|
||||
|
||||
if (this.getFirstPassenger() instanceof Player player) {
|
||||
if (!FMLEnvironment.production) {
|
||||
System.out.println("Firing cannon:");
|
||||
System.out.println(" - Gunpowder: " + gunpowder.getCount());
|
||||
System.out.println(" - Look Angle: " + getLookAngle());
|
||||
System.out.println(" - Final Velocity: " + vel);
|
||||
System.out.println(" - Pitch: " + this.getXRot() + ", Yaw: " + this.getYRot());
|
||||
System.out.println(" - Behavior: " + getBehavior().getClass().getSimpleName());
|
||||
System.out.println(" - [B]Server: Is Passenger = " + player.isPassenger());
|
||||
System.out.println(" - [B]Server: On Ground = " + player.onGround());
|
||||
System.out.println(" - [B]Server: noPhysics =" + player.noPhysics);
|
||||
System.out.println(" - [B]Server: Pose =" + player.getPose());
|
||||
System.out.println(" - [B]Server: riding entity =" + player.getVehicle());
|
||||
System.out.println(" - [B]Server: Bounding Box = " + player.getBoundingBox());
|
||||
System.out.println(" - [B]Server: Delta Movement = " + player.getDeltaMovement());
|
||||
}
|
||||
|
||||
// 关键修改:先设置速度,再停止乘坐
|
||||
player.setDeltaMovement(vel);
|
||||
player.hurtMarked = true; // 强制同步运动状态
|
||||
|
||||
// 然后停止乘坐
|
||||
player.stopRiding();
|
||||
|
||||
// 设置飞行状态
|
||||
((PlayerEntityDuck)player).blasttravel$setCannonFlight(true);
|
||||
|
||||
if (!FMLEnvironment.production) {
|
||||
System.out.println(" - [A]Server: Is Passenger = " + player.isPassenger());
|
||||
System.out.println(" - [A]Server: On Ground = " + player.onGround());
|
||||
System.out.println(" - [A]Server: noPhysics =" + player.noPhysics);
|
||||
System.out.println(" - [A]Server: Pose =" + player.getPose());
|
||||
System.out.println(" - [A]Server: riding entity =" + player.getVehicle());
|
||||
System.out.println(" - [A]Server: Bounding Box = " + player.getBoundingBox());
|
||||
System.out.println(" - [A]Server: Delta Movement = " + player.getDeltaMovement());
|
||||
}
|
||||
if(getFirstPassenger() instanceof Player player) {
|
||||
firedPlayer = player;
|
||||
}
|
||||
pre = new CannonFireEvent.Pre(this, firedPlayer, behaviorStack);
|
||||
if(pre.isCanceled()) return;
|
||||
var vel = getDeltaMovement().add(getLookAngle().scale(Math.sqrt(gunpowder.getCount()) * 0.6));
|
||||
|
||||
CannonBehavior behavior = this.getBehavior();
|
||||
if (firedPlayer != null) {
|
||||
|
||||
// 关键修改:先设置速度,再停止乘坐
|
||||
firedPlayer.setDeltaMovement(vel);
|
||||
firedPlayer.hurtMarked = true; // 强制同步运动状态
|
||||
|
||||
// 然后停止乘坐
|
||||
firedPlayer.stopRiding();
|
||||
|
||||
// 设置飞行状态
|
||||
((PlayerEntityDuck)firedPlayer).blasttravel$setCannonFlight(true);
|
||||
|
||||
}
|
||||
if(pre.isCanceled()) return;
|
||||
behavior.onFired(this, behaviorStack, vel);
|
||||
this.level().playSound(null, this.blockPosition(), SoundEvents.GENERIC_EXPLODE, SoundSource.BLOCKS, 1, 1);
|
||||
for (var to : world.players()) {
|
||||
BTRNetwork.CHANNEL.sendTo(new FireCannonPayload(this, firedPlayer, vel), to.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
package com.leisuretimedock.blasttravelreborn.content.entity.cannon;
|
||||
|
||||
import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
|
||||
import com.leisuretimedock.blasttravelreborn.api.events.CannonFireEvent;
|
||||
import com.leisuretimedock.blasttravelreborn.content.entity.CannonEntity;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
|
|
@ -71,7 +76,7 @@ public class CannonBehavior {
|
|||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public boolean displayHead(CannonEntity entity) {
|
||||
public boolean displayHead(@NotNull CannonEntity entity) {
|
||||
return entity.getClientPlayer() != null;
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +84,13 @@ public class CannonBehavior {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void onFired(CannonEntity cannon, ItemStack behaviorStack, Vec3 velocity) {
|
||||
public void onFired(@NotNull CannonEntity cannon, ItemStack behaviorStack, Vec3 velocity) {
|
||||
Entity firstPassenger = cannon.getFirstPassenger();
|
||||
Player player = null;
|
||||
if (firstPassenger instanceof Player player1) {
|
||||
player = player1;
|
||||
}
|
||||
MinecraftForge.EVENT_BUS.post(new CannonFireEvent.Post(cannon, player, behaviorStack, cannon.position(), velocity));
|
||||
}
|
||||
|
||||
public static CannonBehavior byId(int id) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.ConcretePowderBlock;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
|
|
@ -28,7 +29,7 @@ public class ConcretePowderCannonBehavior extends CannonBehavior {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean displayHead(CannonEntity entity) {
|
||||
public boolean displayHead(@NotNull CannonEntity entity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +47,8 @@ public class ConcretePowderCannonBehavior extends CannonBehavior {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onFired(CannonEntity cannon, ItemStack behaviorStack, Vec3 velocity) {
|
||||
public void onFired(@NotNull CannonEntity cannon, ItemStack behaviorStack, Vec3 velocity) {
|
||||
super.onFired(cannon, behaviorStack, velocity);
|
||||
if (cannon.level() instanceof ServerLevel world) {
|
||||
var rot = cannon.getLookAngle();
|
||||
var origin = cannon.position().add(0, 0.75, 0).add(rot.scale(1.8));
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
|
@ -32,7 +33,8 @@ public class EntityCannonBehavior extends CannonBehavior {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onFired(CannonEntity cannon, ItemStack behaviorStack, Vec3 velocity) {
|
||||
public void onFired(@NotNull CannonEntity cannon, ItemStack behaviorStack, Vec3 velocity) {
|
||||
super.onFired(cannon, behaviorStack, velocity);
|
||||
var pos = cannon.position().add(0, 0.75, 0).add(cannon.getLookAngle().scale(1.8));
|
||||
var entity = entityFactory.create(cannon.level(), pos, behaviorStack);
|
||||
entity.setDeltaMovement(velocity);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,40 @@ public enum BTRLangKeys implements ILangKeyValueCollection {
|
|||
"大炮没有火药了!",
|
||||
"大砲沒有火藥了!"
|
||||
));
|
||||
addLang(LangKeyValue.ofKey(
|
||||
"dialog.blasttravelreborn.add_gunpowder_item", ModPartEnum.MESSAGE,
|
||||
"Added Gunpowder",
|
||||
"填充火药 (当前/最大): %d / %d",
|
||||
"填充火藥 (當前/最大): %d / %d"
|
||||
));
|
||||
|
||||
addLang(LangKeyValue.ofKey(
|
||||
"dialog.blasttravelreborn.add_behavior_item", ModPartEnum.MESSAGE,
|
||||
"Added %s",
|
||||
"填充%s (当前/最大): %d / %d",
|
||||
"填充%s (當前/最大): %d / %d"
|
||||
));
|
||||
|
||||
addLang(LangKeyValue.ofKey(
|
||||
"dialog.blasttravelreborn.add_lock_chain_item", ModPartEnum.MESSAGE,
|
||||
"Cannon Locked",
|
||||
"添加大炮锁链",
|
||||
"添加大砲鎖鏈"
|
||||
));
|
||||
|
||||
addLang(LangKeyValue.ofKey(
|
||||
"dialog.blasttravelreborn.remove_lock_chain_item", ModPartEnum.MESSAGE,
|
||||
"Cannon Unlocked",
|
||||
"移除大炮锁链",
|
||||
"移除大砲鎖鏈"
|
||||
));
|
||||
|
||||
addLang(LangKeyValue.ofKey(
|
||||
"dialog.blasttravelreborn.fire", ModPartEnum.MESSAGE,
|
||||
"Fire",
|
||||
"发射",
|
||||
"發射"
|
||||
));
|
||||
addLang(LangKeyValue.ofKey(
|
||||
"mount.blasttravelreborn.cannon.onboard", ModPartEnum.MESSAGE,
|
||||
"Press %s to Exit, or %s to Fire",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package com.leisuretimedock.blasttravelreborn.mixin;
|
||||
|
||||
import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
|
||||
import com.leisuretimedock.blasttravelreborn.api.events.PlayerCannonFlightTickEvent;
|
||||
import com.leisuretimedock.blasttravelreborn.network.BTRNetwork;
|
||||
import com.leisuretimedock.blasttravelreborn.network.toClient.SyncFlightStatePayload;
|
||||
import com.leisuretimedock.blasttravelreborn.network.toServer.StopCannonFlightServerPayload;
|
||||
import com.leisuretimedock.blasttravelreborn.util.PlayerEntityDuck;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
|
@ -19,6 +21,7 @@ import net.minecraft.world.entity.player.Player;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.entity.EntityTypeTest;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.network.NetworkDirection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -63,30 +66,6 @@ public abstract class PlayerEntityMixin extends LivingEntity implements PlayerEn
|
|||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void blasttravel$beginTick(CallbackInfo ci) {
|
||||
this.blasttravel$prevVel = this.isLocalPlayer() ? blasttravel$vel : blasttravel$trackingVel;
|
||||
if(!FMLEnvironment.production) {
|
||||
if (blasttravel$inCannonFlight) {
|
||||
// 获取当前速度
|
||||
Vec3 currentVelocity = this.getDeltaMovement();
|
||||
double speed = currentVelocity.length();
|
||||
|
||||
// 记录到对应的速度列表
|
||||
if (this.isLocalPlayer()) {
|
||||
// 客户端本地玩家
|
||||
blasttravel$vel = currentVelocity;
|
||||
System.out.println("[Client-Local] Tick: " + this.level().getGameTime() +
|
||||
", Velocity: " + currentVelocity +
|
||||
", Speed: " + String.format("%.3f", speed) +
|
||||
", Position: " + this.position());
|
||||
} else {
|
||||
System.out.println("[Server] Tick: " + this.level().getGameTime() +
|
||||
", Velocity: " + currentVelocity +
|
||||
", Speed: " + String.format("%.3f", speed) +
|
||||
", Position: " + String.format("(%.1f, %.1f, %.1f)", this.getX(), this.getY(), this.getZ()) +
|
||||
", OnGround: " + this.onGround() +
|
||||
", noPhysics: " + this.noPhysics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At("TAIL"))
|
||||
|
|
@ -96,7 +75,7 @@ public abstract class PlayerEntityMixin extends LivingEntity implements PlayerEn
|
|||
|
||||
if (this.blasttravel$inCannonFlight()) {
|
||||
this.noPhysics = true;
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new PlayerCannonFlightTickEvent(self, blasttravel$vel, self.position(), blasttravel$ticksFlying));
|
||||
if (!self.level().isClientSide()) {
|
||||
var vel = self.getDeltaMovement();
|
||||
var frontBox = self.getBoundingBox().expandTowards(0.2, 0.2, 0.2);
|
||||
|
|
|
|||
|
|
@ -44,11 +44,6 @@ public record FireCannonPayload(int cannonId, Optional<Integer> launchedId, doub
|
|||
if (hasPlayer()) {
|
||||
//noinspection OptionalGetWithoutIsPresent
|
||||
if (clientPacketListener.getLevel().getEntity(launchedId.get()) instanceof Player launchedPlayer) {
|
||||
// 记录发射前状态
|
||||
if (!FMLEnvironment.production) {
|
||||
System.out.println(" - [B]Client: Is Passenger = " + launchedPlayer.isPassenger());
|
||||
System.out.println(" - [B]Client: Delta Movement = " + launchedPlayer.getDeltaMovement());
|
||||
}
|
||||
|
||||
// 立即停止乘坐并设置速度
|
||||
if (launchedPlayer.isPassenger()) {
|
||||
|
|
@ -59,11 +54,6 @@ public record FireCannonPayload(int cannonId, Optional<Integer> launchedId, doub
|
|||
launchedPlayer.setDeltaMovement(velocityX, velocityY, velocityZ);
|
||||
((PlayerEntityDuck) launchedPlayer).blasttravel$setCannonFlight(true);
|
||||
|
||||
// 记录发射后状态
|
||||
if (!FMLEnvironment.production) {
|
||||
System.out.println(" - [A]Client: Is Passenger = " + launchedPlayer.isPassenger());
|
||||
System.out.println(" - [A]Client: Delta Movement = " + launchedPlayer.getDeltaMovement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,14 +64,6 @@ public record SyncFlightStatePayload(
|
|||
player.noPhysics = this.noPhysics;
|
||||
player.hurtMarked = true;
|
||||
|
||||
// 调试输出
|
||||
if (!FMLEnvironment.production) {
|
||||
System.out.println("[Client] Received flight sync: " +
|
||||
"Vel=" + this.velocity + ", " +
|
||||
"Pos=" + this.position + ", " +
|
||||
"Flight=" + this.inCannonFlight + ", " +
|
||||
"NoPhysics=" + this.noPhysics);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user