Skip to content
Snippets Groups Projects
Commit 49b1e217 authored by St3eT's avatar St3eT
Browse files

BETA: Updated '''Monastery of Silence''' AI.

* Reviewed by: malyelfil, Zoey76, Adry_85, xban1x, !UnAfraid
parent cbac8b47
No related branches found
No related tags found
No related merge requests found
......@@ -98,7 +98,7 @@ ai/group_template/GiantsCave.java
ai/group_template/IsleOfPrayer.java
ai/group_template/LairOfAntharas.java
ai/group_template/MithrilMines.java
ai/group_template/Monastery.java
ai/group_template/MonasteryOfSilence.java
ai/group_template/NonLethalableNpcs.java
ai/group_template/PavelArchaic.java
ai/group_template/PlainsOfDion.java
......
......@@ -20,7 +20,6 @@ package ai.group_template;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.GeoData;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.model.L2Object;
......@@ -28,39 +27,48 @@ import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jserver.gameserver.model.actor.L2Playable;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.effects.L2EffectType;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.skills.L2Skill;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.clientpackets.Say2;
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
/**
* Monastery AI.
* Monastery of Silence AI.
* @author Kerberos, nonom
*/
public class Monastery extends AbstractNpcAI
public final class MonasteryOfSilence extends AbstractNpcAI
{
private static final int CAPTAIN = 18910;
private static final int KNIGHT = 18909;
private static final int SCARECROW = 18912;
private static final int[] SOLINA_CLAN =
{
22789, // Guide Solina
22790, // Seeker Solina
22791, // Savior Solina
22793, // Ascetic Solina
};
// NPCs
private static final int CAPTAIN = 18910; // Solina Knight Captain
private static final int KNIGHT = 18909; // Solina Knights
private static final int SCARECROW = 18912; // Scarecrow
private static final int GUIDE = 22789; // Guide Solina
private static final int SEEKER = 22790; // Seeker Solina
private static final int SAVIOR = 22791; // Savior Solina
private static final int ASCETIC = 22793; // Ascetic Solina
private static final int[] DIVINITY_CLAN =
{
22794, // Divinity Judge
22795, // Divinity Manager
};
// Skills
private static final SkillHolder ORDEAL_STRIKE = new SkillHolder(6303, 1); // Trial of the Coup
private static final SkillHolder LEADER_STRIKE = new SkillHolder(6304, 1); // Shock
private static final SkillHolder SAVER_STRIKE = new SkillHolder(6305, 1); // Sacred Gnosis
private static final SkillHolder SAVER_BLEED = new SkillHolder(6306, 1); // Solina Strike
private static final SkillHolder LEARNING_MAGIC = new SkillHolder(6308, 1); // Opus of the Wave
private static final SkillHolder STUDENT_CANCEL = new SkillHolder(6310, 1); // Loss of Quest
private static final SkillHolder WARRIOR_THRUSTING = new SkillHolder(6311, 1); // Solina Thrust
private static final SkillHolder KNIGHT_BLESS = new SkillHolder(6313, 1); // Solina Bless
// Misc
private static final NpcStringId[] DIVINITY_MSG =
{
NpcStringId.S1_WHY_WOULD_YOU_CHOOSE_THE_PATH_OF_DARKNESS,
NpcStringId.S1_HOW_DARE_YOU_DEFY_THE_WILL_OF_EINHASAD
};
private static final NpcStringId[] SOLINA_KNIGHTS_MSG =
{
NpcStringId.PUNISH_ALL_THOSE_WHO_TREAD_FOOTSTEPS_IN_THIS_PLACE,
......@@ -68,118 +76,71 @@ public class Monastery extends AbstractNpcAI
NpcStringId.WE_RAISE_OUR_BLADES_FOR_THE_GLORY_OF_SOLINA
};
private static final NpcStringId[] DIVINITY_MSG =
{
NpcStringId.S1_WHY_WOULD_YOU_CHOOSE_THE_PATH_OF_DARKNESS,
NpcStringId.S1_HOW_DARE_YOU_DEFY_THE_WILL_OF_EINHASAD
};
private static final SkillHolder DECREASE_SPEED = new SkillHolder(4589, 8);
private Monastery()
private MonasteryOfSilence()
{
super(Monastery.class.getSimpleName(), "ai/group_template");
addSeeCreatureId(SOLINA_CLAN);
addSeeCreatureId(CAPTAIN, KNIGHT);
super(MonasteryOfSilence.class.getSimpleName(), "ai/group_template");
addSkillSeeId(DIVINITY_CLAN);
addAttackId(KNIGHT, CAPTAIN);
addSpawnId(KNIGHT);
for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(KNIGHT))
{
startQuestTimer("training", 5000, spawn.getLastSpawn(), null, true);
}
addAttackId(KNIGHT, CAPTAIN, GUIDE, SEEKER, ASCETIC);
addNpcHateId(GUIDE, SEEKER, SAVIOR, ASCETIC);
addAggroRangeEnterId(GUIDE, SEEKER, SAVIOR, ASCETIC);
for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(SCARECROW))
{
spawn.getLastSpawn().setIsInvul(true);
spawn.getLastSpawn().disableCoreAI(true);
startQuestTimer("TRAINING", 30000, spawn.getLastSpawn(), null, true);
}
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("training") && !npc.isInCombat() && (getRandom(100) < 25))
switch (event)
{
for (L2Character character : npc.getKnownList().getKnownCharactersInRadius(300))
case "TRAINING":
{
if (character.isNpc() && (character.getId() == SCARECROW))
for (L2Character character : npc.getKnownList().getKnownCharactersInRadius(400))
{
for (L2Skill skill : npc.getAllSkills())
if ((getRandom(100) < 30) && character.isNpc() && !character.isDead() && !character.isInCombat())
{
if (skill.isActive())
if ((character.getId() == CAPTAIN) && (getRandom(100) < 10) && npc.isScriptValue(0))
{
final L2Npc captain = (L2Npc) character;
broadcastNpcSay(captain, Say2.NPC_ALL, SOLINA_KNIGHTS_MSG[getRandom(SOLINA_KNIGHTS_MSG.length)]);
captain.setScriptValue(1);
startQuestTimer("TIMER", 10000, captain, null);
}
else if (character.getId() == KNIGHT)
{
npc.disableSkill(skill, 0);
character.setRunning();
((L2Attackable) character).addDamageHate(npc, 0, 100);
character.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, npc, null);
}
}
npc.setRunning();
((L2Attackable) npc).addDamageHate(character, 0, 100);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, character, null);
break;
}
break;
}
}
else if (event.equals("checking"))
{
if (!npc.getKnownList().getKnownCharacters().contains(player))
{
cancelQuestTimer("checking", npc, player);
return super.onAdvEvent(event, npc, player);
}
if (player.getAppearance().getInvisible() || player.isSilentMoving())
case "DO_CAST":
{
npc.setTarget(null);
npc.getAI().stopFollow();
((L2Attackable) npc).getAggroList().remove(player);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, player, null);
for (L2Character character : player.getKnownList().getKnownCharactersInRadius(500))
if ((npc != null) && (player != null) && (getRandom(100) < 3))
{
if ((character instanceof L2MonsterInstance) && (character.getTarget() == player))
if (npc.checkDoCastConditions(STUDENT_CANCEL.getSkill()))
{
character.setTarget(null);
character.getAI().stopFollow();
((L2Attackable) character).getAggroList().remove(player);
character.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, player, null);
npc.setTarget(player);
npc.doCast(STUDENT_CANCEL.getSkill());
}
npc.setScriptValue(0);
}
return super.onAdvEvent(event, npc, player);
break;
}
final double distance = npc.calculateDistance(player, false, false);
if (((distance < 500) && !player.isDead() && GeoData.getInstance().canSeeTarget(npc, player)))
case "TIMER":
{
switch (npc.getId())
if (npc != null)
{
case CAPTAIN:
case KNIGHT:
{
npc.setRunning();
npc.setTarget(player);
((L2Attackable) npc).addDamageHate(player, 0, 999);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player, null);
break;
}
default:
{
if (player.getActiveWeaponInstance() != null)
{
npc.setRunning();
npc.setTarget(player);
if (getRandom(10) < 2)
{
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_CANNOT_CARRY_A_WEAPON_WITHOUT_AUTHORIZATION);
}
npc.doCast(DECREASE_SPEED.getSkill());
((L2Attackable) npc).addDamageHate(player, 0, 999);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player, null);
}
}
npc.setScriptValue(0);
}
break;
}
}
return super.onAdvEvent(event, npc, player);
}
......@@ -187,21 +148,128 @@ public class Monastery extends AbstractNpcAI
@Override
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
{
if (getRandom(10) < 1)
final L2Attackable mob = (L2Attackable) npc;
switch (npc.getId())
{
broadcastNpcSay(npc, Say2.NPC_ALL, SOLINA_KNIGHTS_MSG[getRandom(2)]);
case KNIGHT:
{
if ((getRandom(100) < 10) && (mob.getMostHated() == player) && mob.checkDoCastConditions(WARRIOR_THRUSTING.getSkill()))
{
npc.setTarget(player);
npc.doCast(WARRIOR_THRUSTING.getSkill());
}
break;
}
case CAPTAIN:
{
if ((getRandom(100) < 20) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) && npc.isScriptValue(0))
{
if (npc.checkDoCastConditions(KNIGHT_BLESS.getSkill()))
{
npc.setTarget(npc);
npc.doCast(KNIGHT_BLESS.getSkill());
}
npc.setScriptValue(1);
broadcastNpcSay(npc, Say2.ALL, NpcStringId.FOR_THE_GLORY_OF_SOLINA);
final L2Attackable knight = (L2Attackable) addSpawn(KNIGHT, npc);
attackPlayer(knight, player);
}
break;
}
case GUIDE:
{
if ((getRandom(100) < 3) && (mob.getMostHated() == player) && npc.checkDoCastConditions(ORDEAL_STRIKE.getSkill()))
{
npc.setTarget(player);
npc.doCast(ORDEAL_STRIKE.getSkill());
}
break;
}
case SEEKER:
{
if ((getRandom(100) < 33) && (mob.getMostHated() == player) && npc.checkDoCastConditions(SAVER_STRIKE.getSkill()))
{
npc.setTarget(npc);
npc.doCast(SAVER_STRIKE.getSkill());
}
break;
}
case ASCETIC:
{
if ((mob.getMostHated() == player) && npc.isScriptValue(0))
{
npc.setScriptValue(1);
startQuestTimer("DO_CAST", 20000, npc, player);
}
break;
}
}
return super.onAttack(npc, player, damage, isSummon);
}
@Override
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
public boolean onNpcHate(L2Attackable mob, L2Playable playable)
{
return playable.getActiveWeaponInstance() != null;
}
@Override
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
{
if (creature.isPlayer())
if (player.getActiveWeaponInstance() != null)
{
startQuestTimer("checking", 2000, npc, (L2PcInstance) creature, true);
SkillHolder skill = null;
switch (npc.getId())
{
case GUIDE:
{
if (getRandom(100) < 3)
{
skill = LEADER_STRIKE;
}
break;
}
case SEEKER:
{
skill = SAVER_BLEED;
break;
}
case SAVIOR:
{
skill = LEARNING_MAGIC;
break;
}
case ASCETIC:
{
if (getRandom(100) < 3)
{
skill = STUDENT_CANCEL;
}
if (npc.isScriptValue(0))
{
npc.setScriptValue(1);
startQuestTimer("DO_CAST", 20000, npc, player);
}
break;
}
}
if ((skill != null) && npc.checkDoCastConditions(skill.getSkill()))
{
npc.setTarget(player);
npc.doCast(skill.getSkill());
}
if (!npc.isInCombat())
{
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_CANNOT_CARRY_A_WEAPON_WITHOUT_AUTHORIZATION);
}
attackPlayer((L2Attackable) npc, player);
}
return super.onSeeCreature(npc, creature, isSummon);
return super.onAggroRangeEnter(npc, player, isSummon);
}
@Override
......@@ -213,11 +281,8 @@ public class Monastery extends AbstractNpcAI
{
if (obj.equals(npc))
{
NpcSay packet = new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), DIVINITY_MSG[getRandom(1)]);
packet.addStringParameter(caster.getName());
npc.broadcastPacket(packet);
((L2Attackable) npc).addDamageHate(caster, 0, 999);
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, caster);
broadcastNpcSay(npc, Say2.NPC_ALL, DIVINITY_MSG[getRandom(DIVINITY_MSG.length)], caster.getName());
attackPlayer((L2Attackable) npc, caster);
break;
}
}
......@@ -225,15 +290,8 @@ public class Monastery extends AbstractNpcAI
return super.onSkillSee(npc, caster, skill, targets, isSummon);
}
@Override
public String onSpawn(L2Npc npc)
{
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.FOR_THE_GLORY_OF_SOLINA);
return super.onSpawn(npc);
}
public static void main(String[] args)
{
new Monastery();
new MonasteryOfSilence();
}
}
......@@ -2409,8 +2409,8 @@ INSERT INTO `npcaidata` VALUES
(18906, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 400, 0, "null", 300, "null", 0, 0, "fighter"), -- Farm Bandit
(18907, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 400, 0, "null", 300, "null", 0, 0, "fighter"), -- Beast Devourer
(18908, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "null", 300, "null", 0, 0, "fighter"), -- Sel Mahum Chef
(18909, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "n_solina_clan", 300, "monastery_scarecrow", 400, 0, "fighter"), -- Solina Knights
(18910, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "n_solina_clan", 300, "null", 0, 0, "fighter"), -- Solina Knight Captain
(18909, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, "n_solina_clan", 300, "monastery_scarecrow", 400, 0, "fighter"), -- Solina Knights
(18910, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, "n_solina_clan", 300, "null", 0, 0, "fighter"), -- Solina Knight Captain
(18911, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "null", 300, "null", 0, 0, "fighter"), -- Abbey Treasure Chest
(18912, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, "null", 300, "dummy_clan", 400, 0, "corpse"), -- Scarecrow
(18913, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "null", 300, "null", 0, 0, "fighter"), -- Furnace
......@@ -4874,11 +4874,11 @@ INSERT INTO `npcaidata` VALUES
(22786, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "xel_private_clan", 400, "null", 0, 0, "fighter"), -- Sel Mahum Squad Leader
(22787, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "xel_private_clan", 400, "null", 0, 0, "fighter"), -- Sel Mahum Squad Leader
(22788, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "xel_private_clan", 400, "null", 0, 0, "fighter"), -- Sel Mahum Squad Leader
(22789, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Guide Solina
(22790, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Seeker Solina
(22791, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Savior Solina
(22792, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Disciple Solina
(22793, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Ascetic Solina
(22789, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Guide Solina
(22790, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Seeker Solina
(22791, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Savior Solina
(22792, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Disciple Solina
(22793, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, "solina_n_clan", 300, "null", 0, 0, "balanced"), -- Ascetic Solina
(22794, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 600, 0, "divine_n_clan", 300, "null", 0, 0, "balanced"), -- Divinity Judge
(22795, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 600, 0, "divine_n_clan", 300, "null", 0, 0, "balanced"), -- Divinity Manager
(22796, 7, 15, 0, 300, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 600, 0, "divine_n_clan", 300, "null", 0, 0, "balanced"), -- Divinity Supervisor
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment