redacted

  • Автор темы Автор темы MrTerf
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

MrTerf

Активный участник
Баллы
66
redacted
 
Последнее редактирование:
В 1.13 BlockData кажется нормально бы работал с таким, но MaterialData не очень в этом
Вариант фикса:
PHP:
public void copyBlock(Block from, Block to) {
    to.setType(from.getType()); //Меняем материал блока
    // Получаем точную копию состояния блока
    BlockState state = from.getState();
    BlockState targetState = to.getState();
    // Применяем данные материала (тип, состояния и т.д.)
    targetState.setData(state.getData());
    // Применяем состояние к блоку
    targetState.update();
}
Да, все таки его в начале надо было дописать, я спешу и уже устал, вообще не думаю 🙂
 
Ещё вопрос. Если использовать Ваши коды, можно получить и текстуру головы? При условии, конечно, если я пойму, что такое data и как его использовать, чтобы копировался зомби - вставлялся зомби.
Текстуру если там скин игрока? Только через NMS.
(Возможно когда-то я напишу API для этого и коммитну в Bukkit, но не сегодня 😎)
 
Короче говоря, ещё не вечер использовать Bukkit.dispatchCommand? Если так, то можно выполнять команды с помощью этого без логирования в консоль?
Ой не не не, лучше уже бери через Skull вручную, но пока подожди, попробуем решить проблему, может завтра на свежий разум будет более понятно.
 
Короче говоря, ещё не вечер использовать Bukkit.dispatchCommand? Если так, то можно выполнять команды с помощью этого без логирования в консоль?
Я проверил как в самой игре работает /clone. Примерно так само как в коде выше. Не пойму почему у тебя не меняет.

Хорошо, подожду) А на скины надеяться стоит, или уже нет?
На какую версию пишешь?
 
Хорошо, подожду) А на скины надеяться стоит, или уже нет?
Ну дак вот порешаем за скины. В любом случае решение будет, на крайняк запилим очень жесткие костыли.
 
Я проверил как в самой игре работает /clone. Примерно так само как в коде выше. Не пойму почему у тебя не меняет.
Я вот только что попробовал последний зафикшеный код, ту же голову дракона копирует в голову скелета.
 
Я вот только что попробовал последний зафикшеный код, ту же голову дракона копирует в голову скелета.
Попробуй вручную setData(byte) делать (хотя этот метод и так делает setData в самом MaterialData, а значит копируется с ним). Могу на 1.13 с BlockData попробовать, работает ли.
 
Этому вопросу это поможет?)
Вот код на копирование блока. Голова зомби, эндер дракона копируется нормально (не превращается в голову скелета). Скины пока что не копирует.
Код:
public void copyBlock(Block from, Block to) {
        to.setType(from.getType());
      
        if(from.getType() == Material.SKULL) {
            Skull skull = (Skull) from.getState();
            Skull toSkull = (Skull) to.getState();
          
            toSkull.setSkullType(skull.getSkullType());
            toSkull.setRotation(skull.getRotation());
            toSkull.update();
        }
      
        BlockState state = from.getState();
        BlockState targetState = to.getState();
      
        targetState.setData(state.getData());
      
        targetState.update();
    }
Вот код с копированием скинов) С рефлексией вы как-нибудь сами там))
Код:
public void copyBlock(Block from, Block to) {
        to.setType(from.getType());
       
        if(from.getType() == Material.SKULL) {
            Skull skull = (Skull) from.getState();
            Skull toSkull = (Skull) to.getState();
           
            toSkull.setSkullType(skull.getSkullType());
       
            toSkull.setRotation(skull.getRotation());
           
            toSkull.update();
           
            final String url = getSkullURL(from, false);
           
            if(url != null) setSkullWithNonPlayerProfile(getSkullURL(from, false), to);

        }
       
        BlockState state = from.getState();
        BlockState targetState = to.getState();
       
        targetState.setData(state.getData());
       
        targetState.update();
    }
   
    public String getSkullURL(Block b, boolean onlyNum){
         
        Skull skull = (Skull) b.getState();
        if(skull.getSkullType() != SkullType.PLAYER) return null;
        TileEntitySkull skullTile = (TileEntitySkull) ((CraftWorld)skull.getWorld()).getHandle().getTileEntity(new BlockPosition(skull.getX(), skull.getY(), skull.getZ()));
        GameProfile profile = skullTile.getGameProfile();
       
        if(profile == null) return null;
       
        Collection<Property> textures = profile.getProperties().get("textures");
       
        if(textures.isEmpty() || textures == null) return null;
       
        String text = "";
     
        for (Property texture : textures) {
            text = texture.getValue();
        }
     
        String decoded = Base64Coder.decodeString(text);
        String url = decoded.replace("{textures:{SKIN:{url:\"", "").replace("\"}}}", "").trim();
        String textureNumber = decoded.replace("{textures:{SKIN:{url:\"", "").replace("\"}}}", "").replace("http://textures.minecraft.net/texture/", "").trim();
     
        return onlyNum ? textureNumber : url;
    }
   
    
    public static GameProfile getNonPlayerProfile(String skinURL) {
        GameProfile newSkinProfile = new GameProfile(UUID.randomUUID(), null);
        newSkinProfile.getProperties().put("textures", new Property("textures", Base64Coder.encodeString("{textures:{SKIN:{url:\"" + skinURL + "\"}}}")));
        return newSkinProfile;
    }
   
    
    public static void setSkullWithNonPlayerProfile(String skinURL, Block skull) {
        if(skull.getType() != Material.SKULL) throw new IllegalArgumentException("Block must be a skull.");
        TileEntitySkull skullTile = (TileEntitySkull)((CraftWorld)skull.getWorld()).getHandle().getTileEntity(new BlockPosition(skull.getX(), skull.getY(), skull.getZ()));
        skullTile.setGameProfile(getNonPlayerProfile(skinURL));
        skull.getState().update();
    }
 
