Всемирные сообщения о получении предмета.

grin362831

Путник
Участник
Сообщения
31
Розыгрыши
0
Репутация
0
Реакции
0
Баллы
14
Хроники
  1. Master Class
Исходники
Присутствуют
Сборка
L2jMobius
Ребята, подскажите пожалуйста где искать спистк итемов при получении которых в инвентарь игрока выводится сообщение по центру экрана о том что такойто персонаж получил такой то итем.
 
Решение
Код:
Compilation diagnostics
-----------------------
    WARNING: Unknown Source, Line -1, Column -1
        code: compiler.warn.option.obsolete.source
        message: source value 8 is obsolete and will be removed in a future release
    WARNING: Unknown Source, Line -1, Column -1
        code: compiler.warn.option.obsolete.target
        message: target value 8 is obsolete and will be removed in a future release
    WARNING: Unknown Source, Line -1, Column -1
        code: compiler.warn.option.obsolete.suppression
        message: To suppress warnings about obsolete options, use -Xlint:-options.
    ERROR: data\scripts\handlers\itemhandlers\ExtractableItems.java, Line 361, Column 63
        code: compiler.err.cant.resolve.location...
Ребята, подскажите пожалуйста где искать спистк итемов при получении которых в инвентарь игрока выводится сообщение по центру экрана о том что такойто персонаж получил такой то итем.
data/limitshop , limishopCraft
в limitshop.xsd есть все атрибуты
XML:
<product id="3707" category="5">
        <ingredient id="94166" enchant="10" count="1" /> <!-- +10 Circlet of Hero (Sealed) -->
        <ingredient id="94166" enchant="10" count="1" /> <!-- +10 Circlet of Hero (Sealed) -->
        <production id="98205" enchant="10" count="1" chance="100" announce="true" /> <!-- +10 Blessed Circlet of Hero -->
    </product>
 
ELSATHESLAYER, Спасибо большое добрый человек!!

data/limitshop , limishopCraft
в limitshop.xsd есть все атрибуты
XML:
<product id="3707" category="5">
        <ingredient id="94166" enchant="10" count="1" /> <!-- +10 Circlet of Hero (Sealed) -->
        <ingredient id="94166" enchant="10" count="1" /> <!-- +10 Circlet of Hero (Sealed) -->
        <production id="98205" enchant="10" count="1" chance="100" announce="true" /> <!-- +10 Blessed Circlet of Hero -->
    </product>
К сожалению это не то. Попробовал прикрутить атрибут к дропу с сундука, ничего не вышло. Мне нужно чтоб когда открываешь лут сундуки и получаешь некоторые итемы сообщение выводилось по центру экрана у всех игроков как при заточке на скрине.
 

Вложения

  • Lineage II 14-06-2025 3_50_06.webp
    Lineage II 14-06-2025 3_50_06.webp
    187,4 КБ · Просмотры: 44
Последнее редактирование модератором:
К сожалению это не то. Попробовал прикрутить атрибут к дропу с сундука, ничего не вышло. Мне нужно чтоб когда открываешь лут сундуки и получаешь некоторые итемы сообщение выводилось по центру экрана у всех игроков как при заточке на скрине.
org\l2jmobius\gameserver\network\serverpackets\autopeel\ExResultItemAutoPeel
 
org\l2jmobius\gameserver\network\serverpackets\autopeel\ExResultItemAutoPeel
Можешь пожалуйста объяснить что и куда нужно добавить чтоб реализовать это? java файл в исходниках я нашел, он ссылается на какой то _itemList. Я так понимаю нужно его ковырять?
 
Тебе надо разбираться с тем где и как вызывается пакет ExItemAnnounce и прикрутить его броадкаст всем игрокам в нужные места в коде.
Но подозреваю что с таким уровнем знаний тебе только один путь, в https://mmo-dev.info/forums/Ищу-исполнителя.56/
 
Оверпостинг
Подозреваю что с таким уровнем знаний тебе только один путь, в https://mmo-dev.info/forums/Ищу-исполнителя.56/
Мне это интересно и я пытаюсь разобраться сам. А уровень знаний у всех когда то был как у меня. Ничего выросли же)?

Тебе надо разбираться с тем где и как вызывается пакет ExItemAnnounce и прикрутить его броадкаст всем игрокам в нужные места в коде.
Но подозреваю что с таким уровнем знаний тебе только один путь, в https://mmo-dev.info/forums/Ищу-исполнителя.56/
Этот функционал уже релизован в сборке, но как я понимаю просто не привязан к id итемов которые нужно анонсить.
 
Последнее редактирование модератором:
В каждой отдельной xml-ки есть "announce", будь-то /stats/items (извлечение) или enchant (там указывается промежуток уровня модификации для анонса) или другие файлы. У анонса рейдов отдельный файлов со список получаемого с них дропа.
Ищите по слову "announce" хоть через тот же notepad++ по всему датапаку.

Извиняюсь, оказывается енчант тут первобытный.

Java:
                    // Announce the success.
                    if ((item.getEnchantLevel() >= (item.isArmor() ? Config.MIN_ARMOR_ENCHANT_ANNOUNCE : Config.MIN_WEAPON_ENCHANT_ANNOUNCE)) //
                        && (item.getEnchantLevel() <= (item.isArmor() ? Config.MAX_ARMOR_ENCHANT_ANNOUNCE : Config.MAX_WEAPON_ENCHANT_ANNOUNCE)))
                    {
                        final SystemMessage sm = new SystemMessage(SystemMessageId.C1_HAS_ENCHANTED_S3_UP_TO_S2);
                        sm.addString(player.getName());
                        sm.addInt(item.getEnchantLevel());
                        sm.addItemName(item);
                        player.broadcastPacket(sm);
                        Broadcast.toAllOnlinePlayers(new ExItemAnnounce(player, item, ExItemAnnounce.ENCHANT));
                        
                        final Skill skill = CommonSkill.FIREWORK.getSkill();
                        if (skill != null)
                        {
                            player.broadcastPacket(new MagicSkillUse(player, player, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay()));
                        }
                    }
 
Последнее редактирование модератором:
  • Мне нравится
Реакции: raz
Оверпостинг
Извиняюсь, оказывается енчант тут первобытный.

Java:
                    // Announce the success.
                    if ((item.getEnchantLevel() >= (item.isArmor() ? Config.MIN_ARMOR_ENCHANT_ANNOUNCE : Config.MIN_WEAPON_ENCHANT_ANNOUNCE)) //
                        && (item.getEnchantLevel() <= (item.isArmor() ? Config.MAX_ARMOR_ENCHANT_ANNOUNCE : Config.MAX_WEAPON_ENCHANT_ANNOUNCE)))
                    {
                        final SystemMessage sm = new SystemMessage(SystemMessageId.C1_HAS_ENCHANTED_S3_UP_TO_S2);
                        sm.addString(player.getName());
                        sm.addInt(item.getEnchantLevel());
                        sm.addItemName(item);
                        player.broadcastPacket(sm);
                        Broadcast.toAllOnlinePlayers(new ExItemAnnounce(player, item, ExItemAnnounce.ENCHANT));
                       
                        final Skill skill = CommonSkill.FIREWORK.getSkill();
                        if (skill != null)
                        {
                            player.broadcastPacket(new MagicSkillUse(player, player, skill.getId(), skill.getLevel(), skill.getHitTime(), skill.getReuseDelay()));
                        }
                    }
Это наверное сборка хроник Master Class? У меня Shinemaker. К сожалению при создании темы засталяет выбирать хроники, и моих там нет. Эти ближе всего. Ну вот даже тут к примеру удачная заточка брони и оружия выведена параметрами в конфиг. Можно же создать условие что если id итема есть в списке (допустим в тот же конфиг вывести айдишники нужных итемов) то анонсировать получение этого предмета.

Или это не так просто?
 
Это наверное сборка хроник Master Class? У меня Shinemaker. К сожалению при создании темы засталяет выбирать хроники, и моих там нет. Эти ближе всего. Ну вот даже тут к примеру удачная заточка брони и оружия выведена параметрами в конфиг. Можно же создать условие что если id итема есть в списке (допустим в тот же конфиг вывести айдишники нужных итемов) то анонсировать получение этого предмета.
анонсировать получение предмета... откуда?
Из заточки? При заточке будет "анонс успешно модификированного предмета" :) Более конкретнее можно?
 
анонсировать получение предмета... откуда?
Из заточки? При заточке будет "анонс успешно модификированного предмета" :) Более конкретнее можно?
При открытии сундуков с рандомным дропом.

При открытии сундуков с рандомным дропом.
Вот так это выглядит на офе. (то что мне нужно)
 

Вложения

  • (276) Lineage 2 ( Main ). Открытие Сундуков Археолога более 10к. шт. - YouTube — Яндекс Брауз...webp
    (276) Lineage 2 ( Main ). Открытие Сундуков Археолога более 10к. шт. - YouTube — Яндекс Брауз...webp
    219,9 КБ · Просмотры: 27
При открытии сундуков с рандомным дропом.

В каждой отдельной xml-ки есть "announce", будь-то /stats/items (извлечение)

прикольно. У мобиуса нет "анонса" для лут-боксов.
Я бы это описал бы "Очаровательно".

Ну в таком случае:
- или хардкодом в ExtractableItems записать ИД предметов, которые нужно будет "анонсить" и отправлять пакет всем, после любого метода "addItem";
- или дописывать всем сундукам announce тег, или создать отдельный файл с анонсами итемами (ака ПТС лайк, где стоит ИДшник и чем меньше он - тем больше нужно итемов единоразово получить чтобы был анонс) - и потом опять же в хендлерах проверять список.

Это уже или самому делать, или как описал Гайка(тсу) - в тему "Ищу исполнителя".
 
прикольно. У мобиуса нет "анонса" для лут-боксов.
Я бы это описал бы "Очаровательно".

Ну в таком случае:
- или хардкодом в ExtractableItems записать ИД предметов, которые нужно будет "анонсить" и отправлять пакет всем, после любого метода "addItem";
- или дописывать всем сундукам announce тег, или создать отдельный файл с анонсами итемами (ака ПТС лайк, где стоит ИДшник и чем меньше он - тем больше нужно итемов единоразово получить чтобы был анонс) - и потом опять же в хендлерах проверять список.

Это уже или самому делать, или как описал Гайка(тсу) - в тему "Ищу исполнителя".
Вот так это должно выглядеть в конечном итоге.
 

Вложения

  • (276) Lineage 2 ( Main ). Открытие Сундуков Археолога более 10к. шт. - YouTube — Яндекс Брауз...webp
    (276) Lineage 2 ( Main ). Открытие Сундуков Археолога более 10к. шт. - YouTube — Яндекс Брауз...webp
    219,9 КБ · Просмотры: 24
Вот так это должно выглядеть в конечном итоге.
я знаю как это должно выглядять.

В последних сборках, с которыми я работал - это есть.

Мобиуса в руках года 2 не держал - так что даже удивлен что он так тормозит.

В любом случае - ответ у Вас есть.
 
я знаю как это должно выглядять.

В последних сборках, с которыми я работал - это есть.

Мобиуса в руках года 2 не держал - так что даже удивлен что он так тормозит.

В любом случае - ответ у Вас есть.
Спасибо большое, может подскажешь к кому можно обратиться по данному вопросу? Или может сам можешь помочь. Не бесплатно конечно.
 
Самый простой способ,удобнее конечно вынести отдельно, announce="false" добавлять не обязательно
Код:
/*
* Copyright (c) 2013 L2jMobius
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package handlers.itemhandlers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.l2jmobius.Config;
import org.l2jmobius.commons.util.Rnd;
import org.l2jmobius.gameserver.data.xml.ItemData;
import org.l2jmobius.gameserver.handler.IItemHandler;
import org.l2jmobius.gameserver.managers.DailyResetManager;
import org.l2jmobius.gameserver.model.ExtractableProduct;
import org.l2jmobius.gameserver.model.actor.Playable;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.actor.request.AutoPeelRequest;
import org.l2jmobius.gameserver.model.item.EtcItem;
import org.l2jmobius.gameserver.model.item.ItemTemplate;
import org.l2jmobius.gameserver.model.item.enums.ItemProcessType;
import org.l2jmobius.gameserver.model.item.enums.SpecialItemType;
import org.l2jmobius.gameserver.model.item.holders.ItemHolder;
import org.l2jmobius.gameserver.model.item.instance.Item;
import org.l2jmobius.gameserver.network.SystemMessageId;
import org.l2jmobius.gameserver.network.serverpackets.ExItemAnnounce;
import org.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo;
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.network.serverpackets.autopeel.ExResultItemAutoPeel;
import org.l2jmobius.gameserver.network.serverpackets.autopeel.ExStopItemAutoPeel;

/**
* Extractable Items handler.
* @author HorridoJoho, Mobius
*/
public class ExtractableItems implements IItemHandler
{
@Override
public boolean useItem(Playable playable, Item item, boolean forceUse)
{
if (!playable.isPlayer())
{
playable.sendPacket(SystemMessageId.YOUR_PET_CANNOT_CARRY_THIS_ITEM);
return false;
}

final Player player = playable.asPlayer();
final EtcItem etcitem = (EtcItem) item.getTemplate();
final List<ExtractableProduct> exitems = etcitem.getExtractableItems();
if (exitems == null)
{
LOGGER.info("No extractable data defined for " + etcitem);
return false;
}

if (!player.isInventoryUnder80(false))
{
player.sendPacket(SystemMessageId.NOT_ENOUGH_SPACE_IN_INVENTORY_UNABLE_TO_PROCESS_THIS_REQUEST_UNTIL_YOUR_INVENTORY_S_WEIGHT_IS_LESS_THAN_80_AND_SLOT_COUNT_IS_LESS_THAN_90_OF_CAPACITY);
return false;
}

// destroy item
if (!DailyResetManager.RESET_ITEMS.contains(item.getId()) && !player.destroyItem(ItemProcessType.FEE, item.getObjectId(), 1, player, true))
{
return false;
}

boolean specialReward = false;
final Map<Item, Long> extractedItems = new HashMap<>();
final List<Item> enchantedItems = new ArrayList<>();
if (etcitem.getExtractableCountMin() > 0)
{
while (extractedItems.size() < etcitem.getExtractableCountMin())
{
for (ExtractableProduct expi : exitems)
{
if ((etcitem.getExtractableCountMax() > 0) && (extractedItems.size() == etcitem.getExtractableCountMax()))
{
break;
}

if (Rnd.get(100000) <= expi.getChance())
{
final long min = (long) (expi.getMin() * Config.RATE_EXTRACTABLE);
final long max = (long) (expi.getMax() * Config.RATE_EXTRACTABLE);
long createItemAmount = (max == min) ? min : (Rnd.get((max - min) + 1) + min);
if (createItemAmount == 0)
{
continue;
}

// Do not extract the same item.
boolean alreadyExtracted = false;
for (Item i : extractedItems.keySet())
{
if (i.getTemplate().getId() == expi.getId())
{
alreadyExtracted = true;
break;
}
}
if (alreadyExtracted && (exitems.size() >= etcitem.getExtractableCountMax()))
{
continue;
}

if (expi.getId() == -1) // Prime points
{
player.setPrimePoints(player.getPrimePoints() + (int) createItemAmount);
player.sendMessage("You have obtained " + (createItemAmount / 100) + " Euro!");
specialReward = true;
continue;
}
else if (expi.getId() == SpecialItemType.PC_CAFE_POINTS.getClientId())
{
final int currentPoints = player.getPcCafePoints();
final int upgradePoints = player.getPcCafePoints() + (int) createItemAmount;
player.setPcCafePoints(upgradePoints);
final SystemMessage message = new SystemMessage(SystemMessageId.YOU_HAVE_RECEIVED_S1_POINT_S_AS_A_DAILY_REWARD_FOR_USING_EVA_S_GRACE).addInt((int) createItemAmount);
player.sendPacket(message);
player.sendPacket(new ExPCCafePointInfo(currentPoints, upgradePoints, 1));
specialReward = true;
continue;
}
else if (expi.getId() == SpecialItemType.HONOR_COINS.getClientId())
{
player.setHonorCoins(player.getHonorCoins() + (int) createItemAmount);
player.sendMessage("You have obtained " + (createItemAmount) + " Honor Coin.");
specialReward = true;
continue;
}

final ItemTemplate template = ItemData.getInstance().getTemplate(expi.getId());
if (template == null)
{
LOGGER.warning("ExtractableItems: Could not find " + item + " product template with id " + expi.getId() + "!");
continue;
}

if (template.isStackable() || (createItemAmount == 1))
{
final Item newItem = player.addItem(ItemProcessType.REWARD, expi.getId(), createItemAmount, player, false);
if (expi.getMaxEnchant() > 0)
{
newItem.setEnchantLevel(Rnd.get(expi.getMinEnchant(), expi.getMaxEnchant()));
enchantedItems.add(newItem);
}
                            // Send item announcement if configured
                            if (expi.isAnnounce())
                            {
                                player.broadcastPacket(new ExItemAnnounce(player, newItem, ExItemAnnounce.CONTAINER, item.getId()));
                            }
addItem(extractedItems, newItem, createItemAmount);
}
else
{
while (createItemAmount > 0)
{
final Item newItem = player.addItem(ItemProcessType.REWARD, expi.getId(), 1, player, false);
if (expi.getMaxEnchant() > 0)
{
newItem.setEnchantLevel(Rnd.get(expi.getMinEnchant(), expi.getMaxEnchant()));
enchantedItems.add(newItem);
}
                                // Send item announcement if configured
                                if (expi.isAnnounce())
                                {
                                    player.broadcastPacket(new ExItemAnnounce(player, newItem, ExItemAnnounce.CONTAINER, item.getId()));
                                }
addItem(extractedItems, newItem, 1);
createItemAmount--;
}
}
}
}
}
}
else
{
for (ExtractableProduct expi : exitems)
{
if ((etcitem.getExtractableCountMax() > 0) && (extractedItems.size() == etcitem.getExtractableCountMax()))
{
break;
}

if (Rnd.get(100000) <= expi.getChance())
{
final long min = (long) (expi.getMin() * Config.RATE_EXTRACTABLE);
final long max = (long) (expi.getMax() * Config.RATE_EXTRACTABLE);
long createItemAmount = (max == min) ? min : (Rnd.get((max - min) + 1) + min);
if (createItemAmount == 0)
{
continue;
}

if (expi.getId() == -1) // Prime points
{
player.setPrimePoints(player.getPrimePoints() + (int) createItemAmount);
player.sendMessage("You have obtained " + (createItemAmount / 100) + " Euro!");
specialReward = true;
continue;
}
else if (expi.getId() == SpecialItemType.PC_CAFE_POINTS.getClientId())
{
final int currentPoints = player.getPcCafePoints();
final int upgradePoints = player.getPcCafePoints() + (int) createItemAmount;
player.setPcCafePoints(upgradePoints);
final SystemMessage message = new SystemMessage(SystemMessageId.YOU_HAVE_RECEIVED_S1_POINT_S_AS_A_DAILY_REWARD_FOR_USING_EVA_S_GRACE).addInt((int) createItemAmount);
player.sendPacket(message);
player.sendPacket(new ExPCCafePointInfo(currentPoints, upgradePoints, 1));
specialReward = true;
continue;
}
else if (expi.getId() == SpecialItemType.HONOR_COINS.getClientId())
{
player.setHonorCoins(player.getHonorCoins() + (int) createItemAmount);
player.sendMessage("You have obtained " + (createItemAmount) + " Honor Coin.");
specialReward = true;
continue;
}

final ItemTemplate template = ItemData.getInstance().getTemplate(expi.getId());
if (template == null)
{
LOGGER.warning("ExtractableItems: Could not find " + item + " product template with id " + expi.getId() + "!");
continue;
}

if (template.isStackable() || (createItemAmount == 1))
{
final Item newItem = player.addItem(ItemProcessType.REWARD, expi.getId(), createItemAmount, player, false);
if (expi.getMaxEnchant() > 0)
{
newItem.setEnchantLevel(Rnd.get(expi.getMinEnchant(), expi.getMaxEnchant()));
enchantedItems.add(newItem);
}
                        // Send item announcement if configured
                        if (expi.isAnnounce())
                        {
                            player.broadcastPacket(new ExItemAnnounce(player, newItem, ExItemAnnounce.CONTAINER, item.getId()));
                        }
addItem(extractedItems, newItem, createItemAmount);
}
else
{
while (createItemAmount > 0)
{
final Item newItem = player.addItem(ItemProcessType.REWARD, expi.getId(), 1, player, false);
if (expi.getMaxEnchant() > 0)
{
newItem.setEnchantLevel(Rnd.get(expi.getMinEnchant(), expi.getMaxEnchant()));
enchantedItems.add(newItem);
}
                            // Send item announcement if configured
                            if (expi.isAnnounce())
                            {
                                player.broadcastPacket(new ExItemAnnounce(player, newItem, ExItemAnnounce.CONTAINER, item.getId()));
                            }
addItem(extractedItems, newItem, 1);
createItemAmount--;
}
}
}
}
}

if (extractedItems.isEmpty() && !specialReward)
{
player.sendPacket(SystemMessageId.FAILED_TO_CHANGE_THE_ITEM);
}
if (!enchantedItems.isEmpty())
{
final InventoryUpdate playerIU = new InventoryUpdate();
for (Item i : enchantedItems)
{
playerIU.addModifiedItem(i);
}
player.sendInventoryUpdate(playerIU);
}

for (Entry<Item, Long> entry : extractedItems.entrySet())
{
sendMessage(player, entry.getKey(), entry.getValue());
}

final AutoPeelRequest request = player.getRequest(AutoPeelRequest.class);
if (request != null)
{
if (request.isProcessing())
{
request.setProcessing(false);
final List<ItemHolder> rewards = new LinkedList<>();
for (Entry<Item, Long> entry : extractedItems.entrySet())
{
rewards.add(new ItemHolder(entry.getKey().getId(), entry.getValue()));
}
player.sendPacket(new ExResultItemAutoPeel(true, request.getTotalPeelCount(), request.getRemainingPeelCount() - 1, rewards));
}
else
{
player.sendPacket(new ExStopItemAutoPeel(false));
}
}
else // Fixes last auto peel not shown. No effect if auto peel window is closed.
{
final List<ItemHolder> rewards = new LinkedList<>();
for (Entry<Item, Long> entry : extractedItems.entrySet())
{
rewards.add(new ItemHolder(entry.getKey().getId(), entry.getValue()));
}
player.sendPacket(new ExResultItemAutoPeel(true, 0, 0, rewards));
}

return true;
}

private void addItem(Map<Item, Long> extractedItems, Item newItem, long count)
{
if (extractedItems.containsKey(newItem))
{
extractedItems.put(newItem, extractedItems.get(newItem) + count);
}
else
{
extractedItems.put(newItem, count);
}
}

private void sendMessage(Player player, Item item, long count)
{
final SystemMessage sm;
if (count > 1)
{
sm = new SystemMessage(SystemMessageId.YOU_HAVE_OBTAINED_S1_X_S2);
sm.addItemName(item);
sm.addLong(count);
}
else if (item.getEnchantLevel() > 0)
{
sm = new SystemMessage(SystemMessageId.YOU_HAVE_OBTAINED_S1_S2);
sm.addInt(item.getEnchantLevel());
sm.addItemName(item);
}
else
{
sm = new SystemMessage(SystemMessageId.YOU_HAVE_OBTAINED_S1);
sm.addItemName(item);
}
player.sendPacket(sm);
}
}
}

Код:
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.model;

/**
* @author JIV
*/
public class ExtractableProduct
{
private final int _id;
private final long _min;
private final long _max;
private final int _chance;
private final int _minEnchant;
private final int _maxEnchant;
    private final boolean _announce;

/**
     * Create Extractable product
@@ -38,13 +39,29 @@
     * @param maxEnchant item max enchant
     */
public ExtractableProduct(int id, long min, long max, double chance, int minEnchant, int maxEnchant)
    {
        this(id, min, max, chance, minEnchant, maxEnchant, false);
    }
    
    /**
     * Create Extractable product
     * @param id create item id
     * @param min item count max
     * @param max item count min
     * @param chance chance for creating
     * @param minEnchant item min enchant
     * @param maxEnchant item max enchant
     * @param announce announce item
     */
    public ExtractableProduct(int id, long min, long max, double chance, int minEnchant, int maxEnchant, boolean announce)
{
_id = id;
_min = min;
_max = max;
_chance = (int) (chance * 1000);
_minEnchant = minEnchant;
_maxEnchant = maxEnchant;
        _announce = announce;
}

public int getId()
@@ -76,4 +93,9 @@
{
return _maxEnchant;
}
    
    public boolean isAnnounce()
    {
        return _announce;
    }
}

Код:
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2jmobius.gameserver.util;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import org.l2jmobius.commons.util.IXmlReader;
import org.l2jmobius.gameserver.model.ExtractableProduct;
import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.conditions.Condition;
import org.l2jmobius.gameserver.model.item.ItemTemplate;
import org.l2jmobius.gameserver.model.item.enums.ItemSkillType;
import org.l2jmobius.gameserver.model.item.holders.ItemSkillHolder;
import org.l2jmobius.gameserver.model.stats.Stat;
import org.l2jmobius.gameserver.model.stats.functions.FuncTemplate;

/**
* @author mkizub, JIV
*/
public class DocumentItem extends DocumentBase implements IXmlReader
{
private static final Logger LOGGER = Logger.getLogger(DocumentItem.class.getName());

private DocumentItemDataHolder _currentItem = null;
private final List<ItemTemplate> _itemsInFile = new ArrayList<>();

private class DocumentItemDataHolder
{
public DocumentItemDataHolder()
{
}

int id;
String type;
StatSet set;
int currentLevel;
ItemTemplate item;
}

public DocumentItem(File file)
{
super(file);
}

@Override
protected StatSet getStatSet()
{
return _currentItem.set;
}

@Override
protected String getTableValue(String name)
{
return _tables.get(name)[_currentItem.currentLevel];
}

@Override
protected String getTableValue(String name, int idx)
{
return _tables.get(name)[idx - 1];
}

@Override
protected void parseDocument(Document document)
{
for (Node n = document.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("item".equalsIgnoreCase(d.getNodeName()))
{
try
{
_currentItem = new DocumentItemDataHolder();
parseItem(d);
_itemsInFile.add(_currentItem.item);
resetTable();
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "Cannot create item " + _currentItem.id, e);
}
}
}
}
}
}

private void parseItem(Node node) throws InvocationTargetException
{
Node n = node;
final int itemId = Integer.parseInt(n.getAttributes().getNamedItem("id").getNodeValue());
final String className = n.getAttributes().getNamedItem("type").getNodeValue();
final String itemName = n.getAttributes().getNamedItem("name").getNodeValue();
final String additionalName = n.getAttributes().getNamedItem("additionalName") != null ? n.getAttributes().getNamedItem("additionalName").getNodeValue() : null;
_currentItem.id = itemId;
_currentItem.type = className;
_currentItem.set = new StatSet();
_currentItem.set.set("item_id", itemId);
_currentItem.set.set("name", itemName);
_currentItem.set.set("additionalName", additionalName);

final Node first = n.getFirstChild();
for (n = first; n != null; n = n.getNextSibling())
{
if ("table".equalsIgnoreCase(n.getNodeName()))
{
if (_currentItem.item != null)
{
throw new IllegalStateException("Item created but table node found! Item " + itemId);
}
parseTable(n);
}
else if ("set".equalsIgnoreCase(n.getNodeName()))
{
if (_currentItem.item != null)
{
throw new IllegalStateException("Item created but set node found! Item " + itemId);
}
parseBeanSet(n, _currentItem.set, 1);
}
else if ("stats".equalsIgnoreCase(n.getNodeName()))
{
makeItem();
for (Node b = n.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("stat".equalsIgnoreCase(b.getNodeName()))
{
final Stat type = Stat.valueOfXml(b.getAttributes().getNamedItem("type").getNodeValue());
final double value = Double.parseDouble(b.getTextContent());
_currentItem.item.addFunctionTemplate(new FuncTemplate(null, null, "add", 0x00, type, value));
}
}
}
else if ("skills".equalsIgnoreCase(n.getNodeName()))
{
makeItem();
for (Node b = n.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("skill".equalsIgnoreCase(b.getNodeName()))
{
final int id = parseInteger(b.getAttributes(), "id");
final int level = parseInteger(b.getAttributes(), "level");
final int subLevel = parseInteger(b.getAttributes(), "subLevel", 0);
final ItemSkillType type = parseEnum(b.getAttributes(), ItemSkillType.class, "type", ItemSkillType.NORMAL);
final int chance = parseInteger(b.getAttributes(), "type_chance", 100);
final int value = parseInteger(b.getAttributes(), "type_value", 0);
final int gearScore = parseInteger(b.getAttributes(), "gearScore", 0);
if (type == ItemSkillType.ON_ENCHANT)
{
final int enchantLimit = _currentItem.item.getEnchantLimit();
if ((enchantLimit > 0) && (value > enchantLimit))
{
LOGGER.warning(getClass().getSimpleName() + ": Item " + itemId + " has ON_ENCHANT value greater than it's enchant limit.");
}
}
_currentItem.item.addSkill(new ItemSkillHolder(id, level, subLevel, type, chance, value, gearScore));

}
}
}
else if ("capsuled_items".equalsIgnoreCase(n.getNodeName()))
{
makeItem();
for (Node b = n.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("item".equals(b.getNodeName()))
{
final int id = parseInteger(b.getAttributes(), "id");
final long min = parseLong(b.getAttributes(), "min");
final long max = parseLong(b.getAttributes(), "max");
final double chance = parseDouble(b.getAttributes(), "chance");
final int minEnchant = parseInteger(b.getAttributes(), "minEnchant", 0);
final int maxEnchant = parseInteger(b.getAttributes(), "maxEnchant", 0);
                        _currentItem.item.addCapsuledItem(new ExtractableProduct(id, min, max, chance, minEnchant, maxEnchant));
                        final boolean announce = parseBoolean(b.getAttributes(), "announce", false);
                        _currentItem.item.addCapsuledItem(new ExtractableProduct(id, min, max, chance, minEnchant, maxEnchant, announce));
}
}
}
else if ("cond".equalsIgnoreCase(n.getNodeName()))
{
makeItem();
final Condition condition = parseCondition(n.getFirstChild(), _currentItem.item);
final Node msg = n.getAttributes().getNamedItem("msg");
final Node msgId = n.getAttributes().getNamedItem("msgId");
if ((condition != null) && (msg != null))
{
condition.setMessage(msg.getNodeValue());
}
else if ((condition != null) && (msgId != null))
{
condition.setMessageId(Integer.decode(getValue(msgId.getNodeValue(), null)));
final Node addName = n.getAttributes().getNamedItem("addName");
if ((addName != null) && (Integer.decode(getValue(msgId.getNodeValue(), null)) > 0))
{
condition.addName();
}
}
_currentItem.item.attachCondition(condition);
}
}
// bah! in this point item doesn't have to be still created
makeItem();
}

