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

grin362831

Путник
Участник
Сообщения
31
Розыгрыши
0
Репутация
0
Реакции
0
Баллы
14
Хроники
  1. Master Class
Исходники
Присутствуют
Сборка
L2jMobius
Ребята, подскажите пожалуйста где искать спистк итемов при получении которых в инвентарь игрока выводится сообщение по центру экрана о том что такойто персонаж получил такой то итем.
 
Решение
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, Спасибо большое добрый человек!!

К сожалению это не то. Попробовал прикрутить атрибут к дропу с сундука, ничего не вышло. Мне нужно чтоб когда открываешь лут сундуки и получаешь некоторые итемы сообщение выводилось по центру экрана у всех игроков как при заточке на скрине.
 

Вложения

  • 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/
 
Оверпостинг
Мне это интересно и я пытаюсь разобраться сам. А уровень знаний у всех когда то был как у меня. Ничего выросли же)?

Этот функционал уже релизован в сборке, но как я понимаю просто не привязан к 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
Оверпостинг
Это наверное сборка хроник Master Class? У меня Shinemaker. К сожалению при создании темы засталяет выбирать хроники, и моих там нет. Эти ближе всего. Ну вот даже тут к примеру удачная заточка брони и оружия выведена параметрами в конфиг. Можно же создать условие что если id итема есть в списке (допустим в тот же конфиг вывести айдишники нужных итемов) то анонсировать получение этого предмета.

Или это не так просто?
 
анонсировать получение предмета... откуда?
Из заточки? При заточке будет "анонс успешно модификированного предмета" Более конкретнее можно?
 
При открытии сундуков с рандомным дропом.

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

Вложения

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

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

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

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

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

Вложения

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

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

Мобиуса в руках года 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, С тобой можно как то связаться для помощи?
 
Последнее редактирование модератором:
Данный сайт использует cookie. Вы должны принять их для продолжения использования. Узнать больше…