diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/commons/util/PrimitiveDoubleEnumMap.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/commons/util/PrimitiveDoubleEnumMap.java
new file mode 100644
index 0000000000..44d02dffeb
--- /dev/null
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/commons/util/PrimitiveDoubleEnumMap.java
@@ -0,0 +1,232 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.l2jmobius.commons.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Mobius
+ */
+public class PrimitiveDoubleEnumMap
+{
+ private Entry[] _array;
+ private final int _initialSize;
+ private int _size = 0;
+
+ private class Entry
+ {
+ private final Enum> key;
+ private double value;
+
+ public Entry(Enum> key, double value)
+ {
+ this.key = key;
+ this.value = value;
+ }
+ }
+
+ public PrimitiveDoubleEnumMap()
+ {
+ _initialSize = 10;
+ _array = new Entry[_initialSize];
+ }
+
+ public PrimitiveDoubleEnumMap(int size)
+ {
+ _initialSize = size;
+ _array = new Entry[size];
+ }
+
+ public PrimitiveDoubleEnumMap(PrimitiveDoubleEnumMap map)
+ {
+ _initialSize = map.getInitialSize();
+ _array = new Entry[map.size()];
+
+ for (Entry element : map.getEntries())
+ {
+ if (element != null)
+ {
+ put(element.key, element.value);
+ }
+ }
+ }
+
+ public int size()
+ {
+ return _size;
+ }
+
+ public int getInitialSize()
+ {
+ return _initialSize;
+ }
+
+ public void clear()
+ {
+ _size = 0;
+ _array = new Entry[_initialSize];
+ }
+
+ public Entry[] getEntries()
+ {
+ return _array;
+ }
+
+ public double get(Enum> key)
+ {
+ return getOrDefault(key, 0);
+ }
+
+ public double getOrDefault(Enum> key, double defaultValue)
+ {
+ for (Entry element : _array)
+ {
+ if ((element != null) && (element.key == key))
+ {
+ return element.value;
+ }
+ }
+ return defaultValue;
+ }
+
+ public void put(Enum> key, double value)
+ {
+ if (_array.length >= _size)
+ {
+ for (int i = 0; i < _array.length; i++)
+ {
+ if (_array[i] == null)
+ {
+ _size++;
+ _array[i] = new Entry(key, value);
+ }
+ }
+ }
+ else
+ {
+ int newPosition = _array.length;
+ increaseSize(_array.length); // Double size.
+ _size++;
+ _array[newPosition] = new Entry(key, value);
+ }
+ }
+
+ public void increaseSize(int count)
+ {
+ Entry[] temp = new Entry[_array.length + count];
+ for (int i = 0; i < _array.length; i++)
+ {
+ temp[i] = _array[i];
+ }
+ _array = temp;
+ temp = null;
+ }
+
+ public void remove(Enum> key)
+ {
+ for (int i = 0; i < _array.length; i++)
+ {
+ if (_array[i] != null)
+ {
+ _size--;
+ _array[i] = null;
+ }
+ }
+ }
+
+ public Set> keySet()
+ {
+ final Set> result = new HashSet<>(_size);
+ for (Entry element : _array)
+ {
+ if (element != null)
+ {
+ result.add(element.key);
+ }
+ }
+ return result;
+ }
+
+ public double[] values()
+ {
+ double[] result = new double[_size];
+ int position = 0;
+ for (Entry element : _array)
+ {
+ if (element != null)
+ {
+ result[position++] = element.value;
+ }
+ }
+ return result;
+ }
+
+ public boolean containsKey(Enum> key)
+ {
+ for (Entry element : _array)
+ {
+ if ((element != null) && (element.key == key))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean containsValue(double value)
+ {
+ for (Entry element : _array)
+ {
+ if ((element != null) && (element.value == value))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void mergeAdd(Enum> key, double value)
+ {
+ // Existing key.
+ for (Entry element : _array)
+ {
+ if ((element != null) && (element.key == key))
+ {
+ element.value += value;
+ return;
+ }
+ }
+ // Non existing key.
+ put(key, value);
+ }
+
+ public void mergeMul(Enum> key, double value)
+ {
+ // Existing key.
+ for (Entry element : _array)
+ {
+ if ((element != null) && (element.key == key))
+ {
+ element.value *= value;
+ return;
+ }
+ }
+ // Non existing key.
+ put(key, value);
+ }
+}
diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/stat/CreatureStat.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/stat/CreatureStat.java
index 893844d6e8..b328ce9c01 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/stat/CreatureStat.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/actor/stat/CreatureStat.java
@@ -18,7 +18,6 @@ package org.l2jmobius.gameserver.model.actor.stat;
import java.util.Collections;
import java.util.Deque;
-import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
@@ -33,6 +32,7 @@ import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.PrimitiveDoubleEnumMap;
import org.l2jmobius.gameserver.enums.AttributeType;
import org.l2jmobius.gameserver.enums.Position;
import org.l2jmobius.gameserver.model.actor.Creature;
@@ -60,8 +60,8 @@ public class CreatureStat
private int _maxBuffCount = Config.BUFFS_MAX_AMOUNT;
private double _vampiricSum = 0;
- private final Map _statsAdd = new EnumMap<>(Stat.class);
- private final Map _statsMul = new EnumMap<>(Stat.class);
+ private final PrimitiveDoubleEnumMap _statsAdd = new PrimitiveDoubleEnumMap();
+ private final PrimitiveDoubleEnumMap _statsMul = new PrimitiveDoubleEnumMap();
private final Map> _moveTypeStats = new ConcurrentHashMap<>();
private final Map _reuseStat = new ConcurrentHashMap<>();
private final Map _mpConsumeStat = new ConcurrentHashMap<>();
@@ -772,7 +772,7 @@ public class CreatureStat
*/
public void mergeAdd(Stat stat, double value)
{
- _statsAdd.merge(stat, value, stat::functionAdd);
+ _statsAdd.mergeAdd(stat, value);
}
/**
@@ -782,7 +782,7 @@ public class CreatureStat
*/
public void mergeMul(Stat stat, double value)
{
- _statsMul.merge(stat, value, stat::functionMul);
+ _statsMul.mergeMul(stat, value);
}
/**
@@ -887,8 +887,9 @@ public class CreatureStat
public void recalculateStats(boolean broadcast)
{
// Copy old data before wiping it out
- final Map adds = !broadcast ? Collections.emptyMap() : new EnumMap<>(_statsAdd);
- final Map muls = !broadcast ? Collections.emptyMap() : new EnumMap<>(_statsMul);
+ final PrimitiveDoubleEnumMap adds = !broadcast ? new PrimitiveDoubleEnumMap() : new PrimitiveDoubleEnumMap(_statsAdd);
+ final PrimitiveDoubleEnumMap muls = !broadcast ? new PrimitiveDoubleEnumMap() : new PrimitiveDoubleEnumMap(_statsMul);
+
_lock.writeLock().lock();
try
{