• Minecraft 1.12.2 Mod开发笔记——实践1:给武器带上爆炸的附魔


    总目录:Minecraft 1.12.2 开发笔记

    实践1:爆炸弓/引爆剑/手榴弹

    显然,Minecraft中的TNT并不能满足我们随意轰炸的欲望

    • 附魔种类判断
    • 攻击/被攻击事件
    • 实现爆炸

    我们来实现之前的引爆附魔效果,效果图如下

    有关攻击的事件

    • AttackEntityEvent 玩家攻击实体时触发,显然先于下面的 LivingAttackEvent 触发
    • LivingAttackEvent 存活的实体被攻击时触发
    • LivingSetAttackTargetEvent 生物设置其攻击目标时触发,这里的生物应该指的就是可主动攻击的生物,不包括玩家。比如僵尸看到村民开始追击。

    有关弓箭的事件

    • ArrowNockEvent 开始拉弓时触发
    • ArrowLooseEvent 松开弓时触发,无论是否射出箭
    • ProjectileImpactEvent.Arrow 弓箭落地时触发,实际是关于射出的弓箭实体的事件

    可以看到,如果是引爆的近程武器,我们可以使用 AttackEntityEvent 或 LivingAttackEvent 来实现;如果是弓这个远程武器,我们可以用 LivingAttackEvent 或 ProjectileImpactEvent.Arrow 来实现。注意箭/火焰弹等远程武器不会触发 AttackEntityEvent。

    爆炸

    Minecraft 中的爆炸使用 World 对象的

    createExplosion(Entity entityIn, x, y, z, strength, boolean isSmoking) 实现。

    • entityIn 爆炸源,可以为 null,不参与爆炸伤害判定
    • x,y,z double,坐标
    • strength float,爆炸威力/范围,普通苦力怕为3.0,TNT为4.0或者更大一点,末影水晶为6.0,所以说。。
    • isSmoking 是否破坏地形和造成伤害

    此外,World 对象还有一个

    newExplosion(Entity entityIn, x, y, z, strength, boolean isFlaming, boolean isSmoking)

    方法,比上面的多了一个 isFlaming 参数,即爆炸是否产生火。而上面的那个方法即为 isFlaming=false 的情况。

    如何判断附魔

    EnchantmentHelper.getEnchantmentLevel(Enchantment enchID, ItemStack stack)
    
    • enchID 需要检测的附魔对象
    • stack 需要检测的物品,可以从player对象上拿到
    • return 返回附魔等级,若无返回0

    通过 AttackEntityEvent 事件实现引爆在近战武器上的效果

    @SubscribeEvent
    public static void onPlayerAttack(AttackEntityEvent event) {
        Entity e = event.getTarget();
        EntityPlayer player = event.getEntityPlayer();
        if (!player.world.isRemote) {
            if (EnchantmentHelper.getEnchantmentLevel(ElementLoader.ignite, player.getHeldItemMainhand()) == 1) {
                player.world.createExplosion(player, e.posX, e.posY, e.posZ, 3.0f, true);
            }
        }
    }
    
    • player.world.isRemote 用于判断是哪个 Side,通常我们只需要一个 Side 去处理即可,比如服务器端。暂时还没有弄明白,但很多事件都是这么写的
    • player.getHeldItemMainhand() 用于获取玩家主手的物品,也可以探索player的其他方法
    • 这里我们设置玩家自身是爆炸源,要不然你想让玩家炸死么

    通过 ProjectileImpactEvent.Arrow 事件实现爆炸弓

    @SubscribeEvent
    public static void onArrowAttack(ProjectileImpactEvent.Arrow event) {
        EntityArrow e = event.getArrow();
        if (!e.world.isRemote) {
            if (e.shootingEntity instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer) e.shootingEntity;
                if (EnchantmentHelper.getEnchantmentLevel(ElementLoader.ignite, player.getHeldItemMainhand()) != 0) {
                    e.world.createExplosion(null, e.posX, e.posY, e.posZ, 10.0f, true);
                }
            }
        }
    }
    
    • 基本大同小异,注意不同的对象有不同的方法和属性

    通过 LivingAttackEvent 事件

    一些伤害类型可以直接使用 event.getSource() 获取伤害类型并与 DamageSource 中的常量进行比较,有些没有常量的伤害类型可以使用 event.getSource().getDamageType() 来获取伤害类型名称进行比较,名称可从 DamageSource 类中查看。其中远程武器比如弓箭等被定义为间接伤害,可以用 getTrueSource() 来获取射箭者实体。

    投掷物手榴弹

    未完待续......

  • 相关阅读:
    Nginx浅谈
    MySQL 规范
    使用nginx反向代理实现隐藏端口号
    -bash: /etc/profile: line 11: syntax error near unexpected token `$'{ ''报错问题解决
    为什么禁止在 foreach 循环里进行元素的 remove/add 操作
    Java中String字符串常量池
    前端学习路径
    Linux关闭防火墙命令
    CXF实现webService服务
    Jquery Ajax 的例子。
  • 原文地址:https://www.cnblogs.com/moonfan/p/12421704.html
Copyright © 2020-2023  润新知