package javastory.channel.handling;
import java.util.List;
import com.google.common.collect.Lists;
import javastory.channel.ChannelCharacter;
import javastory.channel.ChannelClient;
import javastory.channel.client.ActivePlayerStats;
import javastory.channel.client.ISkill;
import javastory.channel.server.AutobanManager;
import javastory.game.Skills;
import javastory.game.Stat;
import javastory.game.StatValue;
import javastory.game.data.SkillInfoProvider;
import javastory.io.PacketFormatException;
import javastory.io.PacketReader;
import javastory.tools.Randomizer;
import javastory.tools.packets.ChannelPackets;
public class StatsHandling {
public static void handleDistributeAbilityPoints(final PacketReader reader, final ChannelClient c, final ChannelCharacter chr) throws PacketFormatException {
final List<StatValue> statupdate = Lists.newArrayListWithCapacity(2);
c.write(ChannelPackets.updatePlayerStats(statupdate, true, chr.getJobId()));
reader.skip(4);
final ActivePlayerStats stat = chr.getStats();
if (chr.getRemainingAp() > 0) {
final ChannelCharacter player = c.getPlayer();
switch (reader.readInt()) {
case 64: // Str
if (stat.getStr() >= player.getMaxStats()) {
return;
}
stat.setStr(stat.getStr() + 1);
statupdate.add(new StatValue(Stat.STR, stat.getStr()));
break;
case 128: // Dex
if (stat.getDex() >= player.getMaxStats()) {
return;
}
stat.setDex(stat.getDex() + 1);
statupdate.add(new StatValue(Stat.DEX, stat.getDex()));
break;
case 256: // Int
if (stat.getInt() >= player.getMaxStats()) {
return;
}
stat.setInt(stat.getInt() + 1);
statupdate.add(new StatValue(Stat.INT, stat.getInt()));
break;
case 512: // Luk
if (stat.getLuk() >= player.getMaxStats()) {
return;
}
stat.setLuk(stat.getLuk() + 1);
statupdate.add(new StatValue(Stat.LUK, stat.getLuk()));
break;
case 2048: // HP
int MaxHP = stat.getMaxHp();
if (chr.getHpApUsed() >= 10000 || MaxHP >= 30000) {
return;
}
ISkill improvingMaxHP = null;
int improvingMaxHPLevel = 0;
if (chr.getJobId() == 0) { // Beginner
MaxHP += Randomizer.rand(8, 12);
} else if (chr.getJobId() >= 100 && chr.getJobId() <= 132) { // Warrior
improvingMaxHP = SkillInfoProvider.getSkill(1000001);
improvingMaxHPLevel = chr.getCurrentSkillLevel(improvingMaxHP);
MaxHP += Randomizer.rand(20, 24);
if (improvingMaxHPLevel >= 1) {
MaxHP += improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
}
} else if (chr.getJobId() >= 200 && chr.getJobId() <= 232) { // Magician
MaxHP += Randomizer.rand(6, 10);
} else if (chr.getJobId() >= 300 && chr.getJobId() <= 322) { // Bowman
MaxHP += Randomizer.rand(16, 20);
} else if (chr.getJobId() >= 400 && chr.getJobId() <= 422) { // Thief
MaxHP += Randomizer.rand(20, 24);
} else if (chr.getJobId() >= 500 && chr.getJobId() <= 522) { // Pirate
improvingMaxHP = SkillInfoProvider.getSkill(5100000);
improvingMaxHPLevel = chr.getCurrentSkillLevel(improvingMaxHP);
MaxHP += Randomizer.rand(16, 20);
if (improvingMaxHPLevel >= 1) {
MaxHP += improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
}
} else if (chr.getJobId() >= 1100 && chr.getJobId() <= 1111) { // Soul Master
improvingMaxHP = SkillInfoProvider.getSkill(11000000);
improvingMaxHPLevel = chr.getCurrentSkillLevel(improvingMaxHP);
MaxHP += Randomizer.rand(36, 42);
if (improvingMaxHPLevel >= 1) {
MaxHP += improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
}
} else if (chr.getJobId() >= 1200 && chr.getJobId() <= 1211) { // Flame Wizard
MaxHP += Randomizer.rand(15, 21);
} else if (chr.getJobId() >= 1300 && chr.getJobId() <= 1311 || chr.getJobId() >= 1400 && chr.getJobId() <= 1411) { // Wind Breaker and Night Walker
MaxHP += Randomizer.rand(30, 36);
} else { // GameMaster
MaxHP += Randomizer.rand(50, 100);
}
MaxHP = Math.min(30000, MaxHP);
chr.setHpApUsed(chr.getHpApUsed() + 1);
stat.setMaxHp(MaxHP);
statupdate.add(new StatValue(Stat.MAX_HP, MaxHP));
break;
case 8192: // MP
int MaxMP = stat.getMaxMp();
if (chr.getMpApUsed() >= 10000 && stat.getMaxMp() >= 30000) {
return;
}
if (chr.getJobId() == 0) { // Beginner
MaxMP += Randomizer.rand(6, 8);
} else if (chr.getJobId() >= 100 && chr.getJobId() <= 132) { // Warrior
MaxMP += Randomizer.rand(2, 4);
} else if (chr.getJobId() >= 200 && chr.getJobId() <= 232) { // Magician
final ISkill improvingMaxMP = SkillInfoProvider.getSkill(2000001);
final int improvingMaxMPLevel = chr.getCurrentSkillLevel(improvingMaxMP);
if (improvingMaxMPLevel >= 1) {
MaxMP += Randomizer.rand(18, 20) + improvingMaxMP.getEffect(improvingMaxMPLevel).getY();
} else {
MaxMP += Randomizer.rand(18, 20);
}
} else if (chr.getJobId() >= 300 && chr.getJobId() <= 322) { // Bowman
MaxMP += Randomizer.rand(10, 12);
} else if (chr.getJobId() >= 400 && chr.getJobId() <= 422) { // Thief
MaxMP += Randomizer.rand(10, 12);
} else if (chr.getJobId() >= 500 && chr.getJobId() <= 522) { // Pirate
MaxMP += Randomizer.rand(10, 12);
} else if (chr.getJobId() >= 1100 && chr.getJobId() <= 1111) { // Soul Master
MaxMP += Randomizer.rand(6, 9);
} else if (chr.getJobId() >= 1200 && chr.getJobId() <= 1211) { // Flame Wizard
final ISkill improvingMaxMP = SkillInfoProvider.getSkill(12000000);
final int improvingMaxMPLevel = chr.getCurrentSkillLevel(improvingMaxMP);
MaxMP += Randomizer.rand(33, 36);
if (improvingMaxMPLevel >= 1) {
MaxMP += improvingMaxMP.getEffect(improvingMaxMPLevel).getY();
}
} else if (chr.getJobId() >= 1300 && chr.getJobId() <= 1311 || chr.getJobId() >= 1400 && chr.getJobId() <= 1411) { // Wind Breaker and Night Walker
MaxMP += Randomizer.rand(21, 24);
} else { // GameMaster
MaxMP += Randomizer.rand(50, 100);
}
MaxMP = Math.min(30000, MaxMP);
chr.setMpApUsed(chr.getMpApUsed() + 1);
stat.setMaxMp(MaxMP);
statupdate.add(new StatValue(Stat.MAX_MP, MaxMP));
break;
default:
c.write(ChannelPackets.updatePlayerStats(ChannelPackets.EMPTY_STATUPDATE, true, chr.getJobId()));
return;
}
chr.setRemainingAp(chr.getRemainingAp() - 1);
statupdate.add(new StatValue(Stat.AVAILABLE_AP, chr.getRemainingAp()));
c.write(ChannelPackets.updatePlayerStats(statupdate, true, chr.getJobId()));
}
}
public static void handleDistributeSkillPoints(final int skillid, final ChannelClient c, final ChannelCharacter chr) {
boolean isBeginnerSkill = false;
int remainingSp = 0;
switch (skillid) {
case 1000:
case 1001:
case 1002: {
final int snailsLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(1000));
final int recoveryLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(1001));
final int nimbleFeetLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(1002));
remainingSp = Math.min(chr.getLevel() - 1, 6) - snailsLevel - recoveryLevel - nimbleFeetLevel;
isBeginnerSkill = true;
break;
}
case 10001000:
case 10001001:
case 10001002: {
final int snailsLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(10001000));
final int recoveryLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(10001001));
final int nimbleFeetLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(10001002));
remainingSp = Math.min(chr.getLevel() - 1, 6) - snailsLevel - recoveryLevel - nimbleFeetLevel;
isBeginnerSkill = true;
break;
}
case 20001000:
case 20001001:
case 20001002: {
final int snailsLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(20001000));
final int recoveryLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(20001001));
final int nimbleFeetLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(20001002));
remainingSp = Math.min(chr.getLevel() - 1, 6) - snailsLevel - recoveryLevel - nimbleFeetLevel;
isBeginnerSkill = true;
break;
}
case 20011000:
case 20011001:
case 20011002: {
final int snailsLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(20011000));
final int recoveryLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(20011001));
final int nimbleFeetLevel = chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(20011002));
remainingSp = Math.min(chr.getLevel() - 1, 6) - snailsLevel - recoveryLevel - nimbleFeetLevel;
isBeginnerSkill = true;
break;
}
default: {
remainingSp = chr.getRemainingSp(Skills.getSkillbookForSkill(skillid));
break;
}
}
final ISkill skill = SkillInfoProvider.getSkill(skillid);
if (skill.hasRequiredSkill()) {
if (chr.getCurrentSkillLevel(SkillInfoProvider.getSkill(skill.getRequiredSkillId())) < skill.getRequiredSkillLevel()) {
AutobanManager.getInstance().addPoints(c, 1000, 0, "Trying to learn a skill without the required skill (" + skillid + ")");
return;
}
}
final int maxlevel = skill.isFourthJob() ? chr.getMasterSkillLevel(skill) : skill.getMaxLevel();
final int curLevel = chr.getCurrentSkillLevel(skill);
if (skill.isInvisible() && chr.getCurrentSkillLevel(skill) == 0) {
if (skill.isFourthJob() && chr.getMasterSkillLevel(skill) == 0 || !skill.isFourthJob() && maxlevel < 10) {
AutobanManager.getInstance().addPoints(c, 1000, 0, "Illegal distribution of SP to invisible skills (" + skillid + ")");
return;
}
}
if (remainingSp > 0 && curLevel + 1 <= maxlevel && skill.canBeLearnedBy(chr.getJobId())) {
if (!isBeginnerSkill) {
final int skillbook = Skills.getSkillbookForSkill(skillid);
chr.setRemainingSp(chr.getRemainingSp(skillbook) - 1, skillbook);
}
chr.updateSingleStat(Stat.AVAILABLE_SP, chr.getRemainingSp());
chr.changeSkillLevel(skill, (byte) (curLevel + 1), chr.getMasterSkillLevel(skill));
} else if (!skill.canBeLearnedBy(chr.getJobId())) {
AutobanManager.getInstance().addPoints(c, 1000, 0, "Trying to learn a skill for a different job (" + skillid + ")");
}
}
public static void handleAutoAssignAbilityPoints(final PacketReader reader, final ChannelClient c, final ChannelCharacter chr) throws PacketFormatException {
reader.skip(8);
final int PrimaryStat = reader.readInt();
final int amount = reader.readInt();
final int SecondaryStat = reader.readInt();
final int amount2 = reader.readInt();
final ActivePlayerStats playerst = chr.getStats();
final List<StatValue> statupdate = Lists.newArrayListWithCapacity(2);
c.write(ChannelPackets.updatePlayerStats(statupdate, true, chr.getJobId()));
if (chr.getRemainingAp() == amount + amount2) {
switch (PrimaryStat) {
case 64: // Str
if (playerst.getStr() + amount > 999) {
return;
}
playerst.setStr(playerst.getStr() + amount);
statupdate.add(new StatValue(Stat.STR, playerst.getStr()));
break;
case 128: // Dex
if (playerst.getDex() + amount > 999) {
return;
}
playerst.setDex(playerst.getDex() + amount);
statupdate.add(new StatValue(Stat.DEX, playerst.getDex()));
break;
case 256: // Int
if (playerst.getInt() + amount > 999) {
return;
}
playerst.setInt(playerst.getInt() + amount);
statupdate.add(new StatValue(Stat.INT, playerst.getInt()));
break;
case 512: // Luk
if (playerst.getLuk() + amount > 999) {
return;
}
playerst.setLuk(playerst.getLuk() + amount);
statupdate.add(new StatValue(Stat.LUK, playerst.getLuk()));
break;
default:
c.write(ChannelPackets.updatePlayerStats(ChannelPackets.EMPTY_STATUPDATE, true, chr.getJobId()));
return;
}
switch (SecondaryStat) {
case 64: // Str
if (playerst.getStr() + amount2 > 999) {
return;
}
playerst.setStr(playerst.getStr() + amount2);
statupdate.add(new StatValue(Stat.STR, playerst.getStr()));
break;
case 128: // Dex
if (playerst.getDex() + amount2 > 999) {
return;
}
playerst.setDex(playerst.getDex() + amount2);
statupdate.add(new StatValue(Stat.DEX, playerst.getDex()));
break;
case 256: // Int
if (playerst.getInt() + amount2 > 999) {
return;
}
playerst.setInt(playerst.getInt() + amount2);
statupdate.add(new StatValue(Stat.INT, playerst.getInt()));
break;
case 512: // Luk
if (playerst.getLuk() + amount2 > 999) {
return;
}
playerst.setLuk(playerst.getLuk() + amount2);
statupdate.add(new StatValue(Stat.LUK, playerst.getLuk()));
break;
default:
c.write(ChannelPackets.updatePlayerStats(ChannelPackets.EMPTY_STATUPDATE, true, chr.getJobId()));
return;
}
chr.setRemainingAp(chr.getRemainingAp() - (amount + amount2));
statupdate.add(new StatValue(Stat.AVAILABLE_AP, chr.getRemainingAp()));
c.write(ChannelPackets.updatePlayerStats(statupdate, true, chr.getJobId()));
}
}
}