Создание щита в майнкрафте

Версия Minecraft
1.7.10
17
2
0
Здравствуйте, хотел бы добавить в игру щит, который будет схож с механикой щита в моде кастом нпс, у них код выглядит как-то так:
(класс самого щита, мб механик)
Java:
package noppes.npcs.items;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import noppes.npcs.CustomItems;
import noppes.npcs.constants.EnumNpcToolMaterial;
import org.lwjgl.opengl.GL11;

public class ItemShield extends ItemNpcInterface {
  public EnumNpcToolMaterial material;
  
  public ItemShield(int par1, EnumNpcToolMaterial material) {
    super(par1);
    this.material = material;
    func_77656_e(material.getMaxUses());
    func_77637_a((CreativeTabs)CustomItems.tabWeapon);
  }
  
  public void renderSpecial() {
    GL11.glScalef(0.6F, 0.6F, 0.6F);
    GL11.glTranslatef(0.0F, 0.0F, -0.2F);
    GL11.glRotatef(-6.0F, 0.0F, 1.0F, 0.0F);
  }
  
  public EnumAction func_77661_b(ItemStack par1ItemStack) {
    return EnumAction.block;
  }
  
  public ItemStack func_77659_a(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {
    par3EntityPlayer.func_71008_a(par1ItemStack, func_77626_a(par1ItemStack));
    return par1ItemStack;
  }
  
  public int func_77626_a(ItemStack par1ItemStack) {
    return 72000;
  }
}
(класс с материалом для щита)
Java:
package noppes.npcs.constants;

public enum EnumNpcToolMaterial {
  WOOD(0, 59, 2.0F, 0, 15),
  STONE(1, 131, 4.0F, 1, 5),
  BRONZE(2, 170, 5.0F, 2, 15),
  IRON(2, 250, 6.0F, 2, 14),
  DIA(3, 1561, 8.0F, 3, 10),
  GOLD(0, 32, 12.0F, 1, 22),
  EMERALD(3, 1000, 8.0F, 4, 10),
  DEMONIC(3, 100, 8.0F, 6, 10),
  FROST(2, 59, 6.0F, 3, 5),
  MITHRIL(3, 3000, 8.0F, 3, 10);
  
  private final int harvestLevel;
  
  private final int maxUses;
  
  private final float efficiencyOnProperMaterial;
  
  private final int damageVsEntity;
  
  private final int enchantability;
  
  EnumNpcToolMaterial(int par3, int par4, float par5, int par6, int par7) {
    this.harvestLevel = par3;
    this.maxUses = par4;
    this.efficiencyOnProperMaterial = par5;
    this.damageVsEntity = par6;
    this.enchantability = par7;
  }
  
  public int getMaxUses() {
    return this.maxUses;
  }
  
  public float getEfficiencyOnProperMaterial() {
    return this.efficiencyOnProperMaterial;
  }
  
  public int getDamageVsEntity() {
    return this.damageVsEntity;
  }
  
  public int getHarvestLevel() {
    return this.harvestLevel;
  }
  
