[解決済み]【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

Modding・サーバPlugin制作・ツール制作など、開発関連の質問があればこちらにお願い致します。
フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999
  • (PostNo.44495)

[解決済み]【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by Schr0 » 2012年6月23日(土) 09:00

トピックを開いていただきありがとう御座います。ほんの少しの事でも良いので答えてくださると嬉しいです。

【質問】
現在作成しているmodのアイテムに、『特定のダメージ(爆発や火など)を一切受けない』という効果を付与したいと思っております。
一応、ポーション効果やエンチャント効果をすることでそれらしい形にはなりましたが、条件が限られてしまい少々コレジャナイ感が漂うものになってしまいました。
そこで、ダメージの大元に関して調べてみるとDamageSourceというクラスでダメージの種類を振り分け(?)しているような処理を見付けました。
これを利用してみようと思ったのですが、エラー続出でお手上げ状態です・・・。

(1)このダメージソースを利用してプレイヤーのダメージを無効化することは可能なのでしょうか?また、どのような処理を行えばいいのでしょうか。

(2)公開されているソースを参考にして、『インベントリ内にアイテムがある場合の処理(=onUpdate)』については知っているのですが、それと同様に『防具欄に装備した場合の処理』はあるのでしょうか?(私には見つけられませんでした・・・)


上記二つについて、何かヒントだけでもお答えいただけたら幸いです。
最後に編集したユーザー Schr0 [ 2012年6月30日(土) 22:07 ], 累計 1 回
アバター
Schr0
ID:b6afdb15
鉄鉱掘り
 
記事: 323
登録日時: 2011年9月07日(水) 05:21

  • (PostNo.44910)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by ayashige » 2012年6月26日(火) 00:04

Schr0 さんが書きました:(1)このダメージソースを利用してプレイヤーのダメージを無効化することは可能なのでしょうか?また、どのような処理を行えばいいのでしょうか。


使ったことはないですが、ForgeのArmorPropertiesとISpecialArmorを使えば、プレイヤーが装備している防具でソースを判別して無効化できそうです。
それ以外だと、基本のクラスを改変する必要があるかもしれません。

Schr0 さんが書きました:(2)公開されているソースを参考にして、『インベントリ内にアイテムがある場合の処理(=onUpdate)』については知っているのですが、それと同様に『防具欄に装備した場合の処理』はあるのでしょうか?(私には見つけられませんでした・・・)



装備をした、装備をはずした、装備が壊れたについてはイベントなどが見つかりませんでした。
改変無しの取得は難しそうです。

装備している間だけ何かをしたいのであれば拙作のライトつきヘルメットで使用している方法ですが、onTickInGameメソッド内でプレイヤーのインベントリのarmorItemInSlotをチェックして現在装備しているかチェックできます。
綾繁那人です、ねこによろしく。
ayashige
ID:35312126
大工さん
 
記事: 47
登録日時: 2012年5月03日(木) 12:52

  • (PostNo.44934)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by Schr0 » 2012年6月26日(火) 07:57

ayashige さんが書きました:使ったことはないですが、ForgeのArmorPropertiesとISpecialArmorを使えば、プレイヤーが装備している防具でソースを判別して無効化できそうです。
それ以外だと、基本のクラスを改変する必要があるかもしれません。

またもや答えて頂き、ありがとうございます!
んー・・・両方とも私にはちょっと厳しい感じですね・・・。
しかし、挑戦はしてみます。ありがとうございます。

ayashige さんが書きました:装備している間だけ何かをしたいのであれば拙作のライトつきヘルメットで使用している方法ですが、onTickInGameメソッド内でプレイヤーのインベントリのarmorItemInSlotをチェックして現在装備しているかチェックできます。

コード: 全て選択
   //インベントリの処理
   public void onUpdate(ItemStack itemstack, World world, Entity entity, int i, boolean flag)
   {
      EntityPlayer EntityPlayer =(EntityPlayer) entity;
      EntityPlayer.addPotionEffect(new PotionEffect(2,1*20, 1));//スピードダウンLv1
      EntityPlayer.addPotionEffect(new PotionEffect(12,1*20, 1));//火耐性Lv1

      if(EntityPlayer.handleLavaMovement())//溶岩中に居る場合
      {
      EntityPlayer.addPotionEffect(new PotionEffect(10,1*20, 1));//リジェネLv1
      EntityPlayer.addPotionEffect(new PotionEffect(11,30*20, 5));//防御力強化Lv5
      EntityPlayer.addPotionEffect(new PotionEffect(5,30*20, 2));//攻撃力強化Lv2
      if(EntityPlayer.getFoodStats().getFoodLevel() < 25)
      {
      EntityPlayer.getFoodStats().addStats(1, 5F);//空腹度を1個分ずつ回復
      }
      }
   }

上記のような処理を、onTickInGameメソッドで『アーマーを装備している』ということを認識することにより可能・・・・という事なのでしょうか?
もしもそうであるなら、その処理が解ればかなり進展しそうです!
アバター
Schr0
ID:b6afdb15
鉄鉱掘り
 
記事: 323
登録日時: 2011年9月07日(水) 05:21

  • (PostNo.45002)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by ayashige » 2012年6月26日(火) 21:37

こんな感じです。
毎Tick実行するので重いときは何らかの方法で処理回数を減らす工夫が必要になるかもしれません。(1回処理したら何Tickかインターバルをおくとか)

コード: 全て選択
package net.minecraft.src;

import net.minecraft.client.Minecraft;

public class mod_Test extends BaseMod {

   @Override
   public String getVersion() {
      return "0.0.1";
   }

   @Override
   public void load() {
      ModLoader.setInGameHook(this, true, true);

   }
    public boolean onTickInGame(float var1, Minecraft var2)
    {
      World worldObj = var2.theWorld;
      EntityPlayer entityPlayer = var2.thePlayer;
      InventoryPlayer inventoryPlayer = entityPlayer.inventory;

      ItemStack itemStack = inventoryPlayer.armorItemInSlot(3);// 3は頭装備
      if ((itemStack != null) && (itemStack.itemID == "チェックしたいアイテムID")) {
         entityPlayer.addPotionEffect(new PotionEffect(2,1*20, 1));//スピードダウンLv1
         entityPlayer.addPotionEffect(new PotionEffect(12,1*20, 1));//火耐性Lv1
   
         if (entityPlayer.handleLavaMovement())// 溶岩中に居る場合
         {
            entityPlayer.addPotionEffect(new PotionEffect(10, 1 * 20, 1));// リジェネLv1
            entityPlayer.addPotionEffect(new PotionEffect(11, 30 * 20, 5));// 防御力強化Lv5
            entityPlayer.addPotionEffect(new PotionEffect(5, 30 * 20, 2));// 攻撃力強化Lv2
            if (entityPlayer.getFoodStats().getFoodLevel() < 25) {
               entityPlayer.getFoodStats().addStats(1, 5F);// 空腹度を1個分ずつ回復
            }
         }
      }

        return true;
    }

}



装備チェックを省いて、常に処理を実行するようにしたとき
使用前
2012-06-26_21.24.11.png

使用後
2012-06-26_21.24.21.png
綾繁那人です、ねこによろしく。
ayashige
ID:35312126
大工さん
 
記事: 47
登録日時: 2012年5月03日(木) 12:52

  • (PostNo.45111)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by Schr0 » 2012年6月27日(水) 23:15

ayashige さんが書きました:

スクショのような処理はこちらでも可能でしたが、防具では何故か認識してくれません・・・orz
mod_Tick
コード: 全て選択
package net.minecraft.src;

import net.minecraft.client.Minecraft;

public class mod_Tick extends BaseMod {

   @Override
   public String getVersion(){
      return "0.0.1";
   }

   @Override
   public void load() {
   ModLoader.setInGameHook(this, true, true);
   }

   public boolean onTickInGame(float var1, Minecraft var2)
   {
   World worldObj = var2.theWorld;
   EntityPlayer entityPlayer = var2.thePlayer;
   InventoryPlayer inventoryPlayer = entityPlayer.inventory;
   ItemStack itemStack = inventoryPlayer.armorItemInSlot(3);// 3は頭装備
   if ((itemStack != null) && (itemStack.itemID == mod_MaidenTool.MaidenSheathId))
   {
   entityPlayer.addPotionEffect(new PotionEffect(10, 1 * 20, 1));// リジェネLv1
   entityPlayer.addPotionEffect(new PotionEffect(11, 30 * 20, 5));// 防御力強化Lv5
   entityPlayer.addPotionEffect(new PotionEffect(5, 30 * 20, 2));// 攻撃力強化Lv2
                if (entityPlayer.getFoodStats().getFoodLevel() < 25)
      {
         entityPlayer.getFoodStats().addStats(1, 5F);// 空腹度を1個分ずつ回復
                }
   }
      return true;
        }

}

IDの部分に指定したID(=2015)を入れたりしたのですが、それでもムリでした。
2012-06-27_23.09.36.png

折角回答を頂いているのに、理解できないで申し訳有りません・・・。
アバター
Schr0
ID:b6afdb15
鉄鉱掘り
 
記事: 323
登録日時: 2011年9月07日(水) 05:21

  • (PostNo.45128)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by edke » 2012年6月28日(木) 00:42

意外と知らない人がつまづくところなのですが、
Itemhoge(アイテムID) で登録したIDは、ブロックIDと重ならないようにするためなのか、-256されて保存されます。
なのでそのIDを他のところで読み込む場合、記憶するときに+256しておくか、読み込むときに-256する必要があります。
おそらくそこでずれてるのではないでしょうか。
IDwakanderなどでIDを見ると本来コンフィグで設定したはずの番号と違うところにある場合があります。これは前途のシステムのせいです。
導入する側が混乱しないようにするためにも、+256しておくことをお勧めします。


追記
MOD1つにつきmod_クラスは1つが適切かと思います。レシピ追加などをしようとしたとき、読み込まれる順番などの関係でエラーが出やすくなるからです。もし複数つくっていたのなら、統一することを勧めます。

余談
こちらでもアーマーの装備を読み込みたかったこともあり、このトピックは自分にも大変参考になっています。
最後に編集したユーザー edke [ 2012年6月28日(木) 01:21 ], 累計 1 回
*初心もっだーの成れの果て*
アバター
edke
ID:a76b853b
金掘り
 
記事: 382
登録日時: 2011年12月12日(月) 21:42

  • (PostNo.45129)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by ayashige » 2012年6月28日(木) 00:43

コード: 全て選択
   if ((itemStack != null) && (itemStack.itemID == mod_MaidenTool.MaidenSheathId))

ここで指定しているmod_MaidenTool.MaidenSheathIdですが、アイテムの作成時
(new Item派生クラス(アイテムID・・・)とするときです。)に-256する処理は入っていますか?

Itemクラスのコンストラクタでは、引き渡されたアイテムID+256を実際のIDにする処理が行われています。
(実際のIDはIDwakanderなどで確認できます)

もしmod_MaidenTool.MaidenSheathIdをそのままItem作成時に使用しているならば、
この条件だと一致しなくなります。

これ以外はソースを見ないとちょっと見当がつきません。

・・・と書いている間に他の方からも同様のご指摘がありましたが、一応こちらも残しておきます。
綾繁那人です、ねこによろしく。
ayashige
ID:35312126
大工さん
 
記事: 47
登録日時: 2012年5月03日(木) 12:52

  • (PostNo.45196)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by edke » 2012年6月28日(木) 20:22

訂正入りまーす!

+256ではなく-256ですね!すみませんでした!!
*初心もっだーの成れの果て*
アバター
edke
ID:a76b853b
金掘り
 
記事: 382
登録日時: 2011年12月12日(月) 21:42

  • (PostNo.45431)

Re: 【質問】特定のダメージ(爆発、火など)を無効化する処理に付いて+α

投稿記事by Schr0 » 2012年6月30日(土) 22:06

申し訳有りません。
リアルが少し込み入ってしまい、返信が遅れてしまいました。

ayashige さんが書きました:
edke さんが書きました:

なんという初歩的なミス・・・!
mod製作にかまけて余りプレイしてなかったからなのか、スッカリ忘れておりました・・・orz
お二人のアドバイス通りにしたら無事に動作しました!
何度もお答え頂き、嬉しいやら申し訳ないやら・・・。
ありがとうございますorz

そして、ayashigeさんのアドバイスを元に色々と調べた所、クリエイティブのクラスを利用する事で『特定のダメージを無効にする』ということは出来るかもしれないです。
ですが、あくまで『奈落以外のダメージ無効』というクリエイティブの動作を参考にしているので、条件次第ではそのまま(=クリエイティブ仕様)になってしまうので注意が必要です。
コード: 全て選択
   //インベントリの処理
   public void onUpdate(ItemStack itemstack, World world, Entity entity, int i, boolean flag)
   {
   EntityPlayer EntityPlayer =(EntityPlayer) entity;
   EntityPlayer.capabilities.disableDamage = false;//ダメージ無効の初期化
      if(!EntityPlayer.onGround)//空中では
      {
      EntityPlayer.capabilities.allowFlying = true;//ダメージ無効
      }
        }

これは『インベントリに所持している場合に空中で受けるダメージを無効化』という感じの処理です。
条件のバリエーションが乏しく私には応用が上手くいきませんが、多少の応用は利くんじゃないかな、と。

問題解決の糸口が見えてきたので、引き続き個人的に色々と試してみる事にします!
優しい回答をしてくださり、ありがとうございました!
アバター
Schr0
ID:b6afdb15
鉄鉱掘り
 
記事: 323
登録日時: 2011年9月07日(水) 05:21


Return to 質問:開発・制作関連

x