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() 來獲取射箭者實體。

投擲物手榴彈

未完待續......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM