Prechádzať zdrojové kódy

Core support for HP bonus of enchanted armor, thanks mrpoke for ideas.
Need DP update.

_DS_ 15 rokov pred
rodič
commit
537752e481

+ 2 - 0
L2_GameServer/java/net/sf/l2j/gameserver/GameServer.java

@@ -40,6 +40,7 @@ import net.sf.l2j.gameserver.datatables.CharNameTable;
 import net.sf.l2j.gameserver.datatables.CharTemplateTable;
 import net.sf.l2j.gameserver.datatables.ClanTable;
 import net.sf.l2j.gameserver.datatables.DoorTable;
+import net.sf.l2j.gameserver.datatables.EnchantHPBonusData;
 import net.sf.l2j.gameserver.datatables.EventDroplist;
 import net.sf.l2j.gameserver.datatables.ExtractableItemsData;
 import net.sf.l2j.gameserver.datatables.ExtractableSkillsData;
@@ -229,6 +230,7 @@ public class GameServer
 		SummonItemsData.getInstance();
 		ZoneManager.getInstance();
 		MerchantPriceConfigTable.getInstance().loadInstances();
+		EnchantHPBonusData.getInstance();
 		TradeController.getInstance();
 		InstanceManager.getInstance();
 		

+ 209 - 0
L2_GameServer/java/net/sf/l2j/gameserver/datatables/EnchantHPBonusData.java

@@ -0,0 +1,209 @@
+/*
+ * 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.datatables;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.StringTokenizer;
+import java.util.logging.Logger;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.model.L2ItemInstance;
+import net.sf.l2j.gameserver.skills.Stats;
+import net.sf.l2j.gameserver.skills.funcs.FuncTemplate;
+import net.sf.l2j.gameserver.skills.funcs.LambdaConst;
+import net.sf.l2j.gameserver.templates.item.L2Item;
+import javolution.util.FastMap;
+
+/**
+ *
+ * @author  MrPoke
+ */
+public class EnchantHPBonusData
+{
+	protected static final Logger _log = Logger.getLogger(EnchantHPBonusData.class.getName());
+
+	private final FastMap<Integer,Integer[]> _singleArmorHPBonus = new FastMap<Integer, Integer[]>();
+	private final FastMap<Integer,Integer[]> _fullArmorHPBonus = new FastMap<Integer, Integer[]>();
+
+	public static final EnchantHPBonusData getInstance()
+	{
+		return SingletonHolder._instance;
+	}
+
+	public EnchantHPBonusData()
+	{
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		factory.setValidating(false);
+		factory.setIgnoringComments(true);
+		File file = new File(Config.DATAPACK_ROOT, "data/enchantHPBonus.xml");
+		Document doc = null;
+
+		if (file.exists())
+		{
+			try
+			{
+				doc = factory.newDocumentBuilder().parse(file);
+			}
+			catch(SAXException e)
+			{
+				e.printStackTrace();
+			}
+			catch(IOException e)
+			{
+				e.printStackTrace();
+			}
+			catch(ParserConfigurationException e)
+			{
+				e.printStackTrace();
+			}
+
+			for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
+			{
+				if ("list".equalsIgnoreCase(n.getNodeName()))
+				{
+					for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
+					{
+						if ("enchantHP".equalsIgnoreCase(d.getNodeName()))
+						{
+							NamedNodeMap attrs = d.getAttributes();
+							Node att;
+							Integer grade;
+							boolean fullArmor;
+
+							att = attrs.getNamedItem("grade");
+							if (att == null)
+							{
+								_log.severe("[EnchantHPBonusData] Missing grade, skipping");
+								continue;
+							}
+							grade = Integer.parseInt(att.getNodeValue());
+
+							att = attrs.getNamedItem("fullArmor");
+							if (att == null)
+							{
+								_log.severe("[EnchantHPBonusData] Missing fullArmor, skipping");
+								continue;
+							}
+							fullArmor = Boolean.valueOf(att.getNodeValue());
+
+							att = attrs.getNamedItem("values");
+							if (att == null)
+							{
+								_log.severe("[EnchantHPBonusData] Missing bonus id: "+grade+", skipping");
+								continue;
+							}
+							StringTokenizer st = new StringTokenizer(att.getNodeValue(), ",");
+							int tokenCount = st.countTokens();
+							Integer[] bonus = new Integer[tokenCount];
+							for (int i=0; i<tokenCount; i++)
+							{
+								Integer value = Integer.decode(st.nextToken().trim());
+								if (value == null)
+								{
+									_log.severe("[EnchantHPBonusData] Bad Hp value!! grade: "+grade + " FullArmor? "+ fullArmor + " token: "+ i);
+									value = 0;
+								}
+								bonus[i] = value;
+							}
+							if (fullArmor)
+								_fullArmorHPBonus.put(grade, bonus);
+							else
+								_singleArmorHPBonus.put(grade, bonus);
+						}
+					}
+				}
+			}
+			if (_fullArmorHPBonus.isEmpty() && _singleArmorHPBonus.isEmpty())
+				return;
+
+			Collection<Integer> itemIds = ItemTable.getInstance().getAllArmorsId();
+			int count = 0;
+
+			for (Integer itemId: itemIds)
+			{
+				L2Item item = ItemTable.getInstance().getTemplate(itemId);
+				if (item != null && item.getCrystalType() != L2Item.CRYSTAL_NONE)
+				{
+					switch(item.getBodyPart())
+					{
+						case L2Item.SLOT_CHEST:
+						case L2Item.SLOT_FEET:
+						case L2Item.SLOT_GLOVES:
+						case L2Item.SLOT_HEAD:
+						case L2Item.SLOT_LEGS:
+						case L2Item.SLOT_BACK:
+						case L2Item.SLOT_FULL_ARMOR:
+						case L2Item.SLOT_UNDERWEAR:
+						case L2Item.SLOT_L_HAND:
+							count++;
+							FuncTemplate ft = new FuncTemplate(null, null, "EnchantHp", Stats.MAX_HP, 0x60, new LambdaConst(0));
+							item.attach(ft);
+							break;
+					}
+				}
+			}
+
+			// shields in the weapons table
+			itemIds = ItemTable.getInstance().getAllWeaponsId();
+			for (Integer itemId: itemIds)
+			{
+				L2Item item = ItemTable.getInstance().getTemplate(itemId);
+				if (item != null && item.getCrystalType() != L2Item.CRYSTAL_NONE)
+				{
+					switch(item.getBodyPart())
+					{
+						case L2Item.SLOT_L_HAND:
+							count++;
+							FuncTemplate ft = new FuncTemplate(null, null, "EnchantHp", Stats.MAX_HP, 0x60, new LambdaConst(0));
+							item.attach(ft);
+							break;
+					}
+				}
+			}
+			_log.info("Enchant HP Bonus registered for " + count + " items!");
+		}
+	}
+
+	public final int getHPBonus(L2ItemInstance item)
+	{
+		final Integer[] values;
+
+		if (item.getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR)
+			values = _fullArmorHPBonus.get(item.getItem().getItemGradeSPlus());
+		else
+			values = _singleArmorHPBonus.get(item.getItem().getItemGradeSPlus());
+
+		if (values == null || values.length == 0)
+			return 0;
+			
+		return values[Math.min(item.getEnchantLevel(), values.length) - 1];
+	}
+
+	@SuppressWarnings("synthetic-access")
+	private static class SingletonHolder
+	{
+		protected static final EnchantHPBonusData _instance = new EnchantHPBonusData();
+	}
+}

+ 12 - 1
L2_GameServer/java/net/sf/l2j/gameserver/datatables/ItemTable.java

@@ -18,6 +18,7 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ScheduledFuture;
 import java.util.logging.Level;
@@ -994,7 +995,17 @@ public class ItemTable
 			_item.setItemLootShedule(null);
 		}
 	}
-	
+
+	public Collection <Integer> getAllArmorsId()
+	{
+		return _armors.keySet();
+	}
+
+	public Collection <Integer> getAllWeaponsId()
+	{
+		return _weapons.keySet();
+	}
+
 	@SuppressWarnings("synthetic-access")
 	private static class SingletonHolder
 	{

+ 2 - 2
L2_GameServer/java/net/sf/l2j/gameserver/skills/DocumentBase.java

@@ -147,8 +147,8 @@ abstract class DocumentBase
             else if ("basemul".equalsIgnoreCase(n.getNodeName())) attachFunc(n, template, "BaseMul", condition);
             else if ("div".equalsIgnoreCase(n.getNodeName())) attachFunc(n, template, "Div", condition);
             else if ("set".equalsIgnoreCase(n.getNodeName())) attachFunc(n, template, "Set", condition);
-            else if ("enchant".equalsIgnoreCase(n.getNodeName())) attachFunc(n, template, "Enchant",
-                                                                             condition);
+            else if ("enchant".equalsIgnoreCase(n.getNodeName())) attachFunc(n, template, "Enchant", condition);
+            else if ("enchanthp".equalsIgnoreCase(n.getNodeName())) attachFunc(n, template, "EnchantHp", condition);
             //else if ("skill".equalsIgnoreCase(n.getNodeName())) attachSkill(n, template, condition);
             else if ("effect".equalsIgnoreCase(n.getNodeName()))
             {

+ 43 - 0
L2_GameServer/java/net/sf/l2j/gameserver/skills/funcs/FuncEnchantHp.java

@@ -0,0 +1,43 @@
+/*
+ * 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.skills.funcs;
+
+import net.sf.l2j.gameserver.datatables.EnchantHPBonusData;
+import net.sf.l2j.gameserver.model.L2ItemInstance;
+import net.sf.l2j.gameserver.skills.Env;
+import net.sf.l2j.gameserver.skills.Stats;
+
+/**
+ *
+ * @author  Yamaneko
+ */
+public class FuncEnchantHp extends Func
+{
+	public FuncEnchantHp(Stats pStat, int pOrder, Object owner, Lambda lambda)
+	{
+		super(pStat, pOrder, owner);
+	}
+
+	@Override
+	public void calc(Env env)
+	{
+		if (cond != null && !cond.test(env)) 
+			return;
+
+		final L2ItemInstance item = (L2ItemInstance) funcOwner;
+		if (item.getEnchantLevel() > 0)
+			env.value += EnchantHPBonusData.getInstance().getHPBonus(item);
+	}
+}