B站视频资源
视频: https://www.bilibili.com/video/BV1zADtYGEuQ/
MC 百科: https://www.mcmod.cn/class/16961.html
视频中使用的枪包是由 Rhodes_koei 创作的 机动军械师
TypeScript 参考类型可以在 types
中找到.
如果你遇到了问题
你可以在上面的视频底下留言, 或加入我的 QQ 群 324617456 交流.
视频中使用到的代码
注意
下面提供的代码是模组版本 1.3.0 之前写的。
因为 TaCZ 有过一次大更新,所以不保证代码依旧可用。
左键攻击右键检视武器,启用原版交互
点我查看代码
javascript
// client_scripts/melee.js
const $HitResult$Type = Java.tryLoadClass("net.minecraft.world.phys.HitResult$Type");
const $IWrenchable = Java.tryLoadClass("com.simibubi.create.content.equipment.wrench.IWrenchable");
const MeleeWeapons = ["create_armorer:special_melee_wrench", "create_armorer:special_melee_atomic"];
// 被视为扳手的枪械
const Wrenchs = ["create_armorer:special_melee_wrench"];
// 是否播放交互动画
const PlayInteractAnimation = true;
// https://github.com/Creators-of-Create/Create/blob/d48a504486311f3175f4ebef3b0649140e728fbb/src/generated/resources/data/create/tags/blocks/wrench_pickup.json
const WrenchPickup = [
"create:andesite_bars",
"create:brass_bars",
"create:copper_bars",
"create:industrial_iron_block",
"minecraft:redstone_wire",
"minecraft:redstone_torch",
"minecraft:repeater",
"minecraft:lever",
"minecraft:comparator",
"minecraft:observer",
"minecraft:redstone_wall_torch",
"minecraft:piston",
"minecraft:sticky_piston",
"minecraft:tripwire",
"minecraft:tripwire_hook",
"minecraft:daylight_detector",
"minecraft:target",
"minecraft:hopper",
"#minecraft:buttons",
"#minecraft:pressure_plates",
"#minecraft:rails",
];
TaCZClientEvents.gunIndexLoad((event) => {
if (MeleeWeapons.includes(event.getGunId().toString())) {
// 为近战武器添加原版交互设置
event.setVanillaInteract(true);
}
});
TaCZClientEvents.playerAim((event) => {
const gunId = event.getGunId().toString();
if (MeleeWeapons.includes(gunId)) {
// 只处理开始瞄准的事件
if (!event.isAim()) return;
// 如果是原版交互并且可以交互, 播放交互动画并取消瞄准
if (event.isVanillaInteract() && event.canInteractEntity()) {
if (PlayInteractAnimation) {
TaCZJSUtils.SoundPlayManager.stopPlayGunSound();
event.runMaimAnimation(
"melee_bayonet_1",
TaCZJSUtils.AnimationPlayType.PLAY_ONCE_STOP,
0.2
);
}
return event.cancelAim();
}
const blockHitResult = event.getBlockHitResult();
if (
Wrenchs.includes(gunId) &&
blockHitResult !== null &&
blockHitResult.getType() === $HitResult$Type.BLOCK
) {
const state = event.getLevel().getBlockState(blockHitResult.getBlockPos());
const block = state.getBlock();
// 如果是可旋转方块或者可拾取的方块, 播放交互动画并取消瞄准
if (
block instanceof $IWrenchable ||
WrenchPickup.includes(state.getBlock().getIdLocation().toString())
) {
if (PlayInteractAnimation) {
TaCZJSUtils.SoundPlayManager.stopPlayGunSound();
event.runMaimAnimation(
"melee_bayonet_1",
TaCZJSUtils.AnimationPlayType.PLAY_ONCE_STOP,
0.2
);
}
return event.cancelAim();
}
}
event.cancelAim();
const gunIndex = event.getGunIndex();
const am = gunIndex.getAnimationStateMachine();
if (am === null) return;
if (am.isPlayingRunIntroOrLoop()) {
// 如果正在跑步, 播放 run_start 动画
event.runMovementAnimation("run_start", TaCZJSUtils.AnimationPlayType.PLAY_ONCE_HOLD, 0.2);
} else if (am.isPlayingIdleAnimation() || am.isPlayingWalkAnimation()) {
// 如果正在站立或者走路, 播放武器检视动画
TaCZJSUtils.SoundPlayManager.stopPlayGunSound();
TaCZJSUtils.SoundPlayManager.playInspectSound(event.getPlayer(), gunIndex, false);
am.onGunInspect();
}
}
});
TaCZClientEvents.playerShoot((event) => {
if (MeleeWeapons.includes(event.getGunId().toString())) {
// 停止播放音效
TaCZJSUtils.SoundPlayManager.stopPlayGunSound();
// 如果近战武器进行射击, 取消射击并执行近战
event.cancelShoot();
event.getGunOperator().melee();
}
});
让 机动军械师
的扳手拥有机械动力的扳手的功能
点我查看代码
javascript
// server_scripts/wrench.js
const $Random = Java.tryLoadClass("java.util.Random");
const RANDOM = new $Random();
const $HitResult$Type = Java.tryLoadClass("net.minecraft.world.phys.HitResult$Type");
const $BlockHitResult = Java.tryLoadClass("net.minecraft.world.phys.BlockHitResult");
const $UseOnContext = Java.tryLoadClass("net.minecraft.world.item.context.UseOnContext");
const $AllSoundEvents = Java.tryLoadClass("com.simibubi.create.AllSoundEvents");
const $InteractionHand = Java.tryLoadClass("net.minecraft.world.InteractionHand");
const $IWrenchable = Java.tryLoadClass("com.simibubi.create.content.equipment.wrench.IWrenchable");
const $Block = Java.tryLoadClass("net.minecraft.world.level.block.Block");
const $ItemStack = Java.tryLoadClass("net.minecraft.world.item.ItemStack");
// https://github.com/Creators-of-Create/Create/blob/d48a504486311f3175f4ebef3b0649140e728fbb/src/generated/resources/data/create/tags/blocks/wrench_pickup.json
const WrenchPickup = [
"create:andesite_bars",
"create:brass_bars",
"create:copper_bars",
"create:industrial_iron_block",
"minecraft:redstone_wire",
"minecraft:redstone_torch",
"minecraft:repeater",
"minecraft:lever",
"minecraft:comparator",
"minecraft:observer",
"minecraft:redstone_wall_torch",
"minecraft:piston",
"minecraft:sticky_piston",
"minecraft:tripwire",
"minecraft:tripwire_hook",
"minecraft:daylight_detector",
"minecraft:target",
"minecraft:hopper",
"#minecraft:buttons",
"#minecraft:pressure_plates",
"#minecraft:rails",
];
const Wrenchs = ["create_armorer:special_melee_wrench"];
ItemEvents.firstRightClicked((event) => {
const item = event.getItem();
if (item.equals(Item.of("minecraft:air"))) return;
const target = event.getTarget();
if (
(target !== null && target.type.toString() !== $HitResult$Type.BLOCK.toString()) ||
!(
item.getId().toString() === "tacz:modern_kinetic_gun" &&
Wrenchs.includes(item.getNbt().getString("GunId"))
)
) {
return;
}
const state = target.block.getBlockState();
const block = state.getBlock();
const world = event.getLevel();
const player = event.getPlayer();
const blockHitResult = new $BlockHitResult(
target.hit,
target.facing,
target.block.getPos(),
false
);
const context = new $UseOnContext(
world,
player,
$InteractionHand.MAIN_HAND,
item,
blockHitResult
);
if (block instanceof $IWrenchable) {
const actor = block;
player.isShiftKeyDown()
? actor.onSneakWrenched(state, context)
: actor.onWrenched(state, context);
} else {
player.isShiftKeyDown() &&
WrenchPickup.includes(state.getBlock().getIdLocation().toString()) &&
onItemUseOnOther(player, world, target, item);
}
});
function onItemUseOnOther(player, world, target, item) {
const state = target.block.getBlockState();
const pos = target.block.getPos();
if (player !== null && !player.isCreative()) {
$Block
.getDrops(state, world, pos, world.getBlockEntity(pos), player, item)
.forEach((itemStack) => {
player.getInventory().placeItemBackInInventory(itemStack);
});
}
state.spawnAfterBreak(world, pos, $ItemStack.EMPTY, true);
world.destroyBlock(pos, false);
$AllSoundEvents.WRENCH_REMOVE.playOnServer(world, pos, 1.0, RANDOM.nextFloat() * 0.5 + 0.5);
}
赞助 ❤️
喜欢 TaCZ JS
吗?你可以在 爱发电 对我进行赞助,助力模组持续更新!