Originally, once I perform the rebirth, character level is decreased to level 1 and it turns to first class. I need to modify this, as that, once the rebirth is done, the charachter should keep the third class status and get the level 1 skills. It just needs a few code modifications that I can't manage how to do them (java newbie :P). Hope you can help me with that.
PS: Sorry for my bad english, and don't think i'm planning to open a live server, I just want to play with some friends (old l2gold players)
Cheers,
- Junkee
This is the code:
### Eclipse Workspace Patch 1.0
#P aCis_gameserver
Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkillInfo.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkillInfo.java (revision 4)
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkillInfo.java (working copy)
@@ -17,8 +17,8 @@
import net.sf.l2j.Config;
import net.sf.l2j.gameserver.datatables.SkillTable;
import net.sf.l2j.gameserver.datatables.SkillTreeTable;
-import net.sf.l2j.gameserver.datatables.SpellbookTable;
import net.sf.l2j.gameserver.model.L2PledgeSkillLearn;
+import net.sf.l2j.gameserver.model.L2RebirthSkillLearn;
import net.sf.l2j.gameserver.model.L2Skill;
import net.sf.l2j.gameserver.model.L2SkillLearn;
import net.sf.l2j.gameserver.model.actor.L2Npc;
@@ -62,7 +62,7 @@
switch (_skillType)
{
- // General skills
+ // Trance's Rebirth skills.
case 0:
int skillLvl = activeChar.getSkillLevel(_skillId);
if (skillLvl >= _skillLevel)
@@ -74,14 +74,13 @@
if (!trainer.getTemplate().canTeach(activeChar.getSkillLearningClassId()))
return;
- for (L2SkillLearn sl : SkillTreeTable.getInstance().getAvailableSkills(activeChar, activeChar.getSkillLearningClassId()))
+ for (L2RebirthSkillLearn rsl : SkillTreeTable.getInstance().getAvailableRebirthSkills(activeChar, activeChar.getSkillLearningClassId()))
{
- if (sl.getId() == _skillId && sl.getLevel() == _skillLevel)
+ if (rsl.getId() == _skillId && rsl.getLevel() == _skillLevel)
{
- AcquireSkillInfo asi = new AcquireSkillInfo(_skillId, _skillLevel, sl.getSpCost(), 0);
- int spellbookItemId = SpellbookTable.getInstance().getBookForSkill(_skillId, _skillLevel);
- if (spellbookItemId != 0)
- asi.addRequirement(99, spellbookItemId, 1, 50);
+ AcquireSkillInfo asi = new AcquireSkillInfo(_skillId, _skillLevel, rsl.getCostSp(), 0);
+ if (Config.LIFE_CRYSTAL_NEEDED && rsl.getItemId() != 0)
+ asi.addRequirement(1, rsl.getItemId(), 1, 0);
sendPacket(asi);
break;
}
Index: java/net/sf/l2j/gameserver/model/base/ClassId.java
===================================================================
--- java/net/sf/l2j/gameserver/model/base/ClassId.java (revision 4)
+++ java/net/sf/l2j/gameserver/model/base/ClassId.java (working copy)
@@ -248,4 +248,15 @@
{
return _parent;
}
+
+ /**
+ * @return to the first class
+ */
+ public final ClassId getFirstClass()
+ {
+ if (_parent == null)
+ return this;
+
+ return _parent.getFirstClass();
+ }
}
\ No newline at end of file
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2RebirthInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2RebirthInstance.java (revision 0)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2RebirthInstance.java (working copy)
@@ -0,0 +1,301 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.model.actor.instance;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.HashMap;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.gameserver.model.base.Experience;
+import net.sf.l2j.gameserver.model.L2ItemInstance;
+import net.sf.l2j.gameserver.model.L2Skill;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.network.SystemMessageId;
+import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
+import net.sf.l2j.gameserver.network.serverpackets.StatusUpdate;
+import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
+import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate;
+
+/**
+ * Rebirth Manager
+ * @author Trance
+ * @skype chr.trance
+ */
+public final class L2RebirthInstance extends L2NpcInstance
+{
+ private static HashMap<Integer, Integer> _rebirthInfo = new HashMap<>();
+
+ public L2RebirthInstance(int objectId, L2NpcTemplate template)
+ {
+ super(objectId, template);
+ }
+
+ @Override
+ public void onBypassFeedback(L2PcInstance player, String command)
+ {
+ if (command.startsWith("performRebirth"))
+ {
+ // Maximum rebirth count. Return the player's current Rebirth Level.
+ int currBirth = getRebirthLevel(player);
+ if (currBirth >= Config.REBIRTH_MAX)
+ {
+ NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+ html.setFile("data/html/managers/rebirth-max.htm");
+
+ player.sendPacket(html);
+ return;
+ }
+
+ // Level requirement for a rebirth.
+ if (player.getLevel() < Config.REBIRTH_MIN_LEVEL)
+ {
+ NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+ html.setFile("data/html/managers/rebirth-level.htm");
+
+ player.sendPacket(html);
+ return;
+ }
+
+ int itemId = 0, itemCount = 0, loopBirth = 0;
+ for (String readItems : Config.REBIRTH_ITEMS)
+ {
+ String[] currItem = readItems.split(",");
+ if (loopBirth == currBirth)
+ {
+ itemId = Integer.parseInt(currItem[0]);
+ itemCount = Integer.parseInt(currItem[1]);
+ break;
+ }
+ loopBirth++;
+ }
+
+ // Rewards the player with an item.
+ rebirthItemReward(player, itemId, itemCount);
+
+ // Check and see if its the player's first rebirth calling.
+ boolean firstBirth = currBirth == 0;
+
+ // Player meets requirements and starts Rebirth process.
+ grantRebirth(player, (currBirth + 1), firstBirth);
+ }
+ else
+ super.onBypassFeedback(player, command);
+ }
+
+ @Override
+ public void showChatWindow(L2PcInstance player)
+ {
+ NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+ html.setFile("data/html/managers/rebirth.htm");
+ html.replace("%objectId%", String.valueOf(getObjectId()));
+ html.replace("%level%", + Config.REBIRTH_RETURN_TO_LEVEL);
+
+ player.sendPacket(html);
+ }
+
+ /**
+ * Physically rewards player and resets status to nothing.
+ *
+ * @param player the player
+ * @param newBirthCount the new birth count
+ * @param firstBirth the first birth
+ */
+ public void grantRebirth(L2PcInstance player, int newBirthCount, boolean firstBirth)
+ {
+ try
+ {
+ // Delevel.
+ player.removeExpAndSp(player.getExp() - Experience.LEVEL[Config.REBIRTH_RETURN_TO_LEVEL], 0);
+
+ // Back to the first class.
+ player.setClassId(player.getClassId().getFirstClass().getId());
+
+ // Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance
+ player.broadcastStatusUpdate();
+
+ // Broadcast informations from a user to himself and his knownlist.
+ player.broadcastUserInfo();
+
+ // Remove the player's current skills.
+ for (L2Skill skill : player.getAllSkills())
+ player.removeSkill(skill);
+
+ // Give all available skills to the player.
+ player.giveAvailableSkills();
+
+ // Update L2PcInstance stats in the characters table of the database.
+ player.store();
+
+ if (firstBirth)
+ // Stores the player's information in the DB.
+ storePlayerBirth(player);
+ else
+ // Updates the player's information in the DB.
+ updatePlayerBirth(player, newBirthCount);
+
+ // Displays a congratulation window to the player.
+ NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+ html.setFile("data/html/managers/rebirth-successfully.htm");
+ html.replace("%level%", + Config.REBIRTH_RETURN_TO_LEVEL);
+
+ player.sendPacket(html);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Rewards the player with an item.
+ *
+ * @param player the player
+ * @param itemId : Identifier of the item.
+ * @param itemCount : Quantity of items to add.
+ */
+ public static void rebirthItemReward(L2PcInstance player, int itemId, int itemCount)
+ {
+ // Incorrect amount.
+ if (itemCount <= 0)
+ return;
+
+ final L2ItemInstance item = player.getInventory().addItem("Quest", itemId, itemCount, player, player);
+ if (item == null)
+ return;
+
+ // Send message to the client.
+ if (itemId == 57)
+ {
+ SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S1_ADENA);
+ smsg.addItemNumber(itemCount);
+ player.sendPacket(smsg);
+ }
+ else
+ {
+ if (itemCount > 1)
+ {
+ SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
+ smsg.addItemName(itemId);
+ smsg.addItemNumber(itemCount);
+ player.sendPacket(smsg);
+ }
+ else
+ {
+ SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
+ smsg.addItemName(itemId);
+ player.sendPacket(smsg);
+ }
+ }
+
+ // Send status update packet.
+ StatusUpdate su = new StatusUpdate(player);
+ su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
+ player.sendPacket(su);
+ }
+
+ /**
+ * Return the player's current Rebirth Level.
+ *
+ * @param player the player
+ * @return the rebirth level
+ */
+ public static int getRebirthLevel(L2PcInstance player)
+ {
+ int playerId = player.getObjectId();
+ if (_rebirthInfo.get(playerId) == null)
+ loadRebirthInfo(player);
+
+ return _rebirthInfo.get(playerId);
+ }
+
+ /**
+ * Database caller to retrieve player's current Rebirth Level.
+ *
+ * @param player the player
+ */
+ public static void loadRebirthInfo(L2PcInstance player)
+ {
+ int playerId = player.getObjectId(), rebirthCount = 0;
+
+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
+ {
+ ResultSet rset;
+ PreparedStatement statement = con.prepareStatement("SELECT * FROM `character_rebirths` WHERE playerId = ?");
+ statement.setInt(1, playerId);
+ rset = statement.executeQuery();
+
+ while (rset.next())
+ {
+ rebirthCount = rset.getInt("rebirthCount");
+ }
+
+ rset.close();
+ statement.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ _rebirthInfo.put(playerId, rebirthCount);
+ }
+
+ /**
+ * Stores the player's information in the DB.
+ *
+ * @param player the player
+ */
+ public static void storePlayerBirth(L2PcInstance player)
+ {
+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
+ {
+ PreparedStatement statement = con.prepareStatement("INSERT INTO `character_rebirths` (playerId,rebirthCount) VALUES (?,1)");
+ statement.setInt(1, player.getObjectId());
+ statement.execute();
+
+ _rebirthInfo.put(player.getObjectId(), 1);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Updates the player's information in the DB.
+ *
+ * @param player the player
+ * @param newRebirthCount the new rebirth count
+ */
+ public static void updatePlayerBirth(L2PcInstance player, int newRebirthCount)
+ {
+ int playerId = player.getObjectId();
+
+ try (Connection con = L2DatabaseFactory.getInstance().getConnection())
+ {
+ PreparedStatement statement = con.prepareStatement("UPDATE `character_rebirths` SET rebirthCount = ? WHERE playerId = ?");
+ statement.setInt(1, newRebirthCount);
+ statement.setInt(2, playerId);
+ statement.execute();
+
+ _rebirthInfo.put(playerId, newRebirthCount);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkill.java
===================================================================
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkill.java (revision 4)
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkill.java (working copy)
@@ -17,8 +17,8 @@
import net.sf.l2j.Config;
import net.sf.l2j.gameserver.datatables.SkillTable;
import net.sf.l2j.gameserver.datatables.SkillTreeTable;
-import net.sf.l2j.gameserver.datatables.SpellbookTable;
import net.sf.l2j.gameserver.model.L2PledgeSkillLearn;
+import net.sf.l2j.gameserver.model.L2RebirthSkillLearn;
import net.sf.l2j.gameserver.model.L2ShortCut;
import net.sf.l2j.gameserver.model.L2Skill;
import net.sf.l2j.gameserver.model.L2SkillLearn;
@@ -80,7 +80,7 @@
// Types.
switch (_skillType)
{
- case 0: // General skills.
+ case 0: // Trance's Rebirth skills.
// Player already has such skill with same or higher level.
int skillLvl = activeChar.getSkillLevel(_skillId);
if (skillLvl >= _skillLevel)
@@ -90,16 +90,17 @@
if (Math.max(skillLvl, 0) + 1 != _skillLevel)
return;
- int spCost = 0;
+ int spCost = 0, idItem = 0;
// Find skill information.
- for (L2SkillLearn sl : SkillTreeTable.getInstance().getAvailableSkills(activeChar, activeChar.getSkillLearningClassId()))
+ for (L2RebirthSkillLearn rsl : SkillTreeTable.getInstance().getAvailableRebirthSkills(activeChar, activeChar.getSkillLearningClassId()))
{
// Skill found.
- if (sl.getId() == _skillId && sl.getLevel() == _skillLevel)
+ if (rsl.getId() == _skillId && rsl.getLevel() == _skillLevel)
{
exists = true;
- spCost = sl.getSpCost();
+ idItem = rsl.getItemId();
+ spCost = rsl.getCostSp();
break;
}
}
@@ -116,11 +117,10 @@
return;
}
- // Get spellbook and try to consume it.
- int spbId = SpellbookTable.getInstance().getBookForSkill(_skillId, _skillLevel);
- if (spbId > 0)
+ // Get item and try to consume it.
+ if (idItem > 0)
{
- if (!activeChar.destroyItemByItemId("SkillLearn", spbId, 1, trainer, true))
+ if (!activeChar.destroyItemByItemId("SkillLearn", idItem, 1, trainer, false))
{
activeChar.sendPacket(SystemMessageId.ITEM_MISSING_TO_LEARN_SKILL);
L2NpcInstance.showSkillList(activeChar, trainer, activeChar.getSkillLearningClassId());
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java (revision 4)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java (working copy)
@@ -19,11 +19,11 @@
import net.sf.l2j.gameserver.datatables.SkillTable;
import net.sf.l2j.gameserver.datatables.SkillTable.FrequentSkill;
import net.sf.l2j.gameserver.datatables.SkillTreeTable;
+import net.sf.l2j.gameserver.model.L2RebirthSkillLearn;
import net.sf.l2j.gameserver.model.L2Effect;
import net.sf.l2j.gameserver.model.L2EnchantSkillData;
import net.sf.l2j.gameserver.model.L2EnchantSkillLearn;
import net.sf.l2j.gameserver.model.L2Skill;
-import net.sf.l2j.gameserver.model.L2SkillLearn;
import net.sf.l2j.gameserver.model.actor.L2Npc;
import net.sf.l2j.gameserver.model.actor.status.FolkStatus;
import net.sf.l2j.gameserver.model.base.ClassId;
@@ -99,13 +99,13 @@
AcquireSkillList asl = new AcquireSkillList(AcquireSkillList.SkillType.Usual);
boolean empty = true;
- for (L2SkillLearn sl : SkillTreeTable.getInstance().getAvailableSkills(player, classId))
+ for (L2RebirthSkillLearn rsl : SkillTreeTable.getInstance().getAvailableRebirthSkills(player, classId))
{
- L2Skill sk = SkillTable.getInstance().getInfo(sl.getId(), sl.getLevel());
+ L2Skill sk = SkillTable.getInstance().getInfo(rsl.getId(), rsl.getLevel());
if (sk == null)
continue;
- asl.addSkill(sl.getId(), sl.getLevel(), sl.getLevel(), sl.getSpCost(), 0);
+ asl.addSkill(rsl.getId(), rsl.getLevel(), rsl.getLevel(), rsl.getCostSp(), 0);
empty = false;
}
Index: config/events.properties
===================================================================
--- config/events.properties (revision 4)
+++ config/events.properties (working copy)
@@ -251,4 +251,19 @@
AltFishChampionshipReward2 = 500000
AltFishChampionshipReward3 = 300000
AltFishChampionshipReward4 = 200000
-AltFishChampionshipReward5 = 100000
\ No newline at end of file
+AltFishChampionshipReward5 = 100000
+
+#================================================================
+# Trance's Rebirth Manager
+#================================================================
+# Minimum level for Rebirth
+RebirthMinLevel = 78
+
+# Maximum rebirth's allowed
+RebirthMaxAllowed = 3
+
+# Return to level
+RebirthReturnToLevel = 1
+
+# Rebirth items
+RebirthItems = 2822,1;2822,1;2822,1;
\ No newline at end of file
Index: java/net/sf/l2j/gameserver/datatables/SkillTreeTable.java
===================================================================
--- java/net/sf/l2j/gameserver/datatables/SkillTreeTable.java (revision 4)
+++ java/net/sf/l2j/gameserver/datatables/SkillTreeTable.java (working copy)
@@ -26,6 +26,7 @@
import net.sf.l2j.gameserver.model.L2EnchantSkillData;
import net.sf.l2j.gameserver.model.L2EnchantSkillLearn;
import net.sf.l2j.gameserver.model.L2PledgeSkillLearn;
+import net.sf.l2j.gameserver.model.L2RebirthSkillLearn;
import net.sf.l2j.gameserver.model.L2Skill;
import net.sf.l2j.gameserver.model.L2SkillLearn;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
@@ -46,6 +47,7 @@
private List<L2PledgeSkillLearn> _pledgeSkillTrees;
private Map<Integer, L2EnchantSkillData> _enchantSkillData;
private List<L2EnchantSkillLearn> _enchantSkillTrees;
+ private List<L2RebirthSkillLearn> _rebirthSkillTrees;
public static SkillTreeTable getInstance()
{
@@ -207,10 +209,43 @@
_log.severe("PledgeTable: Error while loading pledge skills: " + e);
}
+ // Rebirth skills tree
+ try
+ {
+ _rebirthSkillTrees = new ArrayList<>();
+
+ File f = new File("./data/xml/skillstrees/rebirth_skills_tree.xml");
+ Document doc = XMLDocumentFactory.getInstance().loadDocument(f);
+
+ for (Node list = doc.getFirstChild().getFirstChild(); list != null; list = list.getNextSibling())
+ {
+ if ("skill".equalsIgnoreCase(list.getNodeName()))
+ {
+ NamedNodeMap skillAttr = list.getAttributes();
+
+ int skillId = Integer.parseInt(skillAttr.getNamedItem("id").getNodeValue());
+ int skillLvl = Integer.parseInt(skillAttr.getNamedItem("lvl").getNodeValue());
+ int costSp = Integer.valueOf(skillAttr.getNamedItem("sp").getNodeValue());
+ int itemId = 0;
+
+ Node att = skillAttr.getNamedItem("itemId");
+ if (att != null)
+ itemId = Integer.valueOf(att.getNodeValue());
+
+ _rebirthSkillTrees.add(new L2RebirthSkillLearn(skillId, skillLvl, costSp, itemId));
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _log.severe("RebirthTable: Error while loading rebirth skills: " + e);
+ }
+
_log.config("FishingSkillTreeTable: Loaded " + _fishingSkillTrees.size() + " general skills.");
_log.config("DwarvenCraftSkillTreeTable: Loaded " + _expandDwarvenCraftSkillTrees.size() + " dwarven skills.");
_log.config("EnchantSkillTreeTable: Loaded " + _enchantSkillData.size() + " enchant types and " + _enchantSkillTrees.size() + " enchant skills.");
_log.config("PledgeSkillTreeTable: Loaded " + _pledgeSkillTrees.size() + " pledge skills.");
+ _log.config("RebirthSkillTreeTable: Loaded " + _rebirthSkillTrees.size() + " rebirth skills.");
}
/**
@@ -509,6 +544,39 @@
return result;
}
+ /**
+ * @param cha L2PcInstance, player whom skills are compared.
+ * @param classId
+ * @return list of available rebirth skills for L2PcInstance.
+ */
+ public List<L2RebirthSkillLearn> getAvailableRebirthSkills(L2PcInstance cha, ClassId classId)
+ {
+ List<L2RebirthSkillLearn> result = new ArrayList<>();
+
+ L2Skill[] chaSkills = cha.getAllSkills();
+
+ for (L2RebirthSkillLearn rsl : _rebirthSkillTrees)
+ {
+ boolean found = false;
+
+ for (L2Skill s : chaSkills)
+ {
+ if (s.getId() == rsl.getId())
+ {
+ if (s.getLevel() == rsl.getLevel() - 1)
+ result.add(rsl);
+
+ found = true;
+ break;
+ }
+ }
+
+ if (!found && rsl.getLevel() == 1)
+ result.add(rsl);
+ }
+ return result;
+ }
+
public int getMinSkillLevel(int skillId, int skillLvl)
{
int skillHashCode = SkillTable.getSkillHashCode(skillId, skillLvl);
Index: java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (revision 4)
+++ java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (working copy)
@@ -5643,16 +5643,6 @@
player._classIndex = subClass.getClassIndex();
}
}
- if (player.getClassIndex() == 0 && activeClassId != player.getBaseClass())
- {
- // Subclass in use but doesn't exist in DB -
- // a possible restart-while-modifysubclass cheat has been attempted.
- // Switching to use base class
- player.setClassId(player.getBaseClass());
- _log.warning("Player " + player.getName() + " reverted to base class. Possibly has tried a relogin exploit while subclassing.");
- }
- else
- player._activeClass = activeClassId;
player.setApprentice(rset.getInt("apprentice"));
player.setSponsor(rset.getInt("sponsor"));
Index: java/net/sf/l2j/gameserver/model/actor/L2Character.java
===================================================================
--- java/net/sf/l2j/gameserver/model/actor/L2Character.java (revision 4)
+++ java/net/sf/l2j/gameserver/model/actor/L2Character.java (working copy)
@@ -4515,6 +4515,10 @@
if (skill == null)
return null;
+ // Skip the rebirth skills.
+ if (skill.getId() >= 549 && skill.getId() <= 560)
+ return null;
+
return removeSkill(skill.getId(), true);
}
Index: java/net/sf/l2j/Config.java
===================================================================
--- java/net/sf/l2j/Config.java (revision 4)
+++ java/net/sf/l2j/Config.java (working copy)
@@ -225,6 +225,12 @@
public static int ALT_FISH_CHAMPIONSHIP_REWARD_4;
public static int ALT_FISH_CHAMPIONSHIP_REWARD_5;
+ /** Trance's Rebirth Manager */
+ public static int REBIRTH_MIN_LEVEL;
+ public static int REBIRTH_MAX;
+ public static int REBIRTH_RETURN_TO_LEVEL;
+ public static String[] REBIRTH_ITEMS;
+
// --------------------------------------------------
// HexID
// --------------------------------------------------
@@ -870,6 +876,11 @@
ALT_FISH_CHAMPIONSHIP_REWARD_4 = events.getProperty("AltFishChampionshipReward4", 200000);
ALT_FISH_CHAMPIONSHIP_REWARD_5 = events.getProperty("AltFishChampionshipReward5", 100000);
+ REBIRTH_MIN_LEVEL = events.getProperty("RebirthMinLevel", 78);
+ REBIRTH_MAX = events.getProperty("RebirthMaxAllowed", 3);
+ REBIRTH_RETURN_TO_LEVEL = events.getProperty("RebirthReturnToLevel", 1);
+ REBIRTH_ITEMS = events.getProperty("RebirthItems", "").split(";");
+
// FloodProtector
ExProperties security = load(FLOOD_PROTECTOR_FILE);
loadFloodProtectorConfig(security, FLOOD_PROTECTOR_ROLL_DICE, "RollDice", "42");
Index: java/net/sf/l2j/gameserver/model/L2RebirthSkillLearn.java
===================================================================
--- java/net/sf/l2j/gameserver/model/L2RebirthSkillLearn.java (revision 0)
+++ java/net/sf/l2j/gameserver/model/L2RebirthSkillLearn.java (working copy)
@@ -0,0 +1,55 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.sf.l2j.gameserver.model;
+
+/**
+ * @author Trance
+ * @skype chr.trance
+ */
+public final class L2RebirthSkillLearn
+{
+ private final int _id;
+ private final int _level;
+ private final int _costSp;
+ private final int _itemId;
+
+ public L2RebirthSkillLearn(int id, int lvl, int costSp, int itemId)
+ {
+ _id = id;
+ _level = lvl;
+ _costSp = costSp;
+ _itemId = itemId;
+ }
+
+ public int getId()
+ {
+ return _id;
+ }
+
+ public int getLevel()
+ {
+ return _level;
+ }
+
+ public int getCostSp()
+ {
+ return _costSp;
+ }
+
+ public int getItemId()
+ {
+ return _itemId;
+ }
+}
\ No newline at end of file
BLACK FRIDAY — PREMIUM BENEFITS FOR YOUR TRAFFIC
Only on November 28 our special promo code gives you a 13% discount in the store.
PROMO CODE: BLACKFRIDAY (13% Discount)
Shop in our store on the website or via the Telegram bot!
Active links:
Digital goods store (Website): Go
Store Telegram bot: Go – convenient access to the store via Telegram messenger.
Other services:
Virtual numbers service: Go
Telegram bot for purchasing Telegram Stars: Go – fast and profitable purchase of stars in Telegram.
SMM Panel: Go – promotion of your social media accounts.
We want to present you the current list of promotions and special offers for purchasing our service's products and services:
1. You can use a promo code for your first purchase: SOCNET (15% discount)
2. Get $1 to your store balance or a 10–20% discount — just send your username after registering on our website using the following template: "SEND ME BONUS, MY USERNAME IS..." — you need to write this in our forum thread!
3. Get $1 for the first trial start of the SMM Panel: just open a ticket with the subject "Get Trial Bonus" on our website (Support).
4. Weekly Telegram Stars giveaways in our Telegram channel and in our bot for purchasing stars!
News:
➡ Telegram channel: https://t.me/accsforyou_shop
➡ WhatsApp channel: https://chat.whatsapp.com/K8rBy500nA73z27PxgaJUw?mode=ems_copy_t
➡ Discord server: https://discord.gg/y9AStFFsrh
Contacts and Support:
➡ Telegram: https://t.me/socnet_support
➡ WhatsApp: https://wa.me/79051904467
➡ Discord: socnet_support
➡ ✉ Email: solomonbog@socnet.store
Usually, I work alone on my projects, but sometimes the work is much more than I've expected. Could you provide a price list? It would be good if we knew your price before contacting you.
BLACK FRIDAY — PREMIUM BENEFITS FOR YOUR TRAFFIC
Only on November 28 our special promo code gives you a 13% discount in the store.
PROMO CODE: BLACKFRIDAY (13% Discount)
Shop in our store on the website or via the Telegram bot!
Active links:
Digital goods store (Website): Go
Store Telegram bot: Go – convenient access to the store via Telegram messenger.
Other services:
Virtual numbers service: Go
Telegram bot for purchasing Telegram Stars: Go – fast and profitable purchase of stars in Telegram.
SMM Panel: Go – promotion of your social media accounts.
We want to present you the current list of promotions and special offers for purchasing our service's products and services:
1. You can use a promo code for your first purchase: SOCNET (15% discount)
2. Get $1 to your store balance or a 10–20% discount — just send your username after registering on our website using the following template: "SEND ME BONUS, MY USERNAME IS..." — you need to write this in our forum thread!
3. Get $1 for the first trial start of the SMM Panel: just open a ticket with the subject "Get Trial Bonus" on our website (Support).
4. Weekly Telegram Stars giveaways in our Telegram channel and in our bot for purchasing stars!
News:
➡ Telegram channel: https://t.me/accsforyou_shop
➡ WhatsApp channel: https://chat.whatsapp.com/K8rBy500nA73z27PxgaJUw?mode=ems_copy_t
➡ Discord server: https://discord.gg/y9AStFFsrh
Contacts and Support:
➡ Telegram: https://t.me/socnet_support
➡ WhatsApp: https://wa.me/79051904467
➡ Discord: socnet_support
➡ ✉ Email: solomonbog@socnet.store
Question
Junkee
Hello guys,
I need help with this: http://www.maxcheaters.com/topic/158570-trances-rebirth-manager/
Originally, once I perform the rebirth, character level is decreased to level 1 and it turns to first class. I need to modify this, as that, once the rebirth is done, the charachter should keep the third class status and get the level 1 skills. It just needs a few code modifications that I can't manage how to do them (java newbie :P). Hope you can help me with that.
PS: Sorry for my bad english, and don't think i'm planning to open a live server, I just want to play with some friends (old l2gold players)
Cheers,
- Junkee
This is the code:
### Eclipse Workspace Patch 1.0 #P aCis_gameserver Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkillInfo.java =================================================================== --- java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkillInfo.java (revision 4) +++ java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkillInfo.java (working copy) @@ -17,8 +17,8 @@ import net.sf.l2j.Config; import net.sf.l2j.gameserver.datatables.SkillTable; import net.sf.l2j.gameserver.datatables.SkillTreeTable; -import net.sf.l2j.gameserver.datatables.SpellbookTable; import net.sf.l2j.gameserver.model.L2PledgeSkillLearn; +import net.sf.l2j.gameserver.model.L2RebirthSkillLearn; import net.sf.l2j.gameserver.model.L2Skill; import net.sf.l2j.gameserver.model.L2SkillLearn; import net.sf.l2j.gameserver.model.actor.L2Npc; @@ -62,7 +62,7 @@ switch (_skillType) { - // General skills + // Trance's Rebirth skills. case 0: int skillLvl = activeChar.getSkillLevel(_skillId); if (skillLvl >= _skillLevel) @@ -74,14 +74,13 @@ if (!trainer.getTemplate().canTeach(activeChar.getSkillLearningClassId())) return; - for (L2SkillLearn sl : SkillTreeTable.getInstance().getAvailableSkills(activeChar, activeChar.getSkillLearningClassId())) + for (L2RebirthSkillLearn rsl : SkillTreeTable.getInstance().getAvailableRebirthSkills(activeChar, activeChar.getSkillLearningClassId())) { - if (sl.getId() == _skillId && sl.getLevel() == _skillLevel) + if (rsl.getId() == _skillId && rsl.getLevel() == _skillLevel) { - AcquireSkillInfo asi = new AcquireSkillInfo(_skillId, _skillLevel, sl.getSpCost(), 0); - int spellbookItemId = SpellbookTable.getInstance().getBookForSkill(_skillId, _skillLevel); - if (spellbookItemId != 0) - asi.addRequirement(99, spellbookItemId, 1, 50); + AcquireSkillInfo asi = new AcquireSkillInfo(_skillId, _skillLevel, rsl.getCostSp(), 0); + if (Config.LIFE_CRYSTAL_NEEDED && rsl.getItemId() != 0) + asi.addRequirement(1, rsl.getItemId(), 1, 0); sendPacket(asi); break; } Index: java/net/sf/l2j/gameserver/model/base/ClassId.java =================================================================== --- java/net/sf/l2j/gameserver/model/base/ClassId.java (revision 4) +++ java/net/sf/l2j/gameserver/model/base/ClassId.java (working copy) @@ -248,4 +248,15 @@ { return _parent; } + + /** + * @return to the first class + */ + public final ClassId getFirstClass() + { + if (_parent == null) + return this; + + return _parent.getFirstClass(); + } } \ No newline at end of file Index: java/net/sf/l2j/gameserver/model/actor/instance/L2RebirthInstance.java =================================================================== --- java/net/sf/l2j/gameserver/model/actor/instance/L2RebirthInstance.java (revision 0) +++ java/net/sf/l2j/gameserver/model/actor/instance/L2RebirthInstance.java (working copy) @@ -0,0 +1,301 @@ +/* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.sf.l2j.gameserver.model.actor.instance; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.HashMap; + +import net.sf.l2j.Config; +import net.sf.l2j.L2DatabaseFactory; +import net.sf.l2j.gameserver.model.base.Experience; +import net.sf.l2j.gameserver.model.L2ItemInstance; +import net.sf.l2j.gameserver.model.L2Skill; +import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; +import net.sf.l2j.gameserver.network.SystemMessageId; +import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage; +import net.sf.l2j.gameserver.network.serverpackets.StatusUpdate; +import net.sf.l2j.gameserver.network.serverpackets.SystemMessage; +import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate; + +/** + * Rebirth Manager + * @author Trance + * @skype chr.trance + */ +public final class L2RebirthInstance extends L2NpcInstance +{ + private static HashMap<Integer, Integer> _rebirthInfo = new HashMap<>(); + + public L2RebirthInstance(int objectId, L2NpcTemplate template) + { + super(objectId, template); + } + + @Override + public void onBypassFeedback(L2PcInstance player, String command) + { + if (command.startsWith("performRebirth")) + { + // Maximum rebirth count. Return the player's current Rebirth Level. + int currBirth = getRebirthLevel(player); + if (currBirth >= Config.REBIRTH_MAX) + { + NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); + html.setFile("data/html/managers/rebirth-max.htm"); + + player.sendPacket(html); + return; + } + + // Level requirement for a rebirth. + if (player.getLevel() < Config.REBIRTH_MIN_LEVEL) + { + NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); + html.setFile("data/html/managers/rebirth-level.htm"); + + player.sendPacket(html); + return; + } + + int itemId = 0, itemCount = 0, loopBirth = 0; + for (String readItems : Config.REBIRTH_ITEMS) + { + String[] currItem = readItems.split(","); + if (loopBirth == currBirth) + { + itemId = Integer.parseInt(currItem[0]); + itemCount = Integer.parseInt(currItem[1]); + break; + } + loopBirth++; + } + + // Rewards the player with an item. + rebirthItemReward(player, itemId, itemCount); + + // Check and see if its the player's first rebirth calling. + boolean firstBirth = currBirth == 0; + + // Player meets requirements and starts Rebirth process. + grantRebirth(player, (currBirth + 1), firstBirth); + } + else + super.onBypassFeedback(player, command); + } + + @Override + public void showChatWindow(L2PcInstance player) + { + NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); + html.setFile("data/html/managers/rebirth.htm"); + html.replace("%objectId%", String.valueOf(getObjectId())); + html.replace("%level%", + Config.REBIRTH_RETURN_TO_LEVEL); + + player.sendPacket(html); + } + + /** + * Physically rewards player and resets status to nothing. + * + * @param player the player + * @param newBirthCount the new birth count + * @param firstBirth the first birth + */ + public void grantRebirth(L2PcInstance player, int newBirthCount, boolean firstBirth) + { + try + { + // Delevel. + player.removeExpAndSp(player.getExp() - Experience.LEVEL[Config.REBIRTH_RETURN_TO_LEVEL], 0); + + // Back to the first class. + player.setClassId(player.getClassId().getFirstClass().getId()); + + // Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance + player.broadcastStatusUpdate(); + + // Broadcast informations from a user to himself and his knownlist. + player.broadcastUserInfo(); + + // Remove the player's current skills. + for (L2Skill skill : player.getAllSkills()) + player.removeSkill(skill); + + // Give all available skills to the player. + player.giveAvailableSkills(); + + // Update L2PcInstance stats in the characters table of the database. + player.store(); + + if (firstBirth) + // Stores the player's information in the DB. + storePlayerBirth(player); + else + // Updates the player's information in the DB. + updatePlayerBirth(player, newBirthCount); + + // Displays a congratulation window to the player. + NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); + html.setFile("data/html/managers/rebirth-successfully.htm"); + html.replace("%level%", + Config.REBIRTH_RETURN_TO_LEVEL); + + player.sendPacket(html); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Rewards the player with an item. + * + * @param player the player + * @param itemId : Identifier of the item. + * @param itemCount : Quantity of items to add. + */ + public static void rebirthItemReward(L2PcInstance player, int itemId, int itemCount) + { + // Incorrect amount. + if (itemCount <= 0) + return; + + final L2ItemInstance item = player.getInventory().addItem("Quest", itemId, itemCount, player, player); + if (item == null) + return; + + // Send message to the client. + if (itemId == 57) + { + SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S1_ADENA); + smsg.addItemNumber(itemCount); + player.sendPacket(smsg); + } + else + { + if (itemCount > 1) + { + SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S); + smsg.addItemName(itemId); + smsg.addItemNumber(itemCount); + player.sendPacket(smsg); + } + else + { + SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1); + smsg.addItemName(itemId); + player.sendPacket(smsg); + } + } + + // Send status update packet. + StatusUpdate su = new StatusUpdate(player); + su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad()); + player.sendPacket(su); + } + + /** + * Return the player's current Rebirth Level. + * + * @param player the player + * @return the rebirth level + */ + public static int getRebirthLevel(L2PcInstance player) + { + int playerId = player.getObjectId(); + if (_rebirthInfo.get(playerId) == null) + loadRebirthInfo(player); + + return _rebirthInfo.get(playerId); + } + + /** + * Database caller to retrieve player's current Rebirth Level. + * + * @param player the player + */ + public static void loadRebirthInfo(L2PcInstance player) + { + int playerId = player.getObjectId(), rebirthCount = 0; + + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) + { + ResultSet rset; + PreparedStatement statement = con.prepareStatement("SELECT * FROM `character_rebirths` WHERE playerId = ?"); + statement.setInt(1, playerId); + rset = statement.executeQuery(); + + while (rset.next()) + { + rebirthCount = rset.getInt("rebirthCount"); + } + + rset.close(); + statement.close(); + } + catch (Exception e) + { + e.printStackTrace(); + } + _rebirthInfo.put(playerId, rebirthCount); + } + + /** + * Stores the player's information in the DB. + * + * @param player the player + */ + public static void storePlayerBirth(L2PcInstance player) + { + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) + { + PreparedStatement statement = con.prepareStatement("INSERT INTO `character_rebirths` (playerId,rebirthCount) VALUES (?,1)"); + statement.setInt(1, player.getObjectId()); + statement.execute(); + + _rebirthInfo.put(player.getObjectId(), 1); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Updates the player's information in the DB. + * + * @param player the player + * @param newRebirthCount the new rebirth count + */ + public static void updatePlayerBirth(L2PcInstance player, int newRebirthCount) + { + int playerId = player.getObjectId(); + + try (Connection con = L2DatabaseFactory.getInstance().getConnection()) + { + PreparedStatement statement = con.prepareStatement("UPDATE `character_rebirths` SET rebirthCount = ? WHERE playerId = ?"); + statement.setInt(1, newRebirthCount); + statement.setInt(2, playerId); + statement.execute(); + + _rebirthInfo.put(playerId, newRebirthCount); + } + catch (Exception e) + { + e.printStackTrace(); + } + } +} \ No newline at end of file Index: java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkill.java =================================================================== --- java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkill.java (revision 4) +++ java/net/sf/l2j/gameserver/network/clientpackets/RequestAcquireSkill.java (working copy) @@ -17,8 +17,8 @@ import net.sf.l2j.Config; import net.sf.l2j.gameserver.datatables.SkillTable; import net.sf.l2j.gameserver.datatables.SkillTreeTable; -import net.sf.l2j.gameserver.datatables.SpellbookTable; import net.sf.l2j.gameserver.model.L2PledgeSkillLearn; +import net.sf.l2j.gameserver.model.L2RebirthSkillLearn; import net.sf.l2j.gameserver.model.L2ShortCut; import net.sf.l2j.gameserver.model.L2Skill; import net.sf.l2j.gameserver.model.L2SkillLearn; @@ -80,7 +80,7 @@ // Types. switch (_skillType) { - case 0: // General skills. + case 0: // Trance's Rebirth skills. // Player already has such skill with same or higher level. int skillLvl = activeChar.getSkillLevel(_skillId); if (skillLvl >= _skillLevel) @@ -90,16 +90,17 @@ if (Math.max(skillLvl, 0) + 1 != _skillLevel) return; - int spCost = 0; + int spCost = 0, idItem = 0; // Find skill information. - for (L2SkillLearn sl : SkillTreeTable.getInstance().getAvailableSkills(activeChar, activeChar.getSkillLearningClassId())) + for (L2RebirthSkillLearn rsl : SkillTreeTable.getInstance().getAvailableRebirthSkills(activeChar, activeChar.getSkillLearningClassId())) { // Skill found. - if (sl.getId() == _skillId && sl.getLevel() == _skillLevel) + if (rsl.getId() == _skillId && rsl.getLevel() == _skillLevel) { exists = true; - spCost = sl.getSpCost(); + idItem = rsl.getItemId(); + spCost = rsl.getCostSp(); break; } } @@ -116,11 +117,10 @@ return; } - // Get spellbook and try to consume it. - int spbId = SpellbookTable.getInstance().getBookForSkill(_skillId, _skillLevel); - if (spbId > 0) + // Get item and try to consume it. + if (idItem > 0) { - if (!activeChar.destroyItemByItemId("SkillLearn", spbId, 1, trainer, true)) + if (!activeChar.destroyItemByItemId("SkillLearn", idItem, 1, trainer, false)) { activeChar.sendPacket(SystemMessageId.ITEM_MISSING_TO_LEARN_SKILL); L2NpcInstance.showSkillList(activeChar, trainer, activeChar.getSkillLearningClassId()); Index: java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java =================================================================== --- java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java (revision 4) +++ java/net/sf/l2j/gameserver/model/actor/instance/L2NpcInstance.java (working copy) @@ -19,11 +19,11 @@ import net.sf.l2j.gameserver.datatables.SkillTable; import net.sf.l2j.gameserver.datatables.SkillTable.FrequentSkill; import net.sf.l2j.gameserver.datatables.SkillTreeTable; +import net.sf.l2j.gameserver.model.L2RebirthSkillLearn; import net.sf.l2j.gameserver.model.L2Effect; import net.sf.l2j.gameserver.model.L2EnchantSkillData; import net.sf.l2j.gameserver.model.L2EnchantSkillLearn; import net.sf.l2j.gameserver.model.L2Skill; -import net.sf.l2j.gameserver.model.L2SkillLearn; import net.sf.l2j.gameserver.model.actor.L2Npc; import net.sf.l2j.gameserver.model.actor.status.FolkStatus; import net.sf.l2j.gameserver.model.base.ClassId; @@ -99,13 +99,13 @@ AcquireSkillList asl = new AcquireSkillList(AcquireSkillList.SkillType.Usual); boolean empty = true; - for (L2SkillLearn sl : SkillTreeTable.getInstance().getAvailableSkills(player, classId)) + for (L2RebirthSkillLearn rsl : SkillTreeTable.getInstance().getAvailableRebirthSkills(player, classId)) { - L2Skill sk = SkillTable.getInstance().getInfo(sl.getId(), sl.getLevel()); + L2Skill sk = SkillTable.getInstance().getInfo(rsl.getId(), rsl.getLevel()); if (sk == null) continue; - asl.addSkill(sl.getId(), sl.getLevel(), sl.getLevel(), sl.getSpCost(), 0); + asl.addSkill(rsl.getId(), rsl.getLevel(), rsl.getLevel(), rsl.getCostSp(), 0); empty = false; } Index: config/events.properties =================================================================== --- config/events.properties (revision 4) +++ config/events.properties (working copy) @@ -251,4 +251,19 @@ AltFishChampionshipReward2 = 500000 AltFishChampionshipReward3 = 300000 AltFishChampionshipReward4 = 200000 -AltFishChampionshipReward5 = 100000 \ No newline at end of file +AltFishChampionshipReward5 = 100000 + +#================================================================ +# Trance's Rebirth Manager +#================================================================ +# Minimum level for Rebirth +RebirthMinLevel = 78 + +# Maximum rebirth's allowed +RebirthMaxAllowed = 3 + +# Return to level +RebirthReturnToLevel = 1 + +# Rebirth items +RebirthItems = 2822,1;2822,1;2822,1; \ No newline at end of file Index: java/net/sf/l2j/gameserver/datatables/SkillTreeTable.java =================================================================== --- java/net/sf/l2j/gameserver/datatables/SkillTreeTable.java (revision 4) +++ java/net/sf/l2j/gameserver/datatables/SkillTreeTable.java (working copy) @@ -26,6 +26,7 @@ import net.sf.l2j.gameserver.model.L2EnchantSkillData; import net.sf.l2j.gameserver.model.L2EnchantSkillLearn; import net.sf.l2j.gameserver.model.L2PledgeSkillLearn; +import net.sf.l2j.gameserver.model.L2RebirthSkillLearn; import net.sf.l2j.gameserver.model.L2Skill; import net.sf.l2j.gameserver.model.L2SkillLearn; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; @@ -46,6 +47,7 @@ private List<L2PledgeSkillLearn> _pledgeSkillTrees; private Map<Integer, L2EnchantSkillData> _enchantSkillData; private List<L2EnchantSkillLearn> _enchantSkillTrees; + private List<L2RebirthSkillLearn> _rebirthSkillTrees; public static SkillTreeTable getInstance() { @@ -207,10 +209,43 @@ _log.severe("PledgeTable: Error while loading pledge skills: " + e); } + // Rebirth skills tree + try + { + _rebirthSkillTrees = new ArrayList<>(); + + File f = new File("./data/xml/skillstrees/rebirth_skills_tree.xml"); + Document doc = XMLDocumentFactory.getInstance().loadDocument(f); + + for (Node list = doc.getFirstChild().getFirstChild(); list != null; list = list.getNextSibling()) + { + if ("skill".equalsIgnoreCase(list.getNodeName())) + { + NamedNodeMap skillAttr = list.getAttributes(); + + int skillId = Integer.parseInt(skillAttr.getNamedItem("id").getNodeValue()); + int skillLvl = Integer.parseInt(skillAttr.getNamedItem("lvl").getNodeValue()); + int costSp = Integer.valueOf(skillAttr.getNamedItem("sp").getNodeValue()); + int itemId = 0; + + Node att = skillAttr.getNamedItem("itemId"); + if (att != null) + itemId = Integer.valueOf(att.getNodeValue()); + + _rebirthSkillTrees.add(new L2RebirthSkillLearn(skillId, skillLvl, costSp, itemId)); + } + } + } + catch (Exception e) + { + _log.severe("RebirthTable: Error while loading rebirth skills: " + e); + } + _log.config("FishingSkillTreeTable: Loaded " + _fishingSkillTrees.size() + " general skills."); _log.config("DwarvenCraftSkillTreeTable: Loaded " + _expandDwarvenCraftSkillTrees.size() + " dwarven skills."); _log.config("EnchantSkillTreeTable: Loaded " + _enchantSkillData.size() + " enchant types and " + _enchantSkillTrees.size() + " enchant skills."); _log.config("PledgeSkillTreeTable: Loaded " + _pledgeSkillTrees.size() + " pledge skills."); + _log.config("RebirthSkillTreeTable: Loaded " + _rebirthSkillTrees.size() + " rebirth skills."); } /** @@ -509,6 +544,39 @@ return result; } + /** + * @param cha L2PcInstance, player whom skills are compared. + * @param classId + * @return list of available rebirth skills for L2PcInstance. + */ + public List<L2RebirthSkillLearn> getAvailableRebirthSkills(L2PcInstance cha, ClassId classId) + { + List<L2RebirthSkillLearn> result = new ArrayList<>(); + + L2Skill[] chaSkills = cha.getAllSkills(); + + for (L2RebirthSkillLearn rsl : _rebirthSkillTrees) + { + boolean found = false; + + for (L2Skill s : chaSkills) + { + if (s.getId() == rsl.getId()) + { + if (s.getLevel() == rsl.getLevel() - 1) + result.add(rsl); + + found = true; + break; + } + } + + if (!found && rsl.getLevel() == 1) + result.add(rsl); + } + return result; + } + public int getMinSkillLevel(int skillId, int skillLvl) { int skillHashCode = SkillTable.getSkillHashCode(skillId, skillLvl); Index: java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java =================================================================== --- java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (revision 4) +++ java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java (working copy) @@ -5643,16 +5643,6 @@ player._classIndex = subClass.getClassIndex(); } } - if (player.getClassIndex() == 0 && activeClassId != player.getBaseClass()) - { - // Subclass in use but doesn't exist in DB - - // a possible restart-while-modifysubclass cheat has been attempted. - // Switching to use base class - player.setClassId(player.getBaseClass()); - _log.warning("Player " + player.getName() + " reverted to base class. Possibly has tried a relogin exploit while subclassing."); - } - else - player._activeClass = activeClassId; player.setApprentice(rset.getInt("apprentice")); player.setSponsor(rset.getInt("sponsor")); Index: java/net/sf/l2j/gameserver/model/actor/L2Character.java =================================================================== --- java/net/sf/l2j/gameserver/model/actor/L2Character.java (revision 4) +++ java/net/sf/l2j/gameserver/model/actor/L2Character.java (working copy) @@ -4515,6 +4515,10 @@ if (skill == null) return null; + // Skip the rebirth skills. + if (skill.getId() >= 549 && skill.getId() <= 560) + return null; + return removeSkill(skill.getId(), true); } Index: java/net/sf/l2j/Config.java =================================================================== --- java/net/sf/l2j/Config.java (revision 4) +++ java/net/sf/l2j/Config.java (working copy) @@ -225,6 +225,12 @@ public static int ALT_FISH_CHAMPIONSHIP_REWARD_4; public static int ALT_FISH_CHAMPIONSHIP_REWARD_5; + /** Trance's Rebirth Manager */ + public static int REBIRTH_MIN_LEVEL; + public static int REBIRTH_MAX; + public static int REBIRTH_RETURN_TO_LEVEL; + public static String[] REBIRTH_ITEMS; + // -------------------------------------------------- // HexID // -------------------------------------------------- @@ -870,6 +876,11 @@ ALT_FISH_CHAMPIONSHIP_REWARD_4 = events.getProperty("AltFishChampionshipReward4", 200000); ALT_FISH_CHAMPIONSHIP_REWARD_5 = events.getProperty("AltFishChampionshipReward5", 100000); + REBIRTH_MIN_LEVEL = events.getProperty("RebirthMinLevel", 78); + REBIRTH_MAX = events.getProperty("RebirthMaxAllowed", 3); + REBIRTH_RETURN_TO_LEVEL = events.getProperty("RebirthReturnToLevel", 1); + REBIRTH_ITEMS = events.getProperty("RebirthItems", "").split(";"); + // FloodProtector ExProperties security = load(FLOOD_PROTECTOR_FILE); loadFloodProtectorConfig(security, FLOOD_PROTECTOR_ROLL_DICE, "RollDice", "42"); Index: java/net/sf/l2j/gameserver/model/L2RebirthSkillLearn.java =================================================================== --- java/net/sf/l2j/gameserver/model/L2RebirthSkillLearn.java (revision 0) +++ java/net/sf/l2j/gameserver/model/L2RebirthSkillLearn.java (working copy) @@ -0,0 +1,55 @@ +/* + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +package net.sf.l2j.gameserver.model; + +/** + * @author Trance + * @skype chr.trance + */ +public final class L2RebirthSkillLearn +{ + private final int _id; + private final int _level; + private final int _costSp; + private final int _itemId; + + public L2RebirthSkillLearn(int id, int lvl, int costSp, int itemId) + { + _id = id; + _level = lvl; + _costSp = costSp; + _itemId = itemId; + } + + public int getId() + { + return _id; + } + + public int getLevel() + { + return _level; + } + + public int getCostSp() + { + return _costSp; + } + + public int getItemId() + { + return _itemId; + } +} \ No newline at end of fileEdited by Junkee1 answer to this question
Recommended Posts