提供: Minecraft Modding Wiki
移動先: 案内検索

この記事は"Minecraft Forge Universal 10.12.0.xxx~"を前提MODとしています。

Wood pickaxe.png
初心者向けのチュートリアルです。
C block.png
Blockに関係のあるチュートリアルです。


属性値を動的変更できるアイテムの追加

属性値を動的変更できるアイテムを追加する。

属性値について

属性(Attribute)は、1.7から追加された、プレイヤーやモブのパラメータに影響を与えるNBTである。

1.7では、以下の属性値を設定することが出来る。

  • 最大体力(generic.maxHealth)
  • 追跡範囲(generic.followRange)
  • ノックバック耐性(generic.knockbackResistance)
  • 移動速度(generic.movementSpeed)
  • 攻撃力(generic.attackDamage)

上記属性に設定できる値には最小値と最大値が設定されている。

詳しくは以下の公式wikiに載っているので参照のこと。

Attribute - Minecraft Wiki

ソースコード

package ak.sampleMod;

import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;

import javax.annotation.Nonnull;

/**
 * 攻撃力可変ソードクラス
 */
public class SampleVariableSword extends ItemSword {
    /** 属性保存のキー */
    private static final String NBT_ATTRIBUTE_MODIFIERS_KEY = "AttributeModifiers";
    /** 属性値名称保存キー */
    private static final String NBT_ATTRIBUTE_MODIFIERS_NAME = "Name";
    /** 属性名キー。AttributeModifiersとしてMapに登録する際に使用 */
    private static final String NBT_ATTRIBUTE_MODIFIERS_NAME_KEY = "AttributeName";
    /** 属性値double valueキー */
    private static final String NBT_ATTRIBUTE_MODIFIERS_AMOUNT = "Amount";
    /** 属性値Opキー */
    private static final String NBT_ATTRIBUTE_MODIFIERS_OPERATION = "Operation";
    /** 攻撃力の属性値の名称 */
    private static final String NBT_ATTRIBUTE_MODIFIERS_NAME_WEAPON = "Weapon modifier";
    /** UUIDMostを表すlong値用のキー */
    private static final String NBT_ATTRIBUTE_MODIFIERS_UUID_MOST = "UUIDMost";
    /** UUIDLeastを表すlong値用のキー */
    private static final String NBT_ATTRIBUTE_MODIFIERS_UUID_LEAST = "UUIDLeast";

    public SampleVariableSword(ToolMaterial toolMaterial) {
        super(toolMaterial);
        GameRegistry.registerItem(this, "sample_variable_sword");
    }

    @Override
    public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
        if (!world.isRemote) {
            int randAttack = world.rand.nextInt(100);
            this.setAttribute(itemStack, player, SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(),
                    NBT_ATTRIBUTE_MODIFIERS_NAME_WEAPON, randAttack, 0);
        }
        return super.onItemRightClick(itemStack, world, player);
    }

    /**
     * 武器の属性変更メソッド
     * @param itemStack 変更したい武器のItemStack
     * @param player 所有プレイヤー
     * @param attributeKey 属性のMultiMap上でのKey文字列
     * @param attributeName 属性のAttributeModifierName
     * @param amount 属性の値
     * @param op 属性のOp
     */
    protected void setAttribute(@Nonnull ItemStack itemStack, @Nonnull EntityPlayer player, @Nonnull String attributeKey,
                                @Nonnull String attributeName, @Nonnull double amount, @Nonnull int op) {
        NBTTagList nbtTagList;
        NBTTagCompound nbtTagCompound;
        if (!itemStack.hasTagCompound()) {
            /* NBTが設定されていない場合は設定しておく */
            itemStack.setTagCompound(new NBTTagCompound());
        }
        /* "AttributeModifiers"キーをNBTに持っているかどうか */
        if (itemStack.getTagCompound().hasKey(NBT_ATTRIBUTE_MODIFIERS_KEY, 9)) {
            /* TagListとして保存されているので取得 */
            nbtTagList = itemStack.getTagCompound().getTagList(NBT_ATTRIBUTE_MODIFIERS_KEY, 10);
            for (int tagIndex = 0; tagIndex < nbtTagList.tagCount(); tagIndex++) {
                nbtTagCompound = nbtTagList.getCompoundTagAt(tagIndex);
                /* 属性名キーと属性名称保存キーから属性名と属性名称を取得し、該当の属性かどうか判定 */
                if (attributeKey.equals(nbtTagCompound.getString(NBT_ATTRIBUTE_MODIFIERS_NAME_KEY))
                        && attributeName.equals(nbtTagCompound.getString(NBT_ATTRIBUTE_MODIFIERS_NAME))) {
                    /* 新しい値をセット */
                    nbtTagCompound.setDouble(NBT_ATTRIBUTE_MODIFIERS_AMOUNT, amount);
                    break;
                }
            }
        } else {
            /* 新規属性値として設定している。 */
            nbtTagList = new NBTTagList();
            nbtTagCompound = new NBTTagCompound();
            nbtTagCompound.setLong(NBT_ATTRIBUTE_MODIFIERS_UUID_MOST, Item.field_111210_e.getMostSignificantBits());
            nbtTagCompound.setLong(NBT_ATTRIBUTE_MODIFIERS_UUID_LEAST, Item.field_111210_e.getLeastSignificantBits());
            nbtTagCompound.setString(NBT_ATTRIBUTE_MODIFIERS_NAME_KEY, attributeKey);
            nbtTagCompound.setString(NBT_ATTRIBUTE_MODIFIERS_NAME, attributeName);
            nbtTagCompound.setDouble(NBT_ATTRIBUTE_MODIFIERS_AMOUNT, amount);
            nbtTagCompound.setInteger(NBT_ATTRIBUTE_MODIFIERS_OPERATION, op);
            nbtTagList.appendTag(nbtTagCompound);
            if (!itemStack.hasTagCompound()) {
                itemStack.setTagCompound(new NBTTagCompound());
            }
            itemStack.getTagCompound().setTag(NBT_ATTRIBUTE_MODIFIERS_KEY, nbtTagList);
        }

        player.getAttributeMap().applyAttributeModifiers(itemStack.getAttributeModifiers());
    }
}

解説

属性はNBTとして以下の構造で保存されている。

getTagCompound()で取得できるNBTTagCompound
|
|-NBTTagList(AttributeModifiers)
| |-NBTTagCompound
| | |-属性名(AttributeName):SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()等、Map保存用キー文字列
| | |-属性名称(Name):属性の名称。"Weapon modifier"など。
| | |-属性値(Amount):属性に設定するdouble値。
| | |-属性Op(Operation):属性を使用する際に使われる? 0を入れれば良い。
| | |-UUIDMOST:アイテムクラスのUUIDのgetMostSignificantBits()を入れれば良い。
| | |-UUIDLEAST:アイテムクラスのUUIDのgetLeastSignificantBits()を入れれば良い。
| |
| |-NBTTagCompound