『模组开发日记』之暗晶钻套装与工具的加入

本文最后更新于 2024年11月10日 下午

暗晶钻装备正式加入世界


引言

因为我是模组开发一半才开始着手开发个人博客,

所有没有从一开始就记录自己的模组开发过程,

不过从现在开始就可以正式记录啦


需要提到一点的是暗晶钻的来源

关于暗晶钻


暗晶钻的合成

暗晶钻的合成

暗晶钻是由一个暗晶碎片加上四个钻石合成的来


关于暗晶碎片


暗晶碎片

暗晶碎片

暗晶碎片是开采暗晶簇得来,这是在生存中唯一能得到暗晶碎片的方法


暗晶簇

暗晶簇

暗晶簇的生成


在主世界的紫水晶洞中,由于环境的不同,紫水晶簇在生长过程中会发生变质而生成一种奇怪又神秘的褪色水晶簇【暗晶簇】


暗晶簇在水晶洞中的状态

暗晶簇在水晶洞中的状态

玩家在探索矿洞过程中如果幸运的话可以在紫水晶洞中发现这种神秘的矿石

需要知道的是,这种矿物有且只会在紫水晶洞中生成,且它不会像紫水晶那样会在母岩上再重新长出来

看来是一种很神秘的矿物呢

通过打破暗晶簇可以得到1-3块暗晶碎片



通过上面的合成就可以得到暗晶钻啦


暗晶钻装备

合成

暗晶钻装备的合成和钻石装备合成一模一样

如下所示

暗晶钻头盔的合成

暗晶钻头盔的合成

暗晶钻头盔为玩家提供:+3护甲值,+3.5盔甲韧性,+2击退抗性


暗晶钻胸甲的合成

暗晶钻胸甲的合成

暗晶钻头盔为玩家提供:+8护甲值,+3.5盔甲韧性,+2击退抗性


暗晶钻裤腿的合成

暗晶钻裤腿的合成

暗晶钻头盔为玩家提供:+6护甲值,+3.5盔甲韧性,+2击退抗性


暗晶钻靴子的合成

暗晶钻靴子的合成

暗晶钻头盔为玩家提供:+3护甲值,+3.5盔甲韧性,+2击退抗性


这样就可以得到暗晶钻四件套了

集齐四件套穿身上会让玩家每15秒获得6颗心的伤害吸收效果

暗晶钻四件套效果

下面是工具类用品的合成

暗晶钻剑的合成

暗晶钻剑的合成

在使用暗晶钻剑攻击生物时会有吸血效果,一般来说每攻击到一个生物会有吸血效果,为自身增加两点生命值,同时攻击多个生物恢复生命值数则按 2*受攻击生物数 来计算


具体代码实现效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class DarkCrystalDiamondSwordItem extends SwordItem
{

// 增加冷却时间
private long lastHealTime = 0; // 上次回复生命的时间
private static final long HEAL_COOLDOWN = 2000; // 2秒冷却,单位是毫秒
private int enemyHitCount = 0; // 记录击中的敌人数量
private static final int COOLDOWN_TIME = 40; // 设置物品冷却时间,单位是tick(1秒=20tick)

public DarkCrystalDiamondSwordItem(ToolMaterial toolMaterial, int attackDamage, float attackSpeed, Settings settings)
{
super(toolMaterial, attackDamage, attackSpeed, settings);
}

@Override
public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker)
{
//可以在if语句块里引用PlayerEntity user
if (attacker instanceof PlayerEntity user)
{
//检查冷却时间
if (user.getItemCooldownManager().isCoolingDown(stack.getItem()))
{
return true; //如果正在冷却,直接返回
}

stack.damage(1, attacker, e -> e.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
enemyHitCount++; //每次击中敌人时增加计数

long currentTime = System.currentTimeMillis();

//检查冷却时间
if (currentTime - lastHealTime >= HEAL_COOLDOWN)
{
healMultipleFromEnemies(attacker, enemyHitCount);
lastHealTime = currentTime; //更新最后一次回复生命的时间
enemyHitCount = 0; //重置敌人数量计数
}

//设置物品冷却(用物品冷却管理器来设置)
user.getItemCooldownManager().set(stack.getItem(), COOLDOWN_TIME);
}

return true;
}

//用于实现多次攻击回复生命值的逻辑
public void healMultipleFromEnemies(LivingEntity attacker, int enemyCount)
{
//每个敌人回复1点生命值
float healAmount = Math.min(enemyCount * 2, 20 - attacker.getHealth()); //确保不超过最大生命值
attacker.heal(healAmount);
}
}

暗晶钻斧的合成

暗晶钻斧的合成

暗晶钻斧头每次使用可以砍伐目标木头上方所有的木头,并且在使用斧头攻击生物时会将生物打出重伤效果(冷却时间五秒钟)


具体代码实现效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public class DarkCrystalDiamondAxeItem extends AxeItem
{
private static final int COOLDOWN_TIME = 100; //冷却时间,单位是tick(1秒=20tick)

public DarkCrystalDiamondAxeItem(ToolMaterial material, float attackDamage, float attackSpeed, Settings settings) {
super(material, attackDamage, attackSpeed, settings);
}

@Override
public boolean postMine(ItemStack stack, World world, BlockState state, BlockPos pos, LivingEntity miner)
{
if (!(miner instanceof PlayerEntity player))
{
return false; //只有玩家可以使用
}

//检查当前方块是否是木头
if (state.isIn(BlockTags.OVERWORLD_NATURAL_LOGS))
{
int brokenBlocks = 0; //记录破坏的木头块数
if (!world.isClient)
{
//服务器端处理
showWoodInVertical(world, player);

//打破当前的木头
brokenBlocks++;
world.breakBlock(pos, true, player);
//检查并破坏上方的木头
brokenBlocks += checkAndBreakAbove(world, pos.up(), state, player);

//减少斧头耐久
stack.damage(brokenBlocks, player, (p) -> p.sendToolBreakStatus(Hand.MAIN_HAND));
}
return true;
}

return false; //如果不是木头,返回 false
}

//检查并破坏上方的木头
private int checkAndBreakAbove(World world, BlockPos pos, BlockState originalState, PlayerEntity player)
{
BlockState aboveState = world.getBlockState(pos);

//用来计数破坏了多少个方块
int brokenCount = 0;

if (aboveState.isIn(BlockTags.OVERWORLD_NATURAL_LOGS) && aboveState.equals(originalState)) {
//破坏上方的木头
world.breakBlock(pos, true, player);
brokenCount++;

//递归检查上方的木头
brokenCount += checkAndBreakAbove(world, pos.up(), originalState, player);
}
return brokenCount;
}

public void showWoodInVertical(World world, PlayerEntity player)
{
BlockPos playerPos = player.getBlockPos();
for (int i = 1; i <= 5; i++)
{
BlockPos checkPos = playerPos.up(i);
BlockState blockState = world.getBlockState(checkPos); //获取当前检查的方块状态
if (blockState.isIn(BlockTags.OVERWORLD_NATURAL_LOGS))
{
world.playSound(null, checkPos, SoundEvents.BLOCK_WOOD_PLACE, SoundCategory.BLOCKS, 1.0f, 1.0f);
}
}
}

@Override
public boolean postHit(ItemStack stack, LivingEntity target, LivingEntity attacker)
{
//可以在if语句块里引用PlayerEntity user
if (attacker instanceof PlayerEntity user)
{
//检查冷却时间
if (user.getItemCooldownManager().isCoolingDown(stack.getItem()))
{
return true;
}

//扣除斧头耐久
stack.damage(1, attacker, e -> e.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));

//用斧头打中人之后会给对方重伤效果
target.addStatusEffect(new StatusEffectInstance(ModStatusEffects.BADLY_WOUNDED, 80, 0)); // 4秒中重伤

//这是使用后的冷却冷却
user.getItemCooldownManager().set(stack.getItem(), COOLDOWN_TIME);
}

return true;
}

}

暗晶钻镐的合成

暗晶钻镐的合成

暗晶钻镐使用时右键可以瞬间破坏3*3*3范围内的方块(冷却时间四秒钟)


具体代码实现效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public class DarkCrystalDiamondPickaxeItem extends MiningToolItem
{

private static final int COOLDOWN_TIME = 80; //冷却时间,单位是tick(1秒=20tick)

public DarkCrystalDiamondPickaxeItem(ToolMaterial material, int attackDamage, float attackSpeed, Item.Settings settings)
{
super(attackDamage, attackSpeed, material, BlockTags.PICKAXE_MINEABLE, settings);
}

@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand)
{
ItemStack stack = user.getStackInHand(hand);

//检查玩家是否在创造模式(先检查再判断)
boolean isCreative = user.isCreative();

//检查冷却状态(如果不在创造模式下)
if (!isCreative && user.getItemCooldownManager().isCoolingDown(stack.getItem()))
{
return TypedActionResult.fail(stack);
}

//获取玩家当前瞄准的方块
HitResult hitResult = user.raycast(5.0, 1.0F, false);

//检查瞄准的方块类型
if (hitResult.getType() == HitResult.Type.BLOCK)
{
BlockHitResult blockHitResult = (BlockHitResult) hitResult;
BlockPos targetedBlockPos = blockHitResult.getBlockPos();
BlockState state = world.getBlockState(targetedBlockPos);

//检查方块是否可以被挖掘
if (!state.isAir() && canMine(state))
{
//确保玩家可以破坏瞄准的位置
if (user.canModifyAt(world, targetedBlockPos))
{
//挖掘 3x3x3 区域
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
for (int z = -1; z <= 1; z++)
{
BlockPos blockToBreak = targetedBlockPos.add(x, y, z);
BlockState blockState = world.getBlockState(blockToBreak);

// 检查每个方块是否可以被挖掘
if (!blockState.isAir() && canMine(blockState))
{
// 进行方块破坏,设置进度
world.breakBlock(blockToBreak, true, user);
}
}
}
}

if (!isCreative)
{
//播放音效
world.playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.ITEM_AXE_STRIP, user.getSoundCategory(), 1.0F, 1.0F);

//设置物品冷却(用物品冷却管理器来设置)
user.getItemCooldownManager().set(stack.getItem(), COOLDOWN_TIME);

//消耗耐久,假设挖掘了 26 个方块
stack.damage(26, user, (entity) -> entity.sendToolBreakStatus(hand));
}
}
}
}
return TypedActionResult.success(stack);
}

private boolean canMine(BlockState state)
{
// 检查方块是否可以被挖掘
return state.isIn(BlockTags.PICKAXE_MINEABLE); // 请替换为实际可挖掘方块的检查条件
}
}

暗晶钻锄的合成

暗晶钻锄的合成

暗晶钻锄使用时可以一次性耕种3*3的农田


具体代码实现效果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class DarkCrystalDiamondHoeItem extends HoeItem
{

public DarkCrystalDiamondHoeItem(ToolMaterial material, int attackDamage, float attackSpeed, Settings settings)
{
super(material, attackDamage, attackSpeed, settings);
}

@Override
public ActionResult useOnBlock(ItemUsageContext context) {
BlockPos blockPos = context.getBlockPos();
World world = context.getWorld();
PlayerEntity playerEntity = context.getPlayer();

int startX = -1;
int startZ = -1;

int tillCount = 0;

for (int x = startX; x <= 1; x++) {
for (int z = startZ; z <= 1; z++)
{
BlockPos currentPos = blockPos.add(x, 0, z);
BlockState currentState = world.getBlockState(currentPos);
Pair<Predicate<ItemUsageContext>, Consumer<ItemUsageContext>> pair = TILLING_ACTIONS.get(currentState.getBlock());

if (pair != null)
{
Predicate<ItemUsageContext> predicate = pair.getFirst();
Consumer<ItemUsageContext> consumer = pair.getSecond();

BlockHitResult hitResult = new BlockHitResult(new Vec3d(currentPos.getX(), currentPos.getY(), currentPos.getZ()), Direction.UP, currentPos, false);
ItemUsageContext newContext = new ItemUsageContext(world,playerEntity, context.getHand(), context.getStack(), hitResult);

// 在客户端上执行操作 如果是(!world.isClient)则在服务端执行操作
if (world.isClient)
{
if (predicate.test(newContext))
{
// 播放声音效果
world.playSound(playerEntity, currentPos, SoundEvents.ITEM_HOE_TILL, SoundCategory.BLOCKS, 1.0f, 1.0f);
consumer.accept(newContext); //在客户端添加动作的效果
tillCount++;
}
}
else
{
if (predicate.test(newContext))
{
consumer.accept(newContext);
tillCount++;
}
}
}
}
}

// 如果成功耕作的方块数大于 0,处理耐久
if (tillCount > 0)
{
if (playerEntity != null)
{
context.getStack().damage(9, playerEntity, p -> p.sendToolBreakStatus(context.getHand()));
}
return ActionResult.success(world.isClient);
}

return ActionResult.PASS;
}
}

暗晶钻铲的合成

暗晶钻铲的合成

暗晶钻铲暂无特殊功能


以上代码仅供参考,若想摘抄请在下方留言



总结

该套装开发进程已经完成,后续还会更新

“一花一世界,一叶一菩提”


版权所有 © 2024 云梦泽
欢迎访问我的个人网站:https://hgt12.github.io/


『模组开发日记』之暗晶钻套装与工具的加入
http://example.com/2024/10/21/『模组开发日记』之暗晶钻套装与工具的加入/
作者
云梦泽
发布于
2024年10月21日
更新于
2024年11月10日
许可协议