[1.6.4] Деактивировать портал

Статус
В этой теме нельзя размещать новые ответы.
675
2
Доброго времени суток.

Нужно деактивировать портал в эндер мир.
Какой эвент ловить для этого дела?
 
2,955
12
никакой. Только блок портала на свой изменять. Это делать либо ItemTracker'ом, либо просто Block.enderPortal = твойБлок. Но это не очень совместимо будет с другими модами, так что лучше 2 вариантом не пользоваться.
 
675
2
Dragon2488 написал(а):
никакой. Только блок портала на свой изменять. Это делать либо ItemTracker'ом, либо просто Block.enderPortal = твойБлок. Но это не очень совместимо будет с другими модами, так что лучше 2 вариантом не пользоваться.
Портал, как и все блок - final, переназначать их нельзя, а класс ItemTracker в 1.6.4 я найти не смог.
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
Можно достать Field блока порлала рефлекшеном и тем же рефлекшеном изменить в нем значение "финальный" на значение "не финальный".
 
675
2
anti344 написал(а):
Можно достать Field блока порлала рефлекшеном и тем же рефлекшеном изменить в нем значение "финальный" на значение "не финальный".
Могу я получить подсказку? С рефлекшеном понятное дело, раньше не работал.
Код:
...
    private static Block mod;
    
    public static void loadBlocks() {
        
        try {
            Field cPortal = mod.getClass().getDeclaredField("endPortal");
            cPortal.set(new ChangedPortalBlock(119, Material.portal), 0);
        } catch (NoSuchFieldException e) {} catch (SecurityException e) {} catch (IllegalArgumentException e) {} catch (IllegalAccessException e) {} 
...

p.s. выбивает NullPointerException тут: Field cPortal = mod.getClass().getDeclaredField("endPortal")
 
771
5
Есть у меня такой код, вот только пашет он только на 1.7.2.

Код:
public static boolean replaceBlock(Block toReplace, Class<? extends Block> blockClass){
        Field modifiersField=null;
        try{
            modifiersField=Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            
            for(Field field:Blocks.class.getDeclaredFields()){
                if (Block.class.isAssignableFrom(field.getType())){
                    Block block=(Block)field.get(null);
                    if (block==toReplace){
                        String registryName=Block.blockRegistry.getNameForObject(block);
                        int id=Block.getIdFromBlock(block);
                        ItemBlock item=(ItemBlock)Item.getItemFromBlock(block);
                        System.out.println("Replacing block - "+id+"/"+registryName);
                        
                        Block newBlock=blockClass.newInstance();
                        FMLControlledNamespacedRegistry<Block> registry=GameData.blockRegistry;
                        registry.putObject(registryName,newBlock);
                        
                        Field map=RegistryNamespaced.class.getDeclaredFields()[0];
                        map.setAccessible(true);
                        ((ObjectIntIdentityMap)map.get(registry)).func_148746_a(newBlock,id);
                        
                        map=FMLControlledNamespacedRegistry.class.getDeclaredField("namedIds");
                        map.setAccessible(true);
                        ((BiMap)map.get(registry)).put(registryName,id);
                        
                        field.setAccessible(true);
                        int modifiers=modifiersField.getInt(field);
                        modifiers&=~Modifier.FINAL;
                        modifiersField.setInt(field,modifiers);
                        field.set(null,newBlock);
                        
                        Field itemblock=ItemBlock.class.getDeclaredFields()[0];
                        itemblock.setAccessible(true);
                        modifiers=modifiersField.getInt(itemblock);
                        modifiers&=~Modifier.FINAL;
                        modifiersField.setInt(itemblock,modifiers);
                        itemblock.set(item,newBlock);
                        
                        System.out.println("Check field: "+field.get(null).getClass());
                        System.out.println("Check registry: "+Block.blockRegistry.getObjectById(id).getClass());
                        System.out.println("Check item: "+((ItemBlock)Item.getItemFromBlock(newBlock)).field_150939_a.getClass());
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
1. sysout?
2. То бишь ты даешь класс нового блока и создаешь инстанс рефлекшеном, в то время, как можно просто дать ему инстанс и достать из него класс?
 
771
5
Эм, нашел код в интернете, свои правки не вносил, так как пока в замене блоков не нуждаюсь =)
 
675
2
f1rSt1k написал(а):
Есть у меня такой код, вот только пашет он только на 1.7.2.

Код:
public static boolean replaceBlock(Block toReplace, Class<? extends Block> blockClass){
        Field modifiersField=null;
        try{
            modifiersField=Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            
            for(Field field:Blocks.class.getDeclaredFields()){
                if (Block.class.isAssignableFrom(field.getType())){
                    Block block=(Block)field.get(null);
                    if (block==toReplace){
                        String registryName=Block.blockRegistry.getNameForObject(block);
                        int id=Block.getIdFromBlock(block);
                        ItemBlock item=(ItemBlock)Item.getItemFromBlock(block);
                        System.out.println("Replacing block - "+id+"/"+registryName);
                        
                        Block newBlock=blockClass.newInstance();
                        FMLControlledNamespacedRegistry<Block> registry=GameData.blockRegistry;
                        registry.putObject(registryName,newBlock);
                        
                        Field map=RegistryNamespaced.class.getDeclaredFields()[0];
                        map.setAccessible(true);
                        ((ObjectIntIdentityMap)map.get(registry)).func_148746_a(newBlock,id);
                        
                        map=FMLControlledNamespacedRegistry.class.getDeclaredField("namedIds");
                        map.setAccessible(true);
                        ((BiMap)map.get(registry)).put(registryName,id);
                        
                        field.setAccessible(true);
                        int modifiers=modifiersField.getInt(field);
                        modifiers&=~Modifier.FINAL;
                        modifiersField.setInt(field,modifiers);
                        field.set(null,newBlock);
                        
                        Field itemblock=ItemBlock.class.getDeclaredFields()[0];
                        itemblock.setAccessible(true);
                        modifiers=modifiersField.getInt(itemblock);
                        modifiers&=~Modifier.FINAL;
                        modifiersField.setInt(itemblock,modifiers);
                        itemblock.set(item,newBlock);
                        
                        System.out.println("Check field: "+field.get(null).getClass());
                        System.out.println("Check registry: "+Block.blockRegistry.getObjectById(id).getClass());
                        System.out.println("Check item: "+((ItemBlock)Item.getItemFromBlock(newBlock)).field_150939_a.getClass());
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
Как много незнакомых классов...
[merge_posts_bbcode]Добавлено: 08.05.2014 22:09:52[/merge_posts_bbcode]

Все оказалось намного проще :)
Код:
        Block.blocksList[Block.endPortal.blockID] = null;
        ChangedPortalBlock = new ChangedPortalBlock(119, Material.portal);
        GameRegistry.registerBlock(ChangedPortalBlock, "endPortal");
        Block.blocksList[Block.endPortal.blockID] = ChangedPortalBlock;
[merge_posts_bbcode]Добавлено: 08.05.2014 22:26:49[/merge_posts_bbcode]

Другой вопрос:
Есть ли у форжа свой аналог класса I18n, ибо ванильный ищет в стандартный lang-файлах.
[merge_posts_bbcode]Добавлено: 08.05.2014 22:44:15[/merge_posts_bbcode]

И ещё один:
Как мне один раз в 5 секунд отправлять сообщение игроку. Неужто под таймер отдельный поток создавать? Оо
Код:
    @Override
    public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity)
    {
        if (entity.ridingEntity == null && entity.riddenByEntity == null && !world.isRemote)
        {
            if(entity instanceof EntityPlayer) {
                    EntityPlayer player = (EntityPlayer) entity;
                    player.addChatMessage("I18n.getString("message.warning.toend"));
            }
        }
    }
 

necauqua

когда-то был anti344
Администратор
1,216
27
172
if(world.getTotalWorldTime(или как-то так) % 100 == 0)
[merge_posts_bbcode]Добавлено: 08.05.2014 18:00:33[/merge_posts_bbcode]

Ванильный ищет не только в стандартных файлах, он ищет во всех правильным образом размещённых файлах.
 
675
2
anti344 написал(а):
if(world.getTotalWorldTime(или как-то так) % 100 == 0)
[merge_posts_bbcode]Добавлено: 08.05.2014 18:00:33[/merge_posts_bbcode]

Ванильный ищет не только в стандартных файлах, он ищет во всех правильным образом размещённых файлах.
Сделал так, т.к. на один два тика приходится одно время:
Код:
    int lasttime = 1;
    
    @Override
    public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity)
    {
        if (entity.ridingEntity == null && entity.riddenByEntity == null && !world.isRemote)
        {
            if(entity instanceof EntityPlayer) {
                int time = (int) world.getWorldTime() % 100;
                if(world.getWorldTime() % 100 == 0 && time != lasttime) {
                    EntityPlayer player = (EntityPlayer) entity;
                    player.addChatMessage(I18n.getString("message.warning.toend"));
                }
                lasttime = time;
            }
        }
    }

С локализацией мой косяк был, теперь все работает.

Спасибо, можно закрывать.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху