Forráskód Böngészése

BETA: Items related reworks:
* Added ability to verify trigger skills if target matches pvp conditions before activating them
* Note: '''Disabled by default! '''
* Fixing an exploit causing some items to add stats but when unequip do not remove it.
* Reported by: nBd
* Reworking all item instances to verify for all available item modifications (Element, Augment, etc..) no matter what type they are.
* Reworking augmentation system:
* Now is a bit more retail like.
* Added changes for each augmentation option
* Note: '''Not totally randomly as before! '''
* Added config to keep old way.
* Reworked augmentation trigger effects to be handled properly
* Note: '''You will not see them anymore in your skill list! '''
* Patch by: Sandro, UnAfraid

Rumen Nikiforov 12 éve
szülő
commit
5cf320bb02
22 módosított fájl, 1370 hozzáadás és 671 törlés
  1. 24 3
      L2J_Server_BETA/dist/game/config/Character.properties
  2. 37 1
      L2J_Server_BETA/java/com/l2jserver/Config.java
  3. 2 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/GameServer.java
  4. 508 308
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/AugmentationData.java
  5. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/EnchantOptionsData.java
  6. 176 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/OptionsData.java
  7. 1 63
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/ChanceSkillList.java
  8. 40 86
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Augmentation.java
  9. 129 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java
  10. 2 4
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemauction/AuctionItem.java
  11. 36 98
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java
  12. 1 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/PcInventory.java
  13. 1 39
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/L2Armor.java
  14. 7 2
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/L2Item.java
  15. 1 35
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/L2Weapon.java
  16. 65 28
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/instance/L2ItemInstance.java
  17. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/EnchantOptions.java
  18. 254 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/Options.java
  19. 53 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/OptionsSkillHolder.java
  20. 29 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/OptionsSkillType.java
  21. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/MultiSellChoose.java
  22. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestRefine.java

+ 24 - 3
L2J_Server_BETA/dist/game/config/Character.properties

@@ -394,7 +394,6 @@ EnchantBlackList = 7816,7817,7818,7819,7820,7821,7822,7823,7824,7825,7826,7827,7
 # ---------------------------------------------------------------------------
 # Augmenting
 # ---------------------------------------------------------------------------
-
 # These control the chance to get a skill in the augmentation process.
 # Default: 15, 30, 45, 60
 AugmentationNGSkillChance = 15
@@ -419,10 +418,26 @@ AugmentationMidGlowChance = 40
 AugmentationHighGlowChance = 70
 AugmentationTopGlowChance = 100
 
+# This will enable retail like weapon augmentation, but then you cant change 
+# weapon glow, base stat chance, because it wouldnt be retail like again.
+RetailLikeAugmentation = True
+
+# This will have effect ONLY when RetailLikeAugmentation is True. The sum of 4 numbers must be 100!
+# You can change probability (in %) of augment color chances - in order yellow, blue, purple, red
+# Purple and Red always give skill. Default is 55%,35%,7%,3% for all lifestone grades (ie 7+3=10% 
+# for skill, not counting blue ones, that are very rare and not useful anyway). 
+RetailLikeAugmentationNoGradeChance = 55,35,7,3
+RetailLikeAugmentationMidGradeChance = 55,35,7,3
+RetailLikeAugmentationHighGradeChance = 55,35,7,3
+RetailLikeAugmentationTopGradeChance = 55,35,7,3
+
+# This will enable retail like accessory augmentation, but then you cant change skill chances for accessory augments
+RetailLikeAugmentationAccessory = True
+
 # List of non-augmentable items, currently contains only Grand Boss jewels
 # Shadow, common, time-limited, hero, pvp, wear items are hardcoded, as well as all etcitems.
 # Rods can't be augmented too.
-# Default: 6656,6657,6658,6659,6660,6661,6662,8191,10170,10314,13740,13741,13742,13743,13744,13745,13746,13747,13748,14592,14593,14594,14595,14596,14597,14598,14599,14600,14664,14665,14666,14667,14668,14669,14670,14671,14672,14801,14802,14803,14804,14805,14806,14807,14808,14809,15282,15283,15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,15299,16025,16026,21712,22173,22174,22175
+# Default: 6656,6657,6658,6659,6660,6661,6662,8191,10170,10314
 AugmentationBlackList = 6656,6657,6658,6659,6660,6661,6662,8191,10170,10314,13740,13741,13742,13743,13744,13745,13746,13747,13748,14592,14593,14594,14595,14596,14597,14598,14599,14600,14664,14665,14666,14667,14668,14669,14670,14671,14672,14801,14802,14803,14804,14805,14806,14807,14808,14809,15282,15283,15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,15299,16025,16026,21712,22173,22174,22175
 
 # Allows alternative augmentation of PvP items.
@@ -822,4 +837,10 @@ ForbiddenNames = annou,ammou,amnou,anmou,anou,amou
 # If enabled, when character in silence (block PMs) mode sends a PM to a character, silence mode no longer blocks this character, 
 # allowing both characters send each other PMs even with enabled silence mode.
 # The exclude list is cleared each time the character goes into silence mode.
-SilenceModeExclude = False
+SilenceModeExclude = False
+
+# Enables alternative validation of triggering skills.
+# When enabled pvp skills will not be casted on non flagged player.
+# Sadly its non-retail
+# Default: False
+AltValidateTriggerSkills = False

+ 37 - 1
L2J_Server_BETA/java/com/l2jserver/Config.java

@@ -257,6 +257,8 @@ public final class Config
 	public static boolean STORE_UI_SETTINGS;
 	public static String[] FORBIDDEN_NAMES;
 	public static boolean SILENCE_MODE_EXCLUDE;
+	public static boolean ALT_VALIDATE_TRIGGER_SKILLS;
+	
 	// --------------------------------------------------
 	// ClanHall Settings
 	// --------------------------------------------------
@@ -1022,6 +1024,12 @@ public final class Config
 	public static int AUGMENTATION_TOP_GLOW_CHANCE;
 	public static int AUGMENTATION_BASESTAT_CHANCE;
 	public static int AUGMENTATION_ACC_SKILL_CHANCE;
+	public static boolean RETAIL_LIKE_AUGMENTATION;
+	public static int[] RETAIL_LIKE_AUGMENTATION_NG_CHANCE;
+	public static int[] RETAIL_LIKE_AUGMENTATION_MID_CHANCE;
+	public static int[] RETAIL_LIKE_AUGMENTATION_HIGH_CHANCE;
+	public static int[] RETAIL_LIKE_AUGMENTATION_TOP_CHANCE;
+	public static boolean RETAIL_LIKE_AUGMENTATION_ACCESSORY;
 	public static int[] AUGMENTATION_BLACKLIST;
 	public static boolean ALT_ALLOW_AUGMENT_PVP_ITEMS;
 	public static double HP_REGEN_MULTIPLIER;
@@ -1629,7 +1637,34 @@ public final class Config
 			AUGMENTATION_BASESTAT_CHANCE = Integer.parseInt(Character.getProperty("AugmentationBaseStatChance", "1"));
 			AUGMENTATION_ACC_SKILL_CHANCE = Integer.parseInt(Character.getProperty("AugmentationAccSkillChance", "0"));
 			
-			String[] array = Character.getProperty("AugmentationBlackList", "6656,6657,6658,6659,6660,6661,6662,8191,10170,10314,13740,13741,13742,13743,13744,13745,13746,13747,13748,14592,14593,14594,14595,14596,14597,14598,14599,14600,14664,14665,14666,14667,14668,14669,14670,14671,14672,14801,14802,14803,14804,14805,14806,14807,14808,14809,15282,15283,15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,15299,16025,16026,21712,22173,22174,22175").split(",");
+			RETAIL_LIKE_AUGMENTATION = Boolean.parseBoolean(Character.getProperty("RetailLikeAugmentation", "True"));
+			String[] array = Character.getProperty("RetailLikeAugmentationNoGradeChance", "55,35,7,3").split(",");
+			RETAIL_LIKE_AUGMENTATION_NG_CHANCE = new int[array.length];
+			for (int i = 0; i < 4; i++)
+			{
+				RETAIL_LIKE_AUGMENTATION_NG_CHANCE[i] = Integer.parseInt(array[i]);
+			}
+			array = Character.getProperty("RetailLikeAugmentationMidGradeChance", "55,35,7,3").split(",");
+			RETAIL_LIKE_AUGMENTATION_MID_CHANCE = new int[array.length];
+			for (int i = 0; i < 4; i++)
+			{
+				RETAIL_LIKE_AUGMENTATION_MID_CHANCE[i] = Integer.parseInt(array[i]);
+			}
+			array = Character.getProperty("RetailLikeAugmentationHighGradeChance", "55,35,7,3").split(",");
+			RETAIL_LIKE_AUGMENTATION_HIGH_CHANCE = new int[array.length];
+			for (int i = 0; i < 4; i++)
+			{
+				RETAIL_LIKE_AUGMENTATION_HIGH_CHANCE[i] = Integer.parseInt(array[i]);
+			}
+			array = Character.getProperty("RetailLikeAugmentationTopGradeChance", "55,35,7,3").split(",");
+			RETAIL_LIKE_AUGMENTATION_TOP_CHANCE = new int[array.length];
+			for (int i = 0; i < 4; i++)
+			{
+				RETAIL_LIKE_AUGMENTATION_TOP_CHANCE[i] = Integer.parseInt(array[i]);
+			}
+			RETAIL_LIKE_AUGMENTATION_ACCESSORY = Boolean.parseBoolean(Character.getProperty("RetailLikeAugmentationAccessory", "True"));
+			
+			array = Character.getProperty("AugmentationBlackList", "6656,6657,6658,6659,6660,6661,6662,8191,10170,10314,13740,13741,13742,13743,13744,13745,13746,13747,13748,14592,14593,14594,14595,14596,14597,14598,14599,14600,14664,14665,14666,14667,14668,14669,14670,14671,14672,14801,14802,14803,14804,14805,14806,14807,14808,14809,15282,15283,15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,15296,15297,15298,15299,16025,16026,21712,22173,22174,22175").split(",");
 			AUGMENTATION_BLACKLIST = new int[array.length];
 			
 			for (int i = 0; i < array.length; i++)
@@ -1757,6 +1792,7 @@ public final class Config
 			STORE_UI_SETTINGS = Boolean.parseBoolean(Character.getProperty("StoreCharUiSettings", "False"));
 			FORBIDDEN_NAMES = Character.getProperty("ForbiddenNames", "").split(",");
 			SILENCE_MODE_EXCLUDE = Boolean.parseBoolean(Character.getProperty("SilenceModeExclude", "False"));
+			ALT_VALIDATE_TRIGGER_SKILLS = Boolean.parseBoolean(Character.getProperty("AltValidateTriggerSkills", "False"));
 			PLAYER_MOVEMENT_BLOCK_TIME = Integer.parseInt(Character.getProperty("NpcTalkBlockingTime", "0")) * 1000;
 			
 			// Load L2J Server Version L2Properties file (if exists)

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

@@ -67,6 +67,7 @@ import com.l2jserver.gameserver.datatables.MultiSell;
 import com.l2jserver.gameserver.datatables.NpcBufferTable;
 import com.l2jserver.gameserver.datatables.NpcTable;
 import com.l2jserver.gameserver.datatables.OfflineTradersTable;
+import com.l2jserver.gameserver.datatables.OptionsData;
 import com.l2jserver.gameserver.datatables.PetDataTable;
 import com.l2jserver.gameserver.datatables.RecipeData;
 import com.l2jserver.gameserver.datatables.SkillTable;
@@ -219,6 +220,7 @@ public class GameServer
 		ItemTable.getInstance();
 		EnchantItemData.getInstance();
 		EnchantOptionsData.getInstance();
+		OptionsData.getInstance();
 		EnchantHPBonusData.getInstance();
 		MerchantPriceConfigTable.getInstance().loadInstances();
 		TradeController.getInstance();

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 508 - 308
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/AugmentationData.java


+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/EnchantOptionsData.java

@@ -25,8 +25,8 @@ import java.util.logging.Level;
 import org.w3c.dom.Node;
 
 import com.l2jserver.gameserver.engines.DocumentParser;
-import com.l2jserver.gameserver.model.EnchantOptions;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.model.options.EnchantOptions;
 import com.l2jserver.gameserver.util.Util;
 
 /**

+ 176 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/OptionsData.java

@@ -0,0 +1,176 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import com.l2jserver.gameserver.engines.DocumentParser;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.options.Options;
+import com.l2jserver.gameserver.model.options.OptionsSkillHolder;
+import com.l2jserver.gameserver.model.options.OptionsSkillType;
+import com.l2jserver.gameserver.model.skills.funcs.FuncTemplate;
+import com.l2jserver.gameserver.model.skills.funcs.LambdaConst;
+import com.l2jserver.gameserver.model.stats.Stats;
+
+/**
+ * @author UnAfraid
+ */
+public class OptionsData extends DocumentParser
+{
+	private final Map<Integer, Options> _data = new HashMap<>();
+	
+	protected OptionsData()
+	{
+		load();
+	}
+	
+	@Override
+	public synchronized void load()
+	{
+		parseDirectory("data/stats/options");
+		_log.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _data.size() + " Options.");
+	}
+	
+	@Override
+	protected void parseDocument()
+	{
+		int id;
+		Options op;
+		for (Node n = getCurrentDocument().getFirstChild(); n != null; n = n.getNextSibling())
+		{
+			if ("list".equalsIgnoreCase(n.getNodeName()))
+			{
+				for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
+				{
+					if ("option".equalsIgnoreCase(d.getNodeName()))
+					{
+						id = parseInt(d.getAttributes(), "id");
+						op = new Options(id);
+						
+						for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
+						{
+							switch (cd.getNodeName())
+							{
+								case "for":
+								{
+									for (Node fd = cd.getFirstChild(); fd != null; fd = fd.getNextSibling())
+									{
+										switch (fd.getNodeName())
+										{
+											case "add":
+											{
+												parseFuncs(fd.getAttributes(), "Add", op);
+												break;
+											}
+											case "mul":
+											{
+												parseFuncs(fd.getAttributes(), "Mul", op);
+												break;
+											}
+											case "basemul":
+											{
+												parseFuncs(fd.getAttributes(), "BaseMul", op);
+												break;
+											}
+											case "sub":
+											{
+												parseFuncs(fd.getAttributes(), "Sub", op);
+												break;
+											}
+											case "div":
+											{
+												parseFuncs(fd.getAttributes(), "Div", op);
+												break;
+											}
+											case "set":
+											{
+												parseFuncs(fd.getAttributes(), "Set", op);
+												break;
+											}
+										}
+									}
+									break;
+								}
+								case "active_skill":
+								{
+									op.setActiveSkill(new SkillHolder(parseInt(cd.getAttributes(), "id"), parseInt(cd.getAttributes(), "level")));
+									break;
+								}
+								case "passive_skill":
+								{
+									op.setPassiveSkill(new SkillHolder(parseInt(cd.getAttributes(), "id"), parseInt(cd.getAttributes(), "level")));
+									break;
+								}
+								case "attack_skill":
+								{
+									op.addActivationSkill(new OptionsSkillHolder(parseInt(cd.getAttributes(), "id"), parseInt(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.ATTACK));
+									break;
+								}
+								case "magic_skill":
+								{
+									op.addActivationSkill(new OptionsSkillHolder(parseInt(cd.getAttributes(), "id"), parseInt(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.MAGIC));
+									break;
+								}
+								case "critical_skill":
+								{
+									op.addActivationSkill(new OptionsSkillHolder(parseInt(cd.getAttributes(), "id"), parseInt(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.CRITICAL));
+									break;
+								}
+							}
+						}
+						_data.put(op.getId(), op);
+					}
+				}
+			}
+		}
+	}
+	
+	private void parseFuncs(NamedNodeMap attrs, String func, Options op)
+	{
+		Stats stat = Stats.valueOfXml(parseString(attrs, "stat"));
+		int ord = Integer.decode(parseString(attrs, "order"));
+		double val = parseDouble(attrs, "val");
+		op.addFunc(new FuncTemplate(null, null, func, stat, ord, new LambdaConst(val)));
+	}
+	
+	public Options getOptions(int id)
+	{
+		return _data.get(id);
+	}
+	
+	/**
+	 * Gets the single instance of OptionsData.
+	 * @return single instance of OptionsData
+	 */
+	public static final OptionsData getInstance()
+	{
+		return SingletonHolder._instance;
+	}
+	
+	private static class SingletonHolder
+	{
+		protected static final OptionsData _instance = new OptionsData();
+	}
+}

+ 1 - 63
L2J_Server_BETA/java/com/l2jserver/gameserver/model/ChanceSkillList.java

@@ -143,7 +143,7 @@ public class ChanceSkillList extends FastMap<IChanceSkillTrigger, ChanceConditio
 			{
 				if (e.getKey() instanceof L2Skill)
 				{
-					makeCast((L2Skill) e.getKey(), target);
+					_owner.makeTriggerCast((L2Skill) e.getKey(), target);
 				}
 				else
 				{
@@ -153,68 +153,6 @@ public class ChanceSkillList extends FastMap<IChanceSkillTrigger, ChanceConditio
 		}
 	}
 	
-	private void makeCast(L2Skill skill, L2Character target)
-	{
-		try
-		{
-			if (skill.getWeaponDependancy(_owner, true) && skill.checkCondition(_owner, target, false))
-			{
-				if (skill.triggersChanceSkill()) // skill will trigger another skill, but only if its not chance skill
-				{
-					skill = SkillTable.getInstance().getInfo(skill.getTriggeredChanceId(), skill.getTriggeredChanceLevel());
-					if ((skill == null) || (skill.getSkillType() == L2SkillType.NOTDONE))
-					{
-						return;
-					}
-					// We change skill to new one, we should verify conditions and dependancy for new one
-					if (!skill.getWeaponDependancy(_owner, true) || !skill.checkCondition(_owner, target, false))
-					{
-						return;
-					}
-				}
-				
-				if (_owner.isSkillDisabled(skill))
-				{
-					return;
-				}
-				
-				if (skill.getReuseDelay() > 0)
-				{
-					_owner.disableSkill(skill, skill.getReuseDelay());
-				}
-				
-				L2Object[] targets = skill.getTargetList(_owner, false, target);
-				
-				if (targets.length == 0)
-				{
-					return;
-				}
-				
-				L2Character firstTarget = (L2Character) targets[0];
-				
-				ISkillHandler handler = SkillHandler.getInstance().getHandler(skill.getSkillType());
-				
-				_owner.broadcastPacket(new MagicSkillLaunched(_owner, skill.getDisplayId(), skill.getDisplayLevel(), targets));
-				_owner.broadcastPacket(new MagicSkillUse(_owner, firstTarget, skill.getDisplayId(), skill.getDisplayLevel(), 0, 0));
-				
-				// Launch the magic skill and calculate its effects
-				// TODO: once core will support all possible effects, use effects (not handler)
-				if (handler != null)
-				{
-					handler.useSkill(_owner, skill, targets);
-				}
-				else
-				{
-					skill.useSkill(_owner, targets);
-				}
-			}
-		}
-		catch (Exception e)
-		{
-			_log.log(Level.WARNING, "", e);
-		}
-	}
-	
 	private void makeCast(L2Effect effect, L2Character target)
 	{
 		try

+ 40 - 86
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Augmentation.java

@@ -1,77 +1,68 @@
 /*
- * Copyright (C) 2004-2013 L2J Server
+ * 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 file is part of L2J Server.
+ * 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.
  * 
- * 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/>.
+ * 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;
 
-import javolution.util.FastList;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
-import com.l2jserver.gameserver.datatables.AugmentationData;
-import com.l2jserver.gameserver.datatables.SkillTable;
+import com.l2jserver.gameserver.datatables.OptionsData;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.funcs.FuncAdd;
-import com.l2jserver.gameserver.model.skills.funcs.LambdaConst;
-import com.l2jserver.gameserver.model.stats.Stats;
-import com.l2jserver.gameserver.network.serverpackets.SkillCoolTime;
+import com.l2jserver.gameserver.model.options.Options;
 
 /**
  * Used to store an augmentation and its boni
- * @author durgus
+ * @author durgus, UnAfraid
  */
 public final class L2Augmentation
 {
 	private int _effectsId = 0;
 	private AugmentationStatBoni _boni = null;
-	private L2Skill _skill = null;
 	
-	public L2Augmentation(int effects, L2Skill skill)
+	public L2Augmentation(int effects)
 	{
 		_effectsId = effects;
 		_boni = new AugmentationStatBoni(_effectsId);
-		_skill = skill;
-	}
-	
-	public L2Augmentation(int effects, int skill, int skillLevel)
-	{
-		this(effects, skill != 0 ? SkillTable.getInstance().getInfo(skill, skillLevel) : null);
 	}
 	
 	public static class AugmentationStatBoni
 	{
-		private final Stats _stats[];
-		private final float _values[];
+		private static final Logger _log = Logger.getLogger(AugmentationStatBoni.class.getName());
+		private final List<Options> _options = new ArrayList<>();
 		private boolean _active;
 		
 		public AugmentationStatBoni(int augmentationId)
 		{
 			_active = false;
-			FastList<AugmentationData.AugStat> as = AugmentationData.getInstance().getAugStatsById(augmentationId);
+			int[] stats = new int[2];
+			stats[0] = 0x0000FFFF & augmentationId;
+			stats[1] = (augmentationId >> 16);
 			
-			_stats = new Stats[as.size()];
-			_values = new float[as.size()];
-			
-			int i = 0;
-			for (AugmentationData.AugStat aStat : as)
+			for (int stat : stats)
 			{
-				_stats[i] = aStat.getStat();
-				_values[i] = aStat.getValue();
-				i++;
+				Options op = OptionsData.getInstance().getOptions(stat);
+				if (op != null)
+				{
+					_options.add(op);
+				}
+				else
+				{
+					_log.log(Level.WARNING, getClass().getSimpleName() + ": Couldn't find option: " + stat);
+				}
 			}
 		}
 		
@@ -83,9 +74,9 @@ public final class L2Augmentation
 				return;
 			}
 			
-			for (int i = 0; i < _stats.length; i++)
+			for (Options op : _options)
 			{
-				player.addStatFunc(new FuncAdd(_stats[i], 0x40, this, new LambdaConst(_values[i])));
+				op.apply(player);
 			}
 			
 			_active = true;
@@ -98,7 +89,11 @@ public final class L2Augmentation
 			{
 				return;
 			}
-			player.removeStatsOwner(this);
+			
+			for (Options op : _options)
+			{
+				op.remove(player);
+			}
 			
 			_active = false;
 		}
@@ -118,39 +113,13 @@ public final class L2Augmentation
 		return _effectsId;
 	}
 	
-	public L2Skill getSkill()
-	{
-		return _skill;
-	}
-	
 	/**
 	 * Applies the bonuses to the player.
 	 * @param player
 	 */
 	public void applyBonus(L2PcInstance player)
 	{
-		boolean updateTimeStamp = false;
 		_boni.applyBonus(player);
-		
-		// add the skill if any
-		if (_skill != null)
-		{
-			player.addSkill(_skill);
-			if (_skill.isActive())
-			{
-				final long delay = player.getSkillRemainingReuseTime(_skill.getReuseHashCode());
-				if (delay > 0)
-				{
-					player.disableSkill(_skill, delay);
-					updateTimeStamp = true;
-				}
-			}
-			player.sendSkillList();
-			if (updateTimeStamp)
-			{
-				player.sendPacket(new SkillCoolTime(player));
-			}
-		}
 	}
 	
 	/**
@@ -160,20 +129,5 @@ public final class L2Augmentation
 	public void removeBonus(L2PcInstance player)
 	{
 		_boni.removeBonus(player);
-		
-		// remove the skill if any
-		if (_skill != null)
-		{
-			if (_skill.isPassive())
-			{
-				player.removeSkill(_skill, false, true);
-			}
-			else
-			{
-				player.removeSkill(_skill, false, false);
-			}
-			
-			player.sendSkillList();
-		}
 	}
 }

+ 129 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -91,6 +91,8 @@ import com.l2jserver.gameserver.model.items.L2Item;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.L2WeaponType;
+import com.l2jserver.gameserver.model.options.OptionsSkillHolder;
+import com.l2jserver.gameserver.model.options.OptionsSkillType;
 import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.L2Skill;
 import com.l2jserver.gameserver.model.skills.L2SkillType;
@@ -224,6 +226,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 	
 	protected final String COND_EXCEPTIONS = "COND_EX_" + getObjectId();
 	
+	private volatile Map<Integer, OptionsSkillHolder> _triggerSkills;
+	
 	/**
 	 * @return True if debugging is enabled for this L2Character
 	 */
@@ -5698,6 +5702,20 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 					}
 				}
 				
+				if (_triggerSkills != null)
+				{
+					for (OptionsSkillHolder holder : _triggerSkills.values())
+					{
+						if ((!crit && (holder.getSkillType() == OptionsSkillType.ATTACK)) || ((holder.getSkillType() == OptionsSkillType.CRITICAL) && crit))
+						{
+							if (Rnd.get(100) < holder.getChance())
+							{
+								makeTriggerCast(holder.getSkill(), target);
+							}
+						}
+					}
+				}
+				
 				// Maybe launch chance skills on target
 				if (target.getChanceSkills() != null)
 				{
@@ -6858,6 +6876,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 						case DWARVEN_CRAFT:
 							break;
 						default:
+						{
 							// Launch weapon Special ability skill effect if available
 							if ((activeWeapon != null) && !target.isDead())
 							{
@@ -6879,6 +6898,21 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 							{
 								target.getChanceSkills().onSkillHit(this, skill, true);
 							}
+							
+							if (_triggerSkills != null)
+							{
+								for (OptionsSkillHolder holder : _triggerSkills.values())
+								{
+									if ((skill.isMagic() && (holder.getSkillType() == OptionsSkillType.MAGIC)) || (skill.isPhysical() && (holder.getSkillType() == OptionsSkillType.ATTACK)))
+									{
+										if (Rnd.get(100) < holder.getChance())
+										{
+											makeTriggerCast(holder.getSkill(), target);
+										}
+									}
+								}
+							}
+						}
 					}
 				}
 			}
@@ -7733,6 +7767,101 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		return _lethalable;
 	}
 	
+	public Map<Integer, OptionsSkillHolder> getTriggerSkills()
+	{
+		if (_triggerSkills == null)
+		{
+			synchronized (this)
+			{
+				if (_triggerSkills == null)
+				{
+					_triggerSkills = new FastMap<Integer, OptionsSkillHolder>().shared();
+				}
+			}
+		}
+		return _triggerSkills;
+	}
+	
+	public void addTriggerSkill(OptionsSkillHolder holder)
+	{
+		getTriggerSkills().put(holder.getSkillId(), holder);
+	}
+	
+	public void removeTriggerSkill(OptionsSkillHolder holder)
+	{
+		getTriggerSkills().remove(holder.getSkillId());
+	}
+	
+	public void makeTriggerCast(L2Skill skill, L2Character target)
+	{
+		try
+		{
+			if (skill.getWeaponDependancy(this, true) && skill.checkCondition(this, target, false))
+			{
+				if (skill.triggersChanceSkill()) // skill will trigger another skill, but only if its not chance skill
+				{
+					skill = SkillTable.getInstance().getInfo(skill.getTriggeredChanceId(), skill.getTriggeredChanceLevel());
+					if ((skill == null) || (skill.getSkillType() == L2SkillType.NOTDONE))
+					{
+						return;
+					}
+					// We change skill to new one, we should verify conditions and dependancy for new one
+					if (!skill.getWeaponDependancy(this, true) || !skill.checkCondition(this, target, false))
+					{
+						return;
+					}
+				}
+				
+				if (isSkillDisabled(skill))
+				{
+					return;
+				}
+				
+				if (skill.getReuseDelay() > 0)
+				{
+					disableSkill(skill, skill.getReuseDelay());
+				}
+				
+				final L2Object[] targets = skill.getTargetList(this, false, target);
+				
+				if (targets.length == 0)
+				{
+					return;
+				}
+				
+				final L2Character firstTarget = (L2Character) targets[0];
+				
+				if (Config.ALT_VALIDATE_TRIGGER_SKILLS && isPlayable() && (firstTarget != null) && firstTarget.isPlayable())
+				{
+					final L2PcInstance player = getActingPlayer();
+					if (!player.checkPvpSkill(firstTarget, skill, isSummon()))
+					{
+						return;
+					}
+				}
+				
+				final ISkillHandler handler = SkillHandler.getInstance().getHandler(skill.getSkillType());
+				
+				broadcastPacket(new MagicSkillLaunched(this, skill.getDisplayId(), skill.getLevel(), targets));
+				broadcastPacket(new MagicSkillUse(this, firstTarget, skill.getDisplayId(), skill.getLevel(), 0, 0));
+				// Launch the magic skill and calculate its effects
+				// TODO: once core will support all possible effects, use effects (not handler)
+				if (handler != null)
+				{
+					handler.useSkill(this, skill, targets);
+				}
+				else
+				{
+					skill.useSkill(this, targets);
+				}
+			}
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "", e);
+		}
+	}
+	
 	// LISTENERS
 	
 	/**

+ 2 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemauction/AuctionItem.java

@@ -90,11 +90,9 @@ public final class AuctionItem
 		item.setEnchantLevel(item.getDefaultEnchantLevel());
 		
 		final int augmentationId = _itemExtra.getInteger("augmentation_id", 0);
-		if (augmentationId != 0)
+		if (augmentationId > 0)
 		{
-			final int augmentationSkillId = _itemExtra.getInteger("augmentation_skill_id", 0);
-			final int augmentationSkillLevel = _itemExtra.getInteger("augmentation_skill_lvl", 0);
-			item.setAugmentation(new L2Augmentation(augmentationId, augmentationSkillId, augmentationSkillLevel));
+			item.setAugmentation(new L2Augmentation(augmentationId));
 		}
 		
 		return item;

+ 36 - 98
L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java

@@ -39,9 +39,7 @@ import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.PcCondOverride;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
-import com.l2jserver.gameserver.model.items.L2Armor;
 import com.l2jserver.gameserver.model.items.L2Item;
-import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance.ItemLocation;
 import com.l2jserver.gameserver.model.items.type.L2EtcItemType;
@@ -249,18 +247,12 @@ public abstract class Inventory extends ItemContainer
 		@Override
 		public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
 		{
-			/*
-			 * if (slot == PAPERDOLL_RHAND) return;
-			 */
 			inventory.getOwner().removeStatsOwner(item);
 		}
 		
 		@Override
 		public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
 		{
-			/*
-			 * if (slot == PAPERDOLL_RHAND) return;
-			 */
 			inventory.getOwner().addStatFuncs(item.getStatFuncs(inventory.getOwner()));
 		}
 	}
@@ -277,66 +269,39 @@ public abstract class Inventory extends ItemContainer
 		@Override
 		public void notifyUnequiped(int slot, L2ItemInstance item, Inventory inventory)
 		{
-			L2PcInstance player;
-			
-			if (inventory.getOwner() instanceof L2PcInstance)
-			{
-				player = (L2PcInstance) inventory.getOwner();
-			}
-			else
+			if (!(inventory.getOwner() instanceof L2PcInstance))
 			{
 				return;
 			}
+			final L2PcInstance player = (L2PcInstance) inventory.getOwner();
 			
 			L2Skill enchant4Skill, itemSkill;
 			L2Item it = item.getItem();
 			boolean update = false;
 			boolean updateTimeStamp = false;
 			
-			if (it instanceof L2Weapon)
+			// Remove augmentation bonuses on unequip
+			if (item.isAugmented())
 			{
-				// Remove augmentation bonuses on unequip
-				if (item.isAugmented())
-				{
-					item.getAugmentation().removeBonus(player);
-				}
-				
-				item.removeElementAttrBonus(player);
-				// Remove skills bestowed from +4 Rapiers/Duals
-				if (item.getEnchantLevel() >= 4)
-				{
-					enchant4Skill = ((L2Weapon) it).getEnchant4Skill();
-					
-					if (enchant4Skill != null)
-					{
-						player.removeSkill(enchant4Skill, false, enchant4Skill.isPassive());
-						update = true;
-					}
-				}
+				item.getAugmentation().removeBonus(player);
 			}
-			else if (it instanceof L2Armor)
+			
+			item.removeElementAttrBonus(player);
+			
+			// Remove skills bestowed from +4 armor
+			if (item.getEnchantLevel() >= 4)
 			{
-				// Remove augmentation bonuses on unequip
-				if (item.isAugmented())
-				{
-					item.getAugmentation().removeBonus(player);
-				}
-				
-				item.removeElementAttrBonus(player);
+				enchant4Skill = it.getEnchant4Skill();
 				
-				// Remove skills bestowed from +4 armor
-				if (item.getEnchantLevel() >= 4)
+				if (enchant4Skill != null)
 				{
-					enchant4Skill = ((L2Armor) it).getEnchant4Skill();
-					
-					if (enchant4Skill != null)
-					{
-						player.removeSkill(enchant4Skill, false, enchant4Skill.isPassive());
-						update = true;
-					}
+					player.removeSkill(enchant4Skill, false, enchant4Skill.isPassive());
+					update = true;
 				}
 			}
 			
+			item.clearEnchantStats();
+			
 			final SkillHolder[] skills = it.getSkills();
 			
 			if (skills != null)
@@ -436,67 +401,40 @@ public abstract class Inventory extends ItemContainer
 		@Override
 		public void notifyEquiped(int slot, L2ItemInstance item, Inventory inventory)
 		{
-			L2PcInstance player;
-			
-			if (inventory.getOwner() instanceof L2PcInstance)
-			{
-				player = (L2PcInstance) inventory.getOwner();
-			}
-			else
+			if (!(inventory.getOwner() instanceof L2PcInstance))
 			{
 				return;
 			}
 			
+			final L2PcInstance player = (L2PcInstance) inventory.getOwner();
+			
 			L2Skill enchant4Skill, itemSkill;
 			L2Item it = item.getItem();
 			boolean update = false;
 			boolean updateTimeStamp = false;
 			
-			if (it instanceof L2Weapon)
+			// Apply augmentation bonuses on equip
+			if (item.isAugmented())
 			{
-				// Apply augmentation bonuses on equip
-				if (item.isAugmented())
-				{
-					item.getAugmentation().applyBonus(player);
-				}
-				
-				item.updateElementAttrBonus(player);
-				
-				// Add skills bestowed from +4 Rapiers/Duals
-				if (item.getEnchantLevel() >= 4)
-				{
-					enchant4Skill = ((L2Weapon) it).getEnchant4Skill();
-					
-					if (enchant4Skill != null)
-					{
-						player.addSkill(enchant4Skill, false);
-						update = true;
-					}
-				}
+				item.getAugmentation().applyBonus(player);
 			}
-			else if (it instanceof L2Armor)
+			
+			item.updateElementAttrBonus(player);
+			
+			// Add skills bestowed from +4 armor
+			if (item.getEnchantLevel() >= 4)
 			{
-				// Apply augmentation bonuses on equip
-				if (item.isAugmented())
-				{
-					item.getAugmentation().applyBonus(player);
-				}
+				enchant4Skill = it.getEnchant4Skill();
 				
-				item.updateElementAttrBonus(player);
-				
-				// Add skills bestowed from +4 armor
-				if (item.getEnchantLevel() >= 4)
+				if (enchant4Skill != null)
 				{
-					enchant4Skill = ((L2Armor) it).getEnchant4Skill();
-					
-					if (enchant4Skill != null)
-					{
-						player.addSkill(enchant4Skill, false);
-						update = true;
-					}
+					player.addSkill(enchant4Skill, false);
+					update = true;
 				}
 			}
 			
+			item.applyEnchantStats();
+			
 			final SkillHolder[] skills = it.getSkills();
 			
 			if (skills != null)
@@ -565,10 +503,10 @@ public abstract class Inventory extends ItemContainer
 				return;
 			}
 			
-			L2PcInstance player = (L2PcInstance) inventory.getOwner();
+			final L2PcInstance player = (L2PcInstance) inventory.getOwner();
 			
 			// Checks if player is wearing a chest item
-			L2ItemInstance chestItem = inventory.getPaperdollItem(PAPERDOLL_CHEST);
+			final L2ItemInstance chestItem = inventory.getPaperdollItem(PAPERDOLL_CHEST);
 			
 			if (chestItem == null)
 			{
@@ -691,7 +629,7 @@ public abstract class Inventory extends ItemContainer
 				return;
 			}
 			
-			L2PcInstance player = (L2PcInstance) inventory.getOwner();
+			final L2PcInstance player = (L2PcInstance) inventory.getOwner();
 			
 			boolean remove = false;
 			L2Skill itemSkill;

+ 1 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/PcInventory.java

@@ -1038,6 +1038,7 @@ public class PcInventory extends Inventory
 		for (L2ItemInstance item : _items)
 		{
 			item.giveSkillsToOwner();
+			item.applyEnchantStats();
 		}
 	}
 	

+ 1 - 39
L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/L2Armor.java

@@ -18,17 +18,10 @@
  */
 package com.l2jserver.gameserver.model.items;
 
-import java.util.ArrayList;
-
 import com.l2jserver.gameserver.model.StatsSet;
-import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
-import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.L2ArmorType;
 import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.funcs.Func;
-import com.l2jserver.gameserver.model.skills.funcs.FuncTemplate;
-import com.l2jserver.gameserver.model.stats.Env;
 import com.l2jserver.util.StringUtil;
 
 /**
@@ -115,6 +108,7 @@ public final class L2Armor extends L2Item
 	/**
 	 * @return skill that player get when has equipped armor +4 or more
 	 */
+	@Override
 	public L2Skill getEnchant4Skill()
 	{
 		if (_enchant4Skill == null)
@@ -123,36 +117,4 @@ public final class L2Armor extends L2Item
 		}
 		return _enchant4Skill.getSkill();
 	}
-	
-	/**
-	 * @param item : L2ItemInstance pointing out the armor
-	 * @param player : L2Character pointing out the player
-	 * @return array of Func objects containing the list of functions used by the armor
-	 */
-	@Override
-	public Func[] getStatFuncs(L2ItemInstance item, L2Character player)
-	{
-		if ((_funcTemplates == null) || (_funcTemplates.length == 0))
-		{
-			return _emptyFunctionSet;
-		}
-		
-		ArrayList<Func> funcs = new ArrayList<>(_funcTemplates.length);
-		
-		Env env = new Env();
-		env.setCharacter(player);
-		env.setItem(item);
-		
-		Func f;
-		for (FuncTemplate t : _funcTemplates)
-		{
-			
-			f = t.getFunc(env, item);
-			if (f != null)
-			{
-				funcs.add(f);
-			}
-		}
-		return funcs.toArray(new Func[funcs.size()]);
-	}
 }

+ 7 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/L2Item.java

@@ -796,7 +796,7 @@ public abstract class L2Item
 	 * @param player : L2Character pointing out the player
 	 * @return Func[] : array of functions
 	 */
-	public Func[] getStatFuncs(L2ItemInstance item, L2Character player)
+	public final Func[] getStatFuncs(L2ItemInstance item, L2Character player)
 	{
 		if ((_funcTemplates == null) || (_funcTemplates.length == 0))
 		{
@@ -813,7 +813,7 @@ public abstract class L2Item
 		Func f;
 		for (FuncTemplate t : _funcTemplates)
 		{
-			f = t.getFunc(env, this); // skill is owner
+			f = t.getFunc(env, item);
 			if (f != null)
 			{
 				funcs.add(f);
@@ -1161,4 +1161,9 @@ public abstract class L2Item
 	{
 		return getItemType() == L2EtcItemType.PET_COLLAR;
 	}
+	
+	public L2Skill getEnchant4Skill()
+	{
+		return null;
+	}
 }

+ 1 - 35
L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/L2Weapon.java

@@ -18,7 +18,6 @@
  */
 package com.l2jserver.gameserver.model.items;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
@@ -35,13 +34,10 @@ import com.l2jserver.gameserver.model.conditions.Condition;
 import com.l2jserver.gameserver.model.conditions.ConditionGameChance;
 import com.l2jserver.gameserver.model.effects.L2Effect;
 import com.l2jserver.gameserver.model.holders.SkillHolder;
-import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.L2WeaponType;
 import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.quest.Quest.QuestEventType;
 import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.funcs.Func;
-import com.l2jserver.gameserver.model.skills.funcs.FuncTemplate;
 import com.l2jserver.gameserver.model.stats.Env;
 import com.l2jserver.gameserver.model.stats.Formulas;
 import com.l2jserver.util.StringUtil;
@@ -282,6 +278,7 @@ public final class L2Weapon extends L2Item
 	/**
 	 * @return the skill that player get when has equipped weapon +4 or more (for duals SA).
 	 */
+	@Override
 	public L2Skill getEnchant4Skill()
 	{
 		if (_enchant4Skill == null)
@@ -323,37 +320,6 @@ public final class L2Weapon extends L2Item
 		return _useWeaponSkillsOnly;
 	}
 	
-	/**
-	 * @param item the L2ItemInstance pointing out the weapon.
-	 * @param player the L2Character pointing out the player.
-	 * @return an array of Func objects containing the list of functions used by the weapon.
-	 */
-	@Override
-	public Func[] getStatFuncs(L2ItemInstance item, L2Character player)
-	{
-		if ((_funcTemplates == null) || (_funcTemplates.length == 0))
-		{
-			return _emptyFunctionSet;
-		}
-		
-		ArrayList<Func> funcs = new ArrayList<>(_funcTemplates.length);
-		
-		Env env = new Env();
-		env.setCharacter(player);
-		env.setItem(item);
-		
-		Func f;
-		for (FuncTemplate t : _funcTemplates)
-		{
-			f = t.getFunc(env, item);
-			if (f != null)
-			{
-				funcs.add(f);
-			}
-		}
-		return funcs.toArray(new Func[funcs.size()]);
-	}
-	
 	/**
 	 * @param caster the L2Character pointing out the caster
 	 * @param target the L2Character pointing out the target

+ 65 - 28
L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/instance/L2ItemInstance.java

@@ -25,6 +25,8 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.Level;
@@ -40,12 +42,12 @@ import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.cache.HtmCache;
 import com.l2jserver.gameserver.datatables.EnchantOptionsData;
 import com.l2jserver.gameserver.datatables.ItemTable;
+import com.l2jserver.gameserver.datatables.OptionsData;
 import com.l2jserver.gameserver.instancemanager.ItemsOnGroundManager;
 import com.l2jserver.gameserver.instancemanager.MercTicketManager;
 import com.l2jserver.gameserver.instancemanager.QuestManager;
 import com.l2jserver.gameserver.model.DropProtection;
 import com.l2jserver.gameserver.model.Elementals;
-import com.l2jserver.gameserver.model.EnchantOptions;
 import com.l2jserver.gameserver.model.L2Augmentation;
 import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.L2World;
@@ -63,6 +65,8 @@ import com.l2jserver.gameserver.model.items.L2Item;
 import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.type.L2EtcItemType;
 import com.l2jserver.gameserver.model.items.type.L2ItemType;
+import com.l2jserver.gameserver.model.options.EnchantOptions;
+import com.l2jserver.gameserver.model.options.Options;
 import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.quest.QuestState;
 import com.l2jserver.gameserver.model.quest.State;
@@ -186,6 +190,8 @@ public final class L2ItemInstance extends L2Object
 	
 	private int _shotsMask = 0;
 	
+	private final List<Options> _enchantOptions = new ArrayList<>();
+	
 	/**
 	 * Constructor of the L2ItemInstance from the objectId and the itemId.
 	 * @param objectId : int designating the ID of the object in the world
@@ -898,7 +904,9 @@ public final class L2ItemInstance extends L2Object
 		{
 			return;
 		}
+		clearEnchantStats();
 		_enchantLevel = enchantLevel;
+		applyEnchantStats();
 		_storedInDb = false;
 	}
 	
@@ -908,7 +916,7 @@ public final class L2ItemInstance extends L2Object
 	 */
 	public boolean isAugmented()
 	{
-		return _augmentation == null ? false : true;
+		return _augmentation != null;
 	}
 	
 	/**
@@ -930,6 +938,7 @@ public final class L2ItemInstance extends L2Object
 		// there shall be no previous augmentation..
 		if (_augmentation != null)
 		{
+			_log.info("Warning: Augment set for (" + getObjectId() + ") " + getName() + " owner: " + getOwnerId());
 			return false;
 		}
 		if (!fireAugmentListeners(true, augmentation))
@@ -978,7 +987,7 @@ public final class L2ItemInstance extends L2Object
 	public void restoreAttributes()
 	{
 		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement ps1 = con.prepareStatement("SELECT augAttributes,augSkillId,augSkillLevel FROM item_attributes WHERE itemId=?");
+			PreparedStatement ps1 = con.prepareStatement("SELECT augAttributes FROM item_attributes WHERE itemId=?");
 			PreparedStatement ps2 = con.prepareStatement("SELECT elemType,elemValue FROM item_elementals WHERE itemId=?"))
 		{
 			ps1.setInt(1, getObjectId());
@@ -987,11 +996,9 @@ public final class L2ItemInstance extends L2Object
 				if (rs.next())
 				{
 					int aug_attributes = rs.getInt(1);
-					int aug_skillId = rs.getInt(2);
-					int aug_skillLevel = rs.getInt(3);
-					if ((aug_attributes != -1) && (aug_skillId != -1) && (aug_skillLevel != -1))
+					if (aug_attributes != -1)
 					{
-						_augmentation = new L2Augmentation(rs.getInt("augAttributes"), rs.getInt("augSkillId"), rs.getInt("augSkillLevel"));
+						_augmentation = new L2Augmentation(rs.getInt("augAttributes"));
 					}
 				}
 			}
@@ -1018,29 +1025,10 @@ public final class L2ItemInstance extends L2Object
 	
 	private void updateItemAttributes(Connection con)
 	{
-		try (PreparedStatement ps = con.prepareStatement("REPLACE INTO item_attributes VALUES(?,?,?,?)"))
+		try (PreparedStatement ps = con.prepareStatement("REPLACE INTO item_attributes VALUES(?,?)"))
 		{
 			ps.setInt(1, getObjectId());
-			if (_augmentation == null)
-			{
-				ps.setInt(2, -1);
-				ps.setInt(3, -1);
-				ps.setInt(4, -1);
-			}
-			else
-			{
-				ps.setInt(2, _augmentation.getAttributes());
-				if (_augmentation.getSkill() == null)
-				{
-					ps.setInt(3, 0);
-					ps.setInt(4, 0);
-				}
-				else
-				{
-					ps.setInt(3, _augmentation.getSkill().getId());
-					ps.setInt(4, _augmentation.getSkill().getLevel());
-				}
-			}
+			ps.setInt(2, _augmentation != null ? _augmentation.getAttributes() : -1);
 			ps.executeUpdate();
 		}
 		catch (SQLException e)
@@ -2241,6 +2229,10 @@ public final class L2ItemInstance extends L2Object
 		_shotsMask = 0;
 	}
 	
+	/**
+	 * Returns enchant effect object for this item
+	 * @return enchanteffect
+	 */
 	public int[] getEnchantOptions()
 	{
 		EnchantOptions op = EnchantOptionsData.getInstance().getOptions(this);
@@ -2251,6 +2243,51 @@ public final class L2ItemInstance extends L2Object
 		return DEFAULT_ENCHANT_OPTIONS;
 	}
 	
+	/**
+	 * Clears all the enchant bonuses if item is enchanted and containing bonuses for enchant value.
+	 */
+	public void clearEnchantStats()
+	{
+		final L2PcInstance player = getActingPlayer();
+		if (player == null)
+		{
+			_enchantOptions.clear();
+			return;
+		}
+		
+		for (Options op : _enchantOptions)
+		{
+			op.remove(player);
+		}
+		_enchantOptions.clear();
+	}
+	
+	/**
+	 * Clears and applies all the enchant bonuses if item is enchanted and containing bonuses for enchant value.
+	 */
+	public void applyEnchantStats()
+	{
+		final L2PcInstance player = getActingPlayer();
+		if (!isEquipped() || (player == null) || (getEnchantOptions() == DEFAULT_ENCHANT_OPTIONS))
+		{
+			return;
+		}
+		
+		for (int id : getEnchantOptions())
+		{
+			final Options options = OptionsData.getInstance().getOptions(id);
+			if (options != null)
+			{
+				options.apply(player);
+				_enchantOptions.add(options);
+			}
+			else if (id != 0)
+			{
+				_log.log(Level.INFO, "applyEnchantStats: Couldn't find option: " + id);
+			}
+		}
+	}
+	
 	// LISTENERS
 	/**
 	 * Fires all the DropListener.onPickup() methods, if any

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/EnchantOptions.java → L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/EnchantOptions.java

@@ -16,7 +16,7 @@
  * 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;
+package com.l2jserver.gameserver.model.options;
 
 /**
  * @author UnAfraid

+ 254 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/Options.java

@@ -0,0 +1,254 @@
+/*
+ * 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.options;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jserver.gameserver.model.skills.L2Skill;
+import com.l2jserver.gameserver.model.skills.funcs.Func;
+import com.l2jserver.gameserver.model.skills.funcs.FuncTemplate;
+import com.l2jserver.gameserver.model.stats.Env;
+import com.l2jserver.gameserver.network.serverpackets.SkillCoolTime;
+
+/**
+ * @author UnAfraid
+ */
+public class Options
+{
+	private final int _id;
+	private static final Func[] _emptyFunctionSet = new Func[0];
+	private final List<FuncTemplate> _funcs = new ArrayList<>();
+	
+	private SkillHolder _activeSkill = null;
+	private SkillHolder _passiveSkill = null;
+	
+	private final List<OptionsSkillHolder> _activationSkills = new ArrayList<>();
+	
+	/**
+	 * @param id
+	 */
+	public Options(int id)
+	{
+		_id = id;
+	}
+	
+	public final int getId()
+	{
+		return _id;
+	}
+	
+	public boolean hasFuncs()
+	{
+		return !_funcs.isEmpty();
+	}
+	
+	public Func[] getStatFuncs(L2ItemInstance item, L2Character player)
+	{
+		if (_funcs.isEmpty())
+		{
+			return _emptyFunctionSet;
+		}
+		
+		List<Func> funcs = new ArrayList<>(_funcs.size());
+		
+		Env env = new Env();
+		env.setCharacter(player);
+		env.setTarget(player);
+		env.setItem(item);
+		
+		Func f;
+		for (FuncTemplate t : _funcs)
+		{
+			f = t.getFunc(env, this);
+			if (f != null)
+			{
+				funcs.add(f);
+			}
+			player.sendDebugMessage("Adding stats: " + t.stat + " val: " + t.lambda.calc(env));
+		}
+		
+		if (funcs.isEmpty())
+		{
+			return _emptyFunctionSet;
+		}
+		return funcs.toArray(new Func[funcs.size()]);
+	}
+	
+	public void addFunc(FuncTemplate template)
+	{
+		_funcs.add(template);
+	}
+	
+	public boolean hasActiveSkill()
+	{
+		return _activeSkill != null;
+	}
+	
+	public SkillHolder getActiveSkill()
+	{
+		return _activeSkill;
+	}
+	
+	public void setActiveSkill(SkillHolder holder)
+	{
+		_activeSkill = holder;
+	}
+	
+	public boolean hasPassiveSkill()
+	{
+		return _passiveSkill != null;
+	}
+	
+	public SkillHolder getPassiveSkill()
+	{
+		return _passiveSkill;
+	}
+	
+	public void setPassiveSkill(SkillHolder holder)
+	{
+		_passiveSkill = holder;
+	}
+	
+	public boolean hasActivationSkills()
+	{
+		return !_activationSkills.isEmpty();
+	}
+	
+	public boolean hasActivationSkills(OptionsSkillType type)
+	{
+		for (OptionsSkillHolder holder : _activationSkills)
+		{
+			if (holder.getSkillType() == type)
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	public List<OptionsSkillHolder> getActivationsSkills()
+	{
+		return _activationSkills;
+	}
+	
+	public List<OptionsSkillHolder> getActivationsSkills(OptionsSkillType type)
+	{
+		List<OptionsSkillHolder> temp = new ArrayList<>();
+		for (OptionsSkillHolder holder : _activationSkills)
+		{
+			if (holder.getSkillType() == type)
+			{
+				temp.add(holder);
+			}
+		}
+		return temp;
+	}
+	
+	public void addActivationSkill(OptionsSkillHolder holder)
+	{
+		_activationSkills.add(holder);
+	}
+	
+	public void apply(L2PcInstance player)
+	{
+		player.sendDebugMessage("Activating option id: " + _id);
+		if (hasFuncs())
+		{
+			player.addStatFuncs(getStatFuncs(null, player));
+		}
+		if (hasActiveSkill())
+		{
+			addSkill(player, getActiveSkill().getSkill());
+			player.sendDebugMessage("Adding active skill: " + getActiveSkill());
+		}
+		if (hasPassiveSkill())
+		{
+			addSkill(player, getPassiveSkill().getSkill());
+			player.sendDebugMessage("Adding passive skill: " + getPassiveSkill());
+		}
+		if (hasActivationSkills())
+		{
+			for (OptionsSkillHolder holder : _activationSkills)
+			{
+				player.addTriggerSkill(holder);
+				player.sendDebugMessage("Adding trigger skill: " + holder);
+			}
+		}
+		
+		player.sendSkillList();
+	}
+	
+	public void remove(L2PcInstance player)
+	{
+		player.sendDebugMessage("Deactivating option id: " + _id);
+		if (hasFuncs())
+		{
+			player.removeStatsOwner(this);
+		}
+		if (hasActiveSkill())
+		{
+			player.removeSkill(getActiveSkill().getSkill(), false, false);
+			player.sendDebugMessage("Removing active skill: " + getActiveSkill());
+		}
+		if (hasPassiveSkill())
+		{
+			player.removeSkill(getPassiveSkill().getSkill(), false, true);
+			player.sendDebugMessage("Removing passive skill: " + getPassiveSkill());
+		}
+		if (hasActivationSkills())
+		{
+			for (OptionsSkillHolder holder : _activationSkills)
+			{
+				player.removeTriggerSkill(holder);
+				player.sendDebugMessage("Removing trigger skill: " + holder);
+			}
+		}
+		player.sendSkillList();
+	}
+	
+	private final void addSkill(L2PcInstance player, L2Skill skill)
+	{
+		boolean updateTimeStamp = false;
+		
+		player.addSkill(skill, false);
+		
+		if (skill.isActive())
+		{
+			if (skill.isActive())
+			{
+				final long remainingTime = player.getSkillRemainingReuseTime(skill.getReuseHashCode());
+				if (remainingTime > 0)
+				{
+					player.addTimeStamp(skill, remainingTime);
+					player.disableSkill(skill, remainingTime);
+				}
+				updateTimeStamp = true;
+			}
+		}
+		if (updateTimeStamp)
+		{
+			player.sendPacket(new SkillCoolTime(player));
+		}
+	}
+}

+ 53 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/OptionsSkillHolder.java

@@ -0,0 +1,53 @@
+/*
+ * 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.options;
+
+import com.l2jserver.gameserver.model.holders.SkillHolder;
+
+/**
+ * @author UnAfraid
+ */
+public class OptionsSkillHolder extends SkillHolder
+{
+	private final OptionsSkillType _type;
+	private final double _chance;
+	
+	/**
+	 * @param skillId
+	 * @param skillLvl
+	 * @param type
+	 * @param chance
+	 */
+	public OptionsSkillHolder(int skillId, int skillLvl, double chance, OptionsSkillType type)
+	{
+		super(skillId, skillLvl);
+		_chance = chance;
+		_type = type;
+	}
+	
+	public OptionsSkillType getSkillType()
+	{
+		return _type;
+	}
+	
+	public double getChance()
+	{
+		return _chance;
+	}
+}

+ 29 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/options/OptionsSkillType.java

@@ -0,0 +1,29 @@
+/*
+ * 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.options;
+
+/**
+ * @author UnAfraid
+ */
+public enum OptionsSkillType
+{
+	ATTACK,
+	MAGIC,
+	CRITICAL
+}

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/MultiSellChoose.java

@@ -405,7 +405,7 @@ public class MultiSellChoose extends L2GameClientPacket
 									{
 										if (i < augmentation.size())
 										{
-											product.setAugmentation(new L2Augmentation(augmentation.get(i).getAugmentationId(), augmentation.get(i).getSkill()));
+											product.setAugmentation(new L2Augmentation(augmentation.get(i).getAugmentationId()));
 										}
 										if (elemental != null)
 										{

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestRefine.java

@@ -119,7 +119,7 @@ public final class RequestRefine extends AbstractRefinePacket
 			return;
 		}
 		
-		final L2Augmentation aug = AugmentationData.getInstance().generateRandomAugmentation(lifeStoneLevel, lifeStoneGrade, targetItem.getItem().getBodyPart());
+		final L2Augmentation aug = AugmentationData.getInstance().generateRandomAugmentation(lifeStoneLevel, lifeStoneGrade, targetItem.getItem().getBodyPart(), refinerItem.getItemId(), targetItem);
 		targetItem.setAugmentation(aug);
 		
 		final int stat12 = 0x0000FFFF & aug.getAugmentationId();

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott