Fix race condition when concurrently Stealing
This commit is contained in:
@@ -290,16 +290,10 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
player.addHP(Math.min(monster.getMaxHp(), Math.min((int) ((double) totDamage * (double) SkillFactory.getSkill(attack.skill).getEffect(player.getSkillLevel(SkillFactory.getSkill(attack.skill))).getX() / 100.0), player.getCurrentMaxHp() / 2)));
|
||||
} else if (attack.skill == Bandit.STEAL) {
|
||||
Skill steal = SkillFactory.getSkill(Bandit.STEAL);
|
||||
if (monster.getStolen().isEmpty()) { // One steal per mob <3
|
||||
if (steal.getEffect(player.getSkillLevel(steal)).makeChanceResult()) {
|
||||
monster.addStolen(0);
|
||||
if (steal.getEffect(player.getSkillLevel(steal)).makeChanceResult() && monster.trySteal()) {
|
||||
|
||||
Optional<MonsterDropEntry> stolenItem = dropProvider.getRandomStealDrop(monster.getId());
|
||||
if (stolenItem.isPresent()) {
|
||||
map.dropItemsFromMonster(Collections.singletonList(stolenItem.get()), player, monster);
|
||||
monster.addStolen(stolenItem.get().itemId);
|
||||
}
|
||||
}
|
||||
Optional<MonsterDropEntry> stolenItem = dropProvider.getRandomStealDrop(monster.getId());
|
||||
stolenItem.ifPresent(item -> map.dropItemsFromMonster(Collections.singletonList(item), player, monster));
|
||||
}
|
||||
} else if (attack.skill == FPArchMage.FIRE_DEMON) {
|
||||
long duration = SECONDS.toMillis(SkillFactory.getSkill(FPArchMage.FIRE_DEMON).getEffect(player.getSkillLevel(SkillFactory.getSkill(FPArchMage.FIRE_DEMON))).getDuration());
|
||||
|
||||
@@ -60,6 +60,7 @@ import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
@@ -86,7 +87,7 @@ public class Monster extends AbstractLoadedLife {
|
||||
private final Set<Integer> usedAttacks = new HashSet<>();
|
||||
private Set<Integer> calledMobOids = null;
|
||||
private WeakReference<Monster> callerMob = new WeakReference<>(null);
|
||||
private final List<Integer> stolenItems = new ArrayList<>(5);
|
||||
private final AtomicBoolean isStolen = new AtomicBoolean(false);
|
||||
private int team;
|
||||
private int parentMobOid = 0;
|
||||
private int spawnEffect = 0;
|
||||
@@ -1644,12 +1645,9 @@ public class Monster extends AbstractLoadedLife {
|
||||
return stats.getName();
|
||||
}
|
||||
|
||||
public void addStolen(int itemId) {
|
||||
stolenItems.add(itemId);
|
||||
}
|
||||
|
||||
public List<Integer> getStolen() {
|
||||
return stolenItems;
|
||||
public boolean trySteal() {
|
||||
boolean wasAlreadyStolen = this.isStolen.getAndSet(true);
|
||||
return !wasAlreadyStolen;
|
||||
}
|
||||
|
||||
public void setTempEffectiveness(Element e, ElementalEffectiveness ee, long milli) {
|
||||
@@ -2177,4 +2175,4 @@ public class Monster extends AbstractLoadedLife {
|
||||
|
||||
this.getMap().dismissRemoveAfter(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user