Support for alternate required item ids for skill learn.

This commit is contained in:
MobiusDevelopment
2022-03-01 13:11:32 +00:00
parent dd02a4ae77
commit caad76a9be
118 changed files with 1001 additions and 740 deletions

View File

@@ -243,7 +243,13 @@ public class SkillTreeData implements IXmlReader
{
case "item":
{
skillLearn.addRequiredItem(new ItemHolder(parseInteger(attrs, "id"), parseInteger(attrs, "count")));
final List<ItemHolder> itemList = new ArrayList<>(1);
final int count = parseInteger(attrs, "count");
for (String id : parseString(attrs, "id").split(","))
{
itemList.add(new ItemHolder(Integer.parseInt(id), count));
}
skillLearn.addRequiredItem(itemList);
break;
}
case "preRequisiteSkill":

View File

@@ -16,8 +16,10 @@
*/
package org.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.l2jmobius.gameserver.data.xml.SkillData;
@@ -39,7 +41,7 @@ public class SkillLearn
private final int _getDualClassLevel;
private final boolean _autoGet;
private final long _levelUpSp;
private final Set<ItemHolder> _requiredItems = new HashSet<>(1);
private final List<List<ItemHolder>> _requiredItems = new ArrayList<>(1);
private final Set<Race> _races = EnumSet.noneOf(Race.class);
private final Set<SkillHolder> _preReqSkills = new HashSet<>(1);
private SocialClass _socialClass;
@@ -134,18 +136,18 @@ public class SkillLearn
/**
* @return the set with the item holders required to acquire this skill.
*/
public Set<ItemHolder> getRequiredItems()
public List<List<ItemHolder>> getRequiredItems()
{
return _requiredItems;
}
/**
* Adds a required item holder to learn this skill.
* @param item the required item holder.
* Adds a required item holder list to learn this skill.
* @param list the required item holder list.
*/
public void addRequiredItem(ItemHolder item)
public void addRequiredItem(List<ItemHolder> list)
{
_requiredItems.add(item);
_requiredItems.add(list);
}
/**

View File

@@ -209,18 +209,26 @@ public class RequestAcquireSkill implements IClientIncomingPacket
return;
}
for (ItemHolder item : s.getRequiredItems())
int count = 0;
long playerItemCount = 0;
for (List<ItemHolder> items : s.getRequiredItems())
{
if (!player.destroyItemByItemId("SubSkills", item.getId(), item.getCount(), trainer, false))
count = 0;
SEARCH: for (ItemHolder item : items)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ITEMS_TO_LEARN_THIS_SKILL);
return;
count++;
playerItemCount = player.getInventory().getInventoryItemCount(item.getId(), -1);
if ((playerItemCount >= item.getCount()) && player.destroyItemByItemId("SubSkills", item.getId(), item.getCount(), trainer, true))
{
break SEARCH;
}
if (count == items.size())
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ITEMS_TO_LEARN_THIS_SKILL);
return;
}
}
final SystemMessage sm = new SystemMessage(SystemMessageId.S2_S1_S_DISAPPEARED);
sm.addItemName(item.getId());
sm.addLong(item.getCount());
player.sendPacket(sm);
}
if (repCost > 0)
@@ -566,25 +574,46 @@ public class RequestAcquireSkill implements IClientIncomingPacket
if (!skillLearn.getRequiredItems().isEmpty())
{
// Then checks that the player has all the items
long reqItemCount = 0;
for (ItemHolder item : skillLearn.getRequiredItems())
int count = 0;
long playerItemCount = 0;
for (List<ItemHolder> items : skillLearn.getRequiredItems())
{
reqItemCount = player.getInventory().getInventoryItemCount(item.getId(), -1);
if (reqItemCount < item.getCount())
count = 0;
SEARCH: for (ItemHolder item : items)
{
// Player doesn't have required item.
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ITEMS_TO_LEARN_THIS_SKILL);
showSkillList(trainer, player);
return false;
count++;
playerItemCount = player.getInventory().getInventoryItemCount(item.getId(), -1);
if (playerItemCount >= item.getCount())
{
break SEARCH;
}
if (count == items.size())
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ITEMS_TO_LEARN_THIS_SKILL);
showSkillList(trainer, player);
return false;
}
}
}
// If the player has all required items, they are consumed.
for (ItemHolder itemIdCount : skillLearn.getRequiredItems())
for (List<ItemHolder> items : skillLearn.getRequiredItems())
{
if (!player.destroyItemByItemId("SkillLearn", itemIdCount.getId(), itemIdCount.getCount(), trainer, true))
count = 0;
SEARCH: for (ItemHolder item : items)
{
Util.handleIllegalPlayerAction(player, "Somehow " + player + ", level " + player.getLevel() + " lose required item Id: " + itemIdCount.getId() + " to learn skill while learning skill Id: " + _id + " level " + _level + "!", IllegalActionPunishmentType.NONE);
count++;
playerItemCount = player.getInventory().getInventoryItemCount(item.getId(), -1);
if ((playerItemCount >= item.getCount()) && player.destroyItemByItemId("SkillLearn", item.getId(), item.getCount(), trainer, true))
{
break SEARCH;
}
if (count == items.size())
{
Util.handleIllegalPlayerAction(player, "Somehow " + player + ", level " + player.getLevel() + " lose required item Id: " + item.getId() + " to learn skill while learning skill Id: " + _id + " level " + _level + "!", IllegalActionPunishmentType.NONE);
}
}
}
}

View File

@@ -76,15 +76,15 @@ public class AcquireSkillInfo implements IClientOutgoingPacket
_spCost = skillLearn.getLevelUpSp();
_type = skillType;
_reqs = new ArrayList<>();
if ((skillType != AcquireSkillType.PLEDGE) || Config.LIFE_CRYSTAL_NEEDED)
if (!skillLearn.getRequiredItems().isEmpty() && ((skillType != AcquireSkillType.PLEDGE) || Config.LIFE_CRYSTAL_NEEDED))
{
for (ItemHolder item : skillLearn.getRequiredItems())
for (List<ItemHolder> item : skillLearn.getRequiredItems())
{
if (!Config.DIVINE_SP_BOOK_NEEDED && (_id == CommonSkill.DIVINE_INSPIRATION.getId()))
{
continue;
}
_reqs.add(new Req(99, item.getId(), item.getCount(), 50));
_reqs.add(new Req(99, item.get(0).getId(), item.get(0).getCount(), 50));
}
}
}
@@ -103,9 +103,12 @@ public class AcquireSkillInfo implements IClientOutgoingPacket
_spCost = sp;
_type = skillType;
_reqs = new ArrayList<>();
for (ItemHolder item : skillLearn.getRequiredItems())
if (!skillLearn.getRequiredItems().isEmpty())
{
_reqs.add(new Req(99, item.getId(), item.getCount(), 50));
for (List<ItemHolder> item : skillLearn.getRequiredItems())
{
_reqs.add(new Req(99, item.get(0).getId(), item.get(0).getCount(), 50));
}
}
}

View File

@@ -17,6 +17,7 @@
package org.l2jmobius.gameserver.network.serverpackets;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -65,10 +66,10 @@ public class AcquireSkillList implements IClientOutgoingPacket
packet.writeC(skill.getDualClassLevel());
packet.writeC(_player.getKnownSkill(skill.getSkillId()) != null ? 0 : 1);
packet.writeC(skill.getRequiredItems().size());
for (ItemHolder item : skill.getRequiredItems())
for (List<ItemHolder> item : skill.getRequiredItems())
{
packet.writeD(item.getId());
packet.writeQ(item.getCount());
packet.writeD(item.get(0).getId());
packet.writeQ(item.get(0).getCount());
}
final Collection<Skill> removeSkills = skill.getRemoveSkills().stream().map(_player::getKnownSkill).filter(Objects::nonNull).collect(Collectors.toList());
packet.writeC(removeSkills.size());

View File

@@ -18,7 +18,6 @@ package org.l2jmobius.gameserver.network.serverpackets;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.l2jmobius.commons.network.PacketWriter;
@@ -38,7 +37,7 @@ public class ExAcquireSkillInfo implements IClientOutgoingPacket
private final int _dualClassLevel;
private final long _spCost;
private final int _minLevel;
private final Set<ItemHolder> _itemReq;
private final List<List<ItemHolder>> _itemReq;
private final List<Skill> _skillRem;
/**
@@ -68,10 +67,10 @@ public class ExAcquireSkillInfo implements IClientOutgoingPacket
packet.writeH(_minLevel);
packet.writeH(_dualClassLevel);
packet.writeD(_itemReq.size());
for (ItemHolder holder : _itemReq)
for (List<ItemHolder> holder : _itemReq)
{
packet.writeD(holder.getId());
packet.writeQ(holder.getCount());
packet.writeD(holder.get(0).getId());
packet.writeQ(holder.get(0).getCount());
}
packet.writeD(_skillRem.size());
for (Skill skill : _skillRem)