markblack 1 Опубликовано 11 мая, 2015 (изменено) Не работают CapsuledItem. Сделал классы в ItemTemplate. Добавил в парсер. Ошибки не вылетают, но и итемы не отрываются, прошу помощи ItemTemplate.java private final List _capsuledItems = new ArrayList<>();public List getCapsuledItems(){return this._capsuledItems;}public void addCapsuledItem(CapsuledItem ci){this._capsuledItems.add(ci);}public static class CapsuledItem{private final int item_id;private final int min_count;private final int max_count;private final double chance;public CapsuledItem(int item_id, int min_count, int max_count, double chance){this.item_id = item_id;this.min_count = min_count;this.max_count = max_count;this.chance = chance;}public int getItemId(){return this.item_id;}public int getMinCount(){return this.min_count;}public int getMaxCount(){return this.max_count;}public double getChance(){return this.chance;}} ItemParser.java else if (subName.equalsIgnoreCase("capsuled_items")){for (Iterator nextIterator = subElement.elementIterator(); nextIterator.hasNext() {Element nextElement = nextIterator.next();if (nextElement.getName().equalsIgnoreCase("capsuled_item")){int c_item_id = Integer.parseInt(nextElement.attributeValue("id"));int c_min_count = Integer.parseInt(nextElement.attributeValue("min_count"));int c_max_count = Integer.parseInt(nextElement.attributeValue("max_count"));double c_chance = Double.parseDouble(nextElement.attributeValue("chance"));template.addCapsuledItem(new ItemTemplate.CapsuledItem(c_item_id, c_min_count, c_max_count, c_chance));}}} Изменено 11 мая, 2015 пользователем markblack Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 ERROR parser.ItemParser: ItemParser: File: 17000-17099.xml:484 error: Element type "capsuled_items" must be declared. ERROR parser.ItemParser: ItemParser: File: 17000-17099.xml:485 error: Element type "capsuled_item" must be declared. ERROR parser.ItemParser: ItemParser: File: 17000-17099.xml:487 error: The content of element type "etcitem" must match "(set|equip|for|enchant4_skill|cond|skills|triggers|enchant_options)*". Получил данные ошибки, кто подскажет где копать? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 11 мая, 2015 Видимо твой xml документ (17000-17099.xml) содержит DTD, объяви свои элементы capsuled_items, capsuled_item по аналогии, в самом начале файла в !DOCTYPE Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 Видимо твой xml документ (17000-17099.xml) содержит DTD, объяви свои элементы capsuled_items, capsuled_item по аналогии, в самом начале файла в !DOCTYPE Объявил, ошибки ушли, а итемы так и не открываются Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 11 мая, 2015 Ок, данные успешно считываются, но дальше? Должна быть реализация хендлера (ItemHandler), который отвечает за использование предмета, если он есть то ошибка там, а если нет, то написать его по примеру имеющихся хендлеров не сложно, если я правильно понимаю что такое "capsuled items" Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 Он есть, по сравнению со сборками где это реализовано отличий нету Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 11 мая, 2015 Кинь сюда листинг, могу глянуть, если 100% уверенность, что отличий нет, может хендлер не регистрируется? или список ИД капсульных предметов в нем не полный? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 (изменено) ItemHandler.java package org.mmocore.gameserver.handler.items; import org.mmocore.commons.data.xml.AbstractHolder; import org.mmocore.gameserver.data.xml.holder.ItemHolder; import org.mmocore.gameserver.templates.item.ItemTemplate; public class ItemHandler extends AbstractHolder { private static final ItemHandler _instance = new ItemHandler(); public static ItemHandler getInstance() { return _instance; } private ItemHandler() { // } public void registerItemHandler(IItemHandler handler) { int[] ids = handler.getItemIds(); for(int itemId : ids) { ItemTemplate template = ItemHolder.getInstance().getTemplate(itemId); if(template == null) warn("Item not found: " + itemId + " handler: " + handler.getClass().getSimpleName()); else if(template.getHandler() != IItemHandler.DEFAULT) warn("Duplicate handler for item: " + itemId + "(" + template.getHandler().getClass().getSimpleName() + "," + handler.getClass().getSimpleName() + ")"); else template.setHandler(handler); } } @Override public int size() { return 0; } @Override public void clear() { } } ItemTemplate.java package org.mmocore.gameserver.templates.item; import java.util.ArrayList; import java.util.List; import org.mmocore.commons.lang.ArrayUtils; import org.mmocore.commons.time.cron.SchedulingPattern; import org.mmocore.gameserver.handler.items.IItemHandler; import org.mmocore.gameserver.instancemanager.CursedWeaponsManager; import org.mmocore.gameserver.model.Playable; import org.mmocore.gameserver.model.base.Element; import org.mmocore.gameserver.model.items.ItemInstance; import org.mmocore.gameserver.network.l2.components.SystemMsg; import org.mmocore.gameserver.network.l2.s2c.SystemMessage; import org.mmocore.gameserver.skills.SkillEntry; import org.mmocore.gameserver.stats.Env; import org.mmocore.gameserver.stats.StatTemplate; import org.mmocore.gameserver.stats.conditions.Condition; import org.mmocore.gameserver.stats.funcs.FuncTemplate; import org.mmocore.gameserver.templates.StatsSet; import org.mmocore.gameserver.templates.augmentation.AugmentationInfo; import org.mmocore.gameserver.templates.item.EtcItemTemplate.EtcItemType; import org.mmocore.gameserver.templates.item.WeaponTemplate.WeaponType; import org.napile.primitive.Containers; import org.napile.primitive.maps.IntObjectMap; import org.napile.primitive.maps.impl.HashIntObjectMap; /** * This class contains all informations concerning the item (weapon, armor, etc).<BR> * Mother class of : * <LI>L2Armor</LI> * <LI>L2EtcItem</LI> * <LI>L2Weapon</LI> */ public abstract class ItemTemplate extends StatTemplate { public static enum ReuseType { NORMAL(SystemMsg.THERE_ARE_S2_SECONDS_REMAINING_IN_S1S_REUSE_TIME, SystemMsg.THERE_ARE_S2_MINUTES_S3_SECONDS_REMAINING_IN_S1S_REUSE_TIME, SystemMsg.THERE_ARE_S2_HOURS_S3_MINUTES_AND_S4_SECONDS_REMAINING_IN_S1S_REUSE_TIME) { @Override public long next(ItemInstance item) { return System.currentTimeMillis() + item.getTemplate().getReuseDelay(); } }, EVERY_DAY_AT_6_30(SystemMsg.THERE_ARE_S2_SECONDS_REMAINING_FOR_S1S_REUSE_TIME, SystemMsg.THERE_ARE_S2_MINUTES_S3_SECONDS_REMAINING_FOR_S1S_REUSE_TIME, SystemMsg.THERE_ARE_S2_HOURS_S3_MINUTES_S4_SECONDS_REMAINING_FOR_S1S_REUSE_TIME) { private final SchedulingPattern _pattern = new SchedulingPattern("30 6 * * *"); @Override public long next(ItemInstance item) { return _pattern.next(System.currentTimeMillis()); } }; private SystemMsg[] _messages; ReuseType(SystemMsg... msg) { _messages = msg; } public abstract long next(ItemInstance item); public SystemMsg[] getMessages() { return _messages; } } public static enum ItemClass { ALL, WEAPON, ARMOR, JEWELRY, ACCESSORY, /** Soul/Spiritshot, Potions, Scrolls */ CONSUMABLE, /** Common craft matherials */ MATHERIALS, /** Special (item specific) craft matherials */ PIECES, /** Crafting recipies */ RECIPIES, /** Skill learn books */ SPELLBOOKS, /** Dyes, lifestones */ MISC, EXTRACTABLE, /** All other */ OTHER } public static final int ITEM_ID_PC_BANG_POINTS = -100; public static final int ITEM_ID_CLAN_REPUTATION_SCORE = -200; public static final int ITEM_ID_FAME = -300; public static final int ITEM_ID_ADENA = 57; /** Item ID для замковых корон */ public static final int[] ITEM_ID_CASTLE_CIRCLET = { 0, // no castle - no circlet.. 6838, // Circlet of Gludio 6835, // Circlet of Dion 6839, // Circlet of Giran 6837, // Circlet of Oren 6840, // Circlet of Aden 6834, // Circlet of Innadril 6836, // Circlet of Goddard 8182, // Circlet of Rune 8183, // Circlet of Schuttgart }; public static final int ITEM_ID_FORMAL_WEAR = 6408; public static final int TYPE1_WEAPON_RING_EARRING_NECKLACE = 0; public static final int TYPE1_SHIELD_ARMOR = 1; public static final int TYPE1_OTHER = 2; public static final int TYPE1_ITEM_QUESTITEM_ADENA = 4; public static final int TYPE2_WEAPON = 0; public static final int TYPE2_SHIELD_ARMOR = 1; public static final int TYPE2_ACCESSORY = 2; public static final int TYPE2_QUEST = 3; public static final int TYPE2_MONEY = 4; public static final int TYPE2_OTHER = 5; public static final int TYPE2_PET_WOLF = 6; public static final int TYPE2_PET_HATCHLING = 7; public static final int TYPE2_PET_STRIDER = 8; public static final int TYPE2_NODROP = 9; public static final int TYPE2_PET_GWOLF = 10; public static final int TYPE2_PENDANT = 11; public static final int TYPE2_PET_BABY = 12; public static final int SLOT_NONE = 0x00000; public static final int SLOT_UNDERWEAR = 0x00001; public static final int SLOT_R_EAR = 0x00002; public static final int SLOT_L_EAR = 0x00004; public static final int SLOT_NECK = 0x00008; public static final int SLOT_R_FINGER = 0x00010; public static final int SLOT_L_FINGER = 0x00020; public static final int SLOT_HEAD = 0x00040; public static final int SLOT_R_HAND = 0x00080; public static final int SLOT_L_HAND = 0x00100; public static final int SLOT_GLOVES = 0x00200; public static final int SLOT_CHEST = 0x00400; public static final int SLOT_LEGS = 0x00800; public static final int SLOT_FEET = 0x01000; public static final int SLOT_BACK = 0x02000; public static final int SLOT_LR_HAND = 0x04000; public static final int SLOT_FULL_ARMOR = 0x08000; public static final int SLOT_HAIR = 0x10000; public static final int SLOT_FORMAL_WEAR = 0x20000; public static final int SLOT_DHAIR = 0x40000; public static final int SLOT_HAIRALL = 0x80000; public static final int SLOT_R_BRACELET = 0x100000; public static final int SLOT_L_BRACELET = 0x200000; public static final int SLOT_DECO = 0x400000; public static final int SLOT_BELT = 0x10000000; public static final int SLOT_WOLF = -100; public static final int SLOT_HATCHLING = -101; public static final int SLOT_STRIDER = -102; public static final int SLOT_BABYPET = -103; public static final int SLOT_GWOLF = -104; public static final int SLOT_PENDANT = -105; // Все слоты, используемые броней. public static final int SLOTS_ARMOR = SLOT_HEAD|SLOT_L_HAND|SLOT_GLOVES|SLOT_CHEST|SLOT_LEGS|SLOT_FEET|SLOT_BACK|SLOT_FULL_ARMOR; // Все слоты, используемые бижей. public static final int SLOTS_JEWELRY = SLOT_R_EAR|SLOT_L_EAR|SLOT_NECK|SLOT_R_FINGER|SLOT_L_FINGER; public static final int CRYSTAL_NONE = 0; public static final int CRYSTAL_D = 1458; public static final int CRYSTAL_C = 1459; public static final int CRYSTAL_B = 1460; public static final int CRYSTAL_A = 1461; public static final int CRYSTAL_S = 1462; public static enum Grade { NONE(CRYSTAL_NONE, 0), D(CRYSTAL_D, 1), C(CRYSTAL_C, 2), B(CRYSTAL_B, 3), A(CRYSTAL_A, 4), S(CRYSTAL_S, 5), S80(CRYSTAL_S, 5), S84(CRYSTAL_S, 5); /** ID соответствующего грейду кристалла */ public final int cry; /** ID грейда, без учета уровня S */ public final int externalOrdinal; private Grade(int crystal, int ext) { cry = crystal; externalOrdinal = ext; } } public static final int ATTRIBUTE_NONE = -2; public static final int ATTRIBUTE_FIRE = 0; public static final int ATTRIBUTE_WATER = 1; public static final int ATTRIBUTE_WIND = 2; public static final int ATTRIBUTE_EARTH = 3; public static final int ATTRIBUTE_HOLY = 4; public static final int ATTRIBUTE_DARK = 5; protected final int _itemId; private final ItemClass _class; protected final String _name; protected final String _addname; protected final String _icon; protected final String _icon32; protected int _type1; // needed for item list (inventory) protected int _type2; // different lists for armor, weapon, etc private final int _weight; protected final Grade _crystalType; // default to none-grade private final int _durability; protected int _bodyPart; private final int _referencePrice; private final int _crystalCount; private final boolean _temporal; private final boolean _stackable; private final boolean _magicWeapon; private final boolean _petFood; private final boolean _hideConsumeMessage; private final int _flags; private final ReuseType _reuseType; private final int _reuseDelay; private final int _reuseGroup; private final int _agathionEnergy; private final int _equipReuseDelay; protected SkillEntry[] _skills; private SkillEntry _enchant4Skill = null; // skill that activates when item is enchanted +4 (for duals) public ItemType type; private int[] _baseAttributes = new int[6]; private IntObjectMap<int[]> _enchantOptions = Containers.emptyIntObjectMap(); private final List<CapsuledItem> _capsuledItems = new ArrayList<>(); private Condition[] _conditions = Condition.EMPTY_ARRAY; private IItemHandler _handler = IItemHandler.DEFAULT; private IntObjectMap<AugmentationInfo> _augmentationInfos = Containers.emptyIntObjectMap(); /** * Constructor<?> of the L2Item that fill class variables.<BR><BR> * <U><I>Variables filled :</I></U><BR> * <LI>type</LI> * <LI>_itemId</LI> * <LI>_name</LI> * <LI>_type1 & _type2</LI> * <LI>_weight</LI> * <LI>_crystallizable</LI> * <LI>_stackable</LI> * <LI>_materialType & _crystalType & _crystlaCount</LI> * <LI>_durability</LI> * <LI>_bodypart</LI> * <LI>_referencePrice</LI> * <LI>_sellable</LI> * @param set : StatsSet corresponding to a set of couples (key,value) for description of the item */ protected ItemTemplate(final StatsSet set) { _itemId = set.getInteger("item_id"); _class = set.getEnum("class", ItemClass.class, ItemClass.OTHER); _name = set.getString("name"); _addname = set.getString("add_name", ""); _icon = set.getString("icon", ""); _icon32 = "<img src=icon." + _icon + " width=32 height=32>"; _weight = set.getInteger("weight", 0); _stackable = set.getBool("stackable", false); _crystalType = set.getEnum("crystal_type", Grade.class, Grade.NONE); // default to none-grade _durability = set.getInteger("durability", -1); _temporal = set.getBool("temporal", false); _bodyPart = set.getInteger("bodypart", 0); _referencePrice = set.getInteger("price", 0); _crystalCount = set.getInteger("crystal_count", 0); _reuseType = set.getEnum("reuse_type", ReuseType.class, ReuseType.NORMAL); _reuseDelay = set.getInteger("reuse_delay", 0); _reuseGroup = set.getInteger("delay_share_group", -_itemId); _agathionEnergy = set.getInteger("agathion_energy", 0); _equipReuseDelay = set.getInteger("equip_reuse_delay", -1); _magicWeapon = set.getBool("is_magic_weapon", false); _petFood = set.getBool("is_pet_food", false); _hideConsumeMessage = set.getBool("hide_consume_message", false); int flags = 0; for(ItemFlags f : ItemFlags.VALUES) { if(set.getBool(f.lcname(), f.getDefaultValue())) flags |= f.mask(); } _flags = flags; _funcTemplates = FuncTemplate.EMPTY_ARRAY; _skills = SkillEntry.EMPTY_ARRAY; } /** * Returns the itemType. * @return Enum */ public ItemType getItemType() { return type; } public String getIcon() { return _icon; } /** * Возвращает готовую для отображения в html строку вида * <img src=icon.иконка width=32 height=32> */ public String getIcon32() { return _icon32; } /** * Returns the durability of th item * @return int */ public final int getDurability() { return _durability; } public final boolean isTemporal() { return _temporal; } /** * Returns the ID of the item * @return int */ public final int getItemId() { return _itemId; } public abstract long getItemMask(); /** * Returns the type 2 of the item * @return int */ public final int getType2() { return _type2; } public final int getBaseAttributeValue(Element element) { if(element == Element.NONE) return 0; return _baseAttributes[element.getId()]; } public void setBaseAtributeElements(int[] val) { _baseAttributes = val; } public final int getType2ForPackets() { int type2 = _type2; switch(_type2) { case TYPE2_PET_WOLF: case TYPE2_PET_HATCHLING: case TYPE2_PET_STRIDER: case TYPE2_PET_GWOLF: case TYPE2_PET_BABY: if(_bodyPart == ItemTemplate.SLOT_CHEST) type2 = TYPE2_SHIELD_ARMOR; else type2 = TYPE2_WEAPON; break; case TYPE2_PENDANT: type2 = TYPE2_ACCESSORY; break; } return type2; } /** * Returns the weight of the item * @return int */ public final int getWeight() { return _weight; } /** * Return the type of crystal if item is crystallizable * @return int */ public final Grade getCrystalType() { return _crystalType; } /** * Returns the grade of the item.<BR><BR> * <U><I>Concept :</I></U><BR> * In fact, this fucntion returns the type of crystal of the item. * @return int */ public final Grade getItemGrade() { return getCrystalType(); } /** * Returns the quantity of crystals for crystallization * @return int */ public final int getCrystalCount() { return _crystalCount; } public abstract int getCrystalCount(int enchantLevel, boolean enchantFail); /** * Returns the name of the item * @return String */ public final String getName() { return _name; } /** * Returns the additional name of the item * @return String */ public final String getAdditionalName() { return _addname; } /** * Return the part of the body used with the item. * @return int */ public final int getBodyPart() { return _bodyPart; } /** * Returns the type 1 of the item * @return int */ public final int getType1() { return _type1; } /** * Returns if the item is stackable * @return boolean */ public final boolean isStackable() { return _stackable; } /** * Returns the price of reference of the item * @return int */ public final int getReferencePrice() { return _referencePrice; } /** * Returns if item is for hatchling * @return boolean */ public boolean isForHatchling() { return _type2 == TYPE2_PET_HATCHLING; } /** * Returns if item is for strider * @return boolean */ public boolean isForStrider() { return _type2 == TYPE2_PET_STRIDER; } /** * Returns if item is for wolf * @return boolean */ public boolean isForWolf() { return _type2 == TYPE2_PET_WOLF; } public boolean isForPetBaby() { return _type2 == TYPE2_PET_BABY; } /** * Returns if item is for great wolf * @return boolean * [pchayka] GWolfs can wear wolf's armor&weapon */ public boolean isForGWolf() { return _type2 == TYPE2_PET_GWOLF || _type2 == TYPE2_PET_WOLF; } /** * Магическая броня для петов */ public boolean isPendant() { return _type2 == TYPE2_PENDANT; } public boolean isForPet() { return _type2 == TYPE2_PENDANT || _type2 == TYPE2_PET_HATCHLING || _type2 == TYPE2_PET_WOLF || _type2 == TYPE2_PET_STRIDER || _type2 == TYPE2_PET_GWOLF || _type2 == TYPE2_PET_BABY; } /** * Add the L2Skill skill to the list of skills generated by the item * @param skill : L2Skill */ public void attachSkill(SkillEntry skill) { _skills = ArrayUtils.add(_skills, skill); } public SkillEntry[] getAttachedSkills() { return _skills; } public SkillEntry getFirstSkill() { if(_skills.length > 0) return _skills[0]; return null; } /** * @return skill that player get when has equipped weapon +4 or more (for duals SA) */ public SkillEntry getEnchant4Skill() { return _enchant4Skill; } /** * Returns the name of the item * @return String */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getItemId()); sb.append(" - "); sb.append(getName()); if(!getAdditionalName().isEmpty()) { sb.append(' '); sb.append('<').append(getAdditionalName()).append('>'); } return sb.toString(); } /** * Определяет призрачный предмет или нет * @return true, если предмет призрачный */ public boolean isShadowItem() { return _durability > 0 && !isTemporal(); } public boolean isCommonItem() { return _name.startsWith("Common Item - "); } public boolean isSealedItem() { return _name.startsWith("Sealed"); } public boolean isAltSeed() { return _name.contains("Alternative"); } public ItemClass getItemClass() { return _class; } /** * Является ли вещь аденой или камнем печати */ public boolean isAdena() { return _itemId == ItemTemplate.ITEM_ID_ADENA || _itemId == 6360 || _itemId == 6361 || _itemId == 6362; } public boolean isEquipment() { return _type1 != TYPE1_ITEM_QUESTITEM_ADENA; } public boolean isKeyMatherial() { return _class == ItemClass.PIECES; } public boolean isExtractable() { return this._class == ItemClass.EXTRACTABLE; } public boolean isRecipe() { return _class == ItemClass.RECIPIES; } public boolean isTerritoryAccessory() { return _itemId >= 13740 && _itemId <= 13748 || _itemId >= 14592 && _itemId <= 14600 || _itemId >= 14664 && _itemId <= 14672 || _itemId >= 14801 && _itemId <= 14809 || _itemId >= 15282 && _itemId <= 15299; } public boolean isArrow() { return type == EtcItemType.ARROW; } public boolean isBelt() { return _bodyPart == SLOT_BELT; } public boolean isBracelet() { return _bodyPart == SLOT_R_BRACELET || _bodyPart == SLOT_L_BRACELET; } public boolean isUnderwear() { return _bodyPart == SLOT_UNDERWEAR; } public boolean isCloak() { return _bodyPart == SLOT_BACK; } public boolean isTalisman() { return _bodyPart == SLOT_DECO; } public boolean isHerb() { return type == EtcItemType.HERB; } public boolean isAttributeCrystal() { return _itemId == 9552 || _itemId == 9553 || _itemId == 9554 || _itemId == 9555 || _itemId == 9556 || _itemId == 9557; } public boolean isHeroWeapon() { return _itemId >= 6611 && _itemId <= 6621 || _itemId >= 9388 && _itemId <= 9390; } public boolean isCursed() { return CursedWeaponsManager.getInstance().isCursed(_itemId); } public boolean isMercenaryTicket() { return type == EtcItemType.MERCENARY_TICKET; } public boolean isRod() { return getItemType() == WeaponType.ROD; } public boolean isWeapon() { return getType2() == ItemTemplate.TYPE2_WEAPON; } public boolean isArmor() { return getType2() == ItemTemplate.TYPE2_SHIELD_ARMOR; } public boolean isAccessory() { return getType2() == ItemTemplate.TYPE2_ACCESSORY; } public boolean isQuest() { return getType2() == ItemTemplate.TYPE2_QUEST; } /** * gradeCheck - использовать пока не перепишется система заточки * @param gradeCheck * @return */ public boolean canBeEnchanted(@Deprecated boolean gradeCheck) { if(gradeCheck && getCrystalType() == Grade.NONE) return false; if(isCursed()) return false; if(isQuest()) // DS: проверить и убрать return false; return isEnchantable(); } /** * Returns if item is equipable * @return boolean */ public boolean isEquipable() { return getItemType() == EtcItemType.BAIT || getItemType() == EtcItemType.ARROW || getItemType() == EtcItemType.BOLT || !(getBodyPart() == 0 || this instanceof EtcItemTemplate); } public void setEnchant4Skill(SkillEntry enchant4Skill) { _enchant4Skill = enchant4Skill; } public boolean testCondition(Playable player, ItemInstance instance, boolean showMessage) { if(_conditions.length == 0) return true; Env env = new Env(); env.character = player; env.item = instance; for (Condition con : _conditions) { if (!con.test(env)) { if(showMessage && con.getSystemMsg() != null) { if(con.getSystemMsg().size() > 0) player.sendPacket(new SystemMessage(con.getSystemMsg()).addItemName(getItemId())); else player.sendPacket(con.getSystemMsg()); } return false; } } return true; } public void addCondition(Condition condition) { _conditions = ArrayUtils.add(_conditions, condition); } /** * Returns if the item is crystallizable * @return boolean */ public final boolean isCrystallizable() { return getFlag(ItemFlags.CRYSTALLIZABLE); } public boolean isEnchantable() { return getFlag(ItemFlags.ENCHANTABLE); } public boolean isTradeable() { return getFlag(ItemFlags.TRADEABLE); } public boolean isDestroyable() { return getFlag(ItemFlags.DESTROYABLE); } public boolean isDropable() { return getFlag(ItemFlags.DROPABLE); } public final boolean isSellable() { return getFlag(ItemFlags.SELLABLE); } public final boolean isAttributable() { return getFlag(ItemFlags.ATTRIBUTABLE); } public final boolean isStoreable() { return getFlag(ItemFlags.STOREABLE); } public final boolean isFreightable() { return getFlag(ItemFlags.FREIGHTABLE); } private boolean getFlag(ItemFlags f) { return (_flags & f.mask()) == f.mask(); } public IItemHandler getHandler() { return _handler; } public void setHandler(IItemHandler handler) { _handler = handler; } public int getReuseDelay() { return _reuseDelay; } public int getReuseGroup() { return _reuseGroup; } public int getDisplayReuseGroup() { return _reuseGroup < 0 ? -1 : _reuseGroup; } public int getAgathionEnergy() { return _agathionEnergy; } public int getEquipReuseDelay() { return _equipReuseDelay; } public void addEnchantOptions(int level, int[] options) { if(_enchantOptions.isEmpty()) _enchantOptions = new HashIntObjectMap<int[]>(); _enchantOptions.put(level, options); } public IntObjectMap<int[]> getEnchantOptions() { return _enchantOptions; } public ReuseType getReuseType() { return _reuseType; } public List<CapsuledItem> getCapsuledItems() { return this._capsuledItems; } public void addCapsuledItem(CapsuledItem ci) { this._capsuledItems.add(ci); } public static class CapsuledItem { private final int item_id; private final int min_count; private final int max_count; private final double chance; public CapsuledItem(int item_id, int min_count, int max_count, double chance) { this.item_id = item_id; this.min_count = min_count; this.max_count = max_count; this.chance = chance; } public int getItemId() { return this.item_id; } public int getMinCount() { return this.min_count; } public int getMaxCount() { return this.max_count; } public double getChance() { return this.chance; } } public boolean isMagicWeapon() { return _magicWeapon; } public boolean isPetFood() { return _petFood; } public boolean isHideConsumeMessage() { return _hideConsumeMessage; } public void addAugmentationInfo(AugmentationInfo augmentationInfo) { if(_augmentationInfos.isEmpty()) _augmentationInfos = new HashIntObjectMap<AugmentationInfo>(); _augmentationInfos.put(augmentationInfo.getMineralId(), augmentationInfo); } public IntObjectMap<AugmentationInfo> getAugmentationInfos() { return _augmentationInfos; } } ItemParser.java package org.mmocore.gameserver.data.xml.parser; import java.io.File; import java.util.Iterator; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.dom4j.Element; import org.mmocore.gameserver.Config; import org.mmocore.gameserver.data.xml.holder.ItemHolder; import org.mmocore.gameserver.data.xml.holder.OptionDataHolder; import org.mmocore.gameserver.model.Skill.SkillType; import org.mmocore.gameserver.skills.SkillEntry; import org.mmocore.gameserver.stats.conditions.Condition; import org.mmocore.gameserver.tables.SkillTable; import org.mmocore.gameserver.templates.OptionDataTemplate; import org.mmocore.gameserver.templates.StatsSet; import org.mmocore.gameserver.templates.item.ArmorTemplate; import org.mmocore.gameserver.templates.item.Bodypart; import org.mmocore.gameserver.templates.item.EtcItemTemplate; import org.mmocore.gameserver.templates.item.ItemTemplate; import org.mmocore.gameserver.templates.item.WeaponTemplate; /** * @author VISTALL * @date 11:26/15.01.2011 */ public final class ItemParser extends StatParser<ItemHolder> { private static final ItemParser _instance = new ItemParser(); public static ItemParser getInstance() { return _instance; } protected ItemParser() { super(ItemHolder.getInstance()); } @Override public File getXMLDir() { return new File(Config.DATAPACK_ROOT, "data/items/"); } @Override public boolean isIgnored(File f) { return false; } @Override public String getDTDFileName() { return "item.dtd"; } @Override protected void readData(Element rootElement) throws Exception { for(Iterator<Element> itemIterator = rootElement.elementIterator(); itemIterator.hasNext() { Element itemElement = itemIterator.next(); StatsSet set = new StatsSet(); set.set("item_id", itemElement.attributeValue("id")); set.set("name", itemElement.attributeValue("name")); set.set("add_name", itemElement.attributeValue("add_name", StringUtils.EMPTY)); int slot = 0; for(Iterator<Element> subIterator = itemElement.elementIterator(); subIterator.hasNext() { Element subElement = subIterator.next(); String subName = subElement.getName(); if(subName.equalsIgnoreCase("set")) { set.set(subElement.attributeValue("name"), subElement.attributeValue("value")); } else if(subName.equalsIgnoreCase("equip")) { for(Iterator<Element> slotIterator = subElement.elementIterator(); slotIterator.hasNext() { Element slotElement = slotIterator.next(); Bodypart bodypart = Bodypart.valueOf(slotElement.attributeValue("id")); if(bodypart.getReal() != null) slot = bodypart.mask(); else slot |= bodypart.mask(); } } } set.set("bodypart", slot); ItemTemplate template = null; try { if(itemElement.getName().equalsIgnoreCase("weapon")) { if (!set.containsKey("class")) { if ((slot & ItemTemplate.SLOT_L_HAND) > 0) // щиты set.set("class", ItemTemplate.ItemClass.ARMOR); else set.set("class", ItemTemplate.ItemClass.WEAPON); } template = new WeaponTemplate(set); } else if(itemElement.getName().equalsIgnoreCase("armor")) { if (!set.containsKey("class")) { if ((slot & ItemTemplate.SLOTS_ARMOR) > 0) set.set("class", ItemTemplate.ItemClass.ARMOR); else if ((slot & ItemTemplate.SLOTS_JEWELRY) > 0) set.set("class", ItemTemplate.ItemClass.JEWELRY); else set.set("class", ItemTemplate.ItemClass.ACCESSORY); } template = new ArmorTemplate(set); } else //if(itemElement.getName().equalsIgnoreCase("etcitem")) template = new EtcItemTemplate(set); } catch(Exception e) { //for(Map.Entry<String, Object> entry : set.entrySet()) //{ // info("set " + entry.getKey() + ":" + entry.getValue()); //} warn("Fail create item: " + set.get("item_id"), e); continue; } for(Iterator<Element> subIterator = itemElement.elementIterator(); subIterator.hasNext() { Element subElement = subIterator.next(); String subName = subElement.getName(); if(subName.equalsIgnoreCase("for")) { parseFor(subElement, template); } else if(subName.equalsIgnoreCase("triggers")) { parseTriggers(subElement, template); } else if(subName.equalsIgnoreCase("skills")) { for(Iterator<Element> nextIterator = subElement.elementIterator(); nextIterator.hasNext() { Element nextElement = nextIterator.next(); int id = Integer.parseInt(nextElement.attributeValue("id")); int level = Integer.parseInt(nextElement.attributeValue("level")); SkillEntry skill = SkillTable.getInstance().getSkillEntry(id, level); if(skill != null) { template.attachSkill(skill); // Проверка на эксплойты с бесконечной распаковкой if (skill.getTemplate().getSkillType() == SkillType.EXTRACT && !ArrayUtils.contains(skill.getTemplate().getItemConsumeId(), template.getItemId())) info("Skill (" + id + "," + level + ") consume item(s), but attached item " + set.getObject("item_id") + "; file:" + getCurrentFileName() + " not found, possible infinite extraction !"); } else info("Skill not found(" + id + "," + level + ") for item:" + set.getObject("item_id") + "; file:" + getCurrentFileName()); } } else if(subName.equalsIgnoreCase("enchant4_skill")) { int id = Integer.parseInt(subElement.attributeValue("id")); int level = Integer.parseInt(subElement.attributeValue("level")); SkillEntry skill = SkillTable.getInstance().getSkillEntry(id, level); if(skill != null) template.setEnchant4Skill(skill); } else if(subName.equalsIgnoreCase("cond")) { Condition condition = parseFirstCond(subElement); if(condition != null) { int msgId = parseNumber(subElement.attributeValue("msgId", "0")).intValue(); condition.setSystemMsg(msgId); template.addCondition(condition); } } else if(subName.equalsIgnoreCase("attributes")) { int[] attributes = new int[6]; for(Iterator<Element> nextIterator = subElement.elementIterator(); nextIterator.hasNext() { // DS: name collision Element nextElement = nextIterator.next(); org.mmocore.gameserver.model.base.Element element; if(nextElement.getName().equalsIgnoreCase("attribute")) { element = org.mmocore.gameserver.model.base.Element.getElementByName(nextElement.attributeValue("element")); attributes[element.getId()] = Integer.parseInt(nextElement.attributeValue("value")); } } template.setBaseAtributeElements(attributes); } else { if (subName.equalsIgnoreCase("capsuled_items")) { for (Iterator<org.dom4j.Element> nextIterator = subElement.elementIterator(); nextIterator.hasNext() { org.dom4j.Element nextElement = nextIterator.next(); if (nextElement.getName().equalsIgnoreCase("capsuled_item")) { int c_item_id = Integer.parseInt(nextElement.attributeValue("id")); int c_min_count = Integer.parseInt(nextElement.attributeValue("min_count")); int c_max_count = Integer.parseInt(nextElement.attributeValue("max_count")); double c_chance = Double.parseDouble(nextElement.attributeValue("chance")); template.addCapsuledItem(new ItemTemplate.CapsuledItem(c_item_id, c_min_count, c_max_count, c_chance)); } } } else if(subName.equalsIgnoreCase("enchant_options")) { for(Iterator<Element> nextIterator = subElement.elementIterator(); nextIterator.hasNext() { Element nextElement = nextIterator.next(); if(nextElement.getName().equalsIgnoreCase("level")) { int val = Integer.parseInt(nextElement.attributeValue("val")); int i = 0; int[] options = new int[3]; for(Element optionElement : nextElement.elements()) { OptionDataTemplate optionData = OptionDataHolder.getInstance().getTemplate(Integer.parseInt(optionElement.attributeValue("id"))); if(optionData == null) { error("Not found option_data for id: " + optionElement.attributeValue("id") + "; item_id: " + set.get("item_id")); continue; } options[i++] = optionData.getId(); } template.addEnchantOptions(val, options); } } } } } getHolder().addItem(template); } } @Override protected Object getTableValue(String name) { return null; } } Изменено 11 мая, 2015 пользователем markblack Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 11 мая, 2015 Немного не то, нужен класс который реализует интерфейс IItemHandler, а ItemHandler.java это класс, который только регистрирует этот интерфейс. В общем, нужно искать/сделать класс CapsuledItem с интерфейсом IItemHandler. Что за сборка? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 (изменено) Lostworld (шара) IItemHadler.java package org.mmocore.gameserver.handler.items; import org.apache.commons.lang3.ArrayUtils; import org.mmocore.gameserver.model.Playable; import org.mmocore.gameserver.model.Player; import org.mmocore.gameserver.model.items.ItemInstance; import org.mmocore.gameserver.utils.Location; /** * Mother class of all itemHandlers.<BR><BR> * an IItemHandler implementation has to be stateless */ public interface IItemHandler { public static final IItemHandler DEFAULT = new IItemHandler() { @Override public boolean useItem(Playable playable, ItemInstance item, boolean ctrl) { return false; } @Override public boolean dropItem(Player player, ItemInstance item, long count, Location loc) { return true; } @Override public boolean pickupItem(Playable playable, ItemInstance item) { return true; } @Override public int[] getItemIds() { return ArrayUtils.EMPTY_INT_ARRAY; } }; /** * Launch task associated to the item. * @param playable * @param item : L2ItemInstance designating the item to use * @param ctrl */ public boolean useItem(Playable playable, ItemInstance item, boolean ctrl); /** * Check can drop or not * * * @param playable * @param item * @param count *@param loc @return can drop */ public boolean dropItem(Player player, ItemInstance item, long count, Location loc); /** * Check if can pick up item * @param playable * @param item * @return */ public boolean pickupItem(Playable playable, ItemInstance item); /** * Returns the list of item IDs corresponding to the type of item.<BR><BR> * <B><I>Use :</I></U><BR> * This method is called at initialization to register all the item IDs automatically * @return int[] designating all itemIds for a type of item. */ public int[] getItemIds(); } Изменено 11 мая, 2015 пользователем markblack Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
ImmortalPony 126 Опубликовано 11 мая, 2015 Для начала убедись что они верно реализованы (пример проверки: мешок НГ сосок, если откроет то проверяем реализацию остальных). Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 У разработчика большая часть реализована в скриптах. Оно не работает <etcitem id="17000" name="Black Ore Set of Friendship" add_name="90 day limited period"> <set name="reuse_delay" value="3000"/> <set name="class" value="EXTRACTABLE"/> <set name="crystal_type" value="NONE"/> <set name="icon" value="icon.etc_jewel_box_i00"/> <set name="type" value="OTHER"/> <capsuled_items> <capsuled_item id="16858" min_count="1" max_count="1" chance="100.0"/> <capsuled_item id="16857" min_count="2" max_count="2" chance="100.0"/> <capsuled_item id="16859" min_count="2" max_count="2" chance="100.0"/> </capsuled_items> </etcitem> Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 11 мая, 2015 Глянул сборку, набросал скрипт исходя от твоей реализации data/scripts/handler/items package handler.items; import org.apache.commons.lang3.ArrayUtils; import org.mmocore.commons.util.Rnd; import org.mmocore.gameserver.data.xml.holder.ItemHolder; import org.mmocore.gameserver.model.Playable; import org.mmocore.gameserver.model.Player; import org.mmocore.gameserver.model.items.ItemInstance; import org.mmocore.gameserver.network.l2.components.SystemMsg; import org.mmocore.gameserver.network.l2.s2c.SystemMessage; import org.mmocore.gameserver.templates.item.ItemTemplate; import org.mmocore.gameserver.templates.item.ItemTemplate.CapsuledItem; public class CapsuledItems extends ScriptItemHandler { @Override public boolean useItem(Playable playable, ItemInstance item, boolean ctrl) { if(playable == null || !playable.isPlayer()) return false; Player player = playable.getPlayer(); if(!player.getInventory().destroyItem(item, 1L)) { player.sendPacket(SystemMsg.INCORRECT_ITEM_COUNT); return false; } player.sendPacket(SystemMessage.removeItems(item.getItemId(), 1)); for (CapsuledItem ci : item.getTemplate().getCapsuledItems()) { if(Rnd.chance(ci.getChance())) { ItemInstance obtainItem = player.getInventory().addItem(ci.getItemId(), Rnd.get(ci.getMinCount(), ci.getMaxCount())); if (obtainItem != null) player.sendPacket(SystemMessage.obtainItems(obtainItem)); } } return true; } @Override public int[] getItemIds() { int[] items = new int[0]; for (ItemTemplate item : ItemHolder.getInstance().getAllTemplates()) if (item.getCapsuledItems().size() > 0) items = ArrayUtils.add(items, item.getItemId()); return items; } } 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 убрал public у класса (не запускался) после прогрузки итемов пишет ERROR scripts.Scripts: java.lang.IllegalAccessException: Class org.mmocore.gameserver.scripts.Scripts can not access a member of class handler.items.CapsuledItems with modifiers "" at sun.reflect.Reflection.ensureMemberAccess(Unknown Source) at java.lang.Class.newInstance(Unknown Source) at org.mmocore.gameserver.scripts.Scripts.init(Scripts.java:158) at org.mmocore.gameserver.scripts.Scripts.init(Scripts.java:90) at org.mmocore.gameserver.GameServer.<init>(GameServer.java:210) at org.mmocore.gameserver.GameServer.main(GameServer.java:388) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 11 мая, 2015 эта ошибка возникает из-за того, что убран public модификатор, зачем его убирать, в смысле не запускался? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
markblack 1 Опубликовано 11 мая, 2015 С модификатором \gameserver\data\scripts\handler\items\Capsuled.java:16,14: The public type CapsuledItems must be defined in its own file Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Nha 22 Опубликовано 11 мая, 2015 нужно сделать файл CapsuledItems.java (название совпадает с названием класса) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Killmi 6 Опубликовано 16 мая, 2015 package handler.items; import java.util.List; import org.mmocore.commons.util.Rnd; import org.mmocore.gameserver.data.xml.holder.ItemHolder; import org.mmocore.gameserver.model.Playable; import org.mmocore.gameserver.model.Player; import org.mmocore.gameserver.model.items.ItemInstance; import org.mmocore.gameserver.network.l2.components.SystemMsg; import org.mmocore.gameserver.network.l2.s2c.SystemMessage; import org.mmocore.gameserver.templates.item.support.CapsuledItemsContainer; import org.mmocore.gameserver.utils.ItemFunctions; public class Capsuled extends ScriptItemHandler { @Override public final int[] getItemIds() { return ItemHolder.getInstance().getCapsuledItemIds(); } @Override public boolean useItem(Playable playable, ItemInstance item, boolean ctrl) { if(playable == null || !playable.isPlayer()) return false; Player player = (Player) playable; boolean isCapsuled = item.getTemplate().isCapsuled(); if (!canBeExtracted(player, item)) return false; if (!useItem(player, item, 1)) return false; List<CapsuledItemsContainer> extracted_items = item.getTemplate().getCapsuledItems(); boolean random = true; int sizer = 0; int maxSize = extracted_items.size(); int preItemId = 0; int perMinCount = 0; int perMaxCount = 0; for(CapsuledItemsContainer extracted : extracted_items) { if(extracted.getChance() < 100.0) { if(isCapsuled && Rnd.chance(50) && preItemId == 0) { preItemId = extracted.getItemId(); perMinCount = extracted.getMinCount(); perMaxCount = extracted.getMaxCount(); } if(Rnd.chance(extracted.getChance()) && random) { ItemFunctions.addItem(player, extracted.getItemId(), Rnd.get(extracted.getMinCount(), extracted.getMaxCount())); random = false; } if(isCapsuled) { sizer++; if(sizer == maxSize && random) { ItemFunctions.addItem(player, preItemId, Rnd.get(perMinCount, perMaxCount)); random = false; } } } else if(extracted.getChance() == 100.0) ItemFunctions.addItem(player, extracted.getItemId(), Rnd.get(extracted.getMinCount(), extracted.getMaxCount())); } return true; } private static boolean canBeExtracted(Player player, ItemInstance item) { if(player.getWeightPenalty() >= 3 || player.getInventory().getSize() > player.getInventoryLimit() - 10) { player.sendPacket(SystemMsg.YOUR_INVENTORY_IS_FULL, new SystemMessage(SystemMsg.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS).addItemName(item.getItemId())); return false; } if(player.isActionsDisabled()) { player.sendPacket(SystemMsg.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS); return false; } if(player.isInTrade()) { player.sendPacket(SystemMsg.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS); return false; } if(player.isInStoreMode()) { player.sendPacket(SystemMsg.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS); return false; } return true; } public static boolean useItem(Player player, ItemInstance item, long count) { if(player.getInventory().destroyItem(item, count)) { player.sendPacket(new SystemMessage(SystemMsg.YOU_USE_S1).addItemName(item.getItemId())); return true; } player.sendPacket(SystemMsg.INCORRECT_ITEM_COUNT); return false; } } Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Killmi 6 Опубликовано 16 мая, 2015 и всё) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты