Несколько не рядовых вопросов.

Всем привет, возникла потребность сделать >ехидную систему открывания дверей. В общем, нужны подсказки, пинки и толкования. Ряд вопросов таков:
1. Как создать новую дверь, которую игрок установивший ее может открыть в любое время суток, а другие не могли бы открыть ее днем, а открыть другие игроки могли бы ее только ночью.
2. Как создать специальный ключ, логика которого такова: игрок берет его в руки, нажимает шифт+пкм по этой новой двери, далее для этой двери и этого предмета задается случайный ключ который пишется в NBT двери и этого ключа, и без этого ключа дверь нельзя было бы открыть никак.
3. Против лома нет приема. Создать такой предмет, который бы по ПКМ на такую дверь открывал бы ее, будь она под ключом или без залочки. Если есть идейные кодеры - прошу в ЛС, пилится прожект, но не очередной стулкир, нужна помощь в реализации этой дряни. Прошу максимально помочь в толковании и остальном, т.к. все что здесь описано - для меня нереализуемо за недостатком знаний.
 
Как не странно, это можно сделать в условиях самой двери (Блока) в методе "onBlockActivated". Условия и их действия. Ну так понимаю, тебе лучше это показать кодом? Если да, то напиши об этом. Там ни чего сложного нет, просто знать надо как (у меня нету кода для примера, но думаю скоро появиться, но покажу только один метод, так остальные методы не нужны для показа).
 
1.Записать в нбт игрока. В клике чекать
2.UUID + getCommandSenderName(). ТУт надо подумать.Например получать по игроку UUID,но если 2 дверии
3.Создать метод в дери или где нибудь,который сломает
Тут надо подумать
 
Код:
CoordinatesThird {
    public int x, y, z;
    
    public CoordinatesThird(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //@Override the hashCode            !!!!!
    //@Override the equals(Obj)        !!!!!
}


Код:
TickHandler implements ITickHandler {

   public static WorldAdditionalData worldData = null;
   
   @Override
   public void tickStart(EnumSet<TickType> type, Object... tickData) {
      if(type.equals(EnumSet.of(TickType.WORLDLOAD))){
         World world = null;
         for (int i = 0; i < tickData.length; i++)
            if (tickData instanceof World)
               world = (World)tickData;

         if(world == null)
            return;
        
         worldData = WorldAdditionalData.forWorld(world);
         worldData.markDirty();
      }
   }

   @Override
   public void tickEnd(EnumSet<TickType> type, Object... tickData) {}

   @Override
   public EnumSet<TickType> ticks() {
      return EnumSet.of(TickType.WORLDLOAD);
   }

   @Override
   public String getLabel() {
      return "kd_Ticker";
   }
}


Код:
WorldAdditionalData extends WorldSavedData {

   final static String key = "WorldAdditionalData";
   public HashMap<CoordinatesThird, String> mapDayDoors = new HashMap<CoordinatesThird, String>();
   public HashMap<CoordinatesThird, Integer> mapKeyDoors = new HashMap<CoordinatesThird, Integer>();
   
   public static WorldAdditionalData forWorld(World world) {
      MapStorage storage = world.perWorldStorage;

      WorldAdditionalData result = (WorldAdditionalData)storage.loadData(WorldAdditionalData.class, key);
      if (result == null) {
         result = new WorldAdditionalData();
         storage.setData(key, result);
      }
      return result;
   }
   
   public WorldAdditionalData() {
      super(key);
   }
   
   public WorldAdditionalData(String key){
      super(key);
   }

   @Override
   public void readFromNBT(NBTTagCompound nbttagcompound) {
      //load ur data
   }

   @Override
   public void writeToNBT(NBTTagCompound nbttagcompound) {
      //save ur data
   }

}


Код:
BlockSpecialKeyDoor extends BlockDoor {
    
    @Override
    public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) {
    //if (!par1World.isRemote) {
        WorldAdditionalData data = WorldAdditionalData.forWorld(par1World);
        ItemStack item = par5EntityPlayer.equippedItem;

        if (data != null) {
            if (item != null && item.getItem() instanceof ItemKey) {
                CoordinatesThird coords = new CoordinatesThird(par2, par3, par4);

                if (par5EntityPlayer.isSneaking) {
                    if (!item.hashTagCompound()) {
                        NBTTagCompound nbt = new NBTTagCompound();
                        nbt.setInteger("keyID", coords.hashCode());
                        item.stackTagCompound = nbt;
                        data.mapKeyDoors.put(coords, coords.hashCode());
                        //door registered!
                    } else
                        //door already had been registered!!
                }
                else {
                    if (data.mapKeyDoors.keySet().contains(coords)) {
                        int keyID = data.mapKeyDoors.get(coords);
                        if (item.hashTagCompound()) {
                            if (item.stackTagCompound.getInteger("keyID") == keyID)
                                return super.onBlockActivated(par1World, par2,
                            
                            par3, par4, par5EntityPlayer, par6, par7, par8, par9);
                        }
                        else
                            //unregistered key!!!
                    }
                }
            }
        }
    //}

    return false;
    }
}


Код:
BlockSpecialDayDoor extends BlockDoor {

    @Override
    public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack) {
        if (!par5EntityLivingBase instanceof EntityPlayer)
            return;

        EntityPlayer player = (EntityPlayer)par5EntityLivingBase;
        //if (!par1World.isRemote) {
            WorldAdditionalData data = WorldAdditionalData.forWorld(par1World);

            if (data != null) 
                data.mapDayDoors.put(new CoordinatesThird(par2, par3, par4), player.username);
            
        //}
    }


    @Override
    public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) {
    //if (!par1World.isRemote) {
        WorldAdditionalData data = WorldAdditionalData.forWorld(par1World);

        if (data != null) {
            String username = data.mapDayDoors.get(new CoordinatesThird(par2, par3, par4));
            if (username != null && username.equals(par5EntityLivingBase.username) || par1World.isNight())
                return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9);
        }
    //}

    return false;
    }
}

От нечего делать накидал все нужные классы по 1 и 2 пункту. Держи короче.
 
Большое спасибо, буду разбираться, тема еще актуальна, не закрывать.

edit (Oldestkon): не надо цитировать такие большие ответы, тем более что между ним и твоим нет других
[merge_posts_bbcode]Добавлено: 24.11.2014 01:47:26[/merge_posts_bbcode]

timaxa007 написал(а):
Как не странно, это можно сделать в условиях самой двери (Блока) в методе "onBlockActivated". Условия и их действия. Ну так понимаю, тебе лучше это показать кодом? Если да, то напиши об этом. Там ни чего сложного нет, просто знать надо как (у меня нету кода для примера, но думаю скоро появиться, но покажу только один метод, так остальные методы не нужны для показа).
Было бы не плохо.

[merge_posts_bbcode]Добавлено: 24.11.2014 01:47:34[/merge_posts_bbcode]

timaxa007 написал(а):
Как не странно, это можно сделать в условиях самой двери (Блока) в методе "onBlockActivated". Условия и их действия. Ну так понимаю, тебе лучше это показать кодом? Если да, то напиши об этом. Там ни чего сложного нет, просто знать надо как (у меня нету кода для примера, но думаю скоро появиться, но покажу только один метод, так остальные методы не нужны для показа).
Было бы не плохо.
 
Я чуть обновил свой пост, исправил пару ошибок.
Ну и да, я тоже как раз использую onBlockActivated.
По сути в моем сообщении почти весь код на ключи и "дневные" двери - тебе надо только правильно переопределить класс BlockDoor, да добавить сохранение\загрузку всех данных о дверях в NBT мира, это где комментарии save\load ur data.

А, ещё и методы указанные в комментариях в первом классе переопределить, чтобы весь остальной код не был бесполезен.
 
minecraftsrv, у Oldestkon лучше вариант, у меня не очень (и ещё не готов).
 
minecraftsrv написал(а):
Можешь набросать свой вариант?
Во-общем не хотел я дальше делать, так как реализация самой двери у нас будет разной, так что набросок получился таков:
Код:
@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entity, ItemStack is) {
TileEntity te = world.getBlockTileEntity(x, y, z);
NBTTagCompound tag = is.getTagCompound();
if (te != null && te instanceof TECnstorDoors && tag != null) {
if (tag.hasKey("SubID")) {((TECnstorDoors)te).setSubID((int)tag.getByte("SubID"));}
if (tag.hasKey("ColorBlock")) {((TECnstorDoors)te).setColorBlock(tag.getInteger("ColorBlock"));}
if (entity instanceof EntityPlayer) {((TECnstorDoors)te).setOwner(((EntityPlayer)entity).username);}
}
}

@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
int ib = 0;//Сделал два варианта условий, но не метода
TileEntity te = world.getBlockTileEntity(x, y, z);
if (te == null || player.isSneaking()) {return false;}//Если Блок не имеет TileEntity или наш игрок идёт ползком (который вызывается по-умолчанию по shift'у [мой блок таков])

if (te != null && te instanceof TECnstorDoors) {//Если TileEntity не равен нулю и имеет наш класс TECnstorDoors, то...
ItemStack current = player.getCurrentEquippedItem();//Это то что находить или не находиться в руке игрока

if (ib == 0) {//Первый вариант

if (current != null && current.getItem() == PackFurniture.proxy.items_for_furniture) {//Если рука не пуста и имеет в руке наш предмет, то...
NBTTagCompound tag = current.getTagCompound();
if (tag != null && tag.hasKey("CordX") && tag.hasKey("CordY") && tag.hasKey("CordZ")) {//Если тег нашего предмета не пуст и имеет нужные теги, то...
if (tag.getInteger("CordX") == x && tag.getInteger("CordY") == y && tag.getInteger("CordZ") == z) {//При условии, что значения тегов из предмета ровна координатам нашего блока, то...
((TECnstorDoors)te).openDoor(true);//Дверь откроеться...
} else {
if (world.isRemote) {player.addChatMessage("This key does not fit into this door.");}//Если координаты нашего условия не совпали, то пишет в чат игрока, то что ключ не подходит.
return false;
}
} else {//Если наш предмет не имеет нужных тегов, то мы их задаём...
if (tag == null) {tag = new NBTTagCompound();}//Если ранее у него не было тагов, то ему задаём новые...
tag.setInteger("CordX", x);//Сохраняет в теге "CordX" значение "x"
tag.setInteger("CordY", y);//Сохраняет в теге "CordY" значение "y"
tag.setInteger("CordZ", z);//Сохраняет в теге "CordZ" значение "z"
current.setTagCompound(tag);//И сохраняем эти значение...
//Хотя лучше, чтобы он создавал новый предмет с тегами и удалял предмет без тего, это лучше если этот предмет стакаеться.
}
}

}//

if (ib == 1) {//Второй вариант...

if (world.provider.isDaytime()) {//Если в мире день, то...
if (player.username.equals(((TECnstorDoors)te).getOwner())) {//Если игрок является овнером этого блока, то...
((TECnstorDoors)te).openDoor(true);//Дверь откроется...
} else {
return false;//Если не овнер, не откроется...
}
} else {
((TECnstorDoors)te).openDoor(true);//Если ночь, то всем будет открываться...
}

}//

//Место топора можно, что-то другое, просто не стал сейчас создавать новый инструмент.
if (current != null && current.getItem() == Item.axeIron) {//Если рука не пуста и имеет железный топор, то...
current.setItemDamage(current.getItemDamage() + 1);//Предмет повреждаеться,
((TECnstorDoors)te).breakDoor(true);//Дверь ломается,
}

return true;
}

return false;
}

@SideOnly(Side.CLIENT)
public void getSubBlocks(int id, CreativeTabs table, List list) {
list.add(addTag(id, 0, 0xFFFFFF));
}

private static ItemStack addTag(int par1, int par2, int par3) {
ItemStack is = new ItemStack(par1, 1, 0);
NBTTagCompound tag = new NBTTagCompound();
tag.setByte("SubID", (byte)par2);
tag.setInteger("ColorBlock", par3);
is.setTagCompound(tag);
return is;
}
[merge_posts_bbcode]Добавлено: 26.11.2014 05:17:07[/merge_posts_bbcode]

В случаи тебе нужно не только железный топор, а все связанные топоры, то вроде как надо писать место этого:
Код:
current.getItem() == Item.axeIron
на это:
Код:
current.getItem() instanceof ItemAxe
 
Назад
Сверху