提供: defeatedcrow mod wiki
Defeatedcrow (トーク | 投稿記録) (ページの作成:「=発射機能を作る= 無機能だったItemに機能を追加していきます。 #右クリック使用時に弾Entityを発射する #アイテムの耐久値を消...」) |
Defeatedcrow (トーク | 投稿記録) |
||
(同じ利用者による、間の1版が非表示) | |||
1行目: | 1行目: | ||
+ | <[[IGNIS制作記録|目次に戻る]]> | ||
=発射機能を作る= | =発射機能を作る= | ||
無機能だったItemに機能を追加していきます。 | 無機能だったItemに機能を追加していきます。 | ||
210行目: | 211行目: | ||
ここまで作れば、ゲーム中で実際に発射して試すことが出来る。<br /> | ここまで作れば、ゲーム中で実際に発射して試すことが出来る。<br /> | ||
https://dl-web.dropbox.com/s/hw0ugkt3jwktkaz/ignis_entity.png<br /> | https://dl-web.dropbox.com/s/hw0ugkt3jwktkaz/ignis_entity.png<br /> | ||
− | + | 一度に4発ずつ出しているので、炎パーティクルのボリューム感は十分な気がするし、雰囲気はでていると思う。右クリック押しっぱなしでエイム不要な点もまぁまぁ再現されているかなと思う。<br /> | |
− | + | 何ともいえない射程の長さや弾切れの早さ、無強化の状態でのパッとしない攻撃力、視界の悪さなど、IGNISっぽさが出てきたなーと思えば次の段階へ。<br /> | |
− | もちろん、作る人によっては強すぎる/ | + | もちろん、作る人によっては強すぎる/弱すぎるなど感覚に違いがあると思う。その場合はdamageやspeedなどのパラメータやEntityのヒット処理での当たり判定チェック範囲のサイズなど、少しずつ変えて確かめながらバランスを調整すると良いと思う。自分が一番しっくりくる値に決めればOK。 |
2016年9月21日 (水) 10:54時点における最新版
<目次に戻る>
発射機能を作る
無機能だったItemに機能を追加していきます。
- 右クリック使用時に弾Entityを発射する
- アイテムの耐久値を消費せず、代わりにマガジンの弾を消費して弾を撃つようにする。耐久値ではないので、無くなっても破壊されない。
- 弾切れの時に右クリックすると、インベントリの弾薬を消費して補充する。
- 耐久値ゲージをマガジン用のゲージに使用する。
package defeatedcrow.flamethrower.item; import java.util.List; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.MathHelper; import net.minecraft.world.World; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import defeatedcrow.flamethrower.entity.EntityFlame; public class ItemIgnis extends ItemBow { public ItemIgnis() { this.setMaxStackSize(1); this.setMaxDamage(4); this.setNoRepair(); } @Override @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister par1IconRegister) { this.itemIcon = par1IconRegister.registerIcon("dcsflame:flamethrower"); } @Override @SideOnly(Side.CLIENT) public boolean isFull3D() { return true; } /* ここから先が追加した部分 */ // 耐久値を減らそうとする処理が呼ばれた場合に握りつぶす。アイテムロストなどの事故防止。 @Override public void setDamage(ItemStack stack, int damage) { return; } // このメソッドは、プレイヤーがブロックをターゲットしていないときに呼ばれる方のRightClickメソッド。 @Override public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { // クリエイティブモードか boolean creative = par3EntityPlayer.capabilities.isCreativeMode; // マガジンが空でないかどうか boolean hasCharge = false; if (par1ItemStack.getItem() == this) { // 弾薬減少処理。第三引数のbooleanをfalseにすると、実際には減らさないシミュレーション処理になる int c2 = this.discharge(par1ItemStack, 1, false); if (c2 > 0) { hasCharge = true; this.discharge(par1ItemStack, 1, true); } } // 消費できる弾があったら実行 if (creative || hasCharge) { // ダメージ量 float dam = 2.0F; // 0.0F~1.0Fの乱数 float ram = par2World.rand.nextFloat(); int cooltime = 0; // 一旦凍結。常に0を入れる // 弾速 float speed = 1.0F; // ランダムに速度を変えながら、同時に4発ずつ発射する。 for (int i = 0; i < 4; i++) { float f = speed * (i * 0.35F) + ram; // 生成 EntityFlame bullet = new EntityFlame(par2World, par3EntityPlayer, f, 0.0F, dam, 4.0F, cooltime); // Entityの着火機能を利用 bullet.setFire(100); // Entityのスポーン処理はisRemote判定を利用してサーバー側のみで行うこと! if (!par2World.isRemote) { par2World.spawnEntityInWorld(bullet); } } } else { // この処理に飛んでいるということは弾切れなので、弾薬を補充する処理をする // 今はまだ弾薬アイテムを追加前なので、仮のアイテムを消費させておく if (par3EntityPlayer.inventory.hasItem(Items.gunpowder)) { // 弾薬補充処理。マガジンはNBTタグに入っている NBTTagCompound nbt = par1ItemStack.getTagCompound(); if (nbt == null) { nbt = new NBTTagCompound(); } nbt.setInteger("dcf_magazine", 100); par1ItemStack.setTagCompound(nbt); // playerのインベントリの弾薬アイテムを減らす。この処理はInventoryPlayerの既存処理を利用している。 par3EntityPlayer.inventory.consumeInventoryItem(Items.gunpowder); // バニラのドアガチャSEのピッチを弄って、それっぽくしている par2World.playSoundAtEntity(par3EntityPlayer, "random.door_close", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + 1.3F); } } return par1ItemStack; } // onEatenのほうの右クリック処理ではそのままItemStackを返す(つまりなにもしない) @Override public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { return par1ItemStack; } // onItemRightClickで呼んでいる弾の消費処理 // 今は使っていないが、弾薬を2以上減らす場合にも応用できるようにしている public int discharge(ItemStack item, int amount, boolean flag) { if (item == null) return 0; // NBTに入れている弾の数が足りているかの判定と、第三引数がtrueなら減少させている NBTTagCompound nbt = item.getTagCompound(); int charge = 0; int reduce = 0; if (nbt != null && nbt.hasKey("magazine")) { charge = nbt.getInteger("magazine"); } reduce = Math.min(amount, charge); if (flag) { if (nbt != null) { nbt.setInteger("magazine", (charge - reduce)); item.setTagCompound(nbt); } else { NBTTagCompound nbt2 = new NBTTagCompound(); nbt2.setInteger("magazine", (charge - reduce)); item.setTagCompound(nbt2); } } return reduce; } // マウスオーバー時の表示情報。マガジンの残量/MAXを表示している。 @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); NBTTagCompound nbt = par1ItemStack.getTagCompound(); int charge = 0; int max = 100; if (nbt != null && nbt.hasKey("magazine")) { charge = nbt.getInteger("magazine"); } String s = new String("magazine : " + charge + "/" + max); par3List.add(s); } // 耐久値ゲージを表示するかどうかのフラグ @Override public boolean showDurabilityBar(ItemStack stack) { return true; } // このメソッドで耐久値の代わりに弾の残量をゲージ表示できるようにしている。 // 0.0Dを返したときがMAXで、1.0Dを返すとゲージがなくなったように見える。よって、MAX - 残量 を計算して返している。 @Override public double getDurabilityForDisplay(ItemStack stack) { NBTTagCompound nbt = stack.getTagCompound(); int charge = 0; int max = 100; if (nbt != null && nbt.hasKey("magazine")) { charge = nbt.getInteger("magazine"); charge = MathHelper.clamp_int(charge, 0, max); } int i = max - charge; return (double) i / (double) max; } }
主にやっていることは2つ。
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
で、発射機構。
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
public double getDurabilityForDisplay(ItemStack stack)
この2つのメソッドでアイテムの弾薬情報表示。
ここまで作れば、ゲーム中で実際に発射して試すことが出来る。
一度に4発ずつ出しているので、炎パーティクルのボリューム感は十分な気がするし、雰囲気はでていると思う。右クリック押しっぱなしでエイム不要な点もまぁまぁ再現されているかなと思う。
何ともいえない射程の長さや弾切れの早さ、無強化の状態でのパッとしない攻撃力、視界の悪さなど、IGNISっぽさが出てきたなーと思えば次の段階へ。
もちろん、作る人によっては強すぎる/弱すぎるなど感覚に違いがあると思う。その場合はdamageやspeedなどのパラメータやEntityのヒット処理での当たり判定チェック範囲のサイズなど、少しずつ変えて確かめながらバランスを調整すると良いと思う。自分が一番しっくりくる値に決めればOK。