Simplify Monster skills with Set instead of List

Doable now with MobSkillId records
This commit is contained in:
P0nk
2022-09-03 13:30:44 +02:00
parent c47ca4d6a4
commit 7cdaabf6f8
5 changed files with 37 additions and 53 deletions

View File

@@ -32,7 +32,6 @@ import server.maps.MapObject;
import server.maps.MapObjectType; import server.maps.MapObjectType;
import server.maps.MapleMap; import server.maps.MapleMap;
import tools.PacketCreator; import tools.PacketCreator;
import tools.Randomizer;
import tools.exceptions.EmptyMovementException; import tools.exceptions.EmptyMovementException;
import java.awt.*; import java.awt.*;
@@ -80,7 +79,6 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
boolean isAttack = inRangeInclusive(rawActivity, 24, 41); boolean isAttack = inRangeInclusive(rawActivity, 24, 41);
boolean isSkill = inRangeInclusive(rawActivity, 42, 59); boolean isSkill = inRangeInclusive(rawActivity, 42, 59);
MobSkill toUse = null;
int useSkillId = 0, useSkillLevel = 0; int useSkillId = 0, useSkillLevel = 0;
MobSkill nextUse = null; MobSkill nextUse = null;
@@ -88,14 +86,12 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
boolean nextMovementCouldBeSkill = !(isSkill || (pNibbles != 0)); boolean nextMovementCouldBeSkill = !(isSkill || (pNibbles != 0));
int castPos;
if (isSkill) { if (isSkill) {
useSkillId = skillId; useSkillId = skillId;
useSkillLevel = skillLv; useSkillLevel = skillLv;
castPos = monster.getSkillPos(useSkillId, useSkillLevel); if (monster.hasSkill(useSkillId, useSkillLevel)) {
if (castPos != -1) { MobSkill toUse = MobSkillFactory.getMobSkill(MobSkillType.from(useSkillId), useSkillLevel);
toUse = MobSkillFactory.getMobSkill(MobSkillType.from(useSkillId), useSkillLevel);
if (monster.canUseSkill(toUse, true)) { if (monster.canUseSkill(toUse, true)) {
int animationTime = MonsterInformationProvider.getInstance().getMobSkillAnimationTime(toUse); int animationTime = MonsterInformationProvider.getInstance().getMobSkillAnimationTime(toUse);
@@ -108,8 +104,7 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
} }
} }
} else { } else {
castPos = (rawActivity - 24) / 2; int castPos = (rawActivity - 24) / 2;
int atkStatus = monster.canUseAttack(castPos, isSkill); int atkStatus = monster.canUseAttack(castPos, isSkill);
if (atkStatus < 1) { if (atkStatus < 1) {
rawActivity = -1; rawActivity = -1;
@@ -118,15 +113,11 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
} }
int mobMp = monster.getMp(); int mobMp = monster.getMp();
if (nextMovementCouldBeSkill) { if (nextMovementCouldBeSkill && monster.hasAnySkill()) {
int noSkills = monster.getNoSkills(); MobSkillId skillToUse = monster.getRandomSkill();
if (noSkills > 0) {
int rndSkill = Randomizer.nextInt(noSkills);
MobSkillId skillToUse = monster.getSkills().get(rndSkill);
nextSkillId = skillToUse.type().getId(); nextSkillId = skillToUse.type().getId();
nextSkillLevel = skillToUse.level(); nextSkillLevel = skillToUse.level();
nextUse = MobSkillFactory.getMobSkill(MobSkillType.from(nextSkillId), nextSkillLevel); nextUse = MobSkillFactory.getMobSkill(skillToUse.type(), skillToUse.level());
if (!(nextUse != null && monster.canUseSkill(nextUse, false) && nextUse.getHP() >= (int) (((float) monster.getHp() / monster.getMaxHp()) * 100) && mobMp >= nextUse.getMpCon())) { if (!(nextUse != null && monster.canUseSkill(nextUse, false) && nextUse.getHP() >= (int) (((float) monster.getHp() / monster.getMaxHp()) * 100) && mobMp >= nextUse.getMpCon())) {
// thanks OishiiKawaiiDesu for noticing mobs trying to cast skills they are not supposed to be able // thanks OishiiKawaiiDesu for noticing mobs trying to cast skills they are not supposed to be able
@@ -136,7 +127,6 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
nextUse = null; nextUse = null;
} }
} }
}
p.readByte(); p.readByte();
p.readInt(); // whatever p.readInt(); // whatever
@@ -164,8 +154,8 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
p.seek(movementDataStart); p.seek(movementDataStart);
if (YamlConfig.config.server.USE_DEBUG_SHOW_RCVD_MVLIFE) { if (YamlConfig.config.server.USE_DEBUG_SHOW_RCVD_MVLIFE) {
log.debug("{} castPos: {}, rawAct: {}, opt: {}, skillId: {}, skillLv: {}, allowSkill: {}, mobMp: {}", log.debug("{} rawAct: {}, opt: {}, skillId: {}, skillLv: {}, allowSkill: {}, mobMp: {}",
isSkill ? "SKILL" : (isAttack ? "ATTCK" : ""), castPos, rawActivity, pOption, useSkillId, isSkill ? "SKILL" : (isAttack ? "ATTCK" : ""), rawActivity, pOption, useSkillId,
useSkillLevel, nextMovementCouldBeSkill, mobMp); useSkillLevel, nextMovementCouldBeSkill, mobMp);
} }

View File

@@ -188,7 +188,7 @@ public class LifeFactory {
Data monsterSkillInfoData = monsterInfoData.getChildByPath("skill"); Data monsterSkillInfoData = monsterInfoData.getChildByPath("skill");
if (monsterSkillInfoData != null) { if (monsterSkillInfoData != null) {
int i = 0; int i = 0;
List<MobSkillId> skills = new ArrayList<>(); Set<MobSkillId> skills = new HashSet<>();
while (monsterSkillInfoData.getChildByPath(Integer.toString(i)) != null) { while (monsterSkillInfoData.getChildByPath(Integer.toString(i)) != null) {
int skillId = DataTool.getInt(i + "/skill", monsterSkillInfoData, 0); int skillId = DataTool.getInt(i + "/skill", monsterSkillInfoData, 0);
int skillLv = DataTool.getInt(i + "/level", monsterSkillInfoData, 0); int skillLv = DataTool.getInt(i + "/level", monsterSkillInfoData, 0);

View File

@@ -1426,7 +1426,7 @@ public class Monster extends AbstractLoadedLife {
return map.getAggroCoordinator(); return map.getAggroCoordinator();
} }
public List<MobSkillId> getSkills() { public Set<MobSkillId> getSkills() {
return stats.getSkills(); return stats.getSkills();
} }
@@ -1434,19 +1434,6 @@ public class Monster extends AbstractLoadedLife {
return stats.hasSkill(skillId, level); return stats.hasSkill(skillId, level);
} }
public int getSkillPos(int skillId, int level) {
int pos = 0;
for (MobSkillId ms : this.getSkills()) {
if (ms.type().getId() == skillId && ms.level() == level) {
return pos;
}
pos++;
}
return -1;
}
public boolean canUseSkill(MobSkill toUse, boolean apply) { public boolean canUseSkill(MobSkill toUse, boolean apply) {
if (toUse == null || isBuffed(MonsterStatus.SEAL_SKILL)) { if (toUse == null || isBuffed(MonsterStatus.SEAL_SKILL)) {
return false; return false;
@@ -1600,8 +1587,20 @@ public class Monster extends AbstractLoadedLife {
} }
} }
public int getNoSkills() { public boolean hasAnySkill() {
return this.stats.getNoSkills(); return this.stats.getNoSkills() > 0;
}
public MobSkillId getRandomSkill() {
Set<MobSkillId> skills = stats.getSkills();
if (skills.size() == 0) {
return null;
}
// There is no simple way of getting a random element from a Set. Have to make do with this.
return skills.stream()
.skip(Randomizer.nextInt(skills.size()))
.findAny()
.orElse(null);
} }
public boolean isFirstAttack() { public boolean isFirstAttack() {

View File

@@ -41,7 +41,7 @@ public class MonsterStats {
public Map<Element, ElementalEffectiveness> resistance = new HashMap<>(); public Map<Element, ElementalEffectiveness> resistance = new HashMap<>();
public List<Integer> revives = Collections.emptyList(); public List<Integer> revives = Collections.emptyList();
public byte tagColor, tagBgColor; public byte tagColor, tagBgColor;
public List<MobSkillId> skills = new ArrayList<>(); public Set<MobSkillId> skills = new HashSet<>();
public Pair<Integer, Integer> cool = null; public Pair<Integer, Integer> cool = null;
public BanishInfo banish = null; public BanishInfo banish = null;
public List<loseItem> loseItem = null; public List<loseItem> loseItem = null;
@@ -190,17 +190,12 @@ public class MonsterStats {
this.tagBgColor = (byte) tagBgColor; this.tagBgColor = (byte) tagBgColor;
} }
public void setSkills(List<MobSkillId> skills) { public void setSkills(Set<MobSkillId> skills) {
for (int i = this.skills.size(); i < skills.size(); i++) { this.skills = skills;
this.skills.add(null);
}
for (int i = 0; i < skills.size(); i++) {
this.skills.set(i, skills.get(i));
}
} }
public List<MobSkillId> getSkills() { public Set<MobSkillId> getSkills() {
return Collections.unmodifiableList(this.skills); return Collections.unmodifiableSet(this.skills);
} }
public int getNoSkills() { public int getNoSkills() {

View File

@@ -108,7 +108,7 @@ public class MonsterStatFetcher {
Data monsterSkillData = monsterInfoData.getChildByPath("skill"); Data monsterSkillData = monsterInfoData.getChildByPath("skill");
if (monsterSkillData != null) { if (monsterSkillData != null) {
int i = 0; int i = 0;
List<MobSkillId> skills = new ArrayList<>(); Set<MobSkillId> skills = new HashSet<>();
while (monsterSkillData.getChildByPath(Integer.toString(i)) != null) { while (monsterSkillData.getChildByPath(Integer.toString(i)) != null) {
int skillId = DataTool.getInt(i + "/skill", monsterSkillData, 0); int skillId = DataTool.getInt(i + "/skill", monsterSkillData, 0);
MobSkillType type = MobSkillType.from(skillId); MobSkillType type = MobSkillType.from(skillId);