- Хроники
- Fafurion
- Shadow of the Kamael
- Исходники
- Отсутствуют
- Сборка
- Mobius
Hello guys. I pass this day writing this code to ask old 1class itens for change class intead of just change without requirements.
PS:
I make it call the icon again in case of failure.
So its necessary send the packege just 1 time. And player will have it until he change the class.
Only 1jobs add... but u can follow the examples and add the others as u need.
Special thanks to @zikdoz
Java:
package org.l2jmobius.gameserver.network.clientpackets.classchange;
import java.util.EnumMap;
import java.util.Map;
import java.util.Map.Entry;
import org.l2jmobius.Config;
import org.l2jmobius.commons.network.ReadablePacket;
import org.l2jmobius.gameserver.data.xml.CategoryData;
import org.l2jmobius.gameserver.data.xml.SkillData;
import org.l2jmobius.gameserver.data.xml.SkillTreeData;
import org.l2jmobius.gameserver.enums.CategoryType;
import org.l2jmobius.gameserver.enums.ClassId;
import org.l2jmobius.gameserver.enums.Race;
import org.l2jmobius.gameserver.model.SkillLearn;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.network.GameClient;
import org.l2jmobius.gameserver.network.PacketLogger;
import org.l2jmobius.gameserver.network.clientpackets.ClientPacket;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.classchange.ExClassChangeSetAlarm;
/**
* @author Mobius, Horyon, zikdoz
*/
public class ExRequestClassChange implements ClientPacket
{
Items
private static final int MEDALLION_OF_WARRIOR = 1145; Warrior
private static final int SWORD_OF_RITUAL = 1161; Knight
private static final int BEZIQUES_RECOMMENDATION = 1190; Rogue
private static final int ELVEN_KNIGHT_BROOCH = 1204; Elven Knight
private static final int REISAS_RECOMMENDATION = 1217; Elven Scout
private static final int MARK_OF_FAITH = 1201; Cleric
private static final int ETERNITY_DIAMOND = 1230; Elven Wizard
private static final int LEAF_OF_ORACLE = 1235; Elven Oracle
private static final int BEAD_OF_SEASON = 1292; Wizard
private static final int GAZE_OF_ABYSS = 1244; Palus Knight
private static final int IRON_HEART = 1252; Assassins
private static final int JEWEL_OF_DARKNESS = 1261; Dark Wizard
private static final int ORB_OF_ABYSS = 1270; Shillien Oracle
private static final int MARK_OF_RAIDER = 1592; Orc Raider
private static final int KHAVATARI_TOTEM = 1615; Orc Monk
private static final int MASK_OF_MEDIUM = 1631; Orc Shamman
private static final int RING_OF_RAVEN = 1642; Scavenger
private static final int FINAL_PASS_CERTIFICATE = 1635; Artisan
Classes
private static final int WARRIOR = 1;
private static final int KNIGHT = 4;
private static final int ROGUE = 7;
private static final int ELVEN_KNIGHT = 19;
private static final int ELVEN_SCOUT = 22;
private static final int WIZARD = 11;
private static final int CLERIC = 15;
private static final int ELVEN_WIZARD = 26;
private static final int ORACLE = 29;
private static final int PALUS_KNIGHT = 32;
private static final int ASSASSIN = 35;
private static final int DARK_WIZARD = 39;
private static final int SHILLIEN_ORACLE = 42;
private static final int ORC_RAIDER = 45;
private static final int MONK = 47;
private static final int ORC_SHAMMAN = 50;
private static final int SCAVENGER = 54;
private static final int ARTISAN = 56;
private int _classId;
private static final String AWAKE_POWER_REWARDED_VAR = "AWAKE_POWER_REWARDED";
Reward
private static final int CHAOS_POMANDER = 37374;
private static final int VITALITY_MAINTAINING_RUNE = 80712;
private static final int AWAKE_POWER_EVIS = 40268;
private static final int AWAKE_POWER_SAYHA = 40269;
private static final Map<CategoryType, Integer> AWAKE_POWER = new EnumMap<>(CategoryType.class);
static
{
AWAKE_POWER.put(CategoryType.SIXTH_SIGEL_GROUP, 32264);
AWAKE_POWER.put(CategoryType.SIXTH_TIR_GROUP, 32265);
AWAKE_POWER.put(CategoryType.SIXTH_OTHEL_GROUP, 32266);
AWAKE_POWER.put(CategoryType.SIXTH_YR_GROUP, 32267);
AWAKE_POWER.put(CategoryType.SIXTH_FEOH_GROUP, 32268);
AWAKE_POWER.put(CategoryType.SIXTH_WYNN_GROUP, 32269);
AWAKE_POWER.put(CategoryType.SIXTH_IS_GROUP, 32270);
AWAKE_POWER.put(CategoryType.SIXTH_EOLH_GROUP, 32271);
}
@Override
public void read(ReadablePacket packet)
{
_classId = packet.readInt();
}
@Override
public void run(GameClient client)
{
final Player player = client.getPlayer();
if (player == null)
{
return;
}
Check if class id is valid.
boolean canChange = false;
for (ClassId cId : player.getClassId().getNextClassIds())
{
if (cId.getId() == _classId)
{
canChange = true;
break;
}
}
if (!canChange //
&& (_classId != 170) && (player.getClassId().getId() != 133)) // Female Soul Hound fix.
{
PacketLogger.warning(player + " tried to change class from " + player.getClassId() + " to " + ClassId.getClassId(_classId) + "!");
return;
}
Check for player proper class group and level.
canChange = false;
final int playerLevel = player.getLevel();
if (player.isInCategory(CategoryType.FIRST_CLASS_GROUP) && (playerLevel >= 20))
{
canChange = CategoryData.getInstance().isInCategory(player.getRace() == Race.ERTHEIA ? CategoryType.THIRD_CLASS_GROUP : CategoryType.SECOND_CLASS_GROUP, _classId);
}
else if (player.isInCategory(CategoryType.SECOND_CLASS_GROUP) && (playerLevel >= 40))
{
canChange = CategoryData.getInstance().isInCategory(CategoryType.THIRD_CLASS_GROUP, _classId);
}
else if (player.isInCategory(CategoryType.THIRD_CLASS_GROUP) && (playerLevel >= 76))
{
canChange = CategoryData.getInstance().isInCategory(CategoryType.FOURTH_CLASS_GROUP, _classId);
}
else if (player.isInCategory(CategoryType.FOURTH_CLASS_GROUP) && (playerLevel >= 85))
{
canChange = CategoryData.getInstance().isInCategory(CategoryType.SIXTH_CLASS_GROUP, _classId);
}
Change class.
if (canChange)
{
if (player.isSubClassActive())
{
player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
}
else
{
switch (_classId)
{
case WARRIOR:
if ((player.getClassId() == ClassId.FIGHTER) && (player.getInventory().getItemByItemId(MEDALLION_OF_WARRIOR) != null))
{
player.destroyItemByItemId("Change_class", MEDALLION_OF_WARRIOR, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case KNIGHT:
if ((player.getClassId() == ClassId.FIGHTER) && (player.getInventory().getItemByItemId(SWORD_OF_RITUAL) != null))
{
player.destroyItemByItemId("Change_class", SWORD_OF_RITUAL, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ROGUE:
if ((player.getClassId() == ClassId.FIGHTER) && (player.getInventory().getItemByItemId(BEZIQUES_RECOMMENDATION) != null))
{
player.destroyItemByItemId("Change_class", BEZIQUES_RECOMMENDATION, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ELVEN_KNIGHT:
if ((player.getClassId() == ClassId.ELVEN_FIGHTER) && (player.getInventory().getItemByItemId(ELVEN_KNIGHT_BROOCH) != null))
{
player.destroyItemByItemId("Change_class", ELVEN_KNIGHT_BROOCH, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ELVEN_SCOUT:
if ((player.getClassId() == ClassId.ELVEN_FIGHTER) && (player.getInventory().getItemByItemId(REISAS_RECOMMENDATION) != null))
{
player.destroyItemByItemId("Change_class", REISAS_RECOMMENDATION, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case WIZARD:
if ((player.getClassId() == ClassId.MAGE) && (player.getInventory().getItemByItemId(BEAD_OF_SEASON) != null))
{
player.destroyItemByItemId("Change_class", BEAD_OF_SEASON, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case CLERIC:
if ((player.getClassId() == ClassId.MAGE) && (player.getInventory().getItemByItemId(MARK_OF_FAITH) != null))
{
player.destroyItemByItemId("Change_class", MARK_OF_FAITH, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ELVEN_WIZARD:
if ((player.getClassId() == ClassId.ELVEN_MAGE) && (player.getInventory().getItemByItemId(ETERNITY_DIAMOND) != null))
{
player.destroyItemByItemId("Change_class", ETERNITY_DIAMOND, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ORACLE:
if ((player.getClassId() == ClassId.ELVEN_MAGE) && (player.getInventory().getItemByItemId(LEAF_OF_ORACLE) != null))
{
player.destroyItemByItemId("Change_class", LEAF_OF_ORACLE, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case PALUS_KNIGHT:
if ((player.getClassId() == ClassId.DARK_FIGHTER) && (player.getInventory().getItemByItemId(GAZE_OF_ABYSS) != null))
{
player.destroyItemByItemId("Change_class", GAZE_OF_ABYSS, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ASSASSIN:
if ((player.getClassId() == ClassId.DARK_FIGHTER) && (player.getInventory().getItemByItemId(IRON_HEART) != null))
{
player.destroyItemByItemId("Change_class", IRON_HEART, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case DARK_WIZARD:
if ((player.getClassId() == ClassId.DARK_MAGE) && (player.getInventory().getItemByItemId(JEWEL_OF_DARKNESS) != null))
{
player.destroyItemByItemId("Change_class", JEWEL_OF_DARKNESS, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case SHILLIEN_ORACLE:
if ((player.getClassId() == ClassId.DARK_MAGE) && (player.getInventory().getItemByItemId(ORB_OF_ABYSS) != null))
{
player.destroyItemByItemId("Change_class", ORB_OF_ABYSS, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ORC_RAIDER:
if ((player.getClassId() == ClassId.ORC_FIGHTER) && (player.getInventory().getItemByItemId(MARK_OF_RAIDER) != null))
{
player.destroyItemByItemId("Change_class", MARK_OF_RAIDER, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case MONK:
if ((player.getClassId() == ClassId.ORC_FIGHTER) && (player.getInventory().getItemByItemId(KHAVATARI_TOTEM) != null))
{
player.destroyItemByItemId("Change_class", KHAVATARI_TOTEM, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ORC_SHAMMAN:
if ((player.getClassId() == ClassId.ORC_MAGE) && (player.getInventory().getItemByItemId(MASK_OF_MEDIUM) != null))
{
player.destroyItemByItemId("Change_class", MASK_OF_MEDIUM, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case SCAVENGER:
if ((player.getClassId() == ClassId.DWARVEN_FIGHTER) && (player.getInventory().getItemByItemId(RING_OF_RAVEN) != null))
{
player.destroyItemByItemId("Change_class", RING_OF_RAVEN, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
case ARTISAN:
if ((player.getClassId() == ClassId.DWARVEN_FIGHTER) && (player.getInventory().getItemByItemId(FINAL_PASS_CERTIFICATE) != null))
{
player.destroyItemByItemId("Change_class", FINAL_PASS_CERTIFICATE, 1, player, true);
player.setClassId(_classId);
player.setBaseClass(player.getActiveClass());
}
else
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
break;
default:
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET); default action if _classId doesn't match any of the above cases
break;
}
}
if (player.isInCategory(CategoryType.SIXTH_CLASS_GROUP))
{
SkillTreeData.getInstance().cleanSkillUponChangeClass(player); TODO: Move to skill learn method?
for (SkillLearn skill : SkillTreeData.getInstance().getRaceSkillTree(player.getRace()))
{
player.addSkill(SkillData.getInstance().getSkill(skill.getSkillId(), skill.getSkillLevel()), true);
}
if (Config.DISABLE_TUTORIAL && !player.getVariables().getBoolean(AWAKE_POWER_REWARDED_VAR, false))
{
player.addItem("awake", VITALITY_MAINTAINING_RUNE, 1, player, true);
player.addItem("awake", CHAOS_POMANDER, 2, player, true);
if (player.getRace() == Race.ERTHEIA)
{
if (player.getClassId() == ClassId.EVISCERATOR)
{
player.getVariables().set(AWAKE_POWER_REWARDED_VAR, true);
player.addItem("awake", AWAKE_POWER_EVIS, 1, player, true);
}
if (player.getClassId() == ClassId.SAYHA_SEER)
{
player.getVariables().set(AWAKE_POWER_REWARDED_VAR, true);
player.addItem("awake", AWAKE_POWER_SAYHA, 1, player, true);
}
}
else
{
for (Entry<CategoryType, Integer> ent : AWAKE_POWER.entrySet())
{
if (player.isInCategory(ent.getKey()))
{
player.getVariables().set(AWAKE_POWER_REWARDED_VAR, true);
player.addItem("awake", ent.getValue().intValue(), 1, player, true);
break;
}
}
}
}
}
if (Config.AUTO_LEARN_SKILLS)
{
player.giveAvailableSkills(Config.AUTO_LEARN_FS_SKILLS, Config.AUTO_LEARN_FP_SKILLS, true, Config.AUTO_LEARN_SKILLS_WITHOUT_ITEMS);
}
player.store(false); Save player cause if server crashes before this char is saved, he will lose class.
player.broadcastUserInfo();
player.sendSkillList();
player.sendPacket(new PlaySound("ItemSound.quest_fanfare_2"));
if (Config.DISABLE_TUTORIAL && !player.isInCategory(CategoryType.SIXTH_CLASS_GROUP) //
&& ((player.isInCategory(CategoryType.SECOND_CLASS_GROUP) && (playerLevel >= 38)) //
|| (player.isInCategory(CategoryType.THIRD_CLASS_GROUP) && (playerLevel >= 76)) //
|| (player.isInCategory(CategoryType.FOURTH_CLASS_GROUP) && (playerLevel >= 85))))
{
player.sendPacket(ExClassChangeSetAlarm.STATIC_PACKET);
}
}
}
}
PS:
I make it call the icon again in case of failure.
So its necessary send the packege just 1 time. And player will have it until he change the class.
Only 1jobs add... but u can follow the examples and add the others as u need.
Special thanks to @zikdoz