package server;
import clientside.MapleBuffStat;
import clientside.MapleCharacter;
import clientside.MapleStat;
import handling.channel.handler.AttackInfo;
import server.life.MapleLifeFactory;
import server.life.MapleMonster;
import server.maps.MapleMap;
import tools.packet.CField;
import tools.packet.CWvsContext;
public class MaplePVP {
private static int pvpDamage;
private static int maxDis;
private static int maxHeight;
private static boolean isAoe = false;
public static boolean isLeft = false;
public static boolean isRight = false;
private static boolean isMeleeAttack(AttackInfo attack) {
switch (attack.skill) {
case 1001004: //Power Strike
case 1001005: //Slash Blast
case 4001334: //Double Stab
case 4201005: //Savage Blow
case 1111004: //Panic: Axe
case 1111003: //Panic: Sword
case 1311004: //Dragon Fury: Pole Arm
case 1311003: //Dragon Fury: Spear
case 1311002: //Pole Arm Crusher
case 1311005: //Sacrifice
case 1311001: //Spear Crusher
case 1121008: //Brandish
case 1221009: //Blast
case 1121006: //Rush
case 1221007: //Rush
case 1321003: //Rush
case 4221001: //Assassinate
return true;
}
return false;
}
private static boolean isRangeAttack(AttackInfo attack) {
switch (attack.skill) {
case 2001004: //Energy Bolt
case 2001005: //Magic Claw
case 3001004: //Arrow Blow
case 3001005: //Double Shot
case 4001344: //Lucky Seven
case 2101004: //Fire Arrow
case 2101005: //Poison Brace
case 2201004: //Cold Beam
case 2301005: //Holy Arrow
case 4101005: //Drain
case 2211002: //Ice Strike
case 2211003: //Thunder Spear
case 3111006: //Strafe
case 3211006: //Strafe
case 4111005: //Avenger
case 4211002: //Assaulter
case 2121003: //Fire Demon
case 2221006: //Chain Lightning
case 2221003: //Ice Demon
case 2111006: //Element Composition F/P
case 2211006: //Element Composition I/L
case 2321007: //Angel's Ray
case 3121003: //Dragon Pulse
case 3121004: //Hurricane
case 3221003: //Dragon Pulse
case 3221001: //Piercing
case 3221007: //Sniping
case 4121003: //Showdown taunt
case 4121007: //Triple Throw
case 4221007: //Boomerang Step
case 4221003: //Showdown taunt
case 4111004: //Shadow Meso
return true;
}
return false;
}
private static boolean isAoeAttack(AttackInfo attack) {
switch (attack.skill) {
case 2201005: //Thunderbolt
case 3101005: //Arrow Bomb : Bow
case 3201005: //Iron Arrow : Crossbow
case 1111006: //Coma: Axe
case 1111005: //Coma: Sword
case 1211002: //Charged Blow
case 1311006: //Dragon Roar
case 2111002: //Explosion
case 2111003: //Poison Mist
case 2311004: //Shining Ray
case 3111004: //Arrow Rain
case 3111003: //Inferno
case 3211004: //Arrow Eruption
case 3211003: //Blizzard (Sniper)
case 4211004: //Band of Thieves
case 1221011: //Sanctuary Skill
case 2121001: //Big Bang
case 2121007: //Meteo
case 2121006: //Paralyze
case 2221001: //Big Bang
case 2221007: //Blizzard
case 2321008: //Genesis
case 2321001: //Big Bang
case 4121004: //Ninja Ambush
case 4121008: //Ninja Storm knockback
case 4221004: //Ninja Ambush
return true;
}
return false;
}
private static void getDirection(AttackInfo attack) {
isRight = true;
isLeft = true;
}
private static void DamageBalancer(AttackInfo attack) {
if (attack.skill == 0) {
pvpDamage = 100;
maxDis = 130;
maxHeight = 35;
} else if (isMeleeAttack(attack)) {
maxDis = 130;
maxHeight = 45;
isAoe = false;
if (attack.skill == 4201005) {
pvpDamage = (int) (Math.floor(Math.random() * (75 - 5) + 5));
} else if (attack.skill == 1121008) {
pvpDamage = (int) (Math.floor(Math.random() * (320 - 180) + 180));
maxHeight = 50;
} else if (attack.skill == 4221001) {
pvpDamage = (int) (Math.floor(Math.random() * (200 - 150) + 150));
} else if (attack.skill == 1121006 || attack.skill == 1221007 || attack.skill == 1321003) {
pvpDamage = (int) (Math.floor(Math.random() * (200 - 80) + 80));
} else {
pvpDamage = (int) (Math.floor(Math.random() * (600 - 250) + 250));
}
} else if (isRangeAttack(attack)) {
maxDis = 300;
maxHeight = 40;
isAoe = false;
if (attack.skill == 4201005) {
pvpDamage = (int) (Math.floor(Math.random() * (75 - 5) + 5));
} else if (attack.skill == 4121007) {
pvpDamage = (int) (Math.floor(Math.random() * (60 - 15) + 15));
} else if (attack.skill == 4001344 || attack.skill == 2001005) {
pvpDamage = (int) (Math.floor(Math.random() * (195 - 90) + 90));
} else if (attack.skill == 4221007) {
pvpDamage = (int) (Math.floor(Math.random() * (350 - 180) + 180));
} else if (attack.skill == 3121004 || attack.skill == 3111006 || attack.skill == 3211006) {
maxDis = 450;
pvpDamage = (int) (Math.floor(Math.random() * (50 - 20) + 20));
} else if (attack.skill == 2121003 || attack.skill == 2221003) {
pvpDamage = (int) (Math.floor(Math.random() * (600 - 300) + 300));
} else {
pvpDamage = (int) (Math.floor(Math.random() * (400 - 250) + 250));
}
} else if (isAoeAttack(attack)) {
maxDis = 350;
maxHeight = 350;
isAoe = true;
if (attack.skill == 2121001 || attack.skill == 2221001 || attack.skill == 2321001 || attack.skill == 2121006) {
maxDis = 175;
maxHeight = 175;
pvpDamage = (int) (Math.floor(Math.random() * (350 - 180) + 180));
} else {
pvpDamage = (int) (Math.floor(Math.random() * (700 - 300) + 300));
}
}
}
private static void monsterBomb(MapleCharacter player, MapleCharacter attackedPlayers, MapleMap map, AttackInfo attack) {
//level balances
if (attackedPlayers.getLevel() > player.getLevel() + 25) {
pvpDamage *= 1.35;
} else if (attackedPlayers.getLevel() < player.getLevel() - 25) {
pvpDamage /= 1.35;
} else if (attackedPlayers.getLevel() > player.getLevel() + 100) {
pvpDamage *= 1.50;
} else if (attackedPlayers.getLevel() < player.getLevel() - 100) {
pvpDamage /= 1.50;
}
//buff modifiers
Integer mguard = attackedPlayers.getBuffedValue(MapleBuffStat.MAGIC_GUARD);
Integer mesoguard = attackedPlayers.getBuffedValue(MapleBuffStat.MESOGUARD);
if (mguard != null) {
int mploss = (int) (pvpDamage / .5);
pvpDamage *= .70;
if (mploss > attackedPlayers.getStat().getMp()) {
pvpDamage /= .70;
attackedPlayers.cancelEffectFromBuffStat(MapleBuffStat.MAGIC_GUARD);
} else {
attackedPlayers.setMp(attackedPlayers.getStat().getMp() - mploss);
attackedPlayers.updateSingleStat(MapleStat.MP, attackedPlayers.getStat().getMp());
}
} else if (mesoguard != null) {
int mesoloss = (int) (pvpDamage * .75);
pvpDamage *= .75;
if (mesoloss > attackedPlayers.getMeso()) {
pvpDamage /= .75;
attackedPlayers.cancelEffectFromBuffStat(MapleBuffStat.MESOGUARD);
} else {
attackedPlayers.gainMeso(-mesoloss, false);
}
}
//set up us teh bonmb
//training thingy = 9409000
MapleMonster pvpMob = MapleLifeFactory.getMonster(9400711);
map.spawnMonsterOnGroundBelow(pvpMob, attackedPlayers.getPosition());
for (int attacks = 0; attacks < attack.hits; attacks++) {
if (attack.skill == 0) {
map.broadcastMessage(CField.damagePlayer2(attackedPlayers.getId(), 1, pvpDamage, pvpMob.getId(), attack.skill));
// map.broadcastMessage(CField.damagePlayer(attackedPlayers.getId(), type, pvpDamage, pvpMob.getId(, direction, skillid, pDMG, pPhysical, pID, pType, pPos, offset, offset_d, fake), false);
attackedPlayers.addHP(-pvpDamage);
} else {
map.broadcastMessage(CField.damagePlayer2(attackedPlayers.getId(), 1, pvpDamage * attackedPlayers.getLevel(), pvpMob.getId(), attack.skill));
// map.broadcastMessage(CField.damagePlayer(attackedPlayers.getId(), type, pvpDamage, pvpMob.getId(, direction, skillid, pDMG, pPhysical, pID, pType, pPos, offset, offset_d, fake), false);
attackedPlayers.addHP(-pvpDamage * attackedPlayers.getLevel());
}
}
int attackedDamage = 0;
if (attack.skill == 0) {
attackedDamage = pvpDamage * attack.hits * attackedPlayers.getLevel();
} else {
attackedDamage = pvpDamage * attack.hits * attackedPlayers.getLevel();
}
attackedPlayers.getClient().getSession().write(CWvsContext.serverNotice(5, player.getName() + " has hit you for " + attackedDamage + " damage!"));
map.killMonster(pvpMob, player, false, false, (byte) -1);
//rewards
if (attackedPlayers.getStat().getHp() <= 0 && !attackedPlayers.isAlive()) {
int expReward = attackedPlayers.getLevel() * 100;
int gpReward = (int) (Math.floor(Math.random() * (200 - 50) + 50));
if (player.getLevel() * .25 >= player.getLevel()) {
expReward *= 20;
}
player.gainExp(expReward, true, true, true);
// player.gainPvpKill();
player.getClient().getSession().write(CWvsContext.serverNotice(6, "You've killed " + attackedPlayers.getName() + "!! You've gained a pvp kill!"));
// attackedPlayers.gainPvpDeath();
attackedPlayers.getClient().getSession().write(CWvsContext.serverNotice(6, player.getName() + " has killed you!"));
}
}
public static void doPvP(MapleCharacter player, MapleMap map, AttackInfo attack) {
DamageBalancer(attack);
getDirection(attack);
for (MapleCharacter attackedPlayers : player.getMap().getNearestPvpChar(player.getPosition(), maxDis, maxHeight, player.getMap().getCharacters())) {
if (attackedPlayers.isAlive() && (player.getParty() == null || player.getParty() != attackedPlayers.getParty())) {
monsterBomb(player, attackedPlayers, map, attack);
}
}
}
}