Add attack delay to AttackInfo
Meant to be used in item drop packet for timing handled by the client rather than scheduling item drop packets on the server.
This commit is contained in:
@@ -117,7 +117,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
public static class AttackInfo {
|
||||
|
||||
public int numAttacked, numDamage, numAttackedAndDamage, skill, skilllevel, stance, direction, rangedirection, charge, display;
|
||||
public Map<Integer, List<Integer>> allDamage;
|
||||
public Map<Integer, AttackTarget> targets;
|
||||
public boolean ranged, magic;
|
||||
public int speed = 4;
|
||||
public Point position = new Point();
|
||||
@@ -146,6 +146,9 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add position
|
||||
public record AttackTarget(short delay, List<Integer> damageLines) {}
|
||||
|
||||
protected void applyAttack(AttackInfo attack, final Character player, int attackCount) {
|
||||
final MapleMap map = player.getMap();
|
||||
if (map.isOwnershipRestricted(player)) {
|
||||
@@ -216,7 +219,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
|
||||
if (attack.skill == ChiefBandit.MESO_EXPLOSION) {
|
||||
int delay = 0;
|
||||
for (Integer oned : attack.allDamage.keySet()) {
|
||||
for (Integer oned : attack.targets.keySet()) {
|
||||
MapObject mapobject = map.getMapObject(oned);
|
||||
if (mapobject != null && mapobject.getType() == MapObjectType.ITEM) {
|
||||
final MapItem mapitem = (MapItem) mapobject;
|
||||
@@ -249,7 +252,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Integer oned : attack.allDamage.keySet()) {
|
||||
for (Integer oned : attack.targets.keySet()) {
|
||||
final Monster monster = map.getMonsterByOid(oned);
|
||||
if (monster != null) {
|
||||
double distance = player.getPosition().distanceSq(monster.getPosition());
|
||||
@@ -285,7 +288,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
}
|
||||
|
||||
int totDamageToOneMonster = 0;
|
||||
List<Integer> onedList = attack.allDamage.get(oned);
|
||||
List<Integer> onedList = attack.targets.get(oned).damageLines();
|
||||
|
||||
if (attack.magic) { // thanks BHB, Alex (CanIGetaPR) for noticing no immunity status check here
|
||||
if (monster.isBuffed(MonsterStatus.MAGIC_IMMUNITY)) {
|
||||
@@ -600,7 +603,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
ret.numAttackedAndDamage = p.readByte();
|
||||
ret.numAttacked = (ret.numAttackedAndDamage >>> 4) & 0xF;
|
||||
ret.numDamage = ret.numAttackedAndDamage & 0xF;
|
||||
ret.allDamage = new HashMap<>();
|
||||
ret.targets = new HashMap<>();
|
||||
ret.skill = p.readInt();
|
||||
ret.ranged = ranged;
|
||||
ret.magic = magic;
|
||||
@@ -629,7 +632,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
for (int j = 0; j < bullets; j++) {
|
||||
int mesoid = p.readInt();
|
||||
p.skip(1);
|
||||
ret.allDamage.put(mesoid, null);
|
||||
ret.targets.put(mesoid, null);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
@@ -638,6 +641,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
for (int i = 0; i < ret.numAttacked + 1; i++) {
|
||||
int oid = p.readInt();
|
||||
if (i < ret.numAttacked) {
|
||||
// TODO: read delay in from these skipped bytes
|
||||
p.skip(12);
|
||||
int bullets = p.readByte();
|
||||
List<Integer> allDamageNumbers = new ArrayList<>();
|
||||
@@ -645,14 +649,14 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
int damage = p.readInt();
|
||||
allDamageNumbers.add(damage);
|
||||
}
|
||||
ret.allDamage.put(oid, allDamageNumbers);
|
||||
ret.targets.put(oid, new AttackTarget((short) 0, allDamageNumbers));
|
||||
p.skip(4);
|
||||
} else {
|
||||
int bullets = p.readByte();
|
||||
for (int j = 0; j < bullets; j++) {
|
||||
int mesoid = p.readInt();
|
||||
p.skip(1);
|
||||
ret.allDamage.put(mesoid, null);
|
||||
ret.targets.put(mesoid, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -814,10 +818,12 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
}
|
||||
for (int i = 0; i < ret.numAttacked; i++) {
|
||||
int oid = p.readInt();
|
||||
p.skip(14);
|
||||
List<Integer> allDamageNumbers = new ArrayList<>();
|
||||
Monster monster = chr.getMap().getMonsterByOid(oid);
|
||||
|
||||
p.skip(4);
|
||||
Point curPos = p.readPos();
|
||||
Point nextPos = p.readPos();
|
||||
short delay = p.readShort();
|
||||
List<Integer> damageLines = new ArrayList<>();
|
||||
final Monster monster = chr.getMap().getMonsterByOid(oid);
|
||||
if (chr.getBuffEffect(BuffStat.WK_CHARGE) != null) {
|
||||
// Charge, so now we need to check elemental effectiveness
|
||||
int sourceID = chr.getBuffSource(BuffStat.WK_CHARGE);
|
||||
@@ -941,12 +947,12 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
allDamageNumbers.add(damage);
|
||||
damageLines.add(damage);
|
||||
}
|
||||
if (ret.skill != Corsair.RAPID_FIRE || ret.skill != Aran.HIDDEN_FULL_DOUBLE || ret.skill != Aran.HIDDEN_FULL_TRIPLE || ret.skill != Aran.HIDDEN_OVER_DOUBLE || ret.skill != Aran.HIDDEN_OVER_TRIPLE) {
|
||||
p.skip(4);
|
||||
}
|
||||
ret.allDamage.put(oid, allDamageNumbers);
|
||||
ret.targets.put(oid, new AttackTarget(delay, damageLines));
|
||||
}
|
||||
if (ret.skill == NightWalker.POISON_BOMB) { // Poison Bomb
|
||||
p.skip(4);
|
||||
@@ -954,8 +960,4 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static int rand(int l, int u) {
|
||||
return (int) ((Math.random() * (u - l + 1)) + l);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,9 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
c.sendPacket(PacketCreator.getEnergy("energy", chr.getDojoEnergy()));
|
||||
}
|
||||
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.closeRangeAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.speed, attack.direction, attack.display), false, true);
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.closeRangeAttack(chr, attack.skill, attack.skilllevel,
|
||||
attack.stance, attack.numAttackedAndDamage, attack.targets, attack.speed, attack.direction,
|
||||
attack.display), false, true);
|
||||
int numFinisherOrbs = 0;
|
||||
Integer comboBuff = chr.getBuffedValue(BuffStat.COMBO);
|
||||
if (GameConstants.isFinisherSkill(attack.skill)) {
|
||||
@@ -139,9 +141,9 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
}
|
||||
if (attack.numAttacked > 0 && attack.skill == DragonKnight.SACRIFICE) {
|
||||
int totDamageToOneMonster = 0; // sacrifice attacks only 1 mob with 1 attack
|
||||
final Iterator<List<Integer>> dmgIt = attack.allDamage.values().iterator();
|
||||
final Iterator<AttackTarget> dmgIt = attack.targets.values().iterator();
|
||||
if (dmgIt.hasNext()) {
|
||||
totDamageToOneMonster = dmgIt.next().get(0);
|
||||
totDamageToOneMonster = dmgIt.next().damageLines().getFirst();
|
||||
}
|
||||
|
||||
chr.safeAddHP(-1 * totDamageToOneMonster * attack.getAttackEffect(chr, null).getX() / 100);
|
||||
|
||||
@@ -66,7 +66,8 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
||||
}
|
||||
|
||||
int charge = (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) ? attack.charge : -1;
|
||||
Packet packet = PacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display);
|
||||
Packet packet = PacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance,
|
||||
attack.numAttackedAndDamage, attack.targets, charge, attack.speed, attack.direction, attack.display);
|
||||
|
||||
chr.getMap().broadcastMessage(chr, packet, false, true);
|
||||
StatEffect effect = attack.getAttackEffect(chr, null);
|
||||
@@ -84,8 +85,8 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
||||
Skill eaterSkill = SkillFactory.getSkill((chr.getJob().getId() - (chr.getJob().getId() % 10)) * 10000);// MP Eater, works with right job
|
||||
int eaterLevel = chr.getSkillLevel(eaterSkill);
|
||||
if (eaterLevel > 0) {
|
||||
for (Integer singleDamage : attack.allDamage.keySet()) {
|
||||
eaterSkill.getEffect(eaterLevel).applyPassive(chr, chr.getMap().getMapObject(singleDamage), 0);
|
||||
for (Integer oid : attack.targets.keySet()) {
|
||||
eaterSkill.getEffect(eaterLevel).applyPassive(chr, chr.getMap().getMapObject(oid), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,17 +83,23 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
|
||||
}
|
||||
|
||||
if (attack.skill == Buccaneer.ENERGY_ORB || attack.skill == ThunderBreaker.SPARK || attack.skill == Shadower.TAUNT || attack.skill == NightLord.TAUNT) {
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false);
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel,
|
||||
attack.stance, attack.numAttackedAndDamage, 0, attack.targets, attack.speed,
|
||||
attack.direction, attack.display), false);
|
||||
applyAttack(attack, chr, 1);
|
||||
} else if (attack.skill == ThunderBreaker.SHARK_WAVE && chr.getSkillLevel(ThunderBreaker.SHARK_WAVE) > 0) {
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false);
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel,
|
||||
attack.stance, attack.numAttackedAndDamage, 0, attack.targets, attack.speed,
|
||||
attack.direction, attack.display), false);
|
||||
applyAttack(attack, chr, 1);
|
||||
|
||||
for (int i = 0; i < attack.numAttacked; i++) {
|
||||
chr.handleEnergyChargeGain();
|
||||
}
|
||||
} else if (attack.skill == Aran.COMBO_SMASH || attack.skill == Aran.COMBO_FENRIR || attack.skill == Aran.COMBO_TEMPEST) {
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, 0, attack.allDamage, attack.speed, attack.direction, attack.display), false);
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel,
|
||||
attack.stance, attack.numAttackedAndDamage, 0, attack.targets, attack.speed,
|
||||
attack.direction, attack.display), false);
|
||||
if (attack.skill == Aran.COMBO_SMASH && chr.getCombo() >= 30) {
|
||||
chr.setCombo((short) 0);
|
||||
applyAttack(attack, chr, 1);
|
||||
@@ -213,10 +219,14 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
|
||||
case 3221001: // Pierce
|
||||
case 5221004: // Rapid Fire
|
||||
case 13111002: // KoC Hurricane
|
||||
packet = PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.rangedirection, attack.numAttackedAndDamage, visProjectile, attack.allDamage, attack.speed, attack.direction, attack.display);
|
||||
packet = PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.rangedirection,
|
||||
attack.numAttackedAndDamage, visProjectile, attack.targets, attack.speed,
|
||||
attack.direction, attack.display);
|
||||
break;
|
||||
default:
|
||||
packet = PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, visProjectile, attack.allDamage, attack.speed, attack.direction, attack.display);
|
||||
packet = PacketCreator.rangedAttack(chr, attack.skill, attack.skilllevel, attack.stance,
|
||||
attack.numAttackedAndDamage, visProjectile, attack.targets, attack.speed,
|
||||
attack.direction, attack.display);
|
||||
break;
|
||||
}
|
||||
chr.getMap().broadcastMessage(chr, packet, false, true);
|
||||
|
||||
Reference in New Issue
Block a user