private void makeItem() throws InvocationTargetException
{
// If item exists just reload the data.
if (_currentItem.item != null)
{
_currentItem.item.set(_currentItem.set);
return;
}

try
{
final Constructor<?> itemClass = Class.forName("org.l2jmobius.gameserver.model.item." + _currentItem.type).getConstructor(StatSet.class);
_currentItem.item = (ItemTemplate) itemClass.newInstance(_currentItem.set);
}
catch (Exception e)
{
throw new InvocationTargetException(e);
}
}

public List<ItemTemplate> getItemList()
{
return _itemsInFile;
}

@Override
public void load()
{
}

@Override
public void parseDocument(Document document, File file)
{
}
}
}

Код:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="list">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="item">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:choice maxOccurs="unbounded">
                                <xs:element maxOccurs="unbounded" name="set">
                                    <xs:complexType>
                                        <xs:attribute name="name" type="xs:string" use="required" />
                                        <xs:attribute name="val" type="xs:string" use="required" />
                                    </xs:complexType>
                                </xs:element>
                                <xs:element name="skills">
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:element maxOccurs="unbounded" name="skill">
                                                <xs:complexType>
                                                    <xs:attribute name="id" type="xs:int" use="required" />
                                                    <xs:attribute name="level" type="xs:unsignedByte" use="required" />
                                                    <xs:attribute name="subLevel" type="xs:unsignedShort" use="optional" />
                                                    <xs:attribute name="type" type="xs:string" use="optional" />
                                                    <xs:attribute name="type_value" type="xs:unsignedByte" use="optional" />
                                                    <xs:attribute name="type_chance" type="xs:unsignedByte" use="optional" />
                                                    <xs:attribute name="gearScore" type="xs:int" use="optional" />
                                                </xs:complexType>
                                            </xs:element>
                                        </xs:sequence>
                                    </xs:complexType>
                                </xs:element>
                                <xs:element name="stats">
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:element maxOccurs="unbounded" name="stat">
                                                <xs:complexType>
                                                    <xs:simpleContent>
                                                        <xs:extension base="xs:decimal">
                                                            <xs:attribute name="type" type="xs:string" use="required" />
                                                        </xs:extension>
                                                    </xs:simpleContent>
                                                </xs:complexType>
                                            </xs:element>
                                        </xs:sequence>
                                    </xs:complexType>
                                </xs:element>
                                <xs:element name="cond">
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:element minOccurs="0" name="target">
                                                <xs:complexType>
                                                    <xs:attribute name="levelRange" type="xs:string" use="required" />
                                                </xs:complexType>
                                            </xs:element>
                                            <xs:element minOccurs="0" name="and">
                                                <xs:complexType>
                                                    <xs:sequence>
                                                        <xs:element maxOccurs="unbounded" name="player">
                                                            <xs:complexType>
                                                                <xs:attribute name="castle" type="xs:byte" use="optional" />
                                                                <xs:attribute name="pledgeClass" type="xs:byte" use="optional" />
                                                                <xs:attribute name="sex" type="xs:unsignedByte" use="optional" />
                                                                <xs:attribute name="class_id_restriction" type="xs:string" use="optional" />
                                                            </xs:complexType>
                                                        </xs:element>
                                                    </xs:sequence>
                                                </xs:complexType>
                                            </xs:element>
                                            <xs:element minOccurs="0" name="player">
                                                <xs:complexType>
                                                    <xs:attribute name="flyMounted" type="xs:boolean" use="optional" />
                                                    <xs:attribute name="isHero" type="xs:boolean" use="optional" />
                                                    <xs:attribute name="sex" type="xs:unsignedByte" use="optional" />
                                                    <xs:attribute name="level" type="xs:unsignedByte" use="optional" />
                                                    <xs:attribute name="chaotic" type="xs:boolean" use="optional" />
                                                    <xs:attribute name="levelRange" type="xs:string" use="optional" />
                                                    <xs:attribute name="insideZoneId" type="xs:string" use="optional" />
                                                    <xs:attribute name="class_id_restriction" type="xs:string" use="optional" />
                                                    <xs:attribute name="categoryType" type="xs:string" use="optional" />
                                                </xs:complexType>
                                            </xs:element>
                                            <xs:element minOccurs="0" name="not">
                                                <xs:complexType>
                                                    <xs:sequence>
                                                        <xs:element maxOccurs="unbounded" name="player">
                                                            <xs:complexType>
                                                                <xs:attribute name="active_effect_id" type="xs:unsignedShort" use="optional" />
                                                            </xs:complexType>
                                                        </xs:element>
                                                    </xs:sequence>
                                                </xs:complexType>
                                            </xs:element>
                                        </xs:sequence>
                                        <xs:attribute name="addName" type="xs:unsignedByte" use="optional" />
                                        <xs:attribute name="msgId" type="xs:unsignedShort" use="optional" />
                                    </xs:complexType>
                                </xs:element>
                                <xs:element name="capsuled_items">
                                    <xs:complexType mixed="true">
                                        <xs:sequence>
                                            <xs:element maxOccurs="unbounded" name="item">
                                                <xs:complexType>
                                                    <xs:attribute name="id" type="xs:integer" use="required" />
                                                    <xs:attribute name="min" type="xs:unsignedLong" use="required" />
                                                    <xs:attribute name="max" type="xs:unsignedLong" use="required" />
                                                    <xs:attribute name="chance" type="xs:decimal" use="required" />
                                                    <xs:attribute name="minEnchant" type="xs:unsignedByte" use="optional" />
                                                    <xs:attribute name="maxEnchant" type="xs:unsignedByte" use="optional" />
                                                    <xs:attribute name="announce" type="xs:boolean" use="optional" />
                                                </xs:complexType>
                                            </xs:element>
                                        </xs:sequence>
                                    </xs:complexType>
                                </xs:element>
                            </xs:choice>
                        </xs:sequence>
                        <xs:attribute name="id" type="xs:unsignedInt" use="required" />
                        <xs:attribute name="name" type="xs:string" use="required" />
                        <xs:attribute name="type" type="xs:string" use="required" />
                        <xs:attribute name="additionalName" type="xs:string" use="optional" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

XML:
<item id="96821" name="Kit: Pack of Seals (Time-limited)" additionalName="Sealed" type="EtcItem">
        <!-- Double-click to obtain the following. -->
        <set name="icon" val="icon.present_of_destination_event" />
        <set name="default_action" val="PEEL" />
        <set name="immediate_effect" val="true" />
        <set name="material" val="FISH" />
        <set name="is_tradable" val="false" />
        <set name="is_dropable" val="false" />
        <set name="is_sellable" val="false" />
        <set name="is_stackable" val="true" />
        <set name="handler" val="ExtractableItems" />
        <set name="extractableCountMin" val="1" />
        <set name="extractableCountMax" val="1" />
        <capsuled_items>
            <item id="96820" min="100" max="100" chance="47.5" announce="true"/> <!-- Pack of Seals (Time-limited) - Sealed -->
            <item id="96729" min="100" max="100" chance="47.5" announce="true"/> <!-- Einhasad's Protection - Sealed -->
            <item id="92314" min="1" max="1" chance="2.040816" announce="false"/> <!-- Giran Seal -->
        </capsuled_items>
    </item>
 
в extractableItems: player.broadcastPacket(new ExItemAnnounce(player, newItem, ExItemAnnounce.CONTAINER, item.getId()));
замени на ExItemAnnounce.LOOT_BOX
Diff:
--- a/java/org/l2jmobius/gameserver/network/serverpackets/ExItemAnnounce.java
+++ b/java/org/l2jmobius/gameserver/network/serverpackets/ExItemAnnounce.java
@@ -42,12 +42,23 @@ public class ExItemAnnounce extends ServerPacket
     private final Item _item;
     private final int _type;
     private final String _announceName;
