Avoid pointless boxing-unboxing operations.
Contributed by Sahar.
This commit is contained in:
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,12 +129,12 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
||||||
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -140,14 +143,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -88,16 +86,15 @@ public class ArmorSet
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -121,51 +118,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -175,16 +143,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -200,7 +158,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +168,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -220,7 +178,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -249,7 +207,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -261,7 +219,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -273,7 +231,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -286,7 +244,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +254,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,12 +129,12 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
||||||
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -140,14 +143,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -88,16 +86,15 @@ public class ArmorSet
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -121,51 +118,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -175,16 +143,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -200,7 +158,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +168,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -220,7 +178,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -249,7 +207,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -261,7 +219,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -273,7 +231,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -286,7 +244,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +254,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,12 +129,12 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
||||||
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -140,14 +143,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -88,16 +86,15 @@ public class ArmorSet
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -121,51 +118,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -175,16 +143,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -200,7 +158,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +168,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -220,7 +178,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -249,7 +207,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -261,7 +219,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -273,7 +231,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -286,7 +244,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +254,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,12 +129,12 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
||||||
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -140,14 +143,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -88,16 +86,15 @@ public class ArmorSet
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -121,51 +118,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -175,16 +143,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -200,7 +158,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +168,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -220,7 +178,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -249,7 +207,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -261,7 +219,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -273,7 +231,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -286,7 +244,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +254,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,12 +129,12 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
||||||
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -140,14 +143,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -88,16 +86,15 @@ public class ArmorSet
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -121,51 +118,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -175,16 +143,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -200,7 +158,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +168,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -220,7 +178,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -249,7 +207,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -261,7 +219,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -273,7 +231,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -286,7 +244,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +254,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,12 +129,12 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
final int artifactSlotMask = parseInteger(attrs, "slotMask", 0);
|
||||||
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
final int artifactBookSlot = parseInteger(attrs, "bookSlot", 0);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional, artifactSlotMask, artifactBookSlot));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -140,14 +143,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -88,16 +86,15 @@ public class ArmorSet
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -121,51 +118,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -175,16 +143,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -200,7 +158,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +168,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -220,7 +178,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -249,7 +207,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
for (int artifactSlot : ARTIFACT_1_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -261,7 +219,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
for (int artifactSlot : ARTIFACT_2_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -273,7 +231,7 @@ public class ArmorSet
|
|||||||
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
for (int artifactSlot : ARTIFACT_3_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(artifactSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()))
|
||||||
{
|
{
|
||||||
slotMask += artifactSlot;
|
slotMask += artifactSlot;
|
||||||
}
|
}
|
||||||
@@ -286,7 +244,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +254,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
@@ -18,9 +18,13 @@ package org.l2jmobius.gameserver.data.xml.impl;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -74,11 +78,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final int id = parseInteger(setNode.getAttributes(), "id");
|
final int id = parseInteger(setNode.getAttributes(), "id");
|
||||||
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
final int minimumPieces = parseInteger(setNode.getAttributes(), "minimumPieces", 0);
|
||||||
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
final boolean isVisual = parseBoolean(setNode.getAttributes(), "visual", false);
|
||||||
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual);
|
final Set<Integer> requiredItems = new LinkedHashSet<>();
|
||||||
if (_armorSets.putIfAbsent(id, set) != null)
|
final Set<Integer> optionalItems = new LinkedHashSet<>();
|
||||||
{
|
final List<ArmorsetSkillHolder> skills = new ArrayList<>();
|
||||||
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
final Map<BaseStat, Double> stats = new LinkedHashMap<>();
|
||||||
}
|
|
||||||
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
for (Node innerSetNode = setNode.getFirstChild(); innerSetNode != null; innerSetNode = innerSetNode.getNextSibling())
|
||||||
{
|
{
|
||||||
switch (innerSetNode.getNodeName())
|
switch (innerSetNode.getNodeName())
|
||||||
@@ -94,7 +97,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing required item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addRequiredItem(itemId))
|
else if (!requiredItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate required item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -112,7 +115,7 @@ public class ArmorSetData implements IXmlReader
|
|||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register non existing optional item: " + itemId + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
else if (!set.addOptionalItem(itemId))
|
else if (!optionalItems.add(itemId))
|
||||||
{
|
{
|
||||||
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
LOGGER.warning("Attempting to register duplicate optional item " + item + " to a set: " + f.getName());
|
||||||
}
|
}
|
||||||
@@ -126,10 +129,10 @@ public class ArmorSetData implements IXmlReader
|
|||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
final int skillId = parseInteger(attrs, "id");
|
final int skillId = parseInteger(attrs, "id");
|
||||||
final int skillLevel = parseInteger(attrs, "level");
|
final int skillLevel = parseInteger(attrs, "level");
|
||||||
final int minPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
final int minPieces = parseInteger(attrs, "minimumPieces", minimumPieces);
|
||||||
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
final int minEnchant = parseInteger(attrs, "minimumEnchant", 0);
|
||||||
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
final boolean isOptional = parseBoolean(attrs, "optional", false);
|
||||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
skills.add(new ArmorsetSkillHolder(skillId, skillLevel, minPieces, minEnchant, isOptional));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -138,14 +141,20 @@ public class ArmorSetData implements IXmlReader
|
|||||||
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
forEach(innerSetNode, b -> "stat".equals(b.getNodeName()), node ->
|
||||||
{
|
{
|
||||||
final NamedNodeMap attrs = node.getAttributes();
|
final NamedNodeMap attrs = node.getAttributes();
|
||||||
set.addStatsBonus(parseEnum(attrs, BaseStat.class, "type"), parseInteger(attrs, "val"));
|
stats.put(parseEnum(attrs, BaseStat.class, "type"), parseDouble(attrs, "val"));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.concat(set.getRequiredItems().stream(), set.getOptionalItems().stream()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
final ArmorSet set = new ArmorSet(id, minimumPieces, isVisual, requiredItems, optionalItems, skills, stats);
|
||||||
|
if (_armorSets.putIfAbsent(id, set) != null)
|
||||||
|
{
|
||||||
|
LOGGER.warning("Duplicate set entry with id: " + id + " in file: " + f.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream.concat(Arrays.stream(set.getRequiredItems()).boxed(), Arrays.stream(set.getOptionalItems()).boxed()).forEach(itemHolder -> _armorSetItems.computeIfAbsent(itemHolder, key -> new ArrayList<>()).add(set));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.l2jmobius.gameserver.model;
|
package org.l2jmobius.gameserver.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.l2jmobius.commons.util.CommonUtil;
|
||||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||||
@@ -40,11 +38,11 @@ public class ArmorSet
|
|||||||
private final int _minimumPieces;
|
private final int _minimumPieces;
|
||||||
private final boolean _isVisual;
|
private final boolean _isVisual;
|
||||||
|
|
||||||
private final Set<Integer> _requiredItems = new LinkedHashSet<>();
|
private final int[] _requiredItems;
|
||||||
private final Set<Integer> _optionalItems = new LinkedHashSet<>();
|
private final int[] _optionalItems;
|
||||||
|
|
||||||
private final List<ArmorsetSkillHolder> _skills = new ArrayList<>();
|
private final List<ArmorsetSkillHolder> _skills;
|
||||||
private final Map<BaseStat, Double> _stats = new LinkedHashMap<>();
|
private final Map<BaseStat, Double> _stats;
|
||||||
|
|
||||||
private static final int[] ARMORSET_SLOTS = new int[]
|
private static final int[] ARMORSET_SLOTS = new int[]
|
||||||
{
|
{
|
||||||
@@ -55,16 +53,15 @@ public class ArmorSet
|
|||||||
Inventory.PAPERDOLL_FEET
|
Inventory.PAPERDOLL_FEET
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
public ArmorSet(int id, int minimumPieces, boolean isVisual, Set<Integer> requiredItems, Set<Integer> optionalItems, List<ArmorsetSkillHolder> skills, Map<BaseStat, Double> stats)
|
||||||
* @param id
|
|
||||||
* @param minimumPieces
|
|
||||||
* @param isVisual
|
|
||||||
*/
|
|
||||||
public ArmorSet(int id, int minimumPieces, boolean isVisual)
|
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_minimumPieces = minimumPieces;
|
_minimumPieces = minimumPieces;
|
||||||
_isVisual = isVisual;
|
_isVisual = isVisual;
|
||||||
|
_requiredItems = requiredItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_optionalItems = optionalItems.stream().mapToInt(x -> x).toArray();
|
||||||
|
_skills = skills;
|
||||||
|
_stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
@@ -88,51 +85,22 @@ public class ArmorSet
|
|||||||
return _isVisual;
|
return _isVisual;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an item to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if item was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addRequiredItem(Integer item)
|
|
||||||
{
|
|
||||||
return _requiredItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of items that can form a set
|
* @return the set of items that can form a set
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRequiredItems()
|
public int[] getRequiredItems()
|
||||||
{
|
{
|
||||||
return _requiredItems;
|
return _requiredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an shield to the set
|
|
||||||
* @param item
|
|
||||||
* @return {@code true} if shield was successfully added, {@code false} in case it already exists
|
|
||||||
*/
|
|
||||||
public boolean addOptionalItem(Integer item)
|
|
||||||
{
|
|
||||||
return _optionalItems.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the set of shields
|
* @return the set of shields
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getOptionalItems()
|
public int[] getOptionalItems()
|
||||||
{
|
{
|
||||||
return _optionalItems;
|
return _optionalItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an skill to the set
|
|
||||||
* @param holder
|
|
||||||
*/
|
|
||||||
public void addSkill(ArmorsetSkillHolder holder)
|
|
||||||
{
|
|
||||||
_skills.add(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
* The list of skills that are activated when set reaches it's minimal equipped items condition
|
||||||
* @return
|
* @return
|
||||||
@@ -142,16 +110,6 @@ public class ArmorSet
|
|||||||
return _skills;
|
return _skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds stats bonus to the set activated when set reaches it's minimal equipped items condition
|
|
||||||
* @param stat
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
public void addStatsBonus(BaseStat stat, double value)
|
|
||||||
{
|
|
||||||
_stats.putIfAbsent(stat, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param stat
|
* @param stat
|
||||||
* @return the stats bonus value or 0 if doesn't exists
|
* @return the stats bonus value or 0 if doesn't exists
|
||||||
@@ -167,7 +125,7 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public boolean containOptionalItem(int shieldId)
|
public boolean containOptionalItem(int shieldId)
|
||||||
{
|
{
|
||||||
return _optionalItems.contains(shieldId);
|
return CommonUtil.contains(_optionalItems, shieldId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +135,7 @@ public class ArmorSet
|
|||||||
public int getLowestSetEnchant(PlayerInstance player)
|
public int getLowestSetEnchant(PlayerInstance player)
|
||||||
{
|
{
|
||||||
// Player don't have full set
|
// Player don't have full set
|
||||||
if (getPiecesCount(player, ItemInstance::getId) < _minimumPieces)
|
if (getPiecesCountById(player) < _minimumPieces)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -187,7 +145,7 @@ public class ArmorSet
|
|||||||
for (int armorSlot : ARMORSET_SLOTS)
|
for (int armorSlot : ARMORSET_SLOTS)
|
||||||
{
|
{
|
||||||
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
final ItemInstance itemPart = inv.getPaperdollItem(armorSlot);
|
||||||
if ((itemPart != null) && _requiredItems.contains(itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
if ((itemPart != null) && CommonUtil.contains(_requiredItems, itemPart.getId()) && (enchantLevel > itemPart.getEnchantLevel()))
|
||||||
{
|
{
|
||||||
enchantLevel = itemPart.getEnchantLevel();
|
enchantLevel = itemPart.getEnchantLevel();
|
||||||
}
|
}
|
||||||
@@ -201,7 +159,7 @@ public class ArmorSet
|
|||||||
|
|
||||||
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public boolean hasOptionalEquipped(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> _optionalItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItems().stream().anyMatch(item -> CommonUtil.contains(_optionalItems, idProvider.apply(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,6 +169,11 @@ public class ArmorSet
|
|||||||
*/
|
*/
|
||||||
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
public long getPiecesCount(PlayerInstance player, Function<ItemInstance, Integer> idProvider)
|
||||||
{
|
{
|
||||||
return player.getInventory().getPaperdollItemCount(item -> _requiredItems.contains(idProvider.apply(item)));
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, idProvider.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPiecesCountById(PlayerInstance player)
|
||||||
|
{
|
||||||
|
return player.getInventory().getPaperdollItemCount(item -> CommonUtil.contains(_requiredItems, item.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public class BaseStatFinalizer implements IStatFunction
|
|||||||
{
|
{
|
||||||
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
for (ArmorSet set : ArmorSetData.getInstance().getSets(item.getId()))
|
||||||
{
|
{
|
||||||
if ((set.getPiecesCount(player, ItemInstance::getId) >= set.getMinimumPieces()) && appliedSets.add(set))
|
if ((set.getPiecesCountById(player) >= set.getMinimumPieces()) && appliedSets.add(set))
|
||||||
{
|
{
|
||||||
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
baseValue += set.getStatsBonus(BaseStat.valueOf(stat));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user