Prechádzať zdrojové kódy

BETA: Reworking pet summoning system:
* Dropped SummonItemsData.
* Split of PetData.xml into xml for each pet.
* Using itemId reference from L2PetData
* Implemented pet level synchronization (Some pet's are following player's level)
* Added retail-like message when summoning a pet.
* Fixed bug which prevents you from canceling (ESC) the skill that summon a pet while casting.
* Reported by: Tryskell

* Reviewed by: Zoey76, MELERIX

Rumen Nikiforov 12 rokov pred
rodič
commit
6dc54fc9c3

+ 0 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java

@@ -74,7 +74,6 @@ import com.l2jserver.gameserver.datatables.SkillTable;
 import com.l2jserver.gameserver.datatables.SkillTreesData;
 import com.l2jserver.gameserver.datatables.SpawnTable;
 import com.l2jserver.gameserver.datatables.StaticObjects;
-import com.l2jserver.gameserver.datatables.SummonItemsData;
 import com.l2jserver.gameserver.datatables.SummonSkillsTable;
 import com.l2jserver.gameserver.datatables.TeleportLocationTable;
 import com.l2jserver.gameserver.datatables.UITable;
@@ -221,7 +220,6 @@ public class GameServer
 		ItemTable.getInstance();
 		EnchantItemData.getInstance();
 		EnchantOptionsData.getInstance();
-		SummonItemsData.getInstance();
 		EnchantHPBonusData.getInstance();
 		MerchantPriceConfigTable.getInstance().loadInstances();
 		TradeController.getInstance();

+ 3 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/CharSummonTable.java

@@ -29,7 +29,7 @@ import java.util.logging.Logger;
 import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.idfactory.IdFactory;
-import com.l2jserver.gameserver.model.L2SummonItem;
+import com.l2jserver.gameserver.model.L2PetData;
 import com.l2jserver.gameserver.model.actor.instance.L2MerchantSummonInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
@@ -241,8 +241,8 @@ public class CharSummonTable
 	public void restorePet(L2PcInstance activeChar)
 	{
 		L2ItemInstance item = activeChar.getInventory().getItemByObjectId(_pets.get(activeChar.getObjectId()));
-		final L2SummonItem sitem = SummonItemsData.getInstance().getSummonItem(item.getItemId());
-		L2NpcTemplate npcTemplate = NpcTable.getInstance().getTemplate(sitem.getNpcId());
+		final L2PetData petData = PetDataTable.getInstance().getPetDataByItemId(item.getItemId());
+		L2NpcTemplate npcTemplate = NpcTable.getInstance().getTemplate(petData.getNpcId());
 		
 		if (npcTemplate == null)
 		{

+ 24 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/PetDataTable.java

@@ -50,7 +50,7 @@ public final class PetDataTable extends DocumentParser
 	public void load()
 	{
 		_pets.clear();
-		parseDatapackFile("data/stats/npc/PetData.xml");
+		parseDirectory("data/stats/pets/");
 		_log.info(getClass().getSimpleName() + ": Loaded " + _pets.size() + " Pets.");
 	}
 	
@@ -64,8 +64,9 @@ public final class PetDataTable extends DocumentParser
 			if (d.getNodeName().equals("pet"))
 			{
 				int npcId = parseInt(d.getAttributes(), "id");
+				int itemId = parseInt(d.getAttributes(), "itemId");
 				// index ignored for now
-				L2PetData data = new L2PetData();
+				L2PetData data = new L2PetData(npcId, itemId);
 				for (Node p = d.getFirstChild(); p != null; p = p.getNextSibling())
 				{
 					if (p.getNodeName().equals("set"))
@@ -87,7 +88,11 @@ public final class PetDataTable extends DocumentParser
 						{
 							data.setHungryLimit(parseInt(attrs, "val"));
 						}
-						// sync_level and evolve ignored
+						else if ("sync_level".equals(type))
+						{
+							data.setSyncLevel(parseInt(attrs, "val") == 1);
+						}
+						// evolve ignored
 					}
 					else if (p.getNodeName().equals("skills"))
 					{
@@ -126,6 +131,22 @@ public final class PetDataTable extends DocumentParser
 		}
 	}
 	
+	/**
+	 * @param itemId
+	 * @return
+	 */
+	public L2PetData getPetDataByItemId(int itemId)
+	{
+		for (L2PetData data : _pets.values())
+		{
+			if (data.getItemId() == itemId)
+			{
+				return data;
+			}
+		}
+		return null;
+	}
+	
 	/**
 	 * Gets the pet level data.
 	 * @param petId the pet Id.

+ 0 - 114
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/SummonItemsData.java

@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2004-2013 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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.
- * 
- * L2J Server 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 com.l2jserver.gameserver.datatables;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.logging.Logger;
-
-import com.l2jserver.Config;
-import com.l2jserver.gameserver.model.L2SummonItem;
-
-/**
- * @author FBIagent
- */
-public class SummonItemsData
-{
-	private static final Logger _log = Logger.getLogger(SummonItemsData.class.getName());
-	private static final Map<Integer, L2SummonItem> _summonitems = new HashMap<>();
-	
-	protected SummonItemsData()
-	{
-		try (Scanner s = new Scanner(new File(Config.DATAPACK_ROOT, "data/summon_items.csv")))
-		{
-			int lineCount = 0;
-			
-			while (s.hasNextLine())
-			{
-				lineCount++;
-				
-				String line = s.nextLine();
-				
-				if (line.isEmpty() || (line.charAt(0) == '#'))
-				{
-					continue;
-				}
-				
-				String[] lineSplit = line.split(";");
-				int itemID = 0, npcID = 0;
-				byte summonType = 0;
-				int despawn = -1;
-				
-				try
-				{
-					itemID = Integer.parseInt(lineSplit[0]);
-					npcID = Integer.parseInt(lineSplit[1]);
-					summonType = Byte.parseByte(lineSplit[2]);
-					if (summonType == 0)
-					{
-						despawn = Integer.parseInt(lineSplit[3]);
-					}
-				}
-				catch (Exception e)
-				{
-					_log.warning(getClass().getSimpleName() + ": Error in line " + lineCount + " -> incomplete/invalid data or wrong seperator!");
-					_log.warning("		" + line);
-					continue;
-				}
-				_summonitems.put(itemID, new L2SummonItem(itemID, npcID, summonType, despawn));
-			}
-			
-			_log.info(getClass().getSimpleName() + ": Loaded " + _summonitems.size() + " summon items.");
-		}
-		catch (Exception e)
-		{
-			_log.warning(getClass().getSimpleName() + ": Can not find '" + Config.DATAPACK_ROOT + "/data/summon_items.csv'");
-			return;
-		}
-	}
-	
-	public L2SummonItem getSummonItem(int itemId)
-	{
-		return _summonitems.get(itemId);
-	}
-	
-	public int[] itemIDs()
-	{
-		int size = _summonitems.size();
-		int[] result = new int[size];
-		int i = 0;
-		for (L2SummonItem si : _summonitems.values())
-		{
-			result[i++] = si.getItemId();
-		}
-		return result;
-	}
-	
-	public static SummonItemsData getInstance()
-	{
-		return SingletonHolder._instance;
-	}
-	
-	private static class SingletonHolder
-	{
-		protected static final SummonItemsData _instance = new SummonItemsData();
-	}
-}

+ 5 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Object.java

@@ -904,14 +904,16 @@ public abstract class L2Object
 	/**
 	 * @param <T>
 	 * @param script
+	 * @return
 	 */
-	public final <T> void removeScript(T script)
+	@SuppressWarnings("unchecked")
+	public final <T> T removeScript(Class<T> script)
 	{
 		if (_scripts == null)
 		{
-			return;
+			return null;
 		}
-		_scripts.remove(script.getClass().getName());
+		return (T) _scripts.remove(script.getName());
 	}
 	
 	/**

+ 41 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2PetData.java

@@ -35,11 +35,36 @@ public class L2PetData
 	private final Map<Integer, L2PetLevelData> _levelStats = new HashMap<>();
 	private final List<L2PetSkillLearn> _skills = new ArrayList<>();
 	
+	private final int _npcId;
+	private final int _itemId;
 	private int _load = 20000;
 	private int _hungryLimit = 1;
 	private int _minlvl = Byte.MAX_VALUE;
+	private boolean _syncLevel = false;
 	private final List<Integer> _food = new ArrayList<>();
 	
+	public L2PetData(int npcId, int itemId)
+	{
+		_npcId = npcId;
+		_itemId = itemId;
+	}
+	
+	/**
+	 * @return the npc id representing this pet.
+	 */
+	public int getNpcId()
+	{
+		return _npcId;
+	}
+	
+	/**
+	 * @return the item id that could summon this pet.
+	 */
+	public int getItemId()
+	{
+		return _itemId;
+	}
+	
 	/**
 	 * @param level the pet's level.
 	 * @param data the pet's data.
@@ -78,6 +103,14 @@ public class L2PetData
 		return _hungryLimit;
 	}
 	
+	/**
+	 * @return {@code true} if pet synchronizes it's level with his master's
+	 */
+	public boolean isSynchLevel()
+	{
+		return _syncLevel;
+	}
+	
 	/**
 	 * @return the pet's minimum level.
 	 */
@@ -118,6 +151,14 @@ public class L2PetData
 		_hungryLimit = limit;
 	}
 	
+	/**
+	 * @param val synchronizes level with master or not.
+	 */
+	public void setSyncLevel(boolean val)
+	{
+		_syncLevel = val;
+	}
+	
 	// SKILS
 	
 	/**

+ 21 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -1940,10 +1940,28 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		broadcastPacket(new MagicSkillUse(this, target, displayId, level, skillTime, reuseDelay));
 		
 		// Send a system message USE_S1 to the L2Character
-		if (isPlayer() && (magicId != 1312))
+		if (isPlayer())
 		{
-			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.USE_S1);
-			sm.addSkillName(skill);
+			SystemMessage sm = null;
+			switch (magicId)
+			{
+				case 1312: // Fishing
+				{
+					// Done in L2PcInstance.startFishing()
+					break;
+				}
+				case 2046: // Wolf Collar
+				{
+					sm = SystemMessage.getSystemMessage(SystemMessageId.SUMMON_A_PET);
+					break;
+				}
+				default:
+				{
+					sm = SystemMessage.getSystemMessage(SystemMessageId.USE_S1);
+					sm.addSkillName(skill);
+				}
+			}
+			
 			sendPacket(sm);
 		}
 		

+ 5 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PetInstance.java

@@ -264,12 +264,17 @@ public class L2PetInstance extends L2Summon
 		{
 			return null; // owner has a pet listed in world
 		}
+		final L2PetData data = PetDataTable.getInstance().getPetData(template.getNpcId());
 		
 		L2PetInstance pet = restore(control, template, owner);
 		// add the pet instance to world
 		if (pet != null)
 		{
 			pet.setTitle(owner.getName());
+			if (data.isSynchLevel() && (pet.getLevel() != owner.getLevel()))
+			{
+				pet.getStat().setLevel((byte) owner.getLevel());
+			}
 			L2World.getInstance().addPet(owner.getObjectId(), pet);
 		}
 		

+ 10 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java

@@ -288,6 +288,16 @@ public class PcStat extends PlayableStat
 			getActiveChar().getTransformation().onLevelUp();
 		}
 		
+		// Synchronize level with pet if possible.
+		if (getActiveChar().hasSummon() && getActiveChar().getSummon().isPet())
+		{
+			final L2PetInstance pet = (L2PetInstance) getActiveChar().getSummon();
+			if (pet.getPetData().isSynchLevel() && (pet.getLevel() != getLevel()))
+			{
+				pet.getStat().setLevel(getLevel());
+			}
+		}
+		
 		StatusUpdate su = new StatusUpdate(getActiveChar());
 		su.addAttribute(StatusUpdate.LEVEL, getLevel());
 		su.addAttribute(StatusUpdate.MAX_CP, getMaxCp());

+ 1 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/effects/L2EffectType.java

@@ -86,6 +86,7 @@ public enum L2EffectType
 	SPOIL,
 	STUN,
 	SUMMON_AGATHION,
+	SUMMON_PET,
 	TARGET_ME,
 	THROW_UP,
 	TRANSFORMATION,

+ 39 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/holders/PetItemHolder.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2004-2013 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server 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.
+ * 
+ * L2J Server 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 com.l2jserver.gameserver.model.holders;
+
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+
+/**
+ * @author UnAfraid
+ */
+public class PetItemHolder
+{
+	private final L2ItemInstance _item;
+	
+	public PetItemHolder(L2ItemInstance item)
+	{
+		_item = item;
+	}
+	
+	public L2ItemInstance getItem()
+	{
+		return _item;
+	}
+}

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/L2GameClient.java

@@ -264,7 +264,7 @@ public final class L2GameClient extends MMOClient<MMOConnection<L2GameClient>> i
 	
 	public void sendPacket(L2GameServerPacket gsp)
 	{
-		if (_isDetached)
+		if (_isDetached || (gsp == null))
 		{
 			return;
 		}

+ 13 - 13
L2J_Server_BETA/java/com/l2jserver/gameserver/util/Evolve.java

@@ -27,8 +27,8 @@ import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.datatables.NpcTable;
-import com.l2jserver.gameserver.datatables.SummonItemsData;
-import com.l2jserver.gameserver.model.L2SummonItem;
+import com.l2jserver.gameserver.datatables.PetDataTable;
+import com.l2jserver.gameserver.model.L2PetData;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -72,28 +72,28 @@ public final class Evolve
 		int oldY = currentPet.getY();
 		int oldZ = currentPet.getZ();
 		
-		L2SummonItem olditem = SummonItemsData.getInstance().getSummonItem(itemIdtake);
+		L2PetData oldData = PetDataTable.getInstance().getPetDataByItemId(itemIdtake);
 		
-		if (olditem == null)
+		if (oldData == null)
 		{
 			return false;
 		}
 		
-		int oldnpcID = olditem.getNpcId();
+		int oldnpcID = oldData.getNpcId();
 		
 		if ((currentPet.getStat().getLevel() < petminlvl) || (currentPet.getNpcId() != oldnpcID))
 		{
 			return false;
 		}
 		
-		L2SummonItem sitem = SummonItemsData.getInstance().getSummonItem(itemIdgive);
+		L2PetData petData = PetDataTable.getInstance().getPetDataByItemId(itemIdgive);
 		
-		if (sitem == null)
+		if (petData == null)
 		{
 			return false;
 		}
 		
-		int npcID = sitem.getNpcId();
+		int npcID = petData.getNpcId();
 		
 		if (npcID == 0)
 		{
@@ -175,19 +175,19 @@ public final class Evolve
 			oldpetlvl = petminlvl;
 		}
 		
-		L2SummonItem oldItem = SummonItemsData.getInstance().getSummonItem(itemIdtake);
-		if (oldItem == null)
+		L2PetData oldData = PetDataTable.getInstance().getPetDataByItemId(itemIdtake);
+		if (oldData == null)
 		{
 			return false;
 		}
 		
-		L2SummonItem sItem = SummonItemsData.getInstance().getSummonItem(itemIdgive);
-		if (sItem == null)
+		L2PetData petData = PetDataTable.getInstance().getPetDataByItemId(itemIdgive);
+		if (petData == null)
 		{
 			return false;
 		}
 		
-		int npcId = sItem.getNpcId();
+		int npcId = petData.getNpcId();
 		if (npcId == 0)
 		{
 			return false;