  public int getEnchantability() {
    return this.enchantability;
  }
}
Сам я попытался скопировать код и некоторые другие детали, которые автор мода прописывал конкретно для своих вещей, но у меня ничего не получилось, прошу помощи в написании подобного предмета, спасибо.
 
Решение
Такое условие в эвенте
public ItemStack func_77659_a(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { par3EntityPlayer.setItemInUse(par1ItemStack, func_77626_a(par1ItemStack)); return par1ItemStack; }
Так выглядит метод, который должен отвечать за использование предмета(в том числе за прохождение условия выше)

Короткий ответ: учи джаву
Длинный ответ: Обфу сними с названий и метод переопредели, ты сейчас вообще не должен иметь возможность использовать предмет.
219
12
119
Все что тебе нужно это добавить ивент который будет блокировать твой урон
test:
public class PlayerEvent  {
       @SubscribeEvent
       public void invoke(LivingHurtEvent event) { //вот эта штука блочит урон
          if(event.entityLiving instanceof EntityPlayer) {//проверка на игрока
             EntityPlayer player = (EntityPlayer)event.entityLiving;
             if(!event.source.isUnblockable() && !event.source.isFireDamage()) {// тут можно выставить от какого урона щит не будет защищать
                if(player.isUsingItem()) {
                    
                    Minecraft.getMinecraft().thePlayer.sendChatMessage("isBlocking");
                    if (!event.source.isUnblockable()) {
                   ItemStack item = player.getCurrentEquippedItem();
                   if(item != null && item.getItem() instanceof Shield) { //Предметы которые будут блочить урон, а именно все что унаследуется от предмета Shield
                         float damage = (float)item.getItemDamage() + event.ammount;
                         item.damageItem((int)event.ammount, player);
                         if(damage > (float)item.getMaxItemUseDuration()) {
                            event.ammount = damage - (float)item.getMaxItemUseDuration();
                         } else {
                            event.ammount = 0.0F; //урон который наносится
                            event.setCanceled(true);
                            
                         }

                      }
                   }
                }
                }
             }
          }
       }
 
17
2
0
Давайте ещё раз,
класс Shield
Java:
package ru.was.main;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import ru.was.main.Main;

import org.lwjgl.opengl.GL11;

public class Shield extends Main {
  private static int par1;
public EnumNpcToolMaterial material;
  
  public Shield(EnumNpcToolMaterial material) {
    super(par1);
    this.material = material;
    func_77656_e(material.getMaxUses());
    func_77637_a((CreativeTabs)Main.Wastab);
  }
  
  public void renderSpecial() {
    GL11.glScalef(0.6F, 0.6F, 0.6F);
    GL11.glTranslatef(0.0F, 0.0F, -0.2F);
    GL11.glRotatef(-6.0F, 0.0F, 1.0F, 0.0F);
  }
  
  public EnumAction func_77661_b(ItemStack par1ItemStack) {
    return EnumAction.block;
  }
  
  public ItemStack func_77659_a(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {
    par3EntityPlayer.setItemInUse(par1ItemStack, func_77626_a(par1ItemStack));
    return par1ItemStack;
  }
  
  public int func_77626_a(ItemStack par1ItemStack) {
    return 72000;
  }

public Item setUnlocalizedName(String string) {
    return null;
}
}

Ваш код
Java:
    public class PlayerEvent  {
           @SubscribeEvent
           public void invoke(LivingHurtEvent event) { //вот_эта_штука_блочит_урон
              if(event.entityLiving instanceof EntityPlayer) {//проверка_на_игрока
                 EntityPlayer player = (EntityPlayer)event.entityLiving;
                 if(!event.source.isUnblockable() && !event.source.isFireDamage()) {// тут_можно_выставить_от_какого_урона_щит_не_будет_защищать
                    if(player.isUsingItem()) {
                        
                        Minecraft.getMinecraft().thePlayer.sendChatMessage("isBlocking");
                        if (!event.source.isUnblockable()) {
                       ItemStack item = player.getCurrentEquippedItem();
                       if(item != null && item.getItem() instanceof Shield) { //Предметы_которые_будут_блочить_урон, а именно_все_что_унаследуется_от_предмета Shield
                             float damage = (float)item.getItemDamage() + event.ammount;
                             item.damageItem((int)event.ammount, player);
                             if(damage > (float)item.getMaxItemUseDuration()) {
                                event.ammount = damage - (float)item.getMaxItemUseDuration();
                             } else {
                                event.ammount = 0.0F; //урон_который_наносится
                                event.setCanceled(true);
                                
                             }

                          }
                       }
                    }
                    }
                 }
              }
           }

Краш-лог
 

Вложения

  • crash-2022-04-23_13.45.57-client.txt
    4.6 KB · Просмотры: 2
1,007
36
206
public class Shield extends Main
Вот твоя ошибка, наследоваться надо в твоём случае от класса предмета.
И instanceof не дешёвая операция, для сравнивания в этом случае можно использовать item.getItem() == Shield
 
Последнее редактирование:
17
2
0
Написал всё, что надо, но оно всё ещё не хочет работать(
(ну всмысле ошибок никаких нет, майн запускается, но сам щит это обычный предмет, Item)
Регистрирую предмет в основном классе так
Java:
bossShield11Ardemium = new Shield(10, EnumNpcToolMaterial.DIA).setUnlocalizedName("BossShield11Ardemium").setCreativeTab(Wastab).setTextureName("was:BossShield1.1Ardemium");

GameRegistry.registerItem(bossShield11Ardemium, bossShield11Ardemium.getUnlocalizedName().substring(5));

Ваш код в этом же основном классе
Java:
    public class PlayerEvent  {
           @SubscribeEvent
           public void invoke(LivingHurtEvent event) { //вот_эта_штука_блочит_урон
              if(event.entityLiving instanceof EntityPlayer) {//проверка_на_игрока
                 EntityPlayer player = (EntityPlayer)event.entityLiving;
                 if(!event.source.isUnblockable() && !event.source.isFireDamage()) {// тут_можно_выставить_от_какого_урона_щит_не_будет_защищать
                    if(player.isUsingItem()) {
                        
                        Minecraft.getMinecraft().thePlayer.sendChatMessage("isBlocking");
                        if (!event.source.isUnblockable()) {
                       ItemStack item = player.getCurrentEquippedItem();
                       if(item != null && item.getItem() == bossShield11Ardemium) { //Предметы_которые_будут_блочить_урон, а именно_все_что_унаследуется_от_предмета Shield
                             float damage = (float)item.getItemDamage() + event.ammount;
                             item.damageItem((int)event.ammount, player);
                             if(damage > (float)item.getMaxItemUseDuration()) {
                                event.ammount = damage - (float)item.getMaxItemUseDuration();
                             } else {
                                event.ammount = 0.0F; //урон_который_наносится
                                event.setCanceled(true);
                                
                             }

                          }
                       }
                    }
                    }
                 }
              }
           }
Класс Shield
Java:
package ru.was.main;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import ru.was.main.Main;

import org.lwjgl.opengl.GL11;

public class Shield extends ItemNpcInterface {
public EnumNpcToolMaterial material;
  
  public Shield(int par1, EnumNpcToolMaterial material) {
    super(par1);
    this.material = material;
    setMaxDamage(material.getMaxUses());
  }
  
  public void renderSpecial() {
    GL11.glScalef(0.6F, 0.6F, 0.6F);
    GL11.glTranslatef(0.0F, 0.0F, -0.2F);
    GL11.glRotatef(-6.0F, 0.0F, 1.0F, 0.0F);
  }
  
  public EnumAction func_77661_b(ItemStack par1ItemStack) {
    return EnumAction.block;
  }
  
  public ItemStack func_77659_a(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {
    par3EntityPlayer.setItemInUse(par1ItemStack, func_77626_a(par1ItemStack));
    return par1ItemStack;
  }
  
  public int func_77626_a(ItemStack par1ItemStack) {
    return 72000;
  }
}
Класс ItemNpcInterface
Java:
package ru.was.main;

import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;

public class ItemNpcInterface extends Item implements ItemRenderInterface {
  public ItemNpcInterface(int par1) {
  }
  
public void renderSpecial() {
    GL11.glScalef(0.66F, 0.66F, 0.66F);
    GL11.glTranslatef(0.0F, 0.3F, 0.0F);
  }
  
  public int func_77619_b() {
    return super.getItemEnchantability();
  }
 
  
  public boolean func_77644_a(ItemStack par1ItemStack, EntityLivingBase par2EntityLiving, EntityLivingBase par3EntityLiving) {
    if (par2EntityLiving.getHealth() <= 0.0F)
      return false; 
    par1ItemStack.damageItem(1, par3EntityLiving);
    return true;
  }
  
  public boolean hasItem(EntityPlayer player, Item item) {
    return player.inventory.hasItem(item);
  }
  
  public boolean consumeItem(EntityPlayer player, Item item) {
    return player.inventory.consumeInventoryItem(item);
  }
}
(Класс ItemRenderInterface уж скидывать не буду)
 
1,007
36
206
Такое условие в эвенте
public ItemStack func_77659_a(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { par3EntityPlayer.setItemInUse(par1ItemStack, func_77626_a(par1ItemStack)); return par1ItemStack; }
Так выглядит метод, который должен отвечать за использование предмета(в том числе за прохождение условия выше)

Короткий ответ: учи джаву
Длинный ответ: Обфу сними с названий и метод переопредели, ты сейчас вообще не должен иметь возможность использовать предмет.
 
Сверху