+    private final int _sourceId;
 
     public ExItemAnnounce(Player player, Item item, int type)
     {
+        this(player, item, type, 0);
+    }
+   
+    public ExItemAnnounce(Player player, Item item, int type, int sourceId)
+    {
         _item = item;
         _type = type;
+        _sourceId = sourceId;
         if (player.getClientSettings().isAnnounceEnabled())
         {
             _announceName = player.getName();
@@ -82,6 +93,6 @@ public class ExItemAnnounce extends ServerPacket
         buffer.writeSizedString(_announceName); // name of player
         buffer.writeInt(_item.getId()); // item id
         buffer.writeByte(_item.getEnchantLevel()); // enchant level
-        buffer.writeInt(0); // chest item id
+        buffer.writeInt(_sourceId); // chest item id
     }
 }

--- a/java/org/l2jmobius/gameserver/network/serverpackets/ExItemAnnounce.java
+++ b/java/org/l2jmobius/gameserver/network/serverpackets/ExItemAnnounce.java
@@ -42,12 +42,23 @@ public class ExItemAnnounce extends ServerPacket
     private final Item _item;
     private final int _type;
     private final String _announceName;
+    private final int _sourceId;
 
     public ExItemAnnounce(Player player, Item item, int type)
     {
+        this(player, item, type, 0);
+    }
+   
+    public ExItemAnnounce(Player player, Item item, int type, int sourceId)
+    {
         _item = item;
         _type = type;
+        _sourceId = sourceId;
         if (player.getClientSettings().isAnnounceEnabled())
         {
             _announceName = player.getName();
@@ -82,6 +93,6 @@ public class ExItemAnnounce extends ServerPacket
         buffer.writeSizedString(_announceName); // name of player
         buffer.writeInt(_item.getId()); // item id
         buffer.writeByte(_item.getEnchantLevel()); // enchant level
-        buffer.writeInt(0); // chest item id
+        buffer.writeInt(_sourceId); // chest item id
     }
 }
 
ELSATHESLAYER, Не не компилится выдает кучу ошибок.

ELSATHESLAYER, С тобой можно как то связаться для помощи?
 
Последнее редактирование модератором:
Назад
Сверху