Использование предметов из сторонних модов. Хранение информации об игроке. Работа с сообщениями чата

Версия Minecraft
1.7.10

Sainthozier

Стрелочник
623
11
369
Всем привет.

Заранее извиняюсь, что задаю столь глупые вопросы, на которые уже отвечали миллион раз, но всё же хотелось бы чисто для себя узнать окончательные ответы и больше никогда не гуглить по этой теме.

Итак, меня интересует следующее:
1. Необходимо, например, в ивенте ItemPickupEvent отследить подбор конкретного предмета из стороннего мода и произвести некоторые манипуляции. Что для этого нужно? Нужно ли проверять, а есть ли такой мод(Loader.isModLoaded)? Если да, то это нужно делать на этапе пре-инициализации?
2. Если потребуется реализовать что-то, что является "уникальным" для каждого игрока, т.е. у каждого своё, то где лучше всего хранить данную информацию? Например, уровень кузнечнего дела, который повышается при использовании наковальни.
3. Как правильно отправлять сообщения в чат, чтобы его видели все игроки? И наоборот, чтобы видел только я.
 
Решение
1. Можно по пути - Class.forName("main.item.TestItem");, можно по Loader.isModLoaded(modname) для определения мода (а там в зависимости что есть, толи прямой путь использовать, толи тот-же Class.forName или API мода) и есть аннотация, не помню названия, но он вешается на метод.
- Так-же можно по поиску modId'а и id'а (в String типе) предмета GameRegistry.findItem("modId:itemid")
2. Можно IExtendedEntityProperties (сокращённо IEEP). На форме в разделе Учебник посмотри на тему связанной с маной.
3. Для игрока player.addChatMessage(new ChatComponentText(""));, а для всех нужно вроде через сервер писать (хотя не уверен возможно увидят у кого оп).
---
Использование итемов из других модов
Интеграция с другими модами...

timaxa007

Модератор
5,831
409
672
1. Можно по пути - Class.forName("main.item.TestItem");, можно по Loader.isModLoaded(modname) для определения мода (а там в зависимости что есть, толи прямой путь использовать, толи тот-же Class.forName или API мода) и есть аннотация, не помню названия, но он вешается на метод.
- Так-же можно по поиску modId'а и id'а (в String типе) предмета GameRegistry.findItem("modId:itemid")
2. Можно IExtendedEntityProperties (сокращённо IEEP). На форме в разделе Учебник посмотри на тему связанной с маной.
3. Для игрока player.addChatMessage(new ChatComponentText(""));, а для всех нужно вроде через сервер писать (хотя не уверен возможно увидят у кого оп).
---
Использование итемов из других модов
Интеграция с другими модами [1.7.10]
 
Последнее редактирование:

Sainthozier

Стрелочник
623
11
369
Спасибо за подсказки.
Ещё такой вопросик будет по поводу цвета текстуры айтема. В каком-то моде я видел, как красителями окрашивали текстуру инструментов и оружия. А что, если я захочу применить ту же технологию, но чтобы цвет был зависим от нбт меча, например, то мне как-то программно окрашивать меч или юзать заготовленные текстуры?
 

timaxa007

Модератор
5,831
409
672
Пожалуйста.
Всякие моды могут, наверное это может быть Tinkers Construct. Метод getColorFromItemStack, такое-же метод как и в ванильной броне, а точнее кожаная броня. Если вдруг захочешь красить определённые части инструмента, то используй слои. У getColorFromItemStack это второй аргумент в int типе, а также использовать другие методы, особенно getColorFromItemStack у которого возврат будет true.
А так-же пример попроще посмотри пример у яйца спавна (ItemMonsterPlacer).
 

Sainthozier

Стрелочник
623
11
369
Блин, вот вроде бы всё ясно в теории про IEEP, но всё равно как-то туплю.
Допустим, если нужно будет реализовать простенькие ачивки, вроде "Сломать n блоков", "Убить моба n раз", то в таком случае где хранить промежуточные результаты счётчика? Это тоже IEEP или есть что-нибудь попроще для таких простых целей?
 

timaxa007

Модератор
5,831
409
672
Это тоже IEEP или есть что-нибудь попроще для таких простых целей?
Можно и попроще. Но если ты хочешь ещё и сохранять, то лучше типа через IEEP.
Java:
public class PlayerIEEP implements IExtendedEntityProperties {

    private static final String TAG = "PlayerIEEP";

    public int
    blockBreak = 0,
    blockPlace = 0,
    killZombie = 0,
    killPlayer = 0;

    @Override
    public void init(Entity entity, World world) {

    }

    public static void reg(EntityPlayer entity) {
        entity.registerExtendedProperties(TAG, new PlayerIEEP());
    }

    public static PlayerIEEP get(EntityPlayer entity) {
        return (PlayerIEEP)entity.getExtendedProperties(TAG);
    }

    @Override
    public void saveNBTData(NBTTagCompound nbt) {
        NBTTagCompound nbt_tag = new NBTTagCompound();
        nbt_tag.setInteger("blockBreak", blockBreak);
        nbt_tag.setInteger("blockPlace", blockPlace);
        nbt_tag.setInteger("killZombie", killZombie);
        nbt_tag.setInteger("killPlayer", killPlayer);
        nbt.setTag(TAG, nbt_tag);
    }

    @Override
    public void loadNBTData(NBTTagCompound nbt) {
        if (!nbt.hasKey(TAG)) return;
        NBTTagCompound nbt_tag = (NBTTagCompound)nbt.getTag(TAG);
        if (nbt_tag.hasKey("blockBreak", NBT.TAG_INT))
            blockBreak = nbt_tag.getInteger("blockBreak");
        if (nbt_tag.hasKey("blockPlace", NBT.TAG_INT))
            blockPlace = nbt_tag.getInteger("blockPlace");
        if (nbt_tag.hasKey("killZombie", NBT.TAG_INT))
            killZombie = nbt_tag.getInteger("killZombie");
        if (nbt_tag.hasKey("killPlayer", NBT.TAG_INT))
            killPlayer = nbt_tag.getInteger("killPlayer");
    }

}
Java:
    @SubscribeEvent
    public void addEntityConstructing(EntityEvent.EntityConstructing event) {
        if (event.entity instanceof EntityPlayer) {
            if (PlayerIEEP.get((EntityPlayer)event.entity) == null)
                PlayerIEEP.reg((EntityPlayer)event.entity);
        }
    }

    @SubscribeEvent
    public void placeBlock(BlockEvent.PlaceEvent event) {
        PlayerIEEP.get(event.player).blockPlace += 1;
    }

    @SubscribeEvent
    public void breakBlock(BlockEvent.BreakEvent event) {
        PlayerIEEP.get(event.getPlayer()).blockPlace += 1;
    }

    @SubscribeEvent
    public void death(LivingDeathEvent event) {
        if (event.source instanceof EntityDamageSource) {
            EntityDamageSource edc = (EntityDamageSource)event.source;
            if (edc.getSourceOfDamage() instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer)edc.getSourceOfDamage();
                if (event.entityLiving instanceof EntityPlayer)
                    PlayerIEEP.get(player).killPlayer += 1;
                else if (event.entityLiving instanceof EntityZombie)
                    PlayerIEEP.get(player).killZombie += 1;
            }
        }
    }
Код не проверял.
---
И это ещё не всё. Так как после перезахода, значения сбрасываются на стандартные, (нужно будет отправка пакета с сервера на клиент, когда игрок заходит на сервер). А так-же эвент, который копирует старые значение, если игрок умирал или ходил по мирам. Код ещё нужно будет дописывать, что ты хочешь, я написал лишь пример.
 
Последнее редактирование:

Sainthozier

Стрелочник
623
11
369
По поводу сообщения для всех, заюзал следующее:
FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().sendChatMsg(new ChatComponentText("Test #2"));

Не уверен, что так правильно. Будут у кого ещё предложения? Если что, сообщения отправляются всем игрокам в очень редких случаях, злоупотреблять этим не получится, так, для справки.
 
Сверху