Последнее редактирование:
Этому вопросу это поможет?)

Работает идеально. Дальше только сделать поддержку разных версий остается.
PHP:
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
import net.minecraft.server.v1_12_R1.NBTTagCompound;
import net.minecraft.server.v1_12_R1.TileEntity;

public void copyBlock(Player player, Block from, Block to) {
    to.setType(from.getType());
    BlockState state = from.getState();
    BlockState targetState = to.getState();
    targetState.setData(state.getData());
    targetState.update(true);
    if (from.getType() == Material.SKULL) copySkull(player, from, to);
}

public void copySkull(Player player, Block from, Block to) {
    Location fromLoc = from.getLocation();
    Location toLoc = to.getLocation();
    int fromX = fromLoc.getBlockX();
    int fromY = fromLoc.getBlockY();
    int fromZ = fromLoc.getBlockZ();
    int toX = toLoc.getBlockX();
    int toY = toLoc.getBlockY();
    int toZ = toLoc.getBlockZ();
  
    CraftWorld cw = (CraftWorld) player.getWorld();
    TileEntity fromTileEntity = cw.getTileEntityAt(fromX, fromY, fromZ);
    TileEntity toTileEntity = cw.getTileEntityAt(toX, toY, toZ);
    NBTTagCompound fromNBT = new NBTTagCompound();
    fromTileEntity.save(fromNBT);
  
    NBTTagCompound toNBT = (NBTTagCompound) fromNBT.clone();
    toNBT.setInt("x", toX);
    toNBT.setInt("y", toY);
    toNBT.setInt("z", toZ);
    toTileEntity.load(toNBT);
    toTileEntity.update();
}
Сойдет в принципе для любых TileEntity, не только голов.
 
Работает идеально. Дальше только сделать поддержку разных версий остается.
PHP:
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
import net.minecraft.server.v1_12_R1.NBTTagCompound;
import net.minecraft.server.v1_12_R1.TileEntity;

public void copyBlock(Player player, Block from, Block to) {
    to.setType(from.getType());
    BlockState state = from.getState();
    BlockState targetState = to.getState();
    targetState.setData(state.getData());
    targetState.update(true);
    if (from.getType() == Material.SKULL) copySkull(player, from, to);
}

public void copySkull(Player player, Block from, Block to) {
    Location fromLoc = from.getLocation();
    Location toLoc = to.getLocation();
    int fromX = fromLoc.getBlockX();
    int fromY = fromLoc.getBlockY();
    int fromZ = fromLoc.getBlockZ();
    int toX = toLoc.getBlockX();
    int toY = toLoc.getBlockY();
    int toZ = toLoc.getBlockZ();
 
    CraftWorld cw = (CraftWorld) player.getWorld();
    TileEntity fromTileEntity = cw.getTileEntityAt(fromX, fromY, fromZ);
    TileEntity toTileEntity = cw.getTileEntityAt(toX, toY, toZ);
    NBTTagCompound fromNBT = new NBTTagCompound();
    fromTileEntity.save(fromNBT);
 
    NBTTagCompound toNBT = (NBTTagCompound) fromNBT.clone();
    toNBT.setInt("x", toX);
    toNBT.setInt("y", toY);
    toNBT.setInt("z", toZ);
    toTileEntity.load(toNBT);
    toTileEntity.update();
}
Сойдет в принципе для любых TileEntity, не только голов.
Я тут сидел, гугл весь перерыл, а он тут бац и через 2 метода копирование со скинами сделал.. Но мой способ тож работает хД
 
Пишу на 1.12, так что всё равно спасибо. Код только проверю)
Ну ты можешь себе импорт сделать такой как там есть под твою версию. В эклипсе Ctrl + Shift + O.
А можешь изучить как работать с NMS и рефлекцией, чтобы почти плюнуть на эти версии.

P.S. Зачем 1.12, если она баганная?
 
Ну ты можешь себе импорт сделать такой как там есть под твою версию. В эклипсе Ctrl + Shift + O.
А можешь изучить как работать с NMS и рефлекцией, чтобы почти плюнуть на эти версии.

P.S. Зачем 1.12, если она баганная?
А чем 1.12 баганая?
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх