Ver código fonte

BETA: NPC AI Update
- Added Suicide AI
- NpcAIData cleanup and update
- Added min/max chance of using skills
- npcaidata table structure and data refactore

Rumen Nikiforov 13 anos atrás
pai
commit
d132e0b051

+ 54 - 5
L2J_Server_BETA/java/com/l2jserver/gameserver/ai/L2AttackableAI.java

@@ -779,6 +779,28 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 
 		final int combinedCollision = collision + mostHate.getTemplate().collisionRadius;
 
+		if (_skillrender.hasSuesideSkill() && (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30)
+		{
+			L2Skill skill = _skillrender._suesideskills.get(Rnd.nextInt(_skillrender._suesideskills.size()));	
+			if (Util.checkIfInRange(skill.getSkillRadius(), getActiveChar(), mostHate, false) && Rnd.get(100) < Rnd.get(npc.getMinSkillChance(), npc.getMaxSkillChance()))
+			{
+				if (cast(skill))
+				{
+					return;
+				}
+				else
+				{
+					for (L2Skill sk : _skillrender._suesideskills)
+					{
+						if (cast(sk))
+						{
+							return;
+						}
+					}
+				}
+			}
+		}
+		
 		//------------------------------------------------------
 		// In case many mobs are trying to hit from same place, move a bit,
 		// circling around the target
@@ -1062,19 +1084,26 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 			movementDisable();
 			return;
 		}
+		
 		setTimepass(0);
 		//--------------------------------------------------------------------------------
 		//Skill Use
 		if (_skillrender.hasSkill())
 		{
-			if (Rnd.get(100) <= npc.getSkillChance())
+			if (Rnd.get(100) < Rnd.get(npc.getMinSkillChance(), npc.getMaxSkillChance()))
 			{
 				L2Skill skills = _skillrender._generalskills.get(Rnd.nextInt(_skillrender._generalskills.size()));
 				if (cast(skills))
+				{
 					return;
+				}
 				for (L2Skill sk : _skillrender._generalskills)
+				{
 					if (cast(sk))
+					{
 						return;
+					}
+				}
 			}
 			
 			//--------------------------------------------------------------------------------
@@ -1109,7 +1138,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				}
 			}
 		}
-		
+				
 		//--------------------------------------------------------------------------------
 		// Starts Melee or Primary Skill
 		if (dist2 > range || !GeoData.getInstance().canSeeTarget(npc, mostHate))
@@ -1131,7 +1160,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 		}
 		else
 		{
-			melee(npc.getPrimaryAttack());
+			melee(npc.getPrimarySkillId());
 		}
 		
 	}
@@ -1145,26 +1174,46 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				case -1:
 				{
 					if (_skillrender._generalskills != null)
+					{
 						for (L2Skill sk : _skillrender._generalskills)
+						{
 							if (cast(sk))
+							{
 								return;
+							}
+						}
+					}
 					break;
 				}
 				case 1:
 				{
 					if (_skillrender.hasAtkSkill())
+					{
 						for (L2Skill sk : _skillrender._atkskills)
+						{
 							if (cast(sk))
+							{
 								return;
+							}
+						}
+					}
 					break;
 				}
 				default:
 				{
 					if (_skillrender._generalskills != null)
+					{
 						for (L2Skill sk : _skillrender._generalskills)
-							if (sk.getId() == getActiveChar().getPrimaryAttack())
+						{
+							if (sk.getId() == getActiveChar().getPrimarySkillId())
+							{
 								if (cast(sk))
+								{
 									return;
+								}
+							}
+						}
+					}
 				}
 				break;
 			}
@@ -1883,7 +1932,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
 				
 			}
 			
-			melee(npc.getPrimaryAttack());
+			melee(npc.getPrimarySkillId());
 		}
 		catch (NullPointerException e)
 		{

+ 33 - 34
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/NpcTable.java

@@ -49,7 +49,7 @@ public class NpcTable
 {
 	private static Logger _log = Logger.getLogger(NpcTable.class.getName());
 	
-	private TIntObjectHashMap<L2NpcTemplate> _npcs;
+	private final TIntObjectHashMap<L2NpcTemplate> _npcs;
 	
 	public static NpcTable getInstance()
 	{
@@ -360,14 +360,14 @@ public class NpcTable
 			
 			try
 			{
-				statement = con.prepareStatement("SELECT " + L2DatabaseFactory.getInstance().safetyString(new String[] {"npc_id", "primary_attack","skill_chance","can_move","soulshot","spiritshot","sschance","spschance","minrangeskill","minrangechance","maxrangeskill","maxrangechance","ischaos","clan","clan_range","enemyClan","enemyRange","ai_type","dodge"}) + " FROM npcaidata ORDER BY npc_id");
+				statement = con.prepareStatement("SELECT * FROM npcaidata ORDER BY npcId");
 				ResultSet NpcAIDataTable = statement.executeQuery();
 				L2NpcAIData npcAIDat = null;
 				L2NpcTemplate npcDat = null;
 				int cont=0;
 				while (NpcAIDataTable.next())
 				{
-					int npc_id = NpcAIDataTable.getInt("npc_id");
+					int npc_id = NpcAIDataTable.getInt("npcId");
 					npcDat = _npcs.get(npc_id);
 					if (npcDat == null)
 					{
@@ -376,30 +376,29 @@ public class NpcTable
 					}
 					npcAIDat = new L2NpcAIData();
 					
-					npcAIDat.setPrimaryAttack(NpcAIDataTable.getInt("primary_attack"));
-					npcAIDat.setSkillChance(NpcAIDataTable.getInt("skill_chance"));
-					npcAIDat.setCanMove(NpcAIDataTable.getInt("can_move"));
+					npcAIDat.setMinSkillChance(NpcAIDataTable.getInt("minSkillChance"));
+					npcAIDat.setMaxSkillChance(NpcAIDataTable.getInt("maxSkillChance"));
+					npcAIDat.setPrimarySkillId(NpcAIDataTable.getInt("primarySkillId"));
+					npcAIDat.setCanMove(NpcAIDataTable.getInt("canMove"));
+					npcAIDat.setShortRangeSkill(NpcAIDataTable.getInt("minRangeSkill"));
+					npcAIDat.setShortRangeChance(NpcAIDataTable.getInt("minRangeChance"));
+					npcAIDat.setLongRangeSkill(NpcAIDataTable.getInt("maxRangeSkill"));
+					npcAIDat.setLongRangeChance(NpcAIDataTable.getInt("maxRangeChance"));
 					npcAIDat.setSoulShot(NpcAIDataTable.getInt("soulshot"));
 					npcAIDat.setSpiritShot(NpcAIDataTable.getInt("spiritshot"));
-					npcAIDat.setSoulShotChance(NpcAIDataTable.getInt("sschance"));
-					npcAIDat.setSpiritShotChance(NpcAIDataTable.getInt("spschance"));
-					npcAIDat.setIsChaos(NpcAIDataTable.getInt("ischaos"));
-					npcAIDat.setShortRangeSkill(NpcAIDataTable.getInt("minrangeskill"));
-					npcAIDat.setShortRangeChance(NpcAIDataTable.getInt("minrangechance"));
-					npcAIDat.setLongRangeSkill(NpcAIDataTable.getInt("maxrangeskill"));
-					npcAIDat.setLongRangeChance(NpcAIDataTable.getInt("maxrangechance"));
-					//npcAIDat.setSwitchRangeChance(NpcAIDataTable.getInt("rangeswitchchance"));
+					npcAIDat.setSpiritShotChance(NpcAIDataTable.getInt("spsChance"));
+					npcAIDat.setSoulShotChance(NpcAIDataTable.getInt("ssChance"));
+					npcAIDat.setIsChaos(NpcAIDataTable.getInt("isChaos"));
 					npcAIDat.setClan(NpcAIDataTable.getString("clan"));
-					npcAIDat.setClanRange(NpcAIDataTable.getInt("clan_range"));
+					npcAIDat.setClanRange(NpcAIDataTable.getInt("clanRange"));
 					npcAIDat.setEnemyClan(NpcAIDataTable.getString("enemyClan"));
 					npcAIDat.setEnemyRange(NpcAIDataTable.getInt("enemyRange"));
 					npcAIDat.setDodge(NpcAIDataTable.getInt("dodge"));
-					npcAIDat.setAi(NpcAIDataTable.getString("ai_type"));
+					npcAIDat.setAi(NpcAIDataTable.getString("aiType"));
+					//npcAIDat.setSwitchRangeChance(NpcAIDataTable.getInt("rangeswitchchance"));
 					//npcAIDat.setBaseShldRate(NpcAIDataTable.getInt("baseShldRate"));
 					//npcAIDat.setBaseShldDef(NpcAIDataTable.getInt("baseShldDef"));
 					
-					
-					//npcDat.addAIData(npcAIDat);
 					npcDat.setAIData(npcAIDat);
 					cont++;
 				}
@@ -417,14 +416,14 @@ public class NpcTable
 			{
 				try
 				{
-					statement = con.prepareStatement("SELECT " + L2DatabaseFactory.getInstance().safetyString(new String[] { "npc_id", "primary_attack", "skill_chance", "can_move", "soulshot", "spiritshot", "sschance", "spschance", "minrangeskill", "minrangechance", "maxrangeskill", "maxrangechance", "ischaos", "clan", "clan_range", "enemyClan", "enemyRange", "ai_type", "dodge" }) + " FROM custom_npcaidata ORDER BY npc_id");
+					statement = con.prepareStatement("SELECT * FROM custom_npcaidata ORDER BY npcId");
 					ResultSet NpcAIDataTable = statement.executeQuery();
 					L2NpcAIData npcAIDat = null;
 					L2NpcTemplate npcDat = null;
 					int cont = 0;
 					while (NpcAIDataTable.next())
 					{
-						int npc_id = NpcAIDataTable.getInt("npc_id");
+						int npc_id = NpcAIDataTable.getInt("npcId");
 						npcDat = _npcs.get(npc_id);
 						if (npcDat == null)
 						{
@@ -433,29 +432,29 @@ public class NpcTable
 						}
 						npcAIDat = new L2NpcAIData();
 						
-						npcAIDat.setPrimaryAttack(NpcAIDataTable.getInt("primary_attack"));
-						npcAIDat.setSkillChance(NpcAIDataTable.getInt("skill_chance"));
-						npcAIDat.setCanMove(NpcAIDataTable.getInt("can_move"));
+						npcAIDat.setPrimarySkillId(NpcAIDataTable.getInt("primarySkillId"));
+						npcAIDat.setMinSkillChance(NpcAIDataTable.getInt("minSkillChance"));
+						npcAIDat.setMaxSkillChance(NpcAIDataTable.getInt("maxSkillChance"));
+						npcAIDat.setCanMove(NpcAIDataTable.getInt("canMove"));
 						npcAIDat.setSoulShot(NpcAIDataTable.getInt("soulshot"));
 						npcAIDat.setSpiritShot(NpcAIDataTable.getInt("spiritshot"));
-						npcAIDat.setSoulShotChance(NpcAIDataTable.getInt("sschance"));
-						npcAIDat.setSpiritShotChance(NpcAIDataTable.getInt("spschance"));
-						npcAIDat.setIsChaos(NpcAIDataTable.getInt("ischaos"));
-						npcAIDat.setShortRangeSkill(NpcAIDataTable.getInt("minrangeskill"));
-						npcAIDat.setShortRangeChance(NpcAIDataTable.getInt("minrangechance"));
-						npcAIDat.setLongRangeSkill(NpcAIDataTable.getInt("maxrangeskill"));
-						npcAIDat.setLongRangeChance(NpcAIDataTable.getInt("maxrangechance"));
-						//npcAIDat.setSwitchRangeChance(NpcAIDataTable.getInt("rangeswitchchance"));
+						npcAIDat.setSoulShotChance(NpcAIDataTable.getInt("ssChance"));
+						npcAIDat.setSpiritShotChance(NpcAIDataTable.getInt("spsChance"));
+						npcAIDat.setIsChaos(NpcAIDataTable.getInt("isChaos"));
+						npcAIDat.setShortRangeSkill(NpcAIDataTable.getInt("minRangeSkill"));
+						npcAIDat.setShortRangeChance(NpcAIDataTable.getInt("minRangeChance"));
+						npcAIDat.setLongRangeSkill(NpcAIDataTable.getInt("maxRangeSkill"));
+						npcAIDat.setLongRangeChance(NpcAIDataTable.getInt("maxRangeChance"));
 						npcAIDat.setClan(NpcAIDataTable.getString("clan"));
-						npcAIDat.setClanRange(NpcAIDataTable.getInt("clan_range"));
+						npcAIDat.setClanRange(NpcAIDataTable.getInt("clanRange"));
 						npcAIDat.setEnemyClan(NpcAIDataTable.getString("enemyClan"));
 						npcAIDat.setEnemyRange(NpcAIDataTable.getInt("enemyRange"));
 						npcAIDat.setDodge(NpcAIDataTable.getInt("dodge"));
-						npcAIDat.setAi(NpcAIDataTable.getString("ai_type"));
+						npcAIDat.setAi(NpcAIDataTable.getString("aiType"));
+						//npcAIDat.setSwitchRangeChance(NpcAIDataTable.getInt("rangeswitchchance"));
 						//npcAIDat.setBaseShldRate(NpcAIDataTable.getInt("baseShldRate"));
 						//npcAIDat.setBaseShldDef(NpcAIDataTable.getInt("baseShldDef"));
 						
-						//npcDat.addAIData(npcAIDat);
 						npcDat.setAIData(npcAIDat);
 						cont++;
 					}

+ 63 - 121
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2NpcAIData.java

@@ -33,14 +33,15 @@ public class L2NpcAIData
 {
 	
 	//Basic AI
-	private int _primary_attack;
-	private int _skill_chance;
+	private int _primarySkillId;
+	private int _minskillChance;
+	private int _maxskillChance;
 	private int _canMove;
 	private int _soulshot;
 	private int _spiritshot;
-	private int _soulshotchance;
-	private int _spiritshotchance;
-	private int _ischaos;
+	private int _soulshotChance;
+	private int _spiritshotChance;
+	private int _isChaos;
 	private String _clan = null;
 	private int _clanRange;
 	private String _enemyClan = null;
@@ -48,104 +49,84 @@ public class L2NpcAIData
 	//private int _baseShldRate;
 	//private int _baseShldDef;
 	private int _dodge;
-	private int _longrangeskill;
-	private int _shortrangeskill;
-	private int _longrangechance;
-	private int _shortrangechance;
-	private int _switchrangechance;
+	private int _longRangeSkill;
+	private int _shortRangeSkill;
+	private int _longRangeChance;
+	private int _shortRangeChance;
+	private int _switchRangeChance;
 	private AIType _aiType = AIType.FIGHTER;
 	
 	//--------------------------------------------------------------------------------------------------------------
 	//Setting....
 	//--------------------------------------------------------------------------------------------------------------
-	public void setPrimaryAttack(int primaryattack)
+	public void setPrimarySkillId(int primarySkillId)
 	{
-		
-		_primary_attack = primaryattack;
-		
+		_primarySkillId = primarySkillId;
 	}
 	
-	public void setSkillChance(int skill_chance)
+	public void setMinSkillChance(int skill_chance)
+	{	
+		_minskillChance = skill_chance;
+	}
+	
+	public void setMaxSkillChance(int skill_chance)
 	{
-		
-		_skill_chance = skill_chance;
-		
+		_maxskillChance = skill_chance;
 	}
 	
 	public void setCanMove(int canMove)
 	{
-		
-		_canMove = canMove;
-		
+		_canMove = canMove;	
 	}
 	
 	public void setSoulShot(int soulshot)
 	{
-		
-		_soulshot = soulshot;
-		
+		_soulshot = soulshot;	
 	}
 	
 	public void setSpiritShot(int spiritshot)
 	{
-		
 		_spiritshot = spiritshot;
-		
 	}
 	
 	public void setSoulShotChance(int soulshotchance)
 	{
-		
-		_soulshotchance = soulshotchance;
-		
+		_soulshotChance = soulshotchance;	
 	}
 	
 	public void setSpiritShotChance(int spiritshotchance)
 	{
-		
-		_spiritshotchance = spiritshotchance;
-		
+		_spiritshotChance = spiritshotchance;	
 	}
 	
 	public void setShortRangeSkill(int shortrangeskill)
 	{
-		
-		_shortrangeskill = shortrangeskill;
-		
+		_shortRangeSkill = shortrangeskill;
 	}
 	
 	public void setShortRangeChance(int shortrangechance)
 	{
-		
-		_shortrangechance = shortrangechance;
-		
+		_shortRangeChance = shortrangechance;
 	}
 	
 	public void setLongRangeSkill(int longrangeskill)
 	{
-		
-		_longrangeskill = longrangeskill;
-		
+		_longRangeSkill = longrangeskill;	
 	}
 	
 	public void setLongRangeChance(int longrangechance)
 	{
-		
-		_shortrangechance = longrangechance;
-		
+		_shortRangeChance = longrangechance;
 	}
 	
 	public void setSwitchRangeChance(int switchrangechance)
 	{
-		
-		_switchrangechance = switchrangechance;
-		
+		_switchRangeChance = switchrangechance;
 	}
 	
 	public void setIsChaos(int ischaos)
 	{
-		_ischaos = ischaos;
-		
+		_isChaos = ischaos;
 	}
 	
 	public void setClan(String clan)
@@ -167,9 +148,7 @@ public class L2NpcAIData
 	
 	public void setEnemyRange(int enemyRange)
 	{
-		
-		_enemyRange = enemyRange;
-		
+		_enemyRange = enemyRange;	
 	}
 	
 	public void setDodge(int dodge)
@@ -195,120 +174,93 @@ public class L2NpcAIData
 	
 	/*
 	
-	public void setBaseShldRate (int baseShldRate)
+	public void setBaseShldRate(int baseShldRate)
 	{
-		
-		_baseShldRate = baseShldRate;
-		
+		_baseShldRate = baseShldRate;	
 	}
 	
-	public void setBaseShldDef (int baseShldDef)
+	public void setBaseShldDef(int baseShldDef)
 	{
-		
-		_baseShldDef = baseShldDef;
-		
+		_baseShldDef = baseShldDef;	
 	}
 	 */
 	
 	//--------------------------------------------------------------------------------------------------------------
 	//Data Recall....
 	//--------------------------------------------------------------------------------------------------------------
-	public int getPrimaryAttack()
+	public int getPrimarySkillId()
+	{
+		return _primarySkillId;
+	}
+	
+	public int getMinSkillChance()
 	{
-		
-		return _primary_attack;
-		
+		return _minskillChance;
 	}
 	
-	public int getSkillChance()
+	public int getMaxSkillChance()
 	{
-		
-		return _skill_chance;
-		
+		return _maxskillChance;
 	}
 	
 	public int getCanMove()
 	{
-		
-		return _canMove;
-		
+		return _canMove;	
 	}
 	
 	public int getSoulShot()
 	{
-		
-		return _soulshot;
-		
+		return _soulshot;	
 	}
 	
 	public int getSpiritShot()
 	{
-		
-		return _spiritshot;
-		
+		return _spiritshot;	
 	}
 	
 	public int getSoulShotChance()
 	{
-		
-		return _soulshotchance;
-		
+		return _soulshotChance;	
 	}
 	
 	public int getSpiritShotChance()
 	{
-		
-		return _spiritshotchance;
-		
+		return _spiritshotChance;	
 	}
 	
 	public int getShortRangeSkill()
 	{
-		
-		return _shortrangeskill;
-		
+		return _shortRangeSkill;	
 	}
 	
 	public int getShortRangeChance()
 	{
-		
-		return _shortrangechance;
-		
+		return _shortRangeChance;	
 	}
 	
 	public int getLongRangeSkill()
 	{
-		
-		return _longrangeskill;
-		
+		return _longRangeSkill;	
 	}
 	
 	public int getLongRangeChance()
 	{
-		
-		return _longrangechance;
-		
+		return _longRangeChance;	
 	}
 	
 	public int getSwitchRangeChance()
 	{
-		
-		return _switchrangechance;
-		
+		return _switchRangeChance;	
 	}
 	
 	public int getIsChaos()
 	{
-		
-		return _ischaos;
-		
+		return _isChaos;	
 	}
 	
 	public String getClan()
 	{
-		
-		return _clan;
-		
+		return _clan;	
 	}
 	
 	public int getClanRange()
@@ -318,23 +270,17 @@ public class L2NpcAIData
 	
 	public String getEnemyClan()
 	{
-		
-		return _enemyClan;
-		
+		return _enemyClan;	
 	}
 	
 	public int getEnemyRange()
 	{
-		
-		return _enemyRange;
-		
+		return _enemyRange;	
 	}
 	
 	public int getDodge()
 	{
-		
-		return _dodge;
-		
+		return _dodge;	
 	}
 	
 	public AIType getAiType()
@@ -344,18 +290,14 @@ public class L2NpcAIData
 	
 	/*
 	
-	public int getBaseShldRate ()
+	public int getBaseShldRate()
 	{
-		
-		return _baseShldRate;
-		
+		return _baseShldRate;	
 	}
 	
-	public int getBaseShldDef ()
+	public int getBaseShldDef()
 	{
-		
-		return _baseShldDef;
-		
+		return _baseShldDef;	
 	}
 	 */
 }

+ 11 - 13
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Npc.java

@@ -242,18 +242,22 @@ public class L2Npc extends L2Character
 	}
 	
 	// GET THE PRIMARY ATTACK
-	public int getPrimaryAttack()
+	public int getPrimarySkillId()
 	{
 		L2NpcAIData AI = getTemplate().getAIDataStatic();
-		return AI.getPrimaryAttack();
-		
+		return AI.getPrimarySkillId();	
 	}
 	
-	public int getSkillChance()
+	public int getMinSkillChance()
 	{
 		L2NpcAIData AI = getTemplate().getAIDataStatic();
-		return AI.getSkillChance();
-		
+		return AI.getMinSkillChance();
+	}
+	
+	public int getMaxSkillChance()
+	{
+		L2NpcAIData AI = getTemplate().getAIDataStatic();
+		return AI.getMaxSkillChance();
 	}
 	
 	public int getCanMove()
@@ -266,35 +270,30 @@ public class L2Npc extends L2Character
 	{
 		L2NpcAIData AI = getTemplate().getAIDataStatic();
 		return AI.getIsChaos();
-		
 	}
 	
 	public int getCanDodge()
 	{
 		L2NpcAIData AI = getTemplate().getAIDataStatic();
 		return AI.getDodge();
-		
 	}
 	
 	public int getSSkillChance()
 	{
 		L2NpcAIData AI = getTemplate().getAIDataStatic();
 		return AI.getShortRangeChance();
-		
 	}
 	
 	public int getLSkillChance()
 	{
 		L2NpcAIData AI = getTemplate().getAIDataStatic();
 		return AI.getLongRangeChance();
-		
 	}
 	
 	public int getSwitchRangeChance()
 	{
 		L2NpcAIData AI = getTemplate().getAIDataStatic();
-		return AI.getSwitchRangeChance();
-		
+		return AI.getSwitchRangeChance();	
 	}
 	
 	public boolean hasLSkill()
@@ -305,7 +304,6 @@ public class L2Npc extends L2Character
 			return false;
 		else
 			return true;
-		
 	}
 	
 	public boolean hasSSkill()

+ 98 - 74
L2J_Server_BETA/java/com/l2jserver/gameserver/templates/chars/L2NpcTemplate.java

@@ -98,6 +98,7 @@ public final class L2NpcTemplate extends L2CharTemplate
 	public FastList<L2Skill> _Lrangeskills;
 	public FastList<L2Skill> _Srangeskills;
 	public FastList<L2Skill> _generalskills;
+	public FastList<L2Skill> _suesideskills;
 	
 	private boolean _hasbuffskills;
 	private boolean _hasnegativeskills;
@@ -119,6 +120,7 @@ public final class L2NpcTemplate extends L2CharTemplate
 	private boolean _hasLrangeskills;
 	private boolean _hasSrangeskills;
 	private boolean _hasgeneralskills;
+	private boolean _hassuesideskills;
 	
 	private L2NpcAIData _AIdataStatic = new L2NpcAIData();
 	
@@ -315,81 +317,87 @@ public final class L2NpcTemplate extends L2CharTemplate
 		
 		if(!skill.isPassive())
 		{
-			addGeneralSkill(skill);
-			switch(skill.getSkillType())
+			if (skill.isSuicideAttack())
 			{
-				case BUFF:
-					addBuffSkill(skill);
-					break;
-				case HEAL:
-				case HOT:
-				case HEAL_PERCENT:
-				case HEAL_STATIC:
-				case BALANCE_LIFE:
-					addHealSkill(skill);
-					break;
-				case RESURRECT:
-					addResSkill(skill);
-					break;
-				case DEBUFF:
-					addDebuffSkill(skill);
-					addCOTSkill(skill);
-					addRangeSkill(skill);
-					break;
-				case ROOT:
-					addRootSkill(skill);
-					addImmobiliseSkill(skill);
-					addRangeSkill(skill);
-					break;
-				case SLEEP:
-					addSleepSkill(skill);
-					addImmobiliseSkill(skill);
-					break;
-				case STUN:
-					addRootSkill(skill);
-					addImmobiliseSkill(skill);
-					addRangeSkill(skill);
-					break;
-				case PARALYZE:
-					addParalyzeSkill(skill);
-					addImmobiliseSkill(skill);
-					addRangeSkill(skill);
-					break;
-				case PDAM:
-				case MDAM:
-				case BLOW:
-				case DRAIN:
-				case CHARGEDAM:
-				case FATAL:	
-				case DEATHLINK:
-				case CPDAM:
-				case MANADAM:
-				case CPDAMPERCENT:	
-					addAtkSkill(skill);
-					addUniversalSkill(skill);
-					addRangeSkill(skill);
-					break;
-				case POISON:
-				case DOT:
-				case MDOT:
-				case BLEED:
-					addDOTSkill(skill);
-					addRangeSkill(skill);
-					break;
-				case MUTE:
-				case FEAR:
-					addCOTSkill(skill);
-					addRangeSkill(skill);
-					break;
-				case CANCEL:
-				case NEGATE:
-					addNegativeSkill(skill);
-					addRangeSkill(skill);
-					break;
-				default :
-					addUniversalSkill(skill);
-					break;
-					
+				addSuesideSkill(skill);
+			}
+			else
+			{
+				addGeneralSkill(skill);
+				switch(skill.getSkillType())
+				{
+					case BUFF:
+						addBuffSkill(skill);
+						break;
+					case HEAL:
+					case HOT:
+					case HEAL_PERCENT:
+					case HEAL_STATIC:
+					case BALANCE_LIFE:
+						addHealSkill(skill);
+						break;
+					case RESURRECT:
+						addResSkill(skill);
+						break;
+					case DEBUFF:
+						addDebuffSkill(skill);
+						addCOTSkill(skill);
+						addRangeSkill(skill);
+						break;
+					case ROOT:
+						addRootSkill(skill);
+						addImmobiliseSkill(skill);
+						addRangeSkill(skill);
+						break;
+					case SLEEP:
+						addSleepSkill(skill);
+						addImmobiliseSkill(skill);
+						break;
+					case STUN:
+						addRootSkill(skill);
+						addImmobiliseSkill(skill);
+						addRangeSkill(skill);
+						break;
+					case PARALYZE:
+						addParalyzeSkill(skill);
+						addImmobiliseSkill(skill);
+						addRangeSkill(skill);
+						break;
+					case PDAM:
+					case MDAM:
+					case BLOW:
+					case DRAIN:
+					case CHARGEDAM:
+					case FATAL:	
+					case DEATHLINK:
+					case CPDAM:
+					case MANADAM:
+					case CPDAMPERCENT:	
+						addAtkSkill(skill);
+						addUniversalSkill(skill);
+						addRangeSkill(skill);
+						break;
+					case POISON:
+					case DOT:
+					case MDOT:
+					case BLEED:
+						addDOTSkill(skill);
+						addRangeSkill(skill);
+						break;
+					case MUTE:
+					case FEAR:
+						addCOTSkill(skill);
+						addRangeSkill(skill);
+						break;
+					case CANCEL:
+					case NEGATE:
+						addNegativeSkill(skill);
+						addRangeSkill(skill);
+						break;
+					default :
+						addUniversalSkill(skill);
+						break;
+				}
 			}
 		}
 		
@@ -814,6 +822,7 @@ public final class L2NpcTemplate extends L2CharTemplate
 		_manaskills.add(skill);
 		_hasmanaskills=true;
 	}
+	
 	public void addGeneralSkill(L2Skill skill)
 	{
 		if (_generalskills == null)
@@ -822,6 +831,16 @@ public final class L2NpcTemplate extends L2CharTemplate
 		_hasgeneralskills=true;
 	}
 	
+	public void addSuesideSkill(L2Skill skill)
+	{
+		if (_suesideskills == null)
+			_suesideskills = new FastList<L2Skill>();
+		_suesideskills.add(skill);
+		
+		_hassuesideskills = true;
+	}
+	
+	
 	public void addRangeSkill(L2Skill skill)
 	{
 		if (skill.getCastRange() <= 150 && skill.getCastRange() > 0)
@@ -967,4 +986,9 @@ public final class L2NpcTemplate extends L2CharTemplate
 	{
 		return (race == Race.UNDEAD);
 	}
+	
+	public boolean hasSuesideSkill()
+	{
+		return _hassuesideskills;
+	}
 }