add: allow elytra teleport into portal instantly (#50)
This commit is contained in:
1 parent
f76e697262
commit
302cab722a
5 files changed
+83
No files matched your search
@@ -22,6 +22,7 @@ import io.ib67.sfcraft.module.game.commander.CommanderModule;
|
||||
import io.ib67.sfcraft.module.game.crystal.GravityCrystalModule;
|
||||
import io.ib67.sfcraft.module.game.lunchbox.LunchBoxModule;
|
||||
import io.ib67.sfcraft.module.game.mount.MountModule;
|
||||
import io.ib67.sfcraft.module.game.portal.ElytraPortalModule;
|
||||
import io.ib67.sfcraft.module.game.token.TokenModule;
|
||||
import io.ib67.sfcraft.module.game.totem.TotemModule;
|
||||
import io.ib67.sfcraft.registry.CauldronRecipeRegistry;
|
||||
@@ -103,6 +104,7 @@ public class SFCraftInitializer extends GuiceModInitializer {
|
||||
registerFeature(CommanderModule.class);
|
||||
registerFeature(MountModule.class);
|
||||
registerFeature(TotemModule.class);
|
||||
registerFeature(ElytraPortalModule.class);
|
||||
// ItemGroupModule 必须最后注册:它冻结前面各模块被动贡献到 ItemGroupService 的物品,构建创意物品栏
|
||||
registerFeature(ItemGroupModule.class);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,12 @@ public class GameConfig {
|
||||
public Mount mount = new Mount();
|
||||
public Gps gps = new Gps();
|
||||
public StandingFirmTotem standingFirmTotem = new StandingFirmTotem();
|
||||
public ElytraPortal elytraPortal = new ElytraPortal();
|
||||
|
||||
public static class ElytraPortal {
|
||||
// 鞘翅滑翔冲进下界传送门时跳过等待(立即传送)的最低速度,单位米/秒;<= 0 关闭本特性
|
||||
public double minSpeedBlocksPerSecond = 25.0;
|
||||
}
|
||||
|
||||
public static class StandingFirmTotem {
|
||||
// 可反复使用的图腾变种:触发时扣掉一部分总经验,并进入冷却
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.ib67.sfcraft.mixin.gameplay;
|
||||
|
||||
import io.ib67.sfcraft.SFCraft;
|
||||
import io.ib67.sfcraft.module.game.portal.ElytraPortalModule;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.block.NetherPortalBlock;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* 鞘翅冲出下界传送门时跳过等待:本方法每 tick 被 {@code PortalProcessor} 调用来决定
|
||||
* 「还要在门里待多久」,命中条件时覆写为 1 tick(与原版创造模式一致),下一 tick 即跨维度;
|
||||
* 否则不动 cir,等待时间完全由原版游戏规则决定。判定逻辑见 {@link ElytraPortalModule#shouldTeleportNow}。
|
||||
*/
|
||||
@Mixin(NetherPortalBlock.class)
|
||||
public abstract class NetherPortalBlockMixin {
|
||||
@Inject(method = "getPortalTransitionTime", at = @At("HEAD"), cancellable = true)
|
||||
private void sfcraft$elytraRushPortal(ServerLevel level, Entity entity, CallbackInfoReturnable<Integer> cir) {
|
||||
var module = SFCraft.getInjector().getInstance(ElytraPortalModule.class);
|
||||
if (module.shouldTeleportNow(entity)) {
|
||||
cir.setReturnValue(module.getInstantTransitionTicks());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package io.ib67.sfcraft.module.game.portal;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.ib67.sfcraft.ServerModule;
|
||||
import io.ib67.sfcraft.config.GameConfigService;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
/**
|
||||
* 鞘翅冲门:玩家使用鞘翅滑翔、以不低于配置阈值(米/秒)的速度冲进下界传送门时,
|
||||
* 跳过原本的传送门等待(生存默认 80 tick),下一 tick 直接跨维度。
|
||||
* <p>
|
||||
* 本模块不注册任何注册表内容;行为由 {@code NetherPortalBlockMixin} 在
|
||||
* {@code NetherPortalBlock#getPortalTransitionTime} 头部委托 {@link #shouldTeleportNow}
|
||||
* 实现:命中条件时把等待时间覆写为 1 tick,否则放行原版(游戏规则)逻辑。
|
||||
* 配置经 {@link GameConfigService} 每次现读,/sfcraft reload 即时生效。
|
||||
*/
|
||||
public class ElytraPortalModule extends ServerModule {
|
||||
/** 冲门判定时覆写的等待 tick 数:与原版的创造模式进一致。 */
|
||||
private static final int INSTANT_TRANSITION_TICKS = 1;
|
||||
|
||||
@Inject
|
||||
private GameConfigService config;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// 无注册表内容、无事件订阅:特性完全由 mixin 委托驱动
|
||||
}
|
||||
|
||||
/** mixin 在下界传送门询问等待时间时调用;命中即把本次等待覆写为 {@link #INSTANT_TRANSITION_TICKS}。 */
|
||||
public boolean shouldTeleportNow(Entity entity) {
|
||||
if (!(entity instanceof ServerPlayer player) || !player.isFallFlying()) {
|
||||
return false;
|
||||
}
|
||||
double threshold = config.get().elytraPortal.minSpeedBlocksPerSecond;
|
||||
// 速度阈值 <= 0 视为关闭本特性
|
||||
if (threshold <= 0) {
|
||||
return false;
|
||||
}
|
||||
// deltaMovement 单位为 方块/tick,乘 20 换算成米/秒与配置同单位
|
||||
return player.getDeltaMovement().length() * 20.0 >= threshold;
|
||||
}
|
||||
|
||||
public int getInstantTransitionTicks() {
|
||||
return INSTANT_TRANSITION_TICKS;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
"common.fixes.EndermanEntityMixin",
|
||||
"common.fixes.LivingEntityMixin",
|
||||
"gameplay.MobCommanderMixin",
|
||||
"gameplay.NetherPortalBlockMixin",
|
||||
"gameplay.TotemProtectionMixin",
|
||||
"gameplay.ZombieMixin",
|
||||
"gameplay.mount.HoglinMountMixin",
|
||||
|
||||
Reference in new issue
Block a user