This commit is contained in:
87
trunk/dist/game/data/scripts/ai/group_template/AdenReconstructorManager.java
vendored
Normal file
87
trunk/dist/game/data/scripts/ai/group_template/AdenReconstructorManager.java
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Aden Reconstructor Manager AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class AdenReconstructorManager extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] NPCS =
|
||||
{
|
||||
33584, // Moe
|
||||
33581, // Eeny
|
||||
};
|
||||
|
||||
private AdenReconstructorManager()
|
||||
{
|
||||
super(AdenReconstructorManager.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(NPCS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SPAM_TEXT":
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.THE_LAND_OF_ADEN_IS_IN_NEED_OF_MATERIALS_TO_REBUILD_FROM_SHILEN_S_DESTRUCTION);
|
||||
startQuestTimer("SPAM_TEXT2", 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "SPAM_TEXT2":
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.PLEASE_DONATE_ANY_UNUSED_MATERIALS_YOU_HAVE_TO_HELP_REBUILD_ADEN);
|
||||
startQuestTimer("SPAM_TEXT3", 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "SPAM_TEXT3":
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_LL_RECEIVE_A_GIFT_FOR_ANY_APPLICABLE_DONATION);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAM_TEXT", (5 * 60 * 1000), npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new AdenReconstructorManager();
|
||||
}
|
||||
}
|
487
trunk/dist/game/data/scripts/ai/group_template/BeastFarm.java
vendored
Normal file
487
trunk/dist/game/data/scripts/ai/group_template/BeastFarm.java
vendored
Normal file
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Growth-capable mobs: Polymorphing upon successful feeding.<br>
|
||||
* Updated to Freya.
|
||||
* @author Fulminus, Gigiikun
|
||||
*/
|
||||
public final class BeastFarm extends AbstractNpcAI
|
||||
{
|
||||
private static final int GOLDEN_SPICE = 15474;
|
||||
private static final int CRYSTAL_SPICE = 15475;
|
||||
private static final int SKILL_GOLDEN_SPICE = 9049;
|
||||
private static final int SKILL_CRYSTAL_SPICE = 9050;
|
||||
private static final int SKILL_BLESSED_GOLDEN_SPICE = 9051;
|
||||
private static final int SKILL_BLESSED_CRYSTAL_SPICE = 9052;
|
||||
private static final int SKILL_SGRADE_GOLDEN_SPICE = 9053;
|
||||
private static final int SKILL_SGRADE_CRYSTAL_SPICE = 9054;
|
||||
private static final int[] TAMED_BEASTS =
|
||||
{
|
||||
18869,
|
||||
18870,
|
||||
18871,
|
||||
18872
|
||||
};
|
||||
private static final int TAME_CHANCE = 20;
|
||||
protected static final int[] SPECIAL_SPICE_CHANCES =
|
||||
{
|
||||
33,
|
||||
75
|
||||
};
|
||||
|
||||
// all mobs that can eat...
|
||||
private static final int[] FEEDABLE_BEASTS =
|
||||
{
|
||||
// Kookaburras
|
||||
18873,
|
||||
18874,
|
||||
18875,
|
||||
18876,
|
||||
18877,
|
||||
18878,
|
||||
18879,
|
||||
// Cougars
|
||||
18880,
|
||||
18881,
|
||||
18882,
|
||||
18883,
|
||||
18884,
|
||||
18885,
|
||||
18886,
|
||||
// Buffalos
|
||||
18887,
|
||||
18888,
|
||||
18889,
|
||||
18890,
|
||||
18891,
|
||||
18892,
|
||||
18893,
|
||||
// Grendels
|
||||
18894,
|
||||
18895,
|
||||
18896,
|
||||
18897,
|
||||
18898,
|
||||
18899,
|
||||
18900
|
||||
};
|
||||
|
||||
private static Map<Integer, Integer> _FeedInfo = new FastMap<>();
|
||||
private static Map<Integer, GrowthCapableMob> _GrowthCapableMobs = new FastMap<>();
|
||||
private static List<TamedBeast> TAMED_BEAST_DATA = new ArrayList<>();
|
||||
|
||||
private BeastFarm()
|
||||
{
|
||||
super(BeastFarm.class.getSimpleName(), "ai/group_template");
|
||||
addSkillSeeId(FEEDABLE_BEASTS);
|
||||
addKillId(FEEDABLE_BEASTS);
|
||||
|
||||
GrowthCapableMob temp;
|
||||
|
||||
// Kookabura
|
||||
temp = new GrowthCapableMob(100, 0, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18874);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18875);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18878);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18879);
|
||||
_GrowthCapableMobs.put(18873, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18876);
|
||||
_GrowthCapableMobs.put(18874, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18877);
|
||||
_GrowthCapableMobs.put(18875, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18878);
|
||||
_GrowthCapableMobs.put(18876, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18879);
|
||||
_GrowthCapableMobs.put(18877, temp);
|
||||
|
||||
// Cougar
|
||||
temp = new GrowthCapableMob(100, 0, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18881);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18882);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18885);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18886);
|
||||
_GrowthCapableMobs.put(18880, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18883);
|
||||
_GrowthCapableMobs.put(18881, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18884);
|
||||
_GrowthCapableMobs.put(18882, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18885);
|
||||
_GrowthCapableMobs.put(18883, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18886);
|
||||
_GrowthCapableMobs.put(18884, temp);
|
||||
|
||||
// Buffalo
|
||||
temp = new GrowthCapableMob(100, 0, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18888);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18889);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18892);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18893);
|
||||
_GrowthCapableMobs.put(18887, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18890);
|
||||
_GrowthCapableMobs.put(18888, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18891);
|
||||
_GrowthCapableMobs.put(18889, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18892);
|
||||
_GrowthCapableMobs.put(18890, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18893);
|
||||
_GrowthCapableMobs.put(18891, temp);
|
||||
|
||||
// Grendel
|
||||
temp = new GrowthCapableMob(100, 0, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18895);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18896);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18899);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18900);
|
||||
_GrowthCapableMobs.put(18894, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18897);
|
||||
_GrowthCapableMobs.put(18895, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18898);
|
||||
_GrowthCapableMobs.put(18896, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18899);
|
||||
_GrowthCapableMobs.put(18897, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18900);
|
||||
_GrowthCapableMobs.put(18898, temp);
|
||||
|
||||
// Tamed beasts data
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Focus", new SkillHolder(6432, 1), new SkillHolder(6668, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Guiding", new SkillHolder(6433, 1), new SkillHolder(6670, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Swifth", new SkillHolder(6434, 1), new SkillHolder(6667, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("Berserker %name%", new SkillHolder(6671, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Protect", new SkillHolder(6669, 1), new SkillHolder(6672, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Vigor", new SkillHolder(6431, 1), new SkillHolder(6666, 1)));
|
||||
}
|
||||
|
||||
public void spawnNext(L2Npc npc, L2PcInstance player, int nextNpcId, int food)
|
||||
{
|
||||
// remove the feedinfo of the mob that got despawned, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
}
|
||||
// despawn the old mob
|
||||
// TODO: same code? FIXED?
|
||||
/*
|
||||
* if (_GrowthCapableMobs.get(npc.getNpcId()).getGrowthLevel() == 0) { npc.deleteMe(); } else {
|
||||
*/
|
||||
npc.deleteMe();
|
||||
// }
|
||||
|
||||
// if this is finally a trained mob, then despawn any other trained mobs that the
|
||||
// player might have and initialize the Tamed Beast.
|
||||
if (Util.contains(TAMED_BEASTS, nextNpcId))
|
||||
{
|
||||
L2NpcTemplate template = NpcData.getInstance().getTemplate(nextNpcId);
|
||||
L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(IdFactory.getInstance().getNextId(), template, player, food, npc.getX(), npc.getY(), npc.getZ(), true);
|
||||
|
||||
TamedBeast beast = TAMED_BEAST_DATA.get(getRandom(TAMED_BEAST_DATA.size()));
|
||||
String name = beast.getName();
|
||||
switch (nextNpcId)
|
||||
{
|
||||
case 18869:
|
||||
name = name.replace("%name%", "Alpine Kookaburra");
|
||||
break;
|
||||
case 18870:
|
||||
name = name.replace("%name%", "Alpine Cougar");
|
||||
break;
|
||||
case 18871:
|
||||
name = name.replace("%name%", "Alpine Buffalo");
|
||||
break;
|
||||
case 18872:
|
||||
name = name.replace("%name%", "Alpine Grendel");
|
||||
break;
|
||||
}
|
||||
nextNpc.setName(name);
|
||||
nextNpc.broadcastPacket(new NpcInfo(nextNpc));
|
||||
nextNpc.setRunning();
|
||||
|
||||
SkillData st = SkillData.getInstance();
|
||||
for (SkillHolder sh : beast.getSkills())
|
||||
{
|
||||
nextNpc.addBeastSkill(st.getSkill(sh.getSkillId(), sh.getSkillLvl()));
|
||||
}
|
||||
|
||||
Q00020_BringUpWithLove.checkJewelOfInnocence(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not trained, the newly spawned mob will automatically be agro against its feeder
|
||||
// (what happened to "never bite the hand that feeds you" anyway?!)
|
||||
L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
|
||||
|
||||
// register the player in the feedinfo for the mob that just spawned
|
||||
_FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
|
||||
nextNpc.setRunning();
|
||||
nextNpc.addDamageHate(player, 0, 99999);
|
||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
||||
|
||||
player.setTarget(nextNpc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
// this behavior is only run when the target of skill is the passed npc (chest)
|
||||
// i.e. when the player is attempting to open the chest using a skill
|
||||
if (!Util.contains(targets, npc))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
// gather some values on local variables
|
||||
int npcId = npc.getId();
|
||||
int skillId = skill.getId();
|
||||
// check if the npc and skills used are valid for this script. Exit if invalid.
|
||||
if (!Util.contains(FEEDABLE_BEASTS, npcId) || ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE) && (skillId != SKILL_BLESSED_GOLDEN_SPICE) && (skillId != SKILL_BLESSED_CRYSTAL_SPICE) && (skillId != SKILL_SGRADE_GOLDEN_SPICE) && (skillId != SKILL_SGRADE_CRYSTAL_SPICE)))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// first gather some values on local variables
|
||||
int objectId = npc.getObjectId();
|
||||
int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
growthLevel = _GrowthCapableMobs.get(npcId).getGrowthLevel();
|
||||
}
|
||||
|
||||
// prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
|
||||
// If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
|
||||
if ((growthLevel == 0) && _FeedInfo.containsKey(objectId))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
_FeedInfo.put(objectId, caster.getObjectId());
|
||||
|
||||
// display the social action of the beast eating the food.
|
||||
npc.broadcastSocialAction(2);
|
||||
|
||||
int food = 0;
|
||||
if ((skillId == SKILL_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_GOLDEN_SPICE))
|
||||
{
|
||||
food = GOLDEN_SPICE;
|
||||
}
|
||||
else if ((skillId == SKILL_CRYSTAL_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE))
|
||||
{
|
||||
food = CRYSTAL_SPICE;
|
||||
}
|
||||
|
||||
// if this pet can't grow, it's all done.
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
||||
int newNpcId = _GrowthCapableMobs.get(npcId).getLeveledNpcId(skillId);
|
||||
if (newNpcId == -1)
|
||||
{
|
||||
if (growthLevel == 0)
|
||||
{
|
||||
_FeedInfo.remove(objectId);
|
||||
npc.setRunning();
|
||||
((L2Attackable) npc).addDamageHate(caster, 0, 1);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
else if ((growthLevel > 0) && (_FeedInfo.get(objectId) != caster.getObjectId()))
|
||||
{
|
||||
// check if this is the same player as the one who raised it from growth 0.
|
||||
// if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
spawnNext(npc, caster, newNpcId, food);
|
||||
}
|
||||
else
|
||||
{
|
||||
caster.sendMessage("The beast spit out the feed instead of eating it.");
|
||||
npc.dropItem(caster, food, 1);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// remove the feedinfo of the mob that got killed, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
// all mobs that grow by eating
|
||||
private static class GrowthCapableMob
|
||||
{
|
||||
private final int _chance;
|
||||
private final int _growthLevel;
|
||||
private final int _tameNpcId;
|
||||
private final Map<Integer, Integer> _skillSuccessNpcIdList = new FastMap<>();
|
||||
|
||||
public GrowthCapableMob(int chance, int growthLevel, int tameNpcId)
|
||||
{
|
||||
_chance = chance;
|
||||
_growthLevel = growthLevel;
|
||||
_tameNpcId = tameNpcId;
|
||||
}
|
||||
|
||||
public void addNpcIdForSkillId(int skillId, int npcId)
|
||||
{
|
||||
_skillSuccessNpcIdList.put(skillId, npcId);
|
||||
}
|
||||
|
||||
public int getGrowthLevel()
|
||||
{
|
||||
return _growthLevel;
|
||||
}
|
||||
|
||||
public int getLeveledNpcId(int skillId)
|
||||
{
|
||||
if (!_skillSuccessNpcIdList.containsKey(skillId))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_CRYSTAL_SPICE))
|
||||
{
|
||||
if (getRandom(100) < SPECIAL_SPICE_CHANCES[0])
|
||||
{
|
||||
if (getRandom(100) < SPECIAL_SPICE_CHANCES[1])
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(skillId);
|
||||
}
|
||||
else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE))
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(SKILL_GOLDEN_SPICE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(SKILL_CRYSTAL_SPICE);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
else if ((_growthLevel == 2) && (getRandom(100) < TAME_CHANCE))
|
||||
{
|
||||
return _tameNpcId;
|
||||
}
|
||||
else if (getRandom(100) < _chance)
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(skillId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TamedBeast
|
||||
{
|
||||
private final String name;
|
||||
private final SkillHolder[] sh;
|
||||
|
||||
public TamedBeast(String beastName, SkillHolder... holders)
|
||||
{
|
||||
name = beastName;
|
||||
sh = holders;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public SkillHolder[] getSkills()
|
||||
{
|
||||
return sh;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BeastFarm();
|
||||
}
|
||||
}
|
238
trunk/dist/game/data/scripts/ai/group_template/DenOfEvil.java
vendored
Normal file
238
trunk/dist/game/data/scripts/ai/group_template/DenOfEvil.java
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2EffectZone;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Dummy AI for spawns/respawns only for testing.
|
||||
* @author Gnacik
|
||||
*/
|
||||
public final class DenOfEvil extends AbstractNpcAI
|
||||
{
|
||||
// private static final int _buffer_id = 32656;
|
||||
protected static final int[] EYE_IDS =
|
||||
{
|
||||
18812,
|
||||
18813,
|
||||
18814
|
||||
};
|
||||
private static final int SKILL_ID = 6150; // others +2
|
||||
|
||||
private static final Location[] EYE_SPAWNS =
|
||||
{
|
||||
new Location(71544, -129400, -3360, 16472),
|
||||
new Location(70954, -128854, -3360, 16),
|
||||
new Location(72145, -128847, -3368, 32832),
|
||||
new Location(76147, -128372, -3144, 16152),
|
||||
new Location(71573, -128309, -3360, 49152),
|
||||
new Location(75211, -127441, -3152, 0),
|
||||
new Location(77005, -127406, -3144, 32784),
|
||||
new Location(75965, -126486, -3144, 49120),
|
||||
new Location(70972, -126429, -3016, 19208),
|
||||
new Location(69916, -125838, -3024, 2840),
|
||||
new Location(71658, -125459, -3016, 35136),
|
||||
new Location(70605, -124646, -3040, 52104),
|
||||
new Location(67283, -123237, -2912, 12376),
|
||||
new Location(68383, -122754, -2912, 27904),
|
||||
new Location(74137, -122733, -3024, 13272),
|
||||
new Location(66736, -122007, -2896, 60576),
|
||||
new Location(73289, -121769, -3024, 1024),
|
||||
new Location(67894, -121491, -2912, 43872),
|
||||
new Location(75530, -121477, -3008, 34424),
|
||||
new Location(74117, -120459, -3024, 52344),
|
||||
new Location(69608, -119855, -2534, 17251),
|
||||
new Location(71014, -119027, -2520, 31904),
|
||||
new Location(68944, -118964, -2527, 59874),
|
||||
new Location(62261, -118263, -3072, 12888),
|
||||
new Location(70300, -117942, -2528, 46208),
|
||||
new Location(74312, -117583, -2272, 15280),
|
||||
new Location(63276, -117409, -3064, 24760),
|
||||
new Location(68104, -117192, -2168, 15888),
|
||||
new Location(73758, -116945, -2216, 0),
|
||||
new Location(74944, -116858, -2220, 30892),
|
||||
new Location(61715, -116623, -3064, 59888),
|
||||
new Location(69140, -116464, -2168, 28952),
|
||||
new Location(67311, -116374, -2152, 1280),
|
||||
new Location(62459, -116370, -3064, 48624),
|
||||
new Location(74475, -116260, -2216, 47456),
|
||||
new Location(68333, -115015, -2168, 45136),
|
||||
new Location(68280, -108129, -1160, 17992),
|
||||
new Location(62983, -107259, -2384, 12552),
|
||||
new Location(67062, -107125, -1144, 64008),
|
||||
new Location(68893, -106954, -1160, 36704),
|
||||
new Location(63848, -106771, -2384, 32784),
|
||||
new Location(62372, -106514, -2384, 0),
|
||||
new Location(67838, -106143, -1160, 51232),
|
||||
new Location(62905, -106109, -2384, 51288)
|
||||
};
|
||||
|
||||
private DenOfEvil()
|
||||
{
|
||||
super(DenOfEvil.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(EYE_IDS);
|
||||
addSpawnId(EYE_IDS);
|
||||
for (Location loc : EYE_SPAWNS)
|
||||
{
|
||||
addSpawn(EYE_IDS[getRandom(EYE_IDS.length)], loc, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private int getSkillIdByNpcId(int npcId)
|
||||
{
|
||||
int diff = npcId - EYE_IDS[0];
|
||||
diff *= 2;
|
||||
return SKILL_ID + diff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setIsImmobilized(true);
|
||||
L2EffectZone zone = ZoneManager.getInstance().getZone(npc, L2EffectZone.class);
|
||||
if (zone == null)
|
||||
{
|
||||
_log.warning("NPC " + npc + " spawned outside of L2EffectZone, check your zone coords! X:" + npc.getX() + " Y:" + npc.getY() + " Z:" + npc.getZ());
|
||||
return null;
|
||||
}
|
||||
int skillId = getSkillIdByNpcId(npc.getId());
|
||||
int skillLevel = zone.getSkillLevel(skillId);
|
||||
zone.addSkill(skillId, skillLevel + 1);
|
||||
if (skillLevel == 3) // 3+1=4
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleAi(new KashaDestruction(zone), 2 * 60 * 1000l);
|
||||
zone.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.DEFEAT_KASHA_S_EYES_TO_LIFT_THE_GREAT_CURSE));
|
||||
}
|
||||
else if (skillLevel == 2)
|
||||
{
|
||||
zone.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.A_GREAT_CURSE_CAN_BE_FELT_FROM_KASHA_S_EYES));
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleAi(new RespawnNewEye(npc.getLocation()), 15000);
|
||||
L2EffectZone zone = ZoneManager.getInstance().getZone(npc, L2EffectZone.class);
|
||||
if (zone == null)
|
||||
{
|
||||
_log.warning("NPC " + npc + " killed outside of L2EffectZone, check your zone coords! X:" + npc.getX() + " Y:" + npc.getY() + " Z:" + npc.getZ());
|
||||
return null;
|
||||
}
|
||||
int skillId = getSkillIdByNpcId(npc.getId());
|
||||
int skillLevel = zone.getSkillLevel(skillId);
|
||||
zone.addSkill(skillId, skillLevel - 1);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private class RespawnNewEye implements Runnable
|
||||
{
|
||||
private final Location _loc;
|
||||
|
||||
public RespawnNewEye(Location loc)
|
||||
{
|
||||
_loc = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
addSpawn(EYE_IDS[getRandom(EYE_IDS.length)], _loc, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private class KashaDestruction implements Runnable
|
||||
{
|
||||
L2EffectZone _zone;
|
||||
|
||||
public KashaDestruction(L2EffectZone zone)
|
||||
{
|
||||
_zone = zone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
for (int i = SKILL_ID; i <= (SKILL_ID + 4); i = i + 2)
|
||||
{
|
||||
// test 3 skills if some is lvl 4
|
||||
if (_zone.getSkillLevel(i) > 3)
|
||||
{
|
||||
destroyZone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyZone()
|
||||
{
|
||||
for (L2Character character : _zone.getCharactersInside())
|
||||
{
|
||||
if (character == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (character.isPlayable())
|
||||
{
|
||||
Skill skill = SkillData.getInstance().getSkill(6149, 1);
|
||||
skill.applyEffects(character, character);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (character.doDie(null)) // mobs die
|
||||
{
|
||||
if (character.isNpc())
|
||||
{
|
||||
// respawn eye
|
||||
L2Npc npc = (L2Npc) character;
|
||||
if (Util.contains(EYE_IDS, npc.getId()))
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleAi(new RespawnNewEye(npc.getLocation()), 15000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = SKILL_ID; i <= (SKILL_ID + 4); i = i + 2)
|
||||
{
|
||||
_zone.removeSkill(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DenOfEvil();
|
||||
}
|
||||
}
|
299
trunk/dist/game/data/scripts/ai/group_template/DragonValley.java
vendored
Normal file
299
trunk/dist/game/data/scripts/ai/group_template/DragonValley.java
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Dragon Valley AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class DragonValley extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int NECROMANCER_OF_THE_VALLEY = 22858;
|
||||
private static final int EXPLODING_ORC_GHOST = 22818;
|
||||
private static final int WRATHFUL_ORC_GHOST = 22819;
|
||||
private static final int DRAKOS_ASSASSIN = 22823;
|
||||
private static final int[] SUMMON_NPC =
|
||||
{
|
||||
22822, // Drakos Warrior
|
||||
22824, // Drakos Guardian
|
||||
22862, // Drakos Hunter
|
||||
};
|
||||
private static final int[] SPAWN_ANIMATION =
|
||||
{
|
||||
22826, // Scorpion Bones
|
||||
22823, // Drakos Assassin
|
||||
22828, // Parasitic Leech
|
||||
|
||||
};
|
||||
private static final int[] SPOIL_REACT_MONSTER =
|
||||
{
|
||||
22822, // Drakos Warrior
|
||||
22823, // Drakos Assassin
|
||||
22824, // Drakos Guardian
|
||||
22825, // Giant Scorpion Bones
|
||||
22826, // Scorpion Bones
|
||||
22827, // Batwing Drake
|
||||
22828, // Parasitic Leech
|
||||
22829, // Emerald Drake
|
||||
22830, // Gem Dragon
|
||||
22831, // Dragon Tracker of the Valley
|
||||
22832, // Dragon Scout of the Valley
|
||||
22833, // Sand Drake Tracker
|
||||
22834, // Dust Dragon Tracker
|
||||
22860, // Hungry Parasitic Leech
|
||||
22861, // Hard Scorpion Bones
|
||||
22862, // Drakos Hunter
|
||||
};
|
||||
// Items
|
||||
private static final int GREATER_HERB_OF_MANA = 8604;
|
||||
private static final int SUPERIOR_HERB_OF_MANA = 8605;
|
||||
// Skills
|
||||
private static final SkillHolder SELF_DESTRUCTION = new SkillHolder(6850, 1);
|
||||
private static final SkillHolder MORALE_BOOST1 = new SkillHolder(6885, 1);
|
||||
private static final SkillHolder MORALE_BOOST2 = new SkillHolder(6885, 2);
|
||||
private static final SkillHolder MORALE_BOOST3 = new SkillHolder(6885, 3);
|
||||
// Misc
|
||||
private static final int MIN_DISTANCE = 1500;
|
||||
private static final int MIN_MEMBERS = 3;
|
||||
private static final int MIN_LVL = 80;
|
||||
private static final int CLASS_LVL = 3;
|
||||
private static final EnumMap<ClassId, Double> CLASS_POINTS = new EnumMap<>(ClassId.class);
|
||||
{
|
||||
CLASS_POINTS.put(ClassId.ADVENTURER, 0.2);
|
||||
CLASS_POINTS.put(ClassId.ARCANA_LORD, 1.5);
|
||||
CLASS_POINTS.put(ClassId.ARCHMAGE, 0.3);
|
||||
CLASS_POINTS.put(ClassId.CARDINAL, -0.6);
|
||||
CLASS_POINTS.put(ClassId.DOMINATOR, 0.2);
|
||||
CLASS_POINTS.put(ClassId.DOOMBRINGER, 0.2);
|
||||
CLASS_POINTS.put(ClassId.DOOMCRYER, 0.1);
|
||||
CLASS_POINTS.put(ClassId.DREADNOUGHT, 0.7);
|
||||
CLASS_POINTS.put(ClassId.DUELIST, 0.2);
|
||||
CLASS_POINTS.put(ClassId.ELEMENTAL_MASTER, 1.4);
|
||||
CLASS_POINTS.put(ClassId.EVA_SAINT, -0.6);
|
||||
CLASS_POINTS.put(ClassId.EVA_TEMPLAR, 0.8);
|
||||
CLASS_POINTS.put(ClassId.FEMALE_SOUL_HOUND, 0.4);
|
||||
CLASS_POINTS.put(ClassId.FORTUNE_SEEKER, 0.9);
|
||||
CLASS_POINTS.put(ClassId.GHOST_HUNTER, 0.2);
|
||||
CLASS_POINTS.put(ClassId.GHOST_SENTINEL, 0.2);
|
||||
CLASS_POINTS.put(ClassId.GRAND_KHAVATARI, 0.2);
|
||||
CLASS_POINTS.put(ClassId.HELL_KNIGHT, 0.6);
|
||||
CLASS_POINTS.put(ClassId.HIEROPHANT, 0.0);
|
||||
CLASS_POINTS.put(ClassId.JUDICATOR, 0.1);
|
||||
CLASS_POINTS.put(ClassId.MOONLIGHT_SENTINEL, 0.2);
|
||||
CLASS_POINTS.put(ClassId.MAESTRO, 0.7);
|
||||
CLASS_POINTS.put(ClassId.MALE_SOUL_HOUND, 0.4);
|
||||
CLASS_POINTS.put(ClassId.MYSTIC_MUSE, 0.3);
|
||||
CLASS_POINTS.put(ClassId.PHOENIX_KNIGHT, 0.6);
|
||||
CLASS_POINTS.put(ClassId.SAGITTARIUS, 0.2);
|
||||
CLASS_POINTS.put(ClassId.SHILLIEN_SAINT, -0.6);
|
||||
CLASS_POINTS.put(ClassId.SHILLIEN_TEMPLAR, 0.8);
|
||||
CLASS_POINTS.put(ClassId.SOULTAKER, 0.3);
|
||||
CLASS_POINTS.put(ClassId.SPECTRAL_DANCER, 0.4);
|
||||
CLASS_POINTS.put(ClassId.SPECTRAL_MASTER, 1.4);
|
||||
CLASS_POINTS.put(ClassId.STORM_SCREAMER, 0.3);
|
||||
CLASS_POINTS.put(ClassId.SWORD_MUSE, 0.4);
|
||||
CLASS_POINTS.put(ClassId.TITAN, 0.3);
|
||||
CLASS_POINTS.put(ClassId.TRICKSTER, 0.5);
|
||||
CLASS_POINTS.put(ClassId.WIND_RIDER, 0.2);
|
||||
}
|
||||
|
||||
private DragonValley()
|
||||
{
|
||||
super(DragonValley.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(NECROMANCER_OF_THE_VALLEY);
|
||||
addAttackId(SUMMON_NPC);
|
||||
addKillId(NECROMANCER_OF_THE_VALLEY);
|
||||
addKillId(SPOIL_REACT_MONSTER);
|
||||
addSpawnId(EXPLODING_ORC_GHOST, NECROMANCER_OF_THE_VALLEY);
|
||||
addSpawnId(SPOIL_REACT_MONSTER);
|
||||
addSpellFinishedId(EXPLODING_ORC_GHOST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SELF_DESTRUCTION") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
final L2Playable playable = npc.getVariables().getObject("playable", L2Playable.class);
|
||||
|
||||
if ((playable != null) && (npc.calculateDistance(playable, true, false) < 250))
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.doCast(SELF_DESTRUCTION.getSkill());
|
||||
}
|
||||
else if (playable != null)
|
||||
{
|
||||
startQuestTimer("SELF_DESTRUCTION", 3000, npc, null);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == NECROMANCER_OF_THE_VALLEY)
|
||||
{
|
||||
spawnGhost(npc, attacker, isSummon, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((npc.getCurrentHp() < (npc.getMaxHp() / 2)) && (getRandom(100) < 5) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
final int rnd = getRandom(3, 5);
|
||||
for (int i = 0; i < rnd; i++)
|
||||
{
|
||||
final L2Playable playable = isSummon ? attacker.getSummon() : attacker;
|
||||
final L2Npc minion = addSpawn(DRAKOS_ASSASSIN, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), true, 0, true);
|
||||
addAttackPlayerDesire(minion, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == NECROMANCER_OF_THE_VALLEY)
|
||||
{
|
||||
spawnGhost(npc, killer, isSummon, 20);
|
||||
}
|
||||
else if (((L2Attackable) npc).isSweepActive())
|
||||
{
|
||||
npc.dropItem(killer, getRandom(GREATER_HERB_OF_MANA, SUPERIOR_HERB_OF_MANA), 1);
|
||||
manageMoraleBoost(killer, npc);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
((L2Attackable) npc).setOnKillDelay(0);
|
||||
if (npc.getId() == EXPLODING_ORC_GHOST)
|
||||
{
|
||||
startQuestTimer("SELF_DESTRUCTION", 3000, npc, null);
|
||||
}
|
||||
else if (Util.contains(SPAWN_ANIMATION, npc.getId()))
|
||||
{
|
||||
npc.setShowSummonAnimation(true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (skill == SELF_DESTRUCTION.getSkill())
|
||||
{
|
||||
npc.doDie(player);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void manageMoraleBoost(L2PcInstance player, L2Npc npc)
|
||||
{
|
||||
double points = 0;
|
||||
int moraleBoostLv = 0;
|
||||
|
||||
if (player.isInParty() && (player.getParty().getMemberCount() >= MIN_MEMBERS) && (npc != null))
|
||||
{
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
if ((member.getLevel() >= MIN_LVL) && (member.getClassId().level() >= CLASS_LVL) && (npc.calculateDistance(member, true, false) < MIN_DISTANCE))
|
||||
{
|
||||
points += CLASS_POINTS.get(member.getClassId());
|
||||
}
|
||||
}
|
||||
|
||||
if (points >= 3)
|
||||
{
|
||||
moraleBoostLv = 3;
|
||||
}
|
||||
else if (points >= 2)
|
||||
{
|
||||
moraleBoostLv = 2;
|
||||
}
|
||||
else if (points >= 1)
|
||||
{
|
||||
moraleBoostLv = 1;
|
||||
}
|
||||
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
if (npc.calculateDistance(member, true, false) < MIN_DISTANCE)
|
||||
{
|
||||
switch (moraleBoostLv)
|
||||
{
|
||||
case 1:
|
||||
MORALE_BOOST1.getSkill().applyEffects(member, member);
|
||||
break;
|
||||
case 2:
|
||||
MORALE_BOOST2.getSkill().applyEffects(member, member);
|
||||
break;
|
||||
case 3:
|
||||
MORALE_BOOST3.getSkill().applyEffects(member, member);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnGhost(L2Npc npc, L2PcInstance player, boolean isSummon, int chance)
|
||||
{
|
||||
if ((npc.getScriptValue() < 2) && (getRandom(100) < chance))
|
||||
{
|
||||
int val = npc.getScriptValue();
|
||||
final L2Playable attacker = isSummon ? player.getSummon() : player;
|
||||
final L2Npc ghost1 = addSpawn(EXPLODING_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, true);
|
||||
ghost1.getVariables().set("playable", attacker);
|
||||
addAttackPlayerDesire(ghost1, attacker);
|
||||
val++;
|
||||
if ((val < 2) && (getRandomBoolean()))
|
||||
{
|
||||
final L2Npc ghost2 = addSpawn(WRATHFUL_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ() + 20, npc.getHeading(), false, 0, false);
|
||||
addAttackPlayerDesire(ghost2, attacker);
|
||||
val++;
|
||||
}
|
||||
npc.setScriptValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DragonValley();
|
||||
}
|
||||
}
|
90
trunk/dist/game/data/scripts/ai/group_template/FairyTrees.java
vendored
Normal file
90
trunk/dist/game/data/scripts/ai/group_template/FairyTrees.java
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
|
||||
/**
|
||||
* Fairy Trees AI.
|
||||
* @author Charus
|
||||
*/
|
||||
public class FairyTrees extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int SOUL_GUARDIAN = 27189; // Soul of Tree Guardian
|
||||
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
27185, // Fairy Tree of Wind
|
||||
27186, // Fairy Tree of Star
|
||||
27187, // Fairy Tree of Twilight
|
||||
27188, // Fairy Tree of Abyss
|
||||
};
|
||||
|
||||
// Skill
|
||||
private static SkillHolder VENOMOUS_POISON = new SkillHolder(4243, 1); // Venomous Poison
|
||||
|
||||
// Misc
|
||||
private static final int MIN_DISTANCE = 1500;
|
||||
|
||||
private FairyTrees()
|
||||
{
|
||||
super(FairyTrees.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(MOBS);
|
||||
addSpawnId(MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.calculateDistance(killer, true, false) <= MIN_DISTANCE)
|
||||
{
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
final L2Npc guardian = addSpawn(SOUL_GUARDIAN, npc, false, 30000);
|
||||
final L2Playable attacker = isSummon ? killer.getSummon() : killer;
|
||||
addAttackPlayerDesire(guardian, attacker);
|
||||
if (getRandomBoolean())
|
||||
{
|
||||
guardian.setTarget(attacker);
|
||||
guardian.doCast(VENOMOUS_POISON.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsNoRndWalk(true);
|
||||
npc.setIsImmobilized(true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FairyTrees();
|
||||
}
|
||||
}
|
617
trunk/dist/game/data/scripts/ai/group_template/FeedableBeasts.java
vendored
Normal file
617
trunk/dist/game/data/scripts/ai/group_template/FeedableBeasts.java
vendored
Normal file
@@ -0,0 +1,617 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Growth-capable mobs: Polymorphing upon successful feeding.
|
||||
* @author Fulminus
|
||||
*/
|
||||
public final class FeedableBeasts extends AbstractNpcAI
|
||||
{
|
||||
private static final int GOLDEN_SPICE = 6643;
|
||||
private static final int CRYSTAL_SPICE = 6644;
|
||||
private static final int SKILL_GOLDEN_SPICE = 2188;
|
||||
private static final int SKILL_CRYSTAL_SPICE = 2189;
|
||||
private static final int FOODSKILLDIFF = GOLDEN_SPICE - SKILL_GOLDEN_SPICE;
|
||||
// @formatter:off
|
||||
private static final int[] TAMED_BEASTS =
|
||||
{
|
||||
16013, 16014, 16015, 16016, 16017, 16018
|
||||
};
|
||||
// all mobs that can eat...
|
||||
private static final int[] FEEDABLE_BEASTS =
|
||||
{
|
||||
21451, 21452, 21453, 21454, 21455, 21456, 21457, 21458, 21459, 21460,
|
||||
21461, 21462, 21463, 21464, 21465, 21466, 21467, 21468, 21469, 21470,
|
||||
21471, 21472, 21473, 21474, 21475, 21476, 21477, 21478, 21479, 21480,
|
||||
21481, 21482, 21483, 21484, 21485, 21486, 21487, 21488, 21489, 21490,
|
||||
21491, 21492, 21493, 21494, 21495, 21496, 21497, 21498, 21499, 21500,
|
||||
21501, 21502, 21503, 21504, 21505, 21506, 21507, 21824, 21825, 21826,
|
||||
21827, 21828, 21829, 16013, 16014, 16015, 16016, 16017, 16018
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
private static final Map<Integer, Integer> MAD_COW_POLYMORPH = new FastMap<>();
|
||||
static
|
||||
{
|
||||
MAD_COW_POLYMORPH.put(21824, 21468);
|
||||
MAD_COW_POLYMORPH.put(21825, 21469);
|
||||
MAD_COW_POLYMORPH.put(21826, 21487);
|
||||
MAD_COW_POLYMORPH.put(21827, 21488);
|
||||
MAD_COW_POLYMORPH.put(21828, 21506);
|
||||
MAD_COW_POLYMORPH.put(21829, 21507);
|
||||
}
|
||||
|
||||
private static final NpcStringId[][] TEXT =
|
||||
{
|
||||
{
|
||||
NpcStringId.WHAT_DID_YOU_JUST_DO_TO_ME,
|
||||
NpcStringId.ARE_YOU_TRYING_TO_TAME_ME_DON_T_DO_THAT,
|
||||
NpcStringId.DON_T_GIVE_SUCH_A_THING_YOU_CAN_ENDANGER_YOURSELF,
|
||||
NpcStringId.YUCK_WHAT_IS_THIS_IT_TASTES_TERRIBLE,
|
||||
NpcStringId.I_M_HUNGRY_GIVE_ME_A_LITTLE_MORE_PLEASE,
|
||||
NpcStringId.WHAT_IS_THIS_IS_THIS_EDIBLE,
|
||||
NpcStringId.DON_T_WORRY_ABOUT_ME,
|
||||
NpcStringId.THANK_YOU_THAT_WAS_DELICIOUS,
|
||||
NpcStringId.I_THINK_I_AM_STARTING_TO_LIKE_YOU,
|
||||
NpcStringId.EEEEEK_EEEEEK
|
||||
},
|
||||
{
|
||||
NpcStringId.DON_T_KEEP_TRYING_TO_TAME_ME_I_DON_T_WANT_TO_BE_TAMED,
|
||||
NpcStringId.IT_IS_JUST_FOOD_TO_ME_ALTHOUGH_IT_MAY_ALSO_BE_YOUR_HAND,
|
||||
NpcStringId.IF_I_KEEP_EATING_LIKE_THIS_WON_T_I_BECOME_FAT_CHOMP_CHOMP,
|
||||
NpcStringId.WHY_DO_YOU_KEEP_FEEDING_ME,
|
||||
NpcStringId.DON_T_TRUST_ME_I_M_AFRAID_I_MAY_BETRAY_YOU_LATER
|
||||
},
|
||||
{
|
||||
NpcStringId.GRRRRR,
|
||||
NpcStringId.YOU_BROUGHT_THIS_UPON_YOURSELF,
|
||||
NpcStringId.I_FEEL_STRANGE_I_KEEP_HAVING_THESE_EVIL_THOUGHTS,
|
||||
NpcStringId.ALAS_SO_THIS_IS_HOW_IT_ALL_ENDS,
|
||||
NpcStringId.I_DON_T_FEEL_SO_GOOD_OH_MY_MIND_IS_VERY_TROUBLED
|
||||
}
|
||||
};
|
||||
|
||||
private static final NpcStringId[] TAMED_TEXT =
|
||||
{
|
||||
NpcStringId.S1_SO_WHAT_DO_YOU_THINK_IT_IS_LIKE_TO_BE_TAMED,
|
||||
NpcStringId.S1_WHENEVER_I_SEE_SPICE_I_THINK_I_WILL_MISS_YOUR_HAND_THAT_USED_TO_FEED_IT_TO_ME,
|
||||
NpcStringId.S1_DON_T_GO_TO_THE_VILLAGE_I_DON_T_HAVE_THE_STRENGTH_TO_FOLLOW_YOU,
|
||||
NpcStringId.THANK_YOU_FOR_TRUSTING_ME_S1_I_HOPE_I_WILL_BE_HELPFUL_TO_YOU,
|
||||
NpcStringId.S1_WILL_I_BE_ABLE_TO_HELP_YOU,
|
||||
NpcStringId.I_GUESS_IT_S_JUST_MY_ANIMAL_MAGNETISM,
|
||||
NpcStringId.TOO_MUCH_SPICY_FOOD_MAKES_ME_SWEAT_LIKE_A_BEAST,
|
||||
NpcStringId.ANIMALS_NEED_LOVE_TOO
|
||||
};
|
||||
|
||||
private static Map<Integer, Integer> _FeedInfo = new FastMap<>();
|
||||
private static Map<Integer, GrowthCapableMob> _GrowthCapableMobs = new FastMap<>();
|
||||
|
||||
// all mobs that grow by eating
|
||||
private static class GrowthCapableMob
|
||||
{
|
||||
private final int _growthLevel;
|
||||
private final int _chance;
|
||||
|
||||
private final Map<Integer, int[][]> _spiceToMob = new FastMap<>();
|
||||
|
||||
public GrowthCapableMob(int growthLevel, int chance)
|
||||
{
|
||||
_growthLevel = growthLevel;
|
||||
_chance = chance;
|
||||
}
|
||||
|
||||
public void addMobs(int spice, int[][] Mobs)
|
||||
{
|
||||
_spiceToMob.put(spice, Mobs);
|
||||
}
|
||||
|
||||
public Integer getMob(int spice, int mobType, int classType)
|
||||
{
|
||||
if (_spiceToMob.containsKey(spice))
|
||||
{
|
||||
return _spiceToMob.get(spice)[mobType][classType];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Integer getRandomMob(int spice)
|
||||
{
|
||||
int[][] temp;
|
||||
temp = _spiceToMob.get(spice);
|
||||
int rand = getRandom(temp[0].length);
|
||||
return temp[0][rand];
|
||||
}
|
||||
|
||||
public Integer getChance()
|
||||
{
|
||||
return _chance;
|
||||
}
|
||||
|
||||
public Integer getGrowthLevel()
|
||||
{
|
||||
return _growthLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private FeedableBeasts()
|
||||
{
|
||||
super(FeedableBeasts.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(FEEDABLE_BEASTS);
|
||||
addSkillSeeId(FEEDABLE_BEASTS);
|
||||
|
||||
// TODO: no grendels?
|
||||
GrowthCapableMob temp;
|
||||
|
||||
//@formatter:off
|
||||
final int[][] Kookabura_0_Gold = {{ 21452, 21453, 21454, 21455 }};
|
||||
final int[][] Kookabura_0_Crystal = {{ 21456, 21457, 21458, 21459 }};
|
||||
final int[][] Kookabura_1_Gold_1= {{ 21460, 21462 }};
|
||||
final int[][] Kookabura_1_Gold_2 = {{ 21461, 21463 }};
|
||||
final int[][] Kookabura_1_Crystal_1 = {{ 21464, 21466 }};
|
||||
final int[][] Kookabura_1_Crystal_2 = {{ 21465, 21467 }};
|
||||
final int[][] Kookabura_2_1 = {{ 21468, 21824}, { 16017, 16018 }};
|
||||
final int[][] Kookabura_2_2 = {{ 21469, 21825}, { 16017, 16018 }};
|
||||
|
||||
final int[][] Buffalo_0_Gold = {{ 21471, 21472, 21473, 21474 }};
|
||||
final int[][] Buffalo_0_Crystal = {{ 21475, 21476, 21477, 21478 }};
|
||||
final int[][] Buffalo_1_Gold_1 = {{ 21479, 21481 }};
|
||||
final int[][] Buffalo_1_Gold_2 = {{ 21481, 21482 }};
|
||||
final int[][] Buffalo_1_Crystal_1 = {{ 21483, 21485 }};
|
||||
final int[][] Buffalo_1_Crystal_2 = {{ 21484, 21486 }};
|
||||
final int[][] Buffalo_2_1 = {{ 21487,21826}, {16013, 16014 }};
|
||||
final int[][] Buffalo_2_2 = {{ 21488,21827}, {16013, 16014 }};
|
||||
|
||||
final int[][] Cougar_0_Gold = {{ 21490, 21491, 21492, 21493 }};
|
||||
final int[][] Cougar_0_Crystal = {{ 21494,21495, 21496, 21497 }};
|
||||
final int[][] Cougar_1_Gold_1 = {{ 21498, 21500 }};
|
||||
final int[][] Cougar_1_Gold_2 = {{ 21499, 21501 }};
|
||||
final int[][] Cougar_1_Crystal_1 = {{ 21502,21504 }};
|
||||
final int[][] Cougar_1_Crystal_2 = {{ 21503,21505 }};
|
||||
final int[][] Cougar_2_1 = {{ 21506, 21828 }, { 16015,16016 }};
|
||||
final int[][] Cougar_2_2 = {{ 21507, 21829 }, { 16015,16016 }};
|
||||
//@formatter:on
|
||||
|
||||
// Alpen Kookabura
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_0_Crystal);
|
||||
_GrowthCapableMobs.put(21451, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_1);
|
||||
_GrowthCapableMobs.put(21452, temp);
|
||||
_GrowthCapableMobs.put(21454, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_2);
|
||||
_GrowthCapableMobs.put(21453, temp);
|
||||
_GrowthCapableMobs.put(21455, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_1);
|
||||
_GrowthCapableMobs.put(21456, temp);
|
||||
_GrowthCapableMobs.put(21458, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_2);
|
||||
_GrowthCapableMobs.put(21457, temp);
|
||||
_GrowthCapableMobs.put(21459, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_1);
|
||||
_GrowthCapableMobs.put(21460, temp);
|
||||
_GrowthCapableMobs.put(21462, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_2);
|
||||
_GrowthCapableMobs.put(21461, temp);
|
||||
_GrowthCapableMobs.put(21463, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_1);
|
||||
_GrowthCapableMobs.put(21464, temp);
|
||||
_GrowthCapableMobs.put(21466, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_2);
|
||||
_GrowthCapableMobs.put(21465, temp);
|
||||
_GrowthCapableMobs.put(21467, temp);
|
||||
|
||||
// Alpen Buffalo
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_0_Crystal);
|
||||
_GrowthCapableMobs.put(21470, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_1);
|
||||
_GrowthCapableMobs.put(21471, temp);
|
||||
_GrowthCapableMobs.put(21473, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_2);
|
||||
_GrowthCapableMobs.put(21472, temp);
|
||||
_GrowthCapableMobs.put(21474, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_1);
|
||||
_GrowthCapableMobs.put(21475, temp);
|
||||
_GrowthCapableMobs.put(21477, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_2);
|
||||
_GrowthCapableMobs.put(21476, temp);
|
||||
_GrowthCapableMobs.put(21478, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_1);
|
||||
_GrowthCapableMobs.put(21479, temp);
|
||||
_GrowthCapableMobs.put(21481, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_2);
|
||||
_GrowthCapableMobs.put(21480, temp);
|
||||
_GrowthCapableMobs.put(21482, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_1);
|
||||
_GrowthCapableMobs.put(21483, temp);
|
||||
_GrowthCapableMobs.put(21485, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_2);
|
||||
_GrowthCapableMobs.put(21484, temp);
|
||||
_GrowthCapableMobs.put(21486, temp);
|
||||
|
||||
// Alpen Cougar
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_0_Crystal);
|
||||
_GrowthCapableMobs.put(21489, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_1);
|
||||
_GrowthCapableMobs.put(21490, temp);
|
||||
_GrowthCapableMobs.put(21492, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_2);
|
||||
_GrowthCapableMobs.put(21491, temp);
|
||||
_GrowthCapableMobs.put(21493, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_1);
|
||||
_GrowthCapableMobs.put(21494, temp);
|
||||
_GrowthCapableMobs.put(21496, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_2);
|
||||
_GrowthCapableMobs.put(21495, temp);
|
||||
_GrowthCapableMobs.put(21497, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_1);
|
||||
_GrowthCapableMobs.put(21498, temp);
|
||||
_GrowthCapableMobs.put(21500, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_2);
|
||||
_GrowthCapableMobs.put(21499, temp);
|
||||
_GrowthCapableMobs.put(21501, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_1);
|
||||
_GrowthCapableMobs.put(21502, temp);
|
||||
_GrowthCapableMobs.put(21504, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_2);
|
||||
_GrowthCapableMobs.put(21503, temp);
|
||||
_GrowthCapableMobs.put(21505, temp);
|
||||
}
|
||||
|
||||
private void spawnNext(L2Npc npc, int growthLevel, L2PcInstance player, int food)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int nextNpcId = 0;
|
||||
|
||||
// find the next mob to spawn, based on the current npcId, growthlevel, and food.
|
||||
if (growthLevel == 2)
|
||||
{
|
||||
// if tamed, the mob that will spawn depends on the class type (fighter/mage) of the player!
|
||||
if (getRandom(2) == 0)
|
||||
{
|
||||
if (player.getClassId().isMage())
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not tamed, there is a small chance that have "mad cow" disease.
|
||||
// that is a stronger-than-normal animal that attacks its feeder
|
||||
if (getRandom(5) == 0)
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// all other levels of growth are straight-forward
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getRandomMob(food);
|
||||
}
|
||||
|
||||
// remove the feedinfo of the mob that got despawned, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
}
|
||||
// despawn the old mob
|
||||
// TODO: same code? FIXED?
|
||||
// @formatter:off
|
||||
/*
|
||||
* if (_GrowthCapableMobs.get(npcId).getGrowthLevel() == 0)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
npc.deleteMe();
|
||||
// }
|
||||
// @formatter:on
|
||||
|
||||
// if this is finally a trained mob, then despawn any other trained mobs that the
|
||||
// player might have and initialize the Tamed Beast.
|
||||
if (Util.contains(TAMED_BEASTS, nextNpcId))
|
||||
{
|
||||
if ((player.getTrainedBeasts() != null) && !player.getTrainedBeasts().isEmpty())
|
||||
{
|
||||
for (L2TamedBeastInstance oldTrained : player.getTrainedBeasts())
|
||||
{
|
||||
oldTrained.deleteMe();
|
||||
}
|
||||
}
|
||||
|
||||
L2NpcTemplate template = NpcData.getInstance().getTemplate(nextNpcId);
|
||||
L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(IdFactory.getInstance().getNextId(), template, player, food - FOODSKILLDIFF, npc.getX(), npc.getY(), npc.getZ());
|
||||
nextNpc.setRunning();
|
||||
Q00020_BringUpWithLove.checkJewelOfInnocence(player);
|
||||
|
||||
// also, perform a rare random chat
|
||||
if (getRandom(20) == 0)
|
||||
{
|
||||
NpcStringId message = NpcStringId.getNpcStringId(getRandom(2024, 2029));
|
||||
NpcSay packet = new NpcSay(nextNpc, 0, message);
|
||||
if (message.getParamCount() > 0) // player name, $s1
|
||||
{
|
||||
packet.addStringParameter(player.getName());
|
||||
}
|
||||
npc.broadcastPacket(packet);
|
||||
}
|
||||
// @formatter:off
|
||||
/*
|
||||
TODO: The tamed beast consumes one golden/crystal spice
|
||||
every 60 seconds with an initial delay of 60 seconds
|
||||
if (tamed beast exists and is alive)
|
||||
{
|
||||
if (player has 1+ golden/crystal spice)
|
||||
{
|
||||
take one golden/crystal spice;
|
||||
say random NpcString(getRandom(2029, 2038));
|
||||
}
|
||||
}
|
||||
*/
|
||||
// @formatter:on
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not trained, the newly spawned mob will automatically be aggro against its feeder
|
||||
// (what happened to "never bite the hand that feeds you" anyway?!)
|
||||
L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
|
||||
|
||||
if (MAD_COW_POLYMORPH.containsKey(nextNpcId))
|
||||
{
|
||||
this.startQuestTimer("polymorph Mad Cow", 10000, nextNpc, player);
|
||||
}
|
||||
|
||||
// register the player in the feedinfo for the mob that just spawned
|
||||
_FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
|
||||
nextNpc.setRunning();
|
||||
nextNpc.addDamageHate(player, 0, 99999);
|
||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("polymorph Mad Cow") && (npc != null) && (player != null))
|
||||
{
|
||||
if (MAD_COW_POLYMORPH.containsKey(npc.getId()))
|
||||
{
|
||||
// remove the feed info from the previous mob
|
||||
if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
// despawn the mad cow
|
||||
npc.deleteMe();
|
||||
// spawn the new mob
|
||||
L2Attackable nextNpc = (L2Attackable) addSpawn(MAD_COW_POLYMORPH.get(npc.getId()), npc);
|
||||
|
||||
// register the player in the feedinfo for the mob that just spawned
|
||||
_FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
|
||||
nextNpc.setRunning();
|
||||
nextNpc.addDamageHate(player, 0, 99999);
|
||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
// this behavior is only run when the target of skill is the passed npc (chest)
|
||||
// i.e. when the player is attempting to open the chest using a skill
|
||||
if (!Util.contains(targets, npc))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
// gather some values on local variables
|
||||
int npcId = npc.getId();
|
||||
int skillId = skill.getId();
|
||||
// check if the npc and skills used are valid for this script. Exit if invalid.
|
||||
if ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// first gather some values on local variables
|
||||
int objectId = npc.getObjectId();
|
||||
int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
growthLevel = _GrowthCapableMobs.get(npcId).getGrowthLevel();
|
||||
}
|
||||
|
||||
// prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
|
||||
// If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
|
||||
if ((growthLevel == 0) && _FeedInfo.containsKey(objectId))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
_FeedInfo.put(objectId, caster.getObjectId());
|
||||
|
||||
int food = 0;
|
||||
if (skillId == SKILL_GOLDEN_SPICE)
|
||||
{
|
||||
food = GOLDEN_SPICE;
|
||||
}
|
||||
else if (skillId == SKILL_CRYSTAL_SPICE)
|
||||
{
|
||||
food = CRYSTAL_SPICE;
|
||||
}
|
||||
|
||||
// display the social action of the beast eating the food.
|
||||
npc.broadcastSocialAction(2);
|
||||
|
||||
// if this pet can't grow, it's all done.
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
||||
if (_GrowthCapableMobs.get(npcId).getMob(food, 0, 0) == null)
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// rare random talk...
|
||||
if (getRandom(20) == 0)
|
||||
{
|
||||
NpcStringId message = TEXT[growthLevel][getRandom(TEXT[growthLevel].length)];
|
||||
NpcSay packet = new NpcSay(npc, 0, message);
|
||||
if (message.getParamCount() > 0) // player name, $s1
|
||||
{
|
||||
packet.addStringParameter(caster.getName());
|
||||
}
|
||||
npc.broadcastPacket(packet);
|
||||
}
|
||||
|
||||
if ((growthLevel > 0) && (_FeedInfo.get(objectId) != caster.getObjectId()))
|
||||
{
|
||||
// check if this is the same player as the one who raised it from growth 0.
|
||||
// if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// Polymorph the mob, with a certain chance, given its current growth level
|
||||
if (getRandom(100) < _GrowthCapableMobs.get(npcId).getChance())
|
||||
{
|
||||
spawnNext(npc, growthLevel, caster, food);
|
||||
}
|
||||
}
|
||||
else if (Util.contains(TAMED_BEASTS, npcId) && (npc instanceof L2TamedBeastInstance))
|
||||
{
|
||||
L2TamedBeastInstance beast = ((L2TamedBeastInstance) npc);
|
||||
if (skillId == beast.getFoodType())
|
||||
{
|
||||
beast.onReceiveFood();
|
||||
NpcStringId message = TAMED_TEXT[getRandom(TAMED_TEXT.length)];
|
||||
NpcSay packet = new NpcSay(npc, 0, message);
|
||||
if (message.getParamCount() > 0)
|
||||
{
|
||||
packet.addStringParameter(caster.getName());
|
||||
}
|
||||
beast.broadcastPacket(packet);
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// remove the feedinfo of the mob that got killed, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FeedableBeasts();
|
||||
}
|
||||
}
|
94
trunk/dist/game/data/scripts/ai/group_template/FleeMonsters.java
vendored
Normal file
94
trunk/dist/game/data/scripts/ai/group_template/FleeMonsters.java
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Flee Monsters AI.
|
||||
* @author Pandragon, NosBit
|
||||
*/
|
||||
public final class FleeMonsters extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
18150, // Victim
|
||||
18151, // Victim
|
||||
18152, // Victim
|
||||
18153, // Victim
|
||||
18154, // Victim
|
||||
18155, // Victim
|
||||
18156, // Victim
|
||||
18157, // Victim
|
||||
20002, // Rabbit
|
||||
20432, // Elpy
|
||||
22228, // Grey Elpy
|
||||
25604, // Mutated Elpy
|
||||
};
|
||||
// Misc
|
||||
private static final int FLEE_DISTANCE = 500;
|
||||
|
||||
private FleeMonsters()
|
||||
{
|
||||
super(FleeMonsters.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setRunning();
|
||||
|
||||
final L2Summon summon = isSummon ? attacker.getSummon() : null;
|
||||
final ILocational attackerLoc = summon == null ? attacker : summon;
|
||||
final double radians = Math.toRadians(Util.calculateAngleFrom(attackerLoc, npc));
|
||||
final int posX = (int) (npc.getX() + (FLEE_DISTANCE * Math.cos(radians)));
|
||||
final int posY = (int) (npc.getY() + (FLEE_DISTANCE * Math.sin(radians)));
|
||||
final int posZ = npc.getZ();
|
||||
|
||||
final Location destination;
|
||||
if (Config.GEODATA > 0)
|
||||
{
|
||||
destination = GeoData.getInstance().moveCheck(npc.getX(), npc.getY(), npc.getZ(), posX, posY, posZ, attacker.getInstanceId());
|
||||
}
|
||||
else
|
||||
{
|
||||
destination = new Location(posX, posY, posZ);
|
||||
}
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination);
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FleeMonsters();
|
||||
}
|
||||
}
|
71
trunk/dist/game/data/scripts/ai/group_template/FrozenLabyrinth.java
vendored
Normal file
71
trunk/dist/game/data/scripts/ai/group_template/FrozenLabyrinth.java
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Frozen Labyrinth AI.
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class FrozenLabyrinth extends AbstractNpcAI
|
||||
{
|
||||
// Monsters
|
||||
private static final int PRONGHORN_SPIRIT = 22087;
|
||||
private static final int PRONGHORN = 22088;
|
||||
private static final int LOST_BUFFALO = 22093;
|
||||
private static final int FROST_BUFFALO = 22094;
|
||||
|
||||
private FrozenLabyrinth()
|
||||
{
|
||||
super(FrozenLabyrinth.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(PRONGHORN, FROST_BUFFALO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if (npc.isScriptValue(0) && (skill != null) && !skill.isMagic())
|
||||
{
|
||||
final int spawnId = (npc.getId() == PRONGHORN) ? PRONGHORN_SPIRIT : LOST_BUFFALO;
|
||||
int diff = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
final int x = diff < 60 ? npc.getX() + diff : npc.getX();
|
||||
final int y = diff >= 60 ? npc.getY() + (diff - 40) : npc.getY();
|
||||
|
||||
final L2Npc monster = addSpawn(spawnId, x, y, npc.getZ(), npc.getHeading(), false, 0);
|
||||
addAttackPlayerDesire(monster, attacker);
|
||||
diff += 20;
|
||||
}
|
||||
npc.setScriptValue(1);
|
||||
npc.deleteMe();
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FrozenLabyrinth();
|
||||
}
|
||||
}
|
114
trunk/dist/game/data/scripts/ai/group_template/GiantsCave.java
vendored
Normal file
114
trunk/dist/game/data/scripts/ai/group_template/GiantsCave.java
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Giant's Cave AI.
|
||||
* @author Gnacik, St3eT
|
||||
*/
|
||||
public final class GiantsCave extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int[] SCOUTS =
|
||||
{
|
||||
22668, // Gamlin (Scout)
|
||||
22669, // Leogul (Scout)
|
||||
};
|
||||
|
||||
private GiantsCave()
|
||||
{
|
||||
super(GiantsCave.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(SCOUTS);
|
||||
addAggroRangeEnterId(SCOUTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("ATTACK") && (player != null) && (npc != null) && !npc.isDead())
|
||||
{
|
||||
if (npc.getId() == SCOUTS[0]) // Gamlin
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.INTRUDER_DETECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.OH_GIANTS_AN_INTRUDER_HAS_BEEN_DISCOVERED);
|
||||
}
|
||||
|
||||
for (L2Character characters : npc.getKnownList().getKnownCharactersInRadius(450))
|
||||
{
|
||||
if ((characters != null) && (characters.isAttackable()) && (getRandomBoolean()))
|
||||
{
|
||||
addAttackPlayerDesire((L2Npc) characters, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equals("CLEAR") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("ATTACK", 6000, npc, attacker);
|
||||
startQuestTimer("CLEAR", 120000, npc, null);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
if (getRandomBoolean())
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_GUYS_ARE_DETECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.WHAT_KIND_OF_CREATURES_ARE_YOU);
|
||||
}
|
||||
startQuestTimer("ATTACK", 6000, npc, player);
|
||||
startQuestTimer("CLEAR", 120000, npc, null);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new GiantsCave();
|
||||
}
|
||||
}
|
109
trunk/dist/game/data/scripts/ai/group_template/HotSprings.java
vendored
Normal file
109
trunk/dist/game/data/scripts/ai/group_template/HotSprings.java
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Hot Springs AI.
|
||||
* @author Pandragon
|
||||
*/
|
||||
public final class HotSprings extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int BANDERSNATCHLING = 21314;
|
||||
private static final int FLAVA = 21316;
|
||||
private static final int ATROXSPAWN = 21317;
|
||||
private static final int NEPENTHES = 21319;
|
||||
private static final int ATROX = 21321;
|
||||
private static final int BANDERSNATCH = 21322;
|
||||
// Skills
|
||||
private static final int RHEUMATISM = 4551;
|
||||
private static final int CHOLERA = 4552;
|
||||
private static final int FLU = 4553;
|
||||
private static final int MALARIA = 4554;
|
||||
// Misc
|
||||
private static final int DISEASE_CHANCE = 10;
|
||||
|
||||
private HotSprings()
|
||||
{
|
||||
super(HotSprings.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(BANDERSNATCHLING, FLAVA, ATROXSPAWN, NEPENTHES, ATROX, BANDERSNATCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (getRandom(100) < DISEASE_CHANCE)
|
||||
{
|
||||
tryToInfect(npc, attacker, MALARIA);
|
||||
}
|
||||
|
||||
if (getRandom(100) < DISEASE_CHANCE)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case BANDERSNATCHLING:
|
||||
case ATROX:
|
||||
{
|
||||
tryToInfect(npc, attacker, RHEUMATISM);
|
||||
break;
|
||||
}
|
||||
case FLAVA:
|
||||
case NEPENTHES:
|
||||
{
|
||||
tryToInfect(npc, attacker, CHOLERA);
|
||||
break;
|
||||
}
|
||||
case ATROXSPAWN:
|
||||
case BANDERSNATCH:
|
||||
{
|
||||
tryToInfect(npc, attacker, FLU);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
private void tryToInfect(L2Npc npc, L2Character player, int diseaseId)
|
||||
{
|
||||
final BuffInfo info = player.getEffectList().getBuffInfoBySkillId(diseaseId);
|
||||
final int skillLevel = (info == null) ? 1 : (info.getSkill().getLevel() < 10) ? info.getSkill().getLevel() + 1 : 10;
|
||||
final Skill skill = SkillData.getInstance().getSkill(diseaseId, skillLevel);
|
||||
|
||||
if ((skill != null) && !npc.isCastingNow() && npc.checkDoCastConditions(skill))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skill);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new HotSprings();
|
||||
}
|
||||
}
|
83
trunk/dist/game/data/scripts/ai/group_template/IsleOfPrayer.java
vendored
Normal file
83
trunk/dist/game/data/scripts/ai/group_template/IsleOfPrayer.java
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.ItemChanceHolder;
|
||||
|
||||
/**
|
||||
* Isle of Prayer AI.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class IsleOfPrayer extends AbstractNpcAI
|
||||
{
|
||||
// Items
|
||||
private static final int YELLOW_SEED_OF_EVIL_SHARD = 9593;
|
||||
private static final int GREEN_SEED_OF_EVIL_SHARD = 9594;
|
||||
private static final int BLUE_SEED_OF_EVIL_SHARD = 9595;
|
||||
private static final int RED_SEED_OF_EVIL_SHARD = 9596;
|
||||
// Monsters
|
||||
private static final Map<Integer, ItemChanceHolder> MONSTERS = new HashMap<>();
|
||||
static
|
||||
{
|
||||
MONSTERS.put(22257, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2087)); // Island Guardian
|
||||
MONSTERS.put(22258, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2147)); // White Sand Mirage
|
||||
MONSTERS.put(22259, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2642)); // Muddy Coral
|
||||
MONSTERS.put(22260, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2292)); // Kleopora
|
||||
MONSTERS.put(22261, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1171)); // Seychelles
|
||||
MONSTERS.put(22262, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1173)); // Naiad
|
||||
MONSTERS.put(22263, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1403)); // Sonneratia
|
||||
MONSTERS.put(22264, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1207)); // Castalia
|
||||
MONSTERS.put(22265, new ItemChanceHolder(RED_SEED_OF_EVIL_SHARD, 575)); // Chrysocolla
|
||||
MONSTERS.put(22266, new ItemChanceHolder(RED_SEED_OF_EVIL_SHARD, 493)); // Pythia
|
||||
MONSTERS.put(22267, new ItemChanceHolder(RED_SEED_OF_EVIL_SHARD, 770)); // Dark Water Dragon
|
||||
MONSTERS.put(22268, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 987)); // Shade
|
||||
MONSTERS.put(22269, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 995)); // Shade
|
||||
MONSTERS.put(22270, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 1008)); // Water Dragon Detractor
|
||||
MONSTERS.put(22271, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 1008)); // Water Dragon Detractor
|
||||
}
|
||||
|
||||
private IsleOfPrayer()
|
||||
{
|
||||
super(IsleOfPrayer.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(MONSTERS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final ItemChanceHolder holder = MONSTERS.get(npc.getId());
|
||||
if (getRandom(10000) <= holder.getChance())
|
||||
{
|
||||
npc.dropItem(killer, holder);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new IsleOfPrayer();
|
||||
}
|
||||
}
|
144
trunk/dist/game/data/scripts/ai/group_template/LairOfAntharas.java
vendored
Normal file
144
trunk/dist/game/data/scripts/ai/group_template/LairOfAntharas.java
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ValidateLocation;
|
||||
|
||||
/**
|
||||
* Lair of Antharas AI.
|
||||
* @author St3eT, UnAfraid
|
||||
*/
|
||||
public final class LairOfAntharas extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
final private static int KNORIKS = 22857;
|
||||
final private static int DRAGON_KNIGHT = 22844;
|
||||
final private static int DRAGON_KNIGHT2 = 22845;
|
||||
final private static int ELITE_DRAGON_KNIGHT = 22846;
|
||||
|
||||
final private static int DRAGON_GUARD = 22852;
|
||||
final private static int DRAGON_MAGE = 22853;
|
||||
// Misc
|
||||
final private static int KNIGHT_CHANCE = 30;
|
||||
final private static int KNORIKS_CHANCE = 60;
|
||||
final private static int KNORIKS_CHANCE2 = 50;
|
||||
|
||||
private LairOfAntharas()
|
||||
{
|
||||
super(LairOfAntharas.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(DRAGON_KNIGHT, DRAGON_KNIGHT2, DRAGON_GUARD, DRAGON_MAGE);
|
||||
addSpawnId(DRAGON_KNIGHT, DRAGON_KNIGHT2, DRAGON_GUARD, DRAGON_MAGE);
|
||||
addMoveFinishedId(DRAGON_GUARD, DRAGON_MAGE);
|
||||
addAggroRangeEnterId(KNORIKS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("CHECK_HOME") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
if ((npc.calculateDistance(npc.getSpawn().getLocation(), false, false) > 10) && !npc.isInCombat())
|
||||
{
|
||||
((L2Attackable) npc).returnHome();
|
||||
}
|
||||
else if ((npc.getHeading() != npc.getSpawn().getHeading()) && !npc.isInCombat())
|
||||
{
|
||||
npc.setHeading(npc.getSpawn().getHeading());
|
||||
npc.broadcastPacket(new ValidateLocation(npc));
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0) && (getRandom(100) < KNORIKS_CHANCE))
|
||||
{
|
||||
if (getRandom(100) < KNORIKS_CHANCE2)
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.WHO_S_THERE_IF_YOU_DISTURB_THE_TEMPER_OF_THE_GREAT_LAND_DRAGON_ANTHARAS_I_WILL_NEVER_FORGIVE_YOU);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case DRAGON_KNIGHT:
|
||||
{
|
||||
if (getRandom(100) > KNIGHT_CHANCE)
|
||||
{
|
||||
final L2Npc newKnight = addSpawn(DRAGON_KNIGHT2, npc, false, 0, true);
|
||||
npc.deleteMe();
|
||||
broadcastNpcSay(newKnight, Say2.NPC_SHOUT, NpcStringId.THOSE_WHO_SET_FOOT_IN_THIS_PLACE_SHALL_NOT_LEAVE_ALIVE);
|
||||
addAttackPlayerDesire(newKnight, killer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DRAGON_KNIGHT2:
|
||||
{
|
||||
if (getRandom(100) > KNIGHT_CHANCE)
|
||||
{
|
||||
final L2Npc eliteKnight = addSpawn(ELITE_DRAGON_KNIGHT, npc, false, 0, true);
|
||||
npc.deleteMe();
|
||||
broadcastNpcSay(eliteKnight, Say2.NPC_SHOUT, NpcStringId.IF_YOU_WISH_TO_SEE_HELL_I_WILL_GRANT_YOU_YOUR_WISH);
|
||||
addAttackPlayerDesire(eliteKnight, killer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DRAGON_GUARD:
|
||||
case DRAGON_MAGE:
|
||||
{
|
||||
cancelQuestTimer("CHECK_HOME", npc, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
mob.setOnKillDelay(0);
|
||||
if ((npc.getId() == DRAGON_GUARD) || (npc.getId() == DRAGON_MAGE))
|
||||
{
|
||||
mob.setIsNoRndWalk(true);
|
||||
startQuestTimer("CHECK_HOME", 10000, npc, null, true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new LairOfAntharas();
|
||||
}
|
||||
}
|
455
trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java
vendored
Normal file
455
trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java
vendored
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.MinionHolder;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Minion Spawn Manager.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class MinionSpawnManager extends AbstractNpcAI
|
||||
{
|
||||
private static final Set<Integer> NPC = new HashSet<>(354);
|
||||
|
||||
static
|
||||
{
|
||||
NPC.add(18344); // Ancient Egg
|
||||
NPC.add(18352); // Kamael Guard
|
||||
NPC.add(18353); // Guardian of Records
|
||||
NPC.add(18354); // Guardian of Observation
|
||||
NPC.add(18355); // Spicula's Guard
|
||||
NPC.add(18356); // Harkilgamed's Gatekeeper
|
||||
NPC.add(18357); // Rodenpicula's Gatekeeper
|
||||
NPC.add(18359); // Arviterre's Guardian
|
||||
NPC.add(18360); // Katenar's Gatekeeper
|
||||
NPC.add(18361); // Guardian of Prediction
|
||||
NPC.add(18484); // Naia Failan
|
||||
NPC.add(18491); // Lock
|
||||
NPC.add(18547); // Ancient Experiment
|
||||
NPC.add(18551); // Cruma Phantom
|
||||
NPC.add(35375); // Bloody Lord Nurka
|
||||
NPC.add(20376); // Varikan Brigand Leader
|
||||
NPC.add(20398); // Vrykolakas
|
||||
NPC.add(20520); // Pirate Captain Uthanka
|
||||
NPC.add(20522); // White Fang
|
||||
NPC.add(20738); // Kobold Looter Bepook
|
||||
NPC.add(20745); // Gigantiops
|
||||
NPC.add(20747); // Roxide
|
||||
NPC.add(20749); // Death Fire
|
||||
NPC.add(20751); // Snipe
|
||||
NPC.add(20753); // Dark Lord
|
||||
NPC.add(20755); // Talakin
|
||||
NPC.add(20758); // Dragon Bearer Chief
|
||||
NPC.add(20761); // Pytan
|
||||
NPC.add(20767); // Timak Orc Troop Leader
|
||||
NPC.add(20773); // Conjurer Bat Lord
|
||||
NPC.add(20939); // Tanor Silenos Warrior
|
||||
NPC.add(20941); // Tanor Silenos Chieftain
|
||||
NPC.add(20944); // Nightmare Lord
|
||||
NPC.add(20956); // Past Knight
|
||||
NPC.add(20959); // Dark Guard
|
||||
NPC.add(20963); // Bloody Lord
|
||||
NPC.add(20974); // Spiteful Soul Leader
|
||||
NPC.add(20977); // Elmoradan's Lady
|
||||
NPC.add(20980); // Hallate's Follower Mul
|
||||
NPC.add(20983); // Binder
|
||||
NPC.add(20986); // Sairon
|
||||
NPC.add(20991); // Swamp Tribe
|
||||
NPC.add(20994); // Garden Guard Leader
|
||||
NPC.add(21075); // Slaughter Bathin
|
||||
NPC.add(21078); // Magus Valac
|
||||
NPC.add(21081); // Power Angel Amon
|
||||
NPC.add(21090); // Bloody Guardian
|
||||
NPC.add(21312); // Eye of Ruler
|
||||
NPC.add(21343); // Ketra Commander
|
||||
NPC.add(21345); // Ketra's Head Shaman
|
||||
NPC.add(21347); // Ketra Prophet
|
||||
NPC.add(21369); // Varka's Commander
|
||||
NPC.add(21371); // Varka's Head Magus
|
||||
NPC.add(21373); // Varka's Prophet
|
||||
NPC.add(21432); // Chakram Beetle
|
||||
NPC.add(21434); // Seer of Blood
|
||||
NPC.add(21512); // Splinter Stakato Drone
|
||||
NPC.add(21517); // Needle Stakato Drone
|
||||
NPC.add(21541); // Pilgrim of Splendor
|
||||
NPC.add(21544); // Judge of Splendor
|
||||
NPC.add(21596); // Requiem Lord
|
||||
NPC.add(21599); // Requiem Priest
|
||||
NPC.add(21652); // Scarlet Stakato Noble
|
||||
NPC.add(21653); // Assassin Beetle
|
||||
NPC.add(21654); // Necromancer of Destruction
|
||||
NPC.add(21655); // Arimanes of Destruction
|
||||
NPC.add(21656); // Ashuras of Destruction
|
||||
NPC.add(21657); // Magma Drake
|
||||
NPC.add(22028); // Vagabond of the Ruins
|
||||
NPC.add(22080); // Massive Lost Bandersnatch
|
||||
NPC.add(22084); // Panthera
|
||||
NPC.add(22092); // Frost Iron Golem
|
||||
NPC.add(22096); // Ursus
|
||||
NPC.add(22100); // Freya's Gardener
|
||||
NPC.add(22102); // Freya's Servant
|
||||
NPC.add(22104); // Freya's Dog
|
||||
NPC.add(22155); // Triol's High Priest
|
||||
NPC.add(22159); // Triol's High Priest
|
||||
NPC.add(22163); // Triol's High Priest
|
||||
NPC.add(22167); // Triol's High Priest
|
||||
NPC.add(22171); // Triol's High Priest
|
||||
NPC.add(22188); // Andreas' Captain of the Royal Guard
|
||||
NPC.add(22196); // Velociraptor
|
||||
NPC.add(22198); // Velociraptor
|
||||
NPC.add(22202); // Ornithomimus
|
||||
NPC.add(22205); // Deinonychus
|
||||
NPC.add(22210); // Pachycephalosaurus
|
||||
NPC.add(22213); // Wild Strider
|
||||
NPC.add(22223); // Velociraptor
|
||||
NPC.add(22224); // Ornithomimus
|
||||
NPC.add(22225); // Deinonychus
|
||||
NPC.add(22275); // Gatekeeper Lohan
|
||||
NPC.add(22277); // Gatekeeper Provo
|
||||
NPC.add(22305); // Kechi's Captain
|
||||
NPC.add(22306); // Kechi's Captain
|
||||
NPC.add(22307); // Kechi's Captain
|
||||
NPC.add(22320); // Junior Watchman
|
||||
NPC.add(22321); // Junior Summoner
|
||||
NPC.add(22346); // Quarry Foreman
|
||||
NPC.add(22363); // Body Destroyer
|
||||
NPC.add(22370); // Passageway Captain
|
||||
NPC.add(22377); // Master Zelos
|
||||
NPC.add(22390); // Foundry Foreman
|
||||
NPC.add(22416); // Kechi's Captain
|
||||
NPC.add(22423); // Original Sin Warden
|
||||
NPC.add(22431); // Original Sin Warden
|
||||
NPC.add(22448); // Leodas
|
||||
NPC.add(22449); // Amaskari
|
||||
NPC.add(22621); // Male Spiked Stakato
|
||||
NPC.add(22625); // Cannibalistic Stakato Leader
|
||||
NPC.add(22630); // Spiked Stakato Nurse
|
||||
NPC.add(22666); // Barif
|
||||
NPC.add(22670); // Cursed Lord
|
||||
NPC.add(22742); // Ornithomimus
|
||||
NPC.add(22743); // Deinonychus
|
||||
NPC.add(25001); // Greyclaw Kutus
|
||||
NPC.add(25004); // Turek Mercenary Captain
|
||||
NPC.add(25007); // Retreat Spider Cletu
|
||||
NPC.add(25010); // Furious Thieles
|
||||
NPC.add(25013); // Ghost of Peasant Leader
|
||||
NPC.add(25016); // The 3rd Underwater Guardian
|
||||
NPC.add(25020); // Breka Warlock Pastu
|
||||
NPC.add(25023); // Stakato Queen Zyrnna
|
||||
NPC.add(25026); // Ketra Commander Atis
|
||||
NPC.add(25029); // Atraiban
|
||||
NPC.add(25032); // Eva's Guardian Millenu
|
||||
NPC.add(25035); // Shilen's Messenger Cabrio
|
||||
NPC.add(25038); // Tirak
|
||||
NPC.add(25041); // Remmel
|
||||
NPC.add(25044); // Barion
|
||||
NPC.add(25047); // Karte
|
||||
NPC.add(25051); // Rahha
|
||||
NPC.add(25054); // Kernon
|
||||
NPC.add(25057); // Beacon of Blue Sky
|
||||
NPC.add(25060); // Unrequited Kael
|
||||
NPC.add(25064); // Wizard of Storm Teruk
|
||||
NPC.add(25067); // Captain of Red Flag Shaka
|
||||
NPC.add(25070); // Enchanted Forest Watcher Ruell
|
||||
NPC.add(25073); // Bloody Priest Rudelto
|
||||
NPC.add(25076); // Princess Molrang
|
||||
NPC.add(25079); // Cat's Eye Bandit
|
||||
NPC.add(25082); // Leader of Cat Gang
|
||||
NPC.add(25085); // Timak Orc Chief Ranger
|
||||
NPC.add(25089); // Soulless Wild Boar
|
||||
NPC.add(25092); // Korim
|
||||
NPC.add(25095); // Elf Renoa
|
||||
NPC.add(25099); // Rotting Tree Repiro
|
||||
NPC.add(25103); // Sorcerer Isirr
|
||||
NPC.add(25106); // Ghost of the Well Lidia
|
||||
NPC.add(25109); // Antharas Priest Cloe
|
||||
NPC.add(25112); // Beleth's Agent, Meana
|
||||
NPC.add(25115); // Icarus Sample 1
|
||||
NPC.add(25119); // Messenger of Fairy Queen Berun
|
||||
NPC.add(25122); // Refugee Applicant Leo
|
||||
NPC.add(25128); // Vuku Grand Seer Gharmash
|
||||
NPC.add(25131); // Carnage Lord Gato
|
||||
NPC.add(25134); // Leto Chief Talkin
|
||||
NPC.add(25137); // Beleth's Seer, Sephia
|
||||
NPC.add(25140); // Hekaton Prime
|
||||
NPC.add(25143); // Fire of Wrath Shuriel
|
||||
NPC.add(25146); // Serpent Demon Bifrons
|
||||
NPC.add(25149); // Zombie Lord Crowl
|
||||
NPC.add(25152); // Flame Lord Shadar
|
||||
NPC.add(25155); // Shaman King Selu
|
||||
NPC.add(25159); // Paniel the Unicorn
|
||||
NPC.add(25166); // Ikuntai
|
||||
NPC.add(25170); // Lizardmen Leader Hellion
|
||||
NPC.add(25173); // Tiger King Karuta
|
||||
NPC.add(25176); // Black Lily
|
||||
NPC.add(25179); // Guardian of the Statue of Giant Karum
|
||||
NPC.add(25182); // Demon Kuri
|
||||
NPC.add(25185); // Tasaba Patriarch Hellena
|
||||
NPC.add(25189); // Cronos's Servitor Mumu
|
||||
NPC.add(25192); // Earth Protector Panathen
|
||||
NPC.add(25199); // Water Dragon Seer Sheshark
|
||||
NPC.add(25202); // Krokian Padisha Sobekk
|
||||
NPC.add(25205); // Ocean Flame Ashakiel
|
||||
NPC.add(25208); // Water Couatle Ateka
|
||||
NPC.add(25211); // Sebek
|
||||
NPC.add(25214); // Fafurion's Page Sika
|
||||
NPC.add(25217); // Cursed Clara
|
||||
NPC.add(25220); // Death Lord Hallate
|
||||
NPC.add(25223); // Soul Collector Acheron
|
||||
NPC.add(25226); // Roaring Lord Kastor
|
||||
NPC.add(25230); // Timak Seer Ragoth
|
||||
NPC.add(25235); // Vanor Chief Kandra
|
||||
NPC.add(25238); // Abyss Brukunt
|
||||
NPC.add(25241); // Harit Hero Tamash
|
||||
NPC.add(25245); // Last Lesser Giant Glaki
|
||||
NPC.add(25249); // Menacing Palatanos
|
||||
NPC.add(25252); // Palibati Queen Themis
|
||||
NPC.add(25256); // Taik High Prefect Arak
|
||||
NPC.add(25260); // Iron Giant Totem
|
||||
NPC.add(25263); // Kernon's Faithful Servant Kelone
|
||||
NPC.add(25266); // Bloody Empress Decarbia
|
||||
NPC.add(25269); // Beast Lord Behemoth
|
||||
NPC.add(25273); // Carnamakos
|
||||
NPC.add(25277); // Lilith's Witch Marilion
|
||||
NPC.add(25283); // Lilith
|
||||
NPC.add(25286); // Anakim
|
||||
NPC.add(25290); // Daimon the White-Eyed
|
||||
NPC.add(25293); // Hesti Guardian Deity of the Hot Springs
|
||||
NPC.add(25296); // Icicle Emperor Bumbalump
|
||||
NPC.add(25299); // Ketra's Hero Hekaton
|
||||
NPC.add(25302); // Ketra's Commander Tayr
|
||||
NPC.add(25306); // Soul of Fire Nastron
|
||||
NPC.add(25309); // Varka's Hero Shadith
|
||||
NPC.add(25312); // Varka's Commander Mos
|
||||
NPC.add(25316); // Soul of Water Ashutar
|
||||
NPC.add(25319); // Ember
|
||||
NPC.add(25322); // Demon's Agent Falston
|
||||
NPC.add(25325); // Flame of Splendor Barakiel
|
||||
NPC.add(25328); // Eilhalder von Hellmann
|
||||
NPC.add(25352); // Giant Wasteland Basilisk
|
||||
NPC.add(25354); // Gargoyle Lord Sirocco
|
||||
NPC.add(25357); // Sukar Wererat Chief
|
||||
NPC.add(25360); // Tiger Hornet
|
||||
NPC.add(25362); // Tracker Leader Sharuk
|
||||
NPC.add(25366); // Kuroboros' Priest
|
||||
NPC.add(25369); // Soul Scavenger
|
||||
NPC.add(25373); // Malex Herald of Dagoniel
|
||||
NPC.add(25375); // Zombie Lord Ferkel
|
||||
NPC.add(25378); // Madness Beast
|
||||
NPC.add(25380); // Kaysha Herald of Icarus
|
||||
NPC.add(25383); // Revenant of Sir Calibus
|
||||
NPC.add(25385); // Evil Spirit Tempest
|
||||
NPC.add(25388); // Red Eye Captain Trakia
|
||||
NPC.add(25392); // Captain of Queen's Royal Guards
|
||||
NPC.add(25395); // Archon Suscepter
|
||||
NPC.add(25398); // Beleth's Eye
|
||||
NPC.add(25401); // Skyla
|
||||
NPC.add(25404); // Corsair Captain Kylon
|
||||
NPC.add(25407); // Lord Ishka
|
||||
NPC.add(25410); // Road Scavenger Leader
|
||||
NPC.add(25412); // Necrosentinel Royal Guard
|
||||
NPC.add(25415); // Nakondas
|
||||
NPC.add(25418); // Dread Avenger Kraven
|
||||
NPC.add(25420); // Orfen's Handmaiden
|
||||
NPC.add(25423); // Fairy Queen Timiniel
|
||||
NPC.add(25426); // Betrayer of Urutu Freki
|
||||
NPC.add(25429); // Mammon Collector Talos
|
||||
NPC.add(25431); // Flamestone Golem
|
||||
NPC.add(25434); // Bandit Leader Barda
|
||||
NPC.add(25438); // Thief Kelbar
|
||||
NPC.add(25441); // Evil Spirit Cyrion
|
||||
NPC.add(25444); // Enmity Ghost Ramdal
|
||||
NPC.add(25447); // Immortal Savior Mardil
|
||||
NPC.add(25450); // Cherub Galaxia
|
||||
NPC.add(25453); // Meanas Anor
|
||||
NPC.add(25456); // Mirror of Oblivion
|
||||
NPC.add(25460); // Deadman Ereve
|
||||
NPC.add(25463); // Harit Guardian Garangky
|
||||
NPC.add(25467); // Gorgolos
|
||||
NPC.add(25470); // Last Titan Utenus
|
||||
NPC.add(25473); // Grave Robber Kim
|
||||
NPC.add(25475); // Ghost Knight Kabed
|
||||
NPC.add(25478); // Shilen's Priest Hisilrome
|
||||
NPC.add(25481); // Magus Kenishee
|
||||
NPC.add(25484); // Zaken's Chief Mate Tillion
|
||||
NPC.add(25487); // Water Spirit Lian
|
||||
NPC.add(25490); // Gwindorr
|
||||
NPC.add(25493); // Eva's Spirit Niniel
|
||||
NPC.add(25496); // Fafurion's Envoy Pingolpin
|
||||
NPC.add(25498); // Fafurion's Henchman Istary
|
||||
NPC.add(25501); // Boss Akata
|
||||
NPC.add(25504); // Nellis' Vengeful Spirit
|
||||
NPC.add(25506); // Rayito the Looter
|
||||
NPC.add(25509); // Dark Shaman Varangka
|
||||
NPC.add(25514); // Queen Shyeed
|
||||
NPC.add(25524); // Flamestone Giant
|
||||
NPC.add(25528); // Tiberias
|
||||
NPC.add(25536); // Hannibal
|
||||
NPC.add(25546); // Rhianna the Traitor
|
||||
NPC.add(25549); // Tesla the Deceiver
|
||||
NPC.add(25554); // Brutus the Obstinate
|
||||
NPC.add(25557); // Ranger Karankawa
|
||||
NPC.add(25560); // Sargon the Mad
|
||||
NPC.add(25563); // Beautiful Atrielle
|
||||
NPC.add(25566); // Nagen the Tomboy
|
||||
NPC.add(25569); // Jax the Destroyer
|
||||
NPC.add(25572); // Hager the Outlaw
|
||||
NPC.add(25575); // All-Seeing Rango
|
||||
NPC.add(25579); // Helsing
|
||||
NPC.add(25582); // Gillien
|
||||
NPC.add(25585); // Medici
|
||||
NPC.add(25589); // Brand the Exile
|
||||
NPC.add(25593); // Gerg the Hunter
|
||||
NPC.add(25600); // Temenir
|
||||
NPC.add(25601); // Draksius
|
||||
NPC.add(25602); // Kiretcenah
|
||||
NPC.add(25671); // Queen Shyeed
|
||||
NPC.add(25674); // Gwindorr
|
||||
NPC.add(25677); // Water Spirit Lian
|
||||
NPC.add(25681); // Gorgolos
|
||||
NPC.add(25684); // Last Titan Utenus
|
||||
NPC.add(25687); // Hekaton Prime
|
||||
NPC.add(25703); // Gigantic Golem
|
||||
NPC.add(25710); // Lost Captain
|
||||
NPC.add(25735); // Greyclaw Kutus
|
||||
NPC.add(25738); // Lead Tracker Sharuk
|
||||
NPC.add(25741); // Sukar Wererat Chief
|
||||
NPC.add(25744); // Ikuntai
|
||||
NPC.add(25747); // Zombie Lord Crowl
|
||||
NPC.add(25750); // Zombie Lord Ferkel
|
||||
NPC.add(25754); // Fire Lord Shadar
|
||||
NPC.add(25757); // Soul Collector Acheron
|
||||
NPC.add(25760); // Lord Ishka
|
||||
NPC.add(25763); // Demon Kuri
|
||||
NPC.add(25767); // Carnage Lord Gato
|
||||
NPC.add(25770); // Ketra Commander Atis
|
||||
NPC.add(25773); // Beacon of Blue Sky
|
||||
NPC.add(25776); // Earth Protector Panathen
|
||||
NPC.add(25779); // Betrayer of Urutu Freki
|
||||
NPC.add(25782); // Nellis' Vengeful Spirit
|
||||
NPC.add(25784); // Rayito the Looter
|
||||
NPC.add(25787); // Ketra's Hero Hekaton
|
||||
NPC.add(25790); // Varka's Hero Shadith
|
||||
NPC.add(25794); // Kernon
|
||||
NPC.add(25797); // Meanas Anor
|
||||
NPC.add(25800); // Mammon Collector Talos
|
||||
NPC.add(27036); // Calpico
|
||||
NPC.add(27041); // Varangka's Messenger
|
||||
NPC.add(27062); // Tanukia
|
||||
NPC.add(27065); // Roko
|
||||
NPC.add(27068); // Murtika
|
||||
NPC.add(27093); // Delu Chief Kalkis
|
||||
NPC.add(27108); // Stenoa Gorgon Queen
|
||||
NPC.add(27110); // Shyslassys
|
||||
NPC.add(27112); // Gorr
|
||||
NPC.add(27113); // Baraham
|
||||
NPC.add(27114); // Succubus Queen
|
||||
NPC.add(27185); // Fairy Tree of Wind
|
||||
NPC.add(27186); // Fairy Tree of Star
|
||||
NPC.add(27187); // Fairy Tree of Twilight
|
||||
NPC.add(27188); // Fairy Tree of Abyss
|
||||
NPC.add(27259); // Archangel Iconoclasis
|
||||
NPC.add(27260); // Archangel Iconoclasis
|
||||
NPC.add(27266); // Fallen Angel Haures
|
||||
NPC.add(27267); // Fallen Angel Haures
|
||||
NPC.add(27290); // White Wing Commander
|
||||
NPC.add(29030); // Fenril Hound Kerinne
|
||||
NPC.add(29033); // Fenril Hound Freki
|
||||
NPC.add(29037); // Fenril Hound Kinaz
|
||||
NPC.add(29040); // Wings of Flame, Ixion
|
||||
NPC.add(29056); // Ice Fairy Sirra
|
||||
NPC.add(29062); // Andreas Van Halter
|
||||
NPC.add(29096); // Anais
|
||||
NPC.add(29129); // Lost Captain
|
||||
NPC.add(29132); // Lost Captain
|
||||
NPC.add(29135); // Lost Captain
|
||||
NPC.add(29138); // Lost Captain
|
||||
NPC.add(29141); // Lost Captain
|
||||
NPC.add(29144); // Lost Captain
|
||||
NPC.add(29147); // Lost Captain
|
||||
}
|
||||
|
||||
private static final NpcStringId[] ON_ATTACK_MSG =
|
||||
{
|
||||
NpcStringId.COME_OUT_YOU_CHILDREN_OF_DARKNESS,
|
||||
NpcStringId.SHOW_YOURSELVES,
|
||||
NpcStringId.DESTROY_THE_ENEMY_MY_BROTHERS,
|
||||
NpcStringId.FORCES_OF_DARKNESS_FOLLOW_ME
|
||||
};
|
||||
|
||||
private static final int[] ON_ATTACK_NPC =
|
||||
{
|
||||
20767, // Timak Orc Troop Leader
|
||||
};
|
||||
|
||||
private MinionSpawnManager()
|
||||
{
|
||||
super(MinionSpawnManager.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
addSpawnId(NPC);
|
||||
addAttackId(ON_ATTACK_NPC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getTemplate().getParameters().getSet().get("SummonPrivateRate") == null)
|
||||
{
|
||||
((L2MonsterInstance) npc).getMinionList().spawnMinions(npc.getTemplate().getParameters().getMinionList("Privates"));
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isMonster())
|
||||
{
|
||||
final L2MonsterInstance monster = (L2MonsterInstance) npc;
|
||||
if (!monster.isTeleporting())
|
||||
{
|
||||
if (getRandom(1, 100) <= npc.getTemplate().getParameters().getInt("SummonPrivateRate", 0))
|
||||
{
|
||||
for (MinionHolder is : npc.getTemplate().getParameters().getMinionList("Privates"))
|
||||
{
|
||||
addMinion((L2MonsterInstance) npc, is.getId());
|
||||
}
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, ON_ATTACK_MSG[getRandom(ON_ATTACK_MSG.length)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new MinionSpawnManager();
|
||||
}
|
||||
}
|
296
trunk/dist/game/data/scripts/ai/group_template/MonasteryOfSilence.java
vendored
Normal file
296
trunk/dist/game/data/scripts/ai/group_template/MonasteryOfSilence.java
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
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.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Monastery of Silence AI.
|
||||
* @author Kerberos, nonom
|
||||
*/
|
||||
public final class MonasteryOfSilence extends AbstractNpcAI
|
||||
{
|
||||
// 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,
|
||||
NpcStringId.WE_ARE_THE_SWORD_OF_TRUTH_THE_SWORD_OF_SOLINA,
|
||||
NpcStringId.WE_RAISE_OUR_BLADES_FOR_THE_GLORY_OF_SOLINA
|
||||
};
|
||||
|
||||
private MonasteryOfSilence()
|
||||
{
|
||||
super(MonasteryOfSilence.class.getSimpleName(), "ai/group_template");
|
||||
addSkillSeeId(DIVINITY_CLAN);
|
||||
addAttackId(KNIGHT, CAPTAIN, GUIDE, SEEKER, ASCETIC);
|
||||
addNpcHateId(GUIDE, SEEKER, SAVIOR, ASCETIC);
|
||||
addAggroRangeEnterId(GUIDE, SEEKER, SAVIOR, ASCETIC);
|
||||
addSpawnId(SCARECROW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "TRAINING":
|
||||
{
|
||||
for (L2Character character : npc.getKnownList().getKnownCharactersInRadius(400))
|
||||
{
|
||||
if ((getRandom(100) < 30) && character.isNpc() && !character.isDead() && !character.isInCombat())
|
||||
{
|
||||
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)
|
||||
{
|
||||
character.setRunning();
|
||||
((L2Attackable) character).addDamageHate(npc, 0, 100);
|
||||
character.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "DO_CAST":
|
||||
{
|
||||
if ((npc != null) && (player != null) && (getRandom(100) < 3))
|
||||
{
|
||||
if (npc.checkDoCastConditions(STUDENT_CANCEL.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(STUDENT_CANCEL.getSkill());
|
||||
}
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TIMER":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
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);
|
||||
addAttackPlayerDesire(addSpawn(KNIGHT, npc), 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 boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return player.getActiveWeaponInstance() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (player.getActiveWeaponInstance() != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (skill.hasEffectType(L2EffectType.AGGRESSION) && (targets.length != 0))
|
||||
{
|
||||
for (L2Object obj : targets)
|
||||
{
|
||||
if (obj.equals(npc))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, DIVINITY_MSG[getRandom(DIVINITY_MSG.length)], caster.getName());
|
||||
addAttackPlayerDesire(npc, caster);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsInvul(true);
|
||||
npc.disableCoreAI(true);
|
||||
startQuestTimer("TRAINING", 30000, npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new MonasteryOfSilence();
|
||||
}
|
||||
}
|
52
trunk/dist/game/data/scripts/ai/group_template/NonLethalableNpcs.java
vendored
Normal file
52
trunk/dist/game/data/scripts/ai/group_template/NonLethalableNpcs.java
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class NonLethalableNpcs extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] NPCS =
|
||||
{
|
||||
35062, // Headquarters
|
||||
};
|
||||
|
||||
public NonLethalableNpcs()
|
||||
{
|
||||
super(NonLethalableNpcs.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(NPCS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setLethalable(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new NonLethalableNpcs();
|
||||
}
|
||||
}
|
62
trunk/dist/game/data/scripts/ai/group_template/PavelArchaic.java
vendored
Normal file
62
trunk/dist/game/data/scripts/ai/group_template/PavelArchaic.java
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Pavel Archaic AI.
|
||||
* @author Gnacik, St3eT
|
||||
*/
|
||||
public final class PavelArchaic extends AbstractNpcAI
|
||||
{
|
||||
private static final int SAFETY_DEVICE = 18917; // Pavel Safety Device
|
||||
private static final int PINCER_GOLEM = 22801; // Cruel Pincer Golem
|
||||
private static final int PINCER_GOLEM2 = 22802; // Cruel Pincer Golem
|
||||
private static final int PINCER_GOLEM3 = 22803; // Cruel Pincer Golem
|
||||
private static final int JACKHAMMER_GOLEM = 22804; // Horrifying Jackhammer Golem
|
||||
|
||||
private PavelArchaic()
|
||||
{
|
||||
super(PavelArchaic.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(SAFETY_DEVICE, PINCER_GOLEM, JACKHAMMER_GOLEM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (getRandom(100) < 70)
|
||||
{
|
||||
final L2Npc golem1 = addSpawn(PINCER_GOLEM2, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, false);
|
||||
addAttackPlayerDesire(golem1, killer);
|
||||
|
||||
final L2Npc golem2 = addSpawn(PINCER_GOLEM3, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, false);
|
||||
addAttackPlayerDesire(golem2, killer);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PavelArchaic();
|
||||
}
|
||||
}
|
99
trunk/dist/game/data/scripts/ai/group_template/PlainsOfDion.java
vendored
Normal file
99
trunk/dist/game/data/scripts/ai/group_template/PlainsOfDion.java
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* AI for mobs in Plains of Dion (near Floran Village).
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class PlainsOfDion extends AbstractNpcAI
|
||||
{
|
||||
private static final int DELU_LIZARDMEN[] =
|
||||
{
|
||||
21104, // Delu Lizardman Supplier
|
||||
21105, // Delu Lizardman Special Agent
|
||||
21107, // Delu Lizardman Commander
|
||||
};
|
||||
|
||||
private static final NpcStringId[] MONSTERS_MSG =
|
||||
{
|
||||
NpcStringId.S1_HOW_DARE_YOU_INTERRUPT_OUR_FIGHT_HEY_GUYS_HELP,
|
||||
NpcStringId.S1_HEY_WE_RE_HAVING_A_DUEL_HERE,
|
||||
NpcStringId.THE_DUEL_IS_OVER_ATTACK,
|
||||
NpcStringId.FOUL_KILL_THE_COWARD,
|
||||
NpcStringId.HOW_DARE_YOU_INTERRUPT_A_SACRED_DUEL_YOU_MUST_BE_TAUGHT_A_LESSON
|
||||
};
|
||||
|
||||
private static final NpcStringId[] MONSTERS_ASSIST_MSG =
|
||||
{
|
||||
NpcStringId.DIE_YOU_COWARD,
|
||||
NpcStringId.KILL_THE_COWARD,
|
||||
NpcStringId.WHAT_ARE_YOU_LOOKING_AT
|
||||
};
|
||||
|
||||
private PlainsOfDion()
|
||||
{
|
||||
super(PlainsOfDion.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(DELU_LIZARDMEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
final int i = getRandom(5);
|
||||
if (i < 2)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, MONSTERS_MSG[i], player.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, MONSTERS_MSG[i]);
|
||||
}
|
||||
|
||||
for (L2Character obj : npc.getKnownList().getKnownCharactersInRadius(npc.getTemplate().getClanHelpRange()))
|
||||
{
|
||||
if (obj.isMonster() && Util.contains(DELU_LIZARDMEN, obj.getId()) && !obj.isAttackingNow() && !obj.isDead() && GeoData.getInstance().canSeeTarget(npc, obj))
|
||||
{
|
||||
final L2Npc monster = (L2Npc) obj;
|
||||
addAttackPlayerDesire(monster, player);
|
||||
broadcastNpcSay(monster, Say2.NPC_ALL, MONSTERS_ASSIST_MSG[getRandom(3)]);
|
||||
}
|
||||
}
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PlainsOfDion();
|
||||
}
|
||||
}
|
244
trunk/dist/game/data/scripts/ai/group_template/PlainsOfLizardman.java
vendored
Normal file
244
trunk/dist/game/data/scripts/ai/group_template/PlainsOfLizardman.java
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
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.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
|
||||
/**
|
||||
* Plains of Lizardmen AI.
|
||||
* @author Gnacik, malyelfik
|
||||
*/
|
||||
public final class PlainsOfLizardman extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int INVISIBLE_NPC = 18919;
|
||||
private static final int TANTA_GUARD = 18862;
|
||||
private static final int FANTASY_MUSHROOM = 18864;
|
||||
private static final int STICKY_MUSHROOM = 18865;
|
||||
private static final int RAINBOW_FROG = 18866;
|
||||
private static final int ENERGY_PLANT = 18868;
|
||||
private static final int TANTA_SCOUT = 22768;
|
||||
private static final int TANTA_MAGICIAN = 22773;
|
||||
private static final int TANTA_SUMMONER = 22774;
|
||||
private static final int[] TANTA_LIZARDMEN =
|
||||
{
|
||||
22768, // Tanta Lizardman Scout
|
||||
22769, // Tanta Lizardman Warrior
|
||||
22770, // Tanta Lizardman Soldier
|
||||
22771, // Tanta Lizardman Berserker
|
||||
22772, // Tanta Lizardman Archer
|
||||
22773, // Tanta Lizardman Magician
|
||||
22774, // Tanta Lizardman Summoner
|
||||
};
|
||||
// Skills
|
||||
private static final SkillHolder STUN_EFFECT = new SkillHolder(6622, 1);
|
||||
private static final SkillHolder DEMOTIVATION_HEX = new SkillHolder(6425, 1);
|
||||
private static final SkillHolder FANTASY_MUSHROOM_SKILL = new SkillHolder(6427, 1);
|
||||
private static final SkillHolder RAINBOW_FROG_SKILL = new SkillHolder(6429, 1);
|
||||
private static final SkillHolder STICKY_MUSHROOM_SKILL = new SkillHolder(6428, 1);
|
||||
private static final SkillHolder ENERGY_PLANT_SKILL = new SkillHolder(6430, 1);
|
||||
// Buffs
|
||||
private static final SkillHolder[] BUFFS =
|
||||
{
|
||||
new SkillHolder(6625, 1), // Energy of Life
|
||||
new SkillHolder(6626, 2), // Energy of Life's Power
|
||||
new SkillHolder(6627, 3), // Energy of Life's Highest Power
|
||||
new SkillHolder(6628, 1), // Energy of Mana
|
||||
new SkillHolder(6629, 2), // Energy of Mana's Power
|
||||
new SkillHolder(6630, 3), // Energy of Mana's Highest Power
|
||||
new SkillHolder(6631, 1), // Energy of Power
|
||||
new SkillHolder(6633, 1), // Energy of Attack Speed
|
||||
new SkillHolder(6635, 1), // Energy of Crt Rate
|
||||
new SkillHolder(6636, 1), // Energy of Moving Speed
|
||||
new SkillHolder(6638, 1), // Aura of Mystery
|
||||
new SkillHolder(6639, 1), // Bane of Auras - Damage
|
||||
new SkillHolder(6640, 1), // Energizing Aura
|
||||
new SkillHolder(6674, 1), // Energy of Range Increment
|
||||
};
|
||||
// Misc
|
||||
// @formatter:off
|
||||
private static final int[] BUFF_LIST =
|
||||
{
|
||||
6, 7, 8, 11, 13
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
private PlainsOfLizardman()
|
||||
{
|
||||
super(PlainsOfLizardman.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(FANTASY_MUSHROOM, RAINBOW_FROG, STICKY_MUSHROOM, ENERGY_PLANT, TANTA_SUMMONER);
|
||||
addKillId(TANTA_LIZARDMEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("fantasy_mushroom") && (npc != null) && (player != null))
|
||||
{
|
||||
npc.doCast(FANTASY_MUSHROOM_SKILL.getSkill());
|
||||
for (L2Character target : npc.getKnownList().getKnownCharactersInRadius(200))
|
||||
{
|
||||
if ((target != null) && target.isAttackable())
|
||||
{
|
||||
final L2Npc monster = (L2Npc) target;
|
||||
npc.setTarget(monster);
|
||||
npc.doCast(STUN_EFFECT.getSkill());
|
||||
addAttackPlayerDesire(monster, player);
|
||||
}
|
||||
}
|
||||
npc.doDie(player);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case TANTA_SUMMONER:
|
||||
if (!npc.isAffectedBySkill(DEMOTIVATION_HEX.getSkillId()))
|
||||
{
|
||||
npc.doCast(DEMOTIVATION_HEX.getSkill());
|
||||
}
|
||||
break;
|
||||
case RAINBOW_FROG:
|
||||
castSkill(npc, attacker, RAINBOW_FROG_SKILL);
|
||||
break;
|
||||
case ENERGY_PLANT:
|
||||
castSkill(npc, attacker, ENERGY_PLANT_SKILL);
|
||||
break;
|
||||
case STICKY_MUSHROOM:
|
||||
castSkill(npc, attacker, STICKY_MUSHROOM_SKILL);
|
||||
break;
|
||||
case FANTASY_MUSHROOM:
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
npc.setIsInvul(true);
|
||||
for (L2Character target : npc.getKnownList().getKnownCharactersInRadius(1000))
|
||||
{
|
||||
if ((target != null) && target.isAttackable())
|
||||
{
|
||||
final L2Attackable monster = (L2Attackable) target;
|
||||
if ((monster.getId() == TANTA_MAGICIAN) || (monster.getId() == TANTA_SCOUT))
|
||||
{
|
||||
target.setIsRunning(true);
|
||||
target.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getX(), npc.getY(), npc.getZ(), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
startQuestTimer("fantasy_mushroom", 4000, npc, attacker);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// Tanta Guard
|
||||
if (getRandom(1000) == 0)
|
||||
{
|
||||
addAttackPlayerDesire(addSpawn(TANTA_GUARD, npc), killer);
|
||||
}
|
||||
|
||||
// Invisible buff npc
|
||||
final int random = getRandom(100);
|
||||
final L2Npc buffer = addSpawn(INVISIBLE_NPC, npc.getLocation(), false, 6000);
|
||||
buffer.setTarget(killer);
|
||||
|
||||
if (random <= 42)
|
||||
{
|
||||
castRandomBuff(buffer, 7, 45, BUFFS[0], BUFFS[1], BUFFS[2]);
|
||||
}
|
||||
if (random <= 11)
|
||||
{
|
||||
castRandomBuff(buffer, 8, 60, BUFFS[3], BUFFS[4], BUFFS[5]);
|
||||
castRandomBuff(buffer, 3, 6, BUFFS[9], BUFFS[10], BUFFS[12]);
|
||||
}
|
||||
if (random <= 25)
|
||||
{
|
||||
buffer.doCast(BUFFS[BUFF_LIST[getRandom(BUFF_LIST.length)]].getSkill());
|
||||
}
|
||||
if (random <= 10)
|
||||
{
|
||||
buffer.doCast(BUFFS[13].getSkill());
|
||||
}
|
||||
if (random <= 1)
|
||||
{
|
||||
final int i = getRandom(100);
|
||||
if (i <= 34)
|
||||
{
|
||||
buffer.doCast(BUFFS[6].getSkill());
|
||||
buffer.doCast(BUFFS[7].getSkill());
|
||||
buffer.doCast(BUFFS[8].getSkill());
|
||||
}
|
||||
else if (i < 67)
|
||||
{
|
||||
buffer.doCast(BUFFS[13].getSkill());
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.doCast(BUFFS[2].getSkill());
|
||||
buffer.doCast(BUFFS[5].getSkill());
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private void castRandomBuff(L2Npc npc, int chance1, int chance2, SkillHolder... buffs)
|
||||
{
|
||||
final int rand = getRandom(100);
|
||||
if (rand <= chance1)
|
||||
{
|
||||
npc.doCast(buffs[2].getSkill());
|
||||
}
|
||||
else if (rand <= chance2)
|
||||
{
|
||||
npc.doCast(buffs[1].getSkill());
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.doCast(buffs[0].getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void castSkill(L2Npc npc, L2Playable target, SkillHolder skill)
|
||||
{
|
||||
npc.doDie(target);
|
||||
super.castSkill(addSpawn(INVISIBLE_NPC, npc, false, 6000), target, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PlainsOfLizardman();
|
||||
}
|
||||
}
|
63
trunk/dist/game/data/scripts/ai/group_template/PolymorphingAngel.java
vendored
Normal file
63
trunk/dist/game/data/scripts/ai/group_template/PolymorphingAngel.java
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Angel spawns...when one of the angels in the keys dies, the other angel will spawn.
|
||||
*/
|
||||
public final class PolymorphingAngel extends AbstractNpcAI
|
||||
{
|
||||
private static final Map<Integer, Integer> ANGELSPAWNS = new FastMap<>();
|
||||
static
|
||||
{
|
||||
ANGELSPAWNS.put(20830, 20859);
|
||||
ANGELSPAWNS.put(21067, 21068);
|
||||
ANGELSPAWNS.put(21062, 21063);
|
||||
ANGELSPAWNS.put(20831, 20860);
|
||||
ANGELSPAWNS.put(21070, 21071);
|
||||
}
|
||||
|
||||
private PolymorphingAngel()
|
||||
{
|
||||
super(PolymorphingAngel.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(ANGELSPAWNS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final L2Attackable newNpc = (L2Attackable) addSpawn(ANGELSPAWNS.get(npc.getId()), npc);
|
||||
newNpc.setRunning();
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PolymorphingAngel();
|
||||
}
|
||||
}
|
120
trunk/dist/game/data/scripts/ai/group_template/PolymorphingOnAttack.java
vendored
Normal file
120
trunk/dist/game/data/scripts/ai/group_template/PolymorphingOnAttack.java
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
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.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
|
||||
|
||||
/**
|
||||
* Polymorphing on attack monsters AI.
|
||||
* @author Slyce
|
||||
*/
|
||||
public final class PolymorphingOnAttack extends AbstractNpcAI
|
||||
{
|
||||
private static final Map<Integer, List<Integer>> MOBSPAWNS = new HashMap<>();
|
||||
static
|
||||
{
|
||||
MOBSPAWNS.put(21258, Arrays.asList(21259, 100, 100, -1)); // Fallen Orc Shaman -> Sharp Talon Tiger (always polymorphs)
|
||||
MOBSPAWNS.put(21261, Arrays.asList(21262, 100, 20, 0)); // Ol Mahum Transcender 1st stage
|
||||
MOBSPAWNS.put(21262, Arrays.asList(21263, 100, 10, 1)); // Ol Mahum Transcender 2nd stage
|
||||
MOBSPAWNS.put(21263, Arrays.asList(21264, 100, 5, 2)); // Ol Mahum Transcender 3rd stage
|
||||
MOBSPAWNS.put(21265, Arrays.asList(21271, 100, 33, 0)); // Cave Ant Larva -> Cave Ant
|
||||
MOBSPAWNS.put(21266, Arrays.asList(21269, 100, 100, -1)); // Cave Ant Larva -> Cave Ant (always polymorphs)
|
||||
MOBSPAWNS.put(21267, Arrays.asList(21270, 100, 100, -1)); // Cave Ant Larva -> Cave Ant Soldier (always polymorphs)
|
||||
MOBSPAWNS.put(21271, Arrays.asList(21272, 66, 10, 1)); // Cave Ant -> Cave Ant Soldier
|
||||
MOBSPAWNS.put(21272, Arrays.asList(21273, 33, 5, 2)); // Cave Ant Soldier -> Cave Noble Ant
|
||||
MOBSPAWNS.put(21521, Arrays.asList(21522, 100, 30, -1)); // Claws of Splendor
|
||||
MOBSPAWNS.put(21527, Arrays.asList(21528, 100, 30, -1)); // Anger of Splendor
|
||||
MOBSPAWNS.put(21533, Arrays.asList(21534, 100, 30, -1)); // Alliance of Splendor
|
||||
MOBSPAWNS.put(21537, Arrays.asList(21538, 100, 30, -1)); // Fang of Splendor
|
||||
}
|
||||
protected static final NpcStringId[][] MOBTEXTS =
|
||||
{
|
||||
new NpcStringId[]
|
||||
{
|
||||
NpcStringId.ENOUGH_FOOLING_AROUND_GET_READY_TO_DIE,
|
||||
NpcStringId.YOU_IDIOT_I_VE_JUST_BEEN_TOYING_WITH_YOU,
|
||||
NpcStringId.NOW_THE_FUN_STARTS
|
||||
},
|
||||
new NpcStringId[]
|
||||
{
|
||||
NpcStringId.I_MUST_ADMIT_NO_ONE_MAKES_MY_BLOOD_BOIL_QUITE_LIKE_YOU_DO,
|
||||
NpcStringId.NOW_THE_BATTLE_BEGINS,
|
||||
NpcStringId.WITNESS_MY_TRUE_POWER
|
||||
},
|
||||
new NpcStringId[]
|
||||
{
|
||||
NpcStringId.PREPARE_TO_DIE,
|
||||
NpcStringId.I_LL_DOUBLE_MY_STRENGTH,
|
||||
NpcStringId.YOU_HAVE_MORE_SKILL_THAN_I_THOUGHT
|
||||
}
|
||||
};
|
||||
|
||||
private PolymorphingOnAttack()
|
||||
{
|
||||
super(PolymorphingOnAttack.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBSPAWNS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isVisible() && !npc.isDead())
|
||||
{
|
||||
final List<Integer> tmp = MOBSPAWNS.get(npc.getId());
|
||||
if (tmp != null)
|
||||
{
|
||||
if ((npc.getCurrentHp() <= ((npc.getMaxHp() * tmp.get(1)) / 100.0)) && (getRandom(100) < tmp.get(2)))
|
||||
{
|
||||
if (tmp.get(3) >= 0)
|
||||
{
|
||||
NpcStringId npcString = MOBTEXTS[tmp.get(3)][getRandom(MOBTEXTS[tmp.get(3)].length)];
|
||||
npc.broadcastPacket(new CreatureSay(npc.getObjectId(), Say2.NPC_ALL, npc.getName(), npcString));
|
||||
|
||||
}
|
||||
npc.deleteMe();
|
||||
final L2Attackable newNpc = (L2Attackable) addSpawn(tmp.get(0), npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, true);
|
||||
final L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker;
|
||||
newNpc.setRunning();
|
||||
newNpc.addDamageHate(originalAttacker, 0, 500);
|
||||
newNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, originalAttacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PolymorphingOnAttack();
|
||||
}
|
||||
}
|
515
trunk/dist/game/data/scripts/ai/group_template/PrimevalIsle.java
vendored
Normal file
515
trunk/dist/game/data/scripts/ai/group_template/PrimevalIsle.java
vendored
Normal file
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.handler.IItemHandler;
|
||||
import com.l2jserver.gameserver.handler.ItemHandler;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
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.L2Playable;
|
||||
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.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Primeval Isle AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class PrimevalIsle extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int EGG = 18344; // Ancient Egg
|
||||
private static final int SAILREN = 29065; // Sailren
|
||||
private static final int ORNIT = 22742; // Ornithomimus
|
||||
private static final int DEINO = 22743; // Deinonychus
|
||||
private static final int[] SPRIGNANT =
|
||||
{
|
||||
18345, // Sprigant (Anesthesia)
|
||||
18346, // Sprigant (Deadly Poison)
|
||||
};
|
||||
private static final int[] MONSTERS =
|
||||
{
|
||||
22196, // Velociraptor
|
||||
22198, // Velociraptor
|
||||
22200, // Ornithomimus
|
||||
22202, // Ornithomimus
|
||||
22203, // Deinonychus
|
||||
22205, // Deinonychus
|
||||
22208, // Pachycephalosaurus
|
||||
22210, // Pachycephalosaurus
|
||||
22211, // Wild Strider
|
||||
22213, // Wild Strider
|
||||
22223, // Velociraptor
|
||||
22224, // Ornithomimus
|
||||
22225, // Deinonychus
|
||||
22226, // Pachycephalosaurus
|
||||
22227, // Wild Strider
|
||||
22742, // Ornithomimus
|
||||
22743, // Deinonychus
|
||||
};
|
||||
private static final int[] TREX =
|
||||
{
|
||||
22215, // Tyrannosaurus
|
||||
22216, // Tyrannosaurus
|
||||
22217, // Tyrannosaurus
|
||||
};
|
||||
private static final int[] VEGETABLE =
|
||||
{
|
||||
22200, // Ornithomimus
|
||||
22201, // Ornithomimus
|
||||
22202, // Ornithomimus
|
||||
22203, // Deinonychus
|
||||
22204, // Deinonychus
|
||||
22205, // Deinonychus
|
||||
22224, // Ornithomimus
|
||||
22225, // Deinonychus
|
||||
};
|
||||
// Item
|
||||
private static final int DEINONYCHUS = 14828; // Deinonychus Mesozoic Stone
|
||||
// Skill
|
||||
private static final SkillHolder ANESTHESIA = new SkillHolder(5085, 1); // Anesthesia
|
||||
private static final SkillHolder DEADLY_POISON = new SkillHolder(5086, 1); // Deadly Poison
|
||||
private static final SkillHolder SELFBUFF1 = new SkillHolder(5087, 1); // Berserk
|
||||
private static final SkillHolder SELFBUFF2 = new SkillHolder(5087, 2); // Berserk
|
||||
private static final SkillHolder LONGRANGEDMAGIC1 = new SkillHolder(5120, 1); // Stun
|
||||
private static final SkillHolder PHYSICALSPECIAL1 = new SkillHolder(5083, 4); // Stun
|
||||
private static final SkillHolder PHYSICALSPECIAL2 = new SkillHolder(5081, 4); // Silence
|
||||
private static final SkillHolder PHYSICALSPECIAL3 = new SkillHolder(5082, 4); // NPC Spinning, Slashing Trick
|
||||
private static final SkillHolder CREW_SKILL = new SkillHolder(6172, 1); // Presentation - Tyranno
|
||||
private static final SkillHolder INVIN_BUFF_ON = new SkillHolder(5225, 1); // Invincible
|
||||
|
||||
private PrimevalIsle()
|
||||
{
|
||||
super(PrimevalIsle.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(TREX);
|
||||
addSpawnId(SPRIGNANT);
|
||||
addSpawnId(MONSTERS);
|
||||
addAggroRangeEnterId(TREX);
|
||||
addSpellFinishedId(TREX);
|
||||
addAttackId(EGG);
|
||||
addAttackId(TREX);
|
||||
addAttackId(MONSTERS);
|
||||
addKillId(EGG, SAILREN, DEINO, ORNIT);
|
||||
addSeeCreatureId(TREX);
|
||||
addSeeCreatureId(MONSTERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (skill.getId() == CREW_SKILL.getSkillId())
|
||||
{
|
||||
startQuestTimer("START_INVUL", 4000, npc, null);
|
||||
final L2Npc target = (L2Npc) npc.getTarget();
|
||||
if (target != null)
|
||||
{
|
||||
target.doDie(npc);
|
||||
}
|
||||
}
|
||||
if (npc.isInCombat())
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character target = mob.getMostHated();
|
||||
if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 60)
|
||||
{
|
||||
if (skill.getId() == SELFBUFF1.getSkillId())
|
||||
{
|
||||
npc.setScriptValue(3);
|
||||
if ((target != null))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(target, 0, 555);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30)
|
||||
{
|
||||
if (skill.getId() == SELFBUFF1.getSkillId())
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
if ((target != null))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(target, 0, 555);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
else if (skill.getId() == SELFBUFF2.getSkillId())
|
||||
{
|
||||
npc.setScriptValue(5);
|
||||
if ((target != null))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(target, 0, 555);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "USE_SKILL":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
npc.doCast((npc.getId() == SPRIGNANT[0] ? ANESTHESIA.getSkill() : DEADLY_POISON.getSkill()));
|
||||
startQuestTimer("USE_SKILL", 15000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "GHOST_DESPAWN":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
if (!npc.isInCombat())
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("GHOST_DESPAWN", 1800000, npc, null);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TREX_ATTACK":
|
||||
{
|
||||
if ((npc != null) && (player != null))
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
if (player.isInsideRadius(npc, 800, true, false))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(LONGRANGEDMAGIC1.getSkill());
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "START_INVUL":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
npc.doCast(INVIN_BUFF_ON.getSkill());
|
||||
startQuestTimer("START_INVUL_2", 30000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "START_INVUL_2":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
INVIN_BUFF_ON.getSkill().applyEffects(npc, npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (Util.contains(MONSTERS, npc.getId()))
|
||||
{
|
||||
if (creature.isPlayer())
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final int ag_type = npc.getTemplate().getParameters().getInt("ag_type", 0);
|
||||
final int probPhysicalSpecial1 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial1", 0);
|
||||
final int probPhysicalSpecial2 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial2", 0);
|
||||
final SkillHolder physicalSpecial1 = npc.getTemplate().getParameters().getObject("PhysicalSpecial1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial2 = npc.getTemplate().getParameters().getObject("PhysicalSpecial2", SkillHolder.class);
|
||||
|
||||
if (((getRandom(100) < 30) && (npc.getId() == DEINO)) || ((npc.getId() == ORNIT) && npc.isScriptValue(0)))
|
||||
{
|
||||
mob.clearAggroList();
|
||||
npc.setScriptValue(1);
|
||||
npc.setRunning();
|
||||
|
||||
final int distance = 3000;
|
||||
final int heading = Util.calculateHeadingFrom(creature, npc);
|
||||
final double angle = Util.convertHeadingToDegree(heading);
|
||||
final double radian = Math.toRadians(angle);
|
||||
final double sin = Math.sin(radian);
|
||||
final double cos = Math.cos(radian);
|
||||
final int newX = (int) (npc.getX() + (cos * distance));
|
||||
final int newY = (int) (npc.getY() + (sin * distance));
|
||||
final Location loc = GeoData.getInstance().moveCheck(npc.getX(), npc.getY(), npc.getZ(), newX, newY, npc.getZ(), npc.getInstanceId());
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, loc, 0);
|
||||
}
|
||||
else if (ag_type == 1)
|
||||
{
|
||||
if (getRandom(100) <= (probPhysicalSpecial1 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial1.getSkillId()))
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(physicalSpecial1.getSkill());
|
||||
}
|
||||
}
|
||||
else if (getRandom(100) <= (probPhysicalSpecial2 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial2.getSkill()))
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(physicalSpecial2.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Util.contains(VEGETABLE, creature.getId()))
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(CREW_SKILL.getSkill());
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, creature);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, "?");
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
startQuestTimer("TREX_ATTACK", 6000, npc, player);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == EGG)
|
||||
{
|
||||
if ((getRandom(100) <= 80) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
final L2Playable playable = isSummon ? attacker.getSummon() : attacker;
|
||||
for (L2Character characters : npc.getKnownList().getKnownCharactersInRadius(500))
|
||||
{
|
||||
if ((characters != null) && (characters.isAttackable()) && (getRandomBoolean()))
|
||||
{
|
||||
L2Attackable monster = (L2Attackable) characters;
|
||||
addAttackPlayerDesire(monster, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Util.contains(TREX, npc.getId()))
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character target = mob.getMostHated();
|
||||
|
||||
if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 30)
|
||||
{
|
||||
if (npc.isScriptValue(3))
|
||||
{
|
||||
if (!npc.isSkillDisabled(SELFBUFF1.getSkill()))
|
||||
{
|
||||
npc.doCast(SELFBUFF1.getSkill());
|
||||
}
|
||||
}
|
||||
else if (npc.isScriptValue(1))
|
||||
{
|
||||
if (!npc.isSkillDisabled(SELFBUFF2.getSkill()))
|
||||
{
|
||||
npc.doCast(SELFBUFF2.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 60) && (npc.isScriptValue(3)))
|
||||
{
|
||||
if (!npc.isSkillDisabled(SELFBUFF1.getSkill()))
|
||||
{
|
||||
npc.doCast(SELFBUFF1.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
if (Util.calculateDistance(npc, attacker, true, false) > 100)
|
||||
{
|
||||
if (!npc.isSkillDisabled(LONGRANGEDMAGIC1.getSkill()) && (getRandom(100) <= (10 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(LONGRANGEDMAGIC1.getSkill());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!npc.isSkillDisabled(LONGRANGEDMAGIC1.getSkill()) && (getRandom(100) <= (10 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(LONGRANGEDMAGIC1.getSkill());
|
||||
}
|
||||
if (!npc.isSkillDisabled(PHYSICALSPECIAL1.getSkill()) && (getRandom(100) <= (5 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(PHYSICALSPECIAL1.getSkill());
|
||||
}
|
||||
if (!npc.isSkillDisabled(PHYSICALSPECIAL2.getSkill()) && (getRandom(100) <= (3 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(PHYSICALSPECIAL2.getSkill());
|
||||
}
|
||||
if (!npc.isSkillDisabled(PHYSICALSPECIAL3.getSkill()) && (getRandom(100) <= (5 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(PHYSICALSPECIAL3.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
L2Character target = null;
|
||||
final int probPhysicalSpecial1 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial1", 0);
|
||||
final int probPhysicalSpecial2 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial2", 0);
|
||||
final SkillHolder selfRangeBuff1 = npc.getTemplate().getParameters().getObject("SelfRangeBuff1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial1 = npc.getTemplate().getParameters().getObject("PhysicalSpecial1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial2 = npc.getTemplate().getParameters().getObject("PhysicalSpecial2", SkillHolder.class);
|
||||
|
||||
if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 50)
|
||||
{
|
||||
npc.getVariables().set("SKILL_MULTIPLER", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getVariables().set("SKILL_MULTIPLER", 1);
|
||||
}
|
||||
|
||||
if ((((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 30) && (npc.getVariables().getInt("SELFBUFF_USED") == 0))
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
target = mob.getMostHated();
|
||||
mob.clearAggroList();
|
||||
if (!npc.isSkillDisabled(selfRangeBuff1.getSkillId()))
|
||||
{
|
||||
npc.getVariables().set("SELFBUFF_USED", 1);
|
||||
npc.doCast(selfRangeBuff1.getSkill());
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
if (getRandom(100) <= (probPhysicalSpecial1 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial1.getSkill()))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(physicalSpecial1.getSkill());
|
||||
}
|
||||
}
|
||||
if (getRandom(100) <= (probPhysicalSpecial2 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial2.getSkill()))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(physicalSpecial2.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if ((npc.getId() == DEINO) || ((npc.getId() == ORNIT) && !npc.isScriptValue(1)))
|
||||
{
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
if ((npc.getId() == SAILREN) || (getRandom(100) < 3))
|
||||
{
|
||||
final L2PcInstance player = npc.getId() == SAILREN ? getRandomPartyMember(killer) : killer;
|
||||
if (player.getInventory().getSize(false) <= (player.getInventoryLimit() * 0.8))
|
||||
{
|
||||
giveItems(player, DEINONYCHUS, 1);
|
||||
final L2ItemInstance summonItem = player.getInventory().getItemByItemId(DEINONYCHUS);
|
||||
final IItemHandler handler = ItemHandler.getInstance().getHandler(summonItem.getEtcItem());
|
||||
if ((handler != null) && !player.hasPet())
|
||||
{
|
||||
handler.useItem(player, summonItem, true);
|
||||
}
|
||||
showOnScreenMsg(player, NpcStringId.LIFE_STONE_FROM_THE_BEGINNING_ACQUIRED, 2, 6000);
|
||||
}
|
||||
else
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.WHEN_INVENTORY_WEIGHT_NUMBER_ARE_MORE_THAN_80_THE_LIFE_STONE_FROM_THE_BEGINNING_CANNOT_BE_ACQUIRED, 2, 6000);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (Util.contains(SPRIGNANT, npc.getId()))
|
||||
{
|
||||
startQuestTimer("USE_SKILL", 15000, npc, null);
|
||||
}
|
||||
else if (Util.contains(TREX, npc.getId()))
|
||||
{
|
||||
final int collectGhost = npc.getTemplate().getParameters().getInt("CollectGhost", 0);
|
||||
final int collectDespawn = npc.getTemplate().getParameters().getInt("CollectGhostDespawnTime", 30);
|
||||
|
||||
if (collectGhost == 1)
|
||||
{
|
||||
startQuestTimer("GHOST_DESPAWN", collectDespawn * 60000, npc, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getVariables().set("SELFBUFF_USED", 0);
|
||||
npc.getVariables().set("SKILL_MULTIPLER", 1);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PrimevalIsle();
|
||||
}
|
||||
}
|
161
trunk/dist/game/data/scripts/ai/group_template/PrisonGuards.java
vendored
Normal file
161
trunk/dist/game/data/scripts/ai/group_template/PrisonGuards.java
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Prison Guards AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class PrisonGuards extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int GUARD_HEAD = 18367; // Prison Guard
|
||||
private static final int GUARD = 18368; // Prison Guard
|
||||
// Item
|
||||
private static final int STAMP = 10013; // Race Stamp
|
||||
// Skills
|
||||
private static final int TIMER = 5239; // Event Timer
|
||||
private static final SkillHolder STONE = new SkillHolder(4578, 1); // Petrification
|
||||
private static final SkillHolder SILENCE = new SkillHolder(4098, 9); // Silence
|
||||
|
||||
private PrisonGuards()
|
||||
{
|
||||
super(PrisonGuards.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(GUARD_HEAD, GUARD);
|
||||
addSpawnId(GUARD_HEAD, GUARD);
|
||||
addNpcHateId(GUARD);
|
||||
addSkillSeeId(GUARD);
|
||||
addSpellFinishedId(GUARD_HEAD, GUARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("CLEAR_STATUS"))
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
else if (event.equals("CHECK_HOME"))
|
||||
{
|
||||
if ((npc.calculateDistance(npc.getSpawn().getLocation(), false, false) > 10) && !npc.isInCombat() && !npc.isDead())
|
||||
{
|
||||
npc.teleToLocation(npc.getSpawn().getLocation());
|
||||
}
|
||||
startQuestTimer("CHECK_HOME", 30000, npc, null);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == GUARD_HEAD)
|
||||
{
|
||||
if (player.isAffectedBySkill(TIMER))
|
||||
{
|
||||
if ((getRandom(100) < 10) && (npc.calculateDistance(player, true, false) < 100))
|
||||
{
|
||||
if ((getQuestItemsCount(player, STAMP) <= 3) && npc.isScriptValue(0))
|
||||
{
|
||||
giveItems(player, STAMP, 1);
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("CLEAR_STATUS", 600000, npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(STONE.getSkill());
|
||||
broadcastNpcSay(npc, Say2.ALL, NpcStringId.IT_S_NOT_EASY_TO_OBTAIN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!player.isAffectedBySkill(TIMER) && (npc.calculateDistance(npc.getSpawn().getLocation(), false, false) < 2000))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(STONE.getSkill());
|
||||
broadcastNpcSay(npc, Say2.ALL, NpcStringId.YOU_RE_OUT_OF_YOUR_MIND_COMING_HERE);
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (!caster.isAffectedBySkill(TIMER))
|
||||
{
|
||||
npc.setTarget(caster);
|
||||
npc.doCast(SILENCE.getSkill());
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((skill == SILENCE.getSkill()) || (skill == STONE.getSkill()))
|
||||
{
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.setTarget(npc);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return player.isAffectedBySkill(TIMER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == GUARD_HEAD)
|
||||
{
|
||||
npc.setIsImmobilized(true);
|
||||
npc.setIsInvul(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setIsNoRndWalk(true);
|
||||
cancelQuestTimer("CHECK_HOME", npc, null);
|
||||
startQuestTimer("CHECK_HOME", 30000, npc, null);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PrisonGuards();
|
||||
}
|
||||
}
|
123
trunk/dist/game/data/scripts/ai/group_template/RandomSpawn.java
vendored
Normal file
123
trunk/dist/game/data/scripts/ai/group_template/RandomSpawn.java
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Manages spawn of NPCs having several random spawn points.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class RandomSpawn extends AbstractNpcAI
|
||||
{
|
||||
private static Map<Integer, Location[]> SPAWN_POINTS = new FastMap<>();
|
||||
static
|
||||
{
|
||||
// Keltas
|
||||
SPAWN_POINTS.put(22341, new Location[]
|
||||
{
|
||||
new Location(-27136, 250938, -3523),
|
||||
new Location(-29658, 252897, -3523),
|
||||
new Location(-27237, 251943, -3527),
|
||||
new Location(-28868, 250113, -3479)
|
||||
});
|
||||
// Keymaster
|
||||
SPAWN_POINTS.put(22361, new Location[]
|
||||
{
|
||||
new Location(14091, 250533, -1940),
|
||||
new Location(15762, 252440, -2015),
|
||||
new Location(19836, 256212, -2090),
|
||||
new Location(21940, 254107, -2010),
|
||||
new Location(17299, 252943, -2015),
|
||||
});
|
||||
// Typhoon
|
||||
SPAWN_POINTS.put(25539, new Location[]
|
||||
{
|
||||
new Location(-20641, 255370, -3235),
|
||||
new Location(-16157, 250993, -3058),
|
||||
new Location(-18269, 250721, -3151),
|
||||
new Location(-16532, 254864, -3223),
|
||||
new Location(-19055, 253489, -3440),
|
||||
new Location(-9684, 254256, -3148),
|
||||
new Location(-6209, 251924, -3189),
|
||||
new Location(-10547, 251359, -2929),
|
||||
new Location(-7254, 254997, -3261),
|
||||
new Location(-4883, 253171, -3322)
|
||||
});
|
||||
// Mutated Elpy
|
||||
SPAWN_POINTS.put(25604, new Location[]
|
||||
{
|
||||
new Location(-46080, 246368, -14183),
|
||||
new Location(-44816, 246368, -14183),
|
||||
new Location(-44224, 247440, -14184),
|
||||
new Location(-44896, 248464, -14183),
|
||||
new Location(-46064, 248544, -14183),
|
||||
new Location(-46720, 247424, -14183)
|
||||
});
|
||||
}
|
||||
|
||||
public RandomSpawn()
|
||||
{
|
||||
super(RandomSpawn.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(SPAWN_POINTS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
final Location[] spawnlist = SPAWN_POINTS.get(npc.getId());
|
||||
final Location loc = spawnlist[getRandom(spawnlist.length)];
|
||||
if (!npc.isInsideRadius(loc, 200, false, false))
|
||||
{
|
||||
npc.getSpawn().setLocation(loc);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Teleport(npc, loc), 100);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
private static class Teleport implements Runnable
|
||||
{
|
||||
private final L2Npc _npc;
|
||||
private final Location _loc;
|
||||
|
||||
public Teleport(L2Npc npc, Location loc)
|
||||
{
|
||||
_npc = npc;
|
||||
_loc = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
_npc.teleToLocation(_loc, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RandomSpawn();
|
||||
}
|
||||
}
|
118
trunk/dist/game/data/scripts/ai/group_template/RangeGuard.java
vendored
Normal file
118
trunk/dist/game/data/scripts/ai/group_template/RangeGuard.java
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Range Guard AI.
|
||||
* @author St3eT.
|
||||
*/
|
||||
public final class RangeGuard extends AbstractNpcAI
|
||||
{
|
||||
// Skill
|
||||
private static SkillHolder ULTIMATE_DEFENSE = new SkillHolder(5044, 3); // NPC Ultimate Defense
|
||||
//@formatter:off
|
||||
private static final int[] NOT_ALLOWED_SKILLS =
|
||||
{
|
||||
15, 28, // Charm / Aggression
|
||||
51, 65, // Lure / Horror
|
||||
106, 115, // Veil / Power Break
|
||||
122, 127, // Hex / Hamstring
|
||||
254, 352, // Spoil / Shield Bash
|
||||
353, 358, // Shield Slam / Bluff
|
||||
402, 403, // Arrest / Shackle
|
||||
412, 485, // Sand Bomb / Disarm
|
||||
501, 511, // Violent Temper / Temptation
|
||||
522, 531, // Real Target / Critical Wound
|
||||
680, 695, // Divine Knight Hate / Divine Wizard Divine Cloud
|
||||
696, 716, // Divine Wizard Surrender to Divine / Zaken Hold
|
||||
775, 792, // Weapon Blockade / Betrayal Mark
|
||||
1042, 1049, // Hold Undead / Requiem
|
||||
1069, 1071, // Sleep / Surrender To Water
|
||||
1072, 1074, // Sleeping Cloud / Surrender To Wind
|
||||
1083, 1097, // Surrender To Fire / Dreaming Spirit
|
||||
1092, 1064, // Fear / Silence
|
||||
1160, 1164, // Slow / Curse Weakness
|
||||
1169, 1170, // Curse Fear / Anchor
|
||||
1201, 1206, // Dryad Root / Wind Shackle
|
||||
1222, 1223, // Curse Chaos / Surrender To Earth
|
||||
1224, 1263, // Surrender To Poison / Curse Gloom
|
||||
1269, 1336, // Curse Disease / Curse of Doom
|
||||
1337, 1338, // Curse of Abyss / Arcane Chaos
|
||||
1358, 1359, // Block Shield / Block Wind Walk
|
||||
1386, 1394, // Arcane Disruption / Trance
|
||||
1396, 1445, // Magical BackFire / Surrender to Dark
|
||||
1446, 1447, // Shadow Bind / Voice Bind
|
||||
1481, 1482, // Oblivion / Weak Constitution
|
||||
1483, 1484, // Thin Skin / Enervation
|
||||
1485, 1486, // Spite / Mental Impoverish
|
||||
1511, 1524, // Curse of Life Flow / Surrender to the Divine
|
||||
1529, // Soul Web
|
||||
};
|
||||
//@formatter:on
|
||||
// Misc
|
||||
private static final int MIN_DISTANCE = 150;
|
||||
|
||||
private RangeGuard()
|
||||
{
|
||||
super(RangeGuard.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
for (L2NpcTemplate template : NpcData.getInstance().getAllNpcOfClassType("L2Monster"))
|
||||
{
|
||||
if (template.getParameters().getInt("LongRangeGuardRate", -1) > 0)
|
||||
{
|
||||
addAttackId(template.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
final L2Playable playable = (isSummon) ? attacker.getSummon() : attacker;
|
||||
final int longRangeGuardRate = npc.getTemplate().getParameters().getInt("LongRangeGuardRate");
|
||||
final double distance = Util.calculateDistance(npc, playable, true, false);
|
||||
|
||||
if (npc.isAffectedBySkill(ULTIMATE_DEFENSE.getSkillId()) && (distance <= MIN_DISTANCE))
|
||||
{
|
||||
npc.stopSkillEffects(true, ULTIMATE_DEFENSE.getSkillId());
|
||||
}
|
||||
else if ((distance > MIN_DISTANCE) && !npc.isSkillDisabled(ULTIMATE_DEFENSE.getSkillId()) && !((skill != null) && Util.contains(NOT_ALLOWED_SKILLS, skill.getId())) && (getRandom(100) < longRangeGuardRate))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ULTIMATE_DEFENSE.getSkill());
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RangeGuard();
|
||||
}
|
||||
}
|
93
trunk/dist/game/data/scripts/ai/group_template/Remnants.java
vendored
Normal file
93
trunk/dist/game/data/scripts/ai/group_template/Remnants.java
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Remnants AI.
|
||||
* @author DS
|
||||
*/
|
||||
public final class Remnants extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] NPCS =
|
||||
{
|
||||
18463,
|
||||
18464,
|
||||
18465
|
||||
};
|
||||
private static final int SKILL_HOLY_WATER = 2358;
|
||||
|
||||
// TODO: Find retail strings.
|
||||
// private static final String MSG = "The holy water affects Remnants Ghost. You have freed his soul.";
|
||||
// private static final String MSG_DEREK = "The holy water affects Derek. You have freed his soul.";
|
||||
private Remnants()
|
||||
{
|
||||
super(Remnants.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(NPCS);
|
||||
addSkillSeeId(NPCS);
|
||||
// Do not override onKill for Derek here. Let's make global Hellbound manipulations in Engine where it is possible.
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsMortal(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (skill.getId() == SKILL_HOLY_WATER)
|
||||
{
|
||||
if (!npc.isDead())
|
||||
{
|
||||
if ((targets.length > 0) && (targets[0] == npc))
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.02)) // Lower, than 2%
|
||||
{
|
||||
npc.doDie(caster);
|
||||
//@formatter:off
|
||||
/*if (npc.getNpcId() == DEREK)
|
||||
{
|
||||
caster.sendMessage(MSG_DEREK);
|
||||
}
|
||||
else
|
||||
{
|
||||
caster.sendMessage(MSG);
|
||||
}*/
|
||||
//@formatter:on
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Remnants();
|
||||
}
|
||||
}
|
56
trunk/dist/game/data/scripts/ai/group_template/Sandstorms.java
vendored
Normal file
56
trunk/dist/game/data/scripts/ai/group_template/Sandstorms.java
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
|
||||
/**
|
||||
* Sandstorms AI.
|
||||
* @author Ectis
|
||||
*/
|
||||
public class Sandstorms extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SANDSTORM = 32350;
|
||||
// Skills
|
||||
private static final SkillHolder GUST = new SkillHolder(5435, 1); // Gust
|
||||
|
||||
public Sandstorms()
|
||||
{
|
||||
super(Sandstorms.class.getSimpleName(), "ai/group_template");
|
||||
addAggroRangeEnterId(SANDSTORM); // Sandstorm
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(GUST.getSkill());
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Sandstorms();
|
||||
}
|
||||
}
|
63
trunk/dist/game/data/scripts/ai/group_template/SeeThroughSilentMove.java
vendored
Normal file
63
trunk/dist/game/data/scripts/ai/group_template/SeeThroughSilentMove.java
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* See Through Silent Move AI.
|
||||
* @author Gigiikun
|
||||
*/
|
||||
public class SeeThroughSilentMove extends AbstractNpcAI
|
||||
{
|
||||
//@formatter:off
|
||||
private static final int[] MONSTERS =
|
||||
{
|
||||
18001, 18002, 22199, 22215, 22216, 22217, 22327, 22746, 22747, 22748,
|
||||
22749, 22750, 22751, 22752, 22753, 22754, 22755, 22756, 22757, 22758,
|
||||
22759, 22760, 22761, 22762, 22763, 22764, 22765, 22794, 22795, 22796,
|
||||
22797, 22798, 22799, 22800, 22843, 22857, 25725, 25726, 25727, 29009,
|
||||
29010, 29011, 29012, 29013
|
||||
};
|
||||
//@formatter:on
|
||||
|
||||
private SeeThroughSilentMove()
|
||||
{
|
||||
super(SeeThroughSilentMove.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(MONSTERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.isAttackable())
|
||||
{
|
||||
((L2Attackable) npc).setSeeThroughSilentMove(true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SeeThroughSilentMove();
|
||||
}
|
||||
}
|
321
trunk/dist/game/data/scripts/ai/group_template/SelMahumDrill.java
vendored
Normal file
321
trunk/dist/game/data/scripts/ai/group_template/SelMahumDrill.java
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SpawnTable;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Sel Mahum Training Ground AI for drill groups.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class SelMahumDrill extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] MAHUM_CHIEFS =
|
||||
{
|
||||
22775, // Sel Mahum Drill Sergeant
|
||||
22776, // Sel Mahum Training Officer
|
||||
22778, // Sel Mahum Drill Sergeant
|
||||
};
|
||||
|
||||
private static final int[] MAHUM_SOLDIERS =
|
||||
{
|
||||
22780, // Sel Mahum Recruit
|
||||
22782, // Sel Mahum Recruit
|
||||
22783, // Sel Mahum Soldier
|
||||
22784, // Sel Mahum Recruit
|
||||
22785, // Sel Mahum Soldier
|
||||
};
|
||||
|
||||
private static final int[] CHIEF_SOCIAL_ACTIONS =
|
||||
{
|
||||
1,
|
||||
4,
|
||||
5,
|
||||
7
|
||||
};
|
||||
|
||||
private static final Actions[] SOLDIER_SOCIAL_ACTIONS =
|
||||
{
|
||||
Actions.SCE_TRAINING_ACTION_A,
|
||||
Actions.SCE_TRAINING_ACTION_B,
|
||||
Actions.SCE_TRAINING_ACTION_C,
|
||||
Actions.SCE_TRAINING_ACTION_D
|
||||
};
|
||||
|
||||
private static final NpcStringId[] CHIEF_FSTRINGS =
|
||||
{
|
||||
NpcStringId.HOW_DARE_YOU_ATTACK_MY_RECRUITS,
|
||||
NpcStringId.WHO_IS_DISRUPTING_THE_ORDER
|
||||
};
|
||||
|
||||
private static final NpcStringId[] SOLDIER_FSTRINGS =
|
||||
{
|
||||
NpcStringId.THE_DRILLMASTER_IS_DEAD,
|
||||
NpcStringId.LINE_UP_THE_RANKS
|
||||
};
|
||||
|
||||
// Chiefs event broadcast range
|
||||
private static final int TRAINING_RANGE = 1000;
|
||||
|
||||
private static enum Actions
|
||||
{
|
||||
SCE_TRAINING_ACTION_A(4, -1, 2, 2333),
|
||||
SCE_TRAINING_ACTION_B(1, -1, 2, 4333),
|
||||
SCE_TRAINING_ACTION_C(6, 5, 4, 1000),
|
||||
SCE_TRAINING_ACTION_D(7, -1, 2, 1000);
|
||||
|
||||
private final int _socialActionId;
|
||||
private final int _altSocialActionId;
|
||||
private final int _repeatCount;
|
||||
private final int _repeatInterval;
|
||||
|
||||
private Actions(int socialActionId, int altSocialActionId, int repeatCount, int repeatInterval)
|
||||
{
|
||||
_socialActionId = socialActionId;
|
||||
_altSocialActionId = altSocialActionId;
|
||||
_repeatCount = repeatCount;
|
||||
_repeatInterval = repeatInterval;
|
||||
}
|
||||
|
||||
protected int getSocialActionId()
|
||||
{
|
||||
return _socialActionId;
|
||||
}
|
||||
|
||||
protected int getAltSocialActionId()
|
||||
{
|
||||
return _altSocialActionId;
|
||||
}
|
||||
|
||||
protected int getRepeatCount()
|
||||
{
|
||||
return _repeatCount;
|
||||
}
|
||||
|
||||
protected int getRepeatInterval()
|
||||
{
|
||||
return _repeatInterval;
|
||||
}
|
||||
}
|
||||
|
||||
private SelMahumDrill()
|
||||
{
|
||||
super(SelMahumDrill.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
addAttackId(MAHUM_SOLDIERS);
|
||||
addKillId(MAHUM_CHIEFS);
|
||||
addEventReceivedId(MAHUM_CHIEFS);
|
||||
addEventReceivedId(MAHUM_SOLDIERS);
|
||||
addSpawnId(MAHUM_CHIEFS);
|
||||
addSpawnId(MAHUM_SOLDIERS);
|
||||
// Start global return home timer
|
||||
startQuestTimer("return_home", 120000, null, null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "do_social_action":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
if (Util.contains(MAHUM_CHIEFS, npc.getId()))
|
||||
{
|
||||
if ((npc.getVariables().getInt("BUSY_STATE") == 0) && (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE) && npc.staysInSpawnLoc())
|
||||
{
|
||||
final int idx = getRandom(6);
|
||||
if (idx <= (CHIEF_SOCIAL_ACTIONS.length - 1))
|
||||
{
|
||||
npc.broadcastSocialAction(CHIEF_SOCIAL_ACTIONS[idx]);
|
||||
npc.getVariables().set("SOCIAL_ACTION_NEXT_INDEX", idx); // Pass social action index to soldiers via script value
|
||||
npc.broadcastEvent("do_social_action", TRAINING_RANGE, null);
|
||||
}
|
||||
}
|
||||
|
||||
startQuestTimer("do_social_action", 15000, npc, null);
|
||||
}
|
||||
else if (Util.contains(MAHUM_SOLDIERS, npc.getId()))
|
||||
{
|
||||
handleSocialAction(npc, SOLDIER_SOCIAL_ACTIONS[npc.getVariables().getInt("SOCIAL_ACTION_NEXT_INDEX")], false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "reset_busy_state":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.getVariables().remove("BUSY_STATE");
|
||||
npc.disableCoreAI(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "return_home":
|
||||
{
|
||||
for (int npcId : MAHUM_SOLDIERS)
|
||||
{
|
||||
for (L2Spawn npcSpawn : SpawnTable.getInstance().getSpawns(npcId))
|
||||
{
|
||||
final L2Npc soldier = npcSpawn.getLastSpawn();
|
||||
if ((soldier != null) && !soldier.isDead() && (npcSpawn.getName() != null) && npcSpawn.getName().startsWith("smtg_drill_group") && !soldier.staysInSpawnLoc() && ((soldier.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE) || (soldier.getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)))
|
||||
{
|
||||
soldier.setHeading(npcSpawn.getHeading());
|
||||
soldier.teleToLocation(npcSpawn.getLocation(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (getRandom(10) < 1)
|
||||
{
|
||||
npc.broadcastEvent("ATTACKED", 1000, null);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
if ((receiver != null) && !receiver.isDead() && receiver.isInMySpawnGroup(sender))
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "do_social_action":
|
||||
{
|
||||
if (Util.contains(MAHUM_SOLDIERS, receiver.getId()))
|
||||
{
|
||||
final int actionIndex = sender.getVariables().getInt("SOCIAL_ACTION_NEXT_INDEX");
|
||||
receiver.getVariables().set("SOCIAL_ACTION_NEXT_INDEX", actionIndex);
|
||||
handleSocialAction(receiver, SOLDIER_SOCIAL_ACTIONS[actionIndex], true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CHIEF_DIED":
|
||||
{
|
||||
if (Util.contains(MAHUM_SOLDIERS, receiver.getId()))
|
||||
{
|
||||
if (getRandom(4) < 1)
|
||||
{
|
||||
broadcastNpcSay(receiver, Say2.NPC_ALL, SOLDIER_FSTRINGS[getRandom(2)]);
|
||||
}
|
||||
if (receiver.canBeAttacked())
|
||||
{
|
||||
((L2Attackable) receiver).clearAggroList();
|
||||
}
|
||||
receiver.disableCoreAI(true);
|
||||
receiver.getVariables().set("BUSY_STATE", 1);
|
||||
receiver.setIsRunning(true);
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location((receiver.getX() + getRandom(-800, 800)), (receiver.getY() + getRandom(-800, 800)), receiver.getZ(), receiver.getHeading()));
|
||||
startQuestTimer("reset_busy_state", 5000, receiver, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ATTACKED":
|
||||
{
|
||||
if (Util.contains(MAHUM_CHIEFS, receiver.getId()))
|
||||
{
|
||||
broadcastNpcSay(receiver, Say2.NPC_ALL, CHIEF_FSTRINGS[getRandom(2)]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
npc.broadcastEvent("CHIEF_DIED", TRAINING_RANGE, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (Util.contains(MAHUM_CHIEFS, npc.getId()))
|
||||
{
|
||||
startQuestTimer("do_social_action", 15000, npc, null);
|
||||
}
|
||||
|
||||
else if ((getRandom(18) < 1) && Util.contains(MAHUM_SOLDIERS, npc.getId()))
|
||||
{
|
||||
npc.getVariables().set("SOCIAL_ACTION_ALT_BEHAVIOR", 1);
|
||||
}
|
||||
|
||||
// Restore AI handling by core
|
||||
npc.disableCoreAI(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
private void handleSocialAction(L2Npc npc, Actions action, boolean firstCall)
|
||||
{
|
||||
if ((npc.getVariables().getInt("BUSY_STATE") != 0) || (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ACTIVE) || !npc.staysInSpawnLoc())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int socialActionId = (npc.getVariables().getInt("SOCIAL_ACTION_ALT_BEHAVIOR") == 0) ? action.getSocialActionId() : action.getAltSocialActionId();
|
||||
|
||||
if (socialActionId < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
npc.getVariables().set("SOCIAL_ACTION_REMAINED_COUNT", action.getRepeatCount());
|
||||
}
|
||||
|
||||
npc.broadcastSocialAction(socialActionId);
|
||||
|
||||
final int remainedCount = npc.getVariables().getInt("SOCIAL_ACTION_REMAINED_COUNT");
|
||||
if (remainedCount > 0)
|
||||
{
|
||||
npc.getVariables().set("SOCIAL_ACTION_REMAINED_COUNT", (remainedCount - 1));
|
||||
startQuestTimer("do_social_action", action.getRepeatInterval(), npc, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SelMahumDrill();
|
||||
}
|
||||
}
|
405
trunk/dist/game/data/scripts/ai/group_template/SelMahumSquad.java
vendored
Normal file
405
trunk/dist/game/data/scripts/ai/group_template/SelMahumSquad.java
vendored
Normal file
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.GameTimeController;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Sel Mahum Training Ground AI for squads and chefs.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class SelMahumSquad extends AbstractNpcAI
|
||||
{
|
||||
// NPC's
|
||||
private static final int CHEF = 18908;
|
||||
private static final int FIRE = 18927;
|
||||
private static final int STOVE = 18933;
|
||||
|
||||
private static final int OHS_Weapon = 15280;
|
||||
private static final int THS_Weapon = 15281;
|
||||
|
||||
// Sel Mahum Squad Leaders
|
||||
private static final int[] SQUAD_LEADERS =
|
||||
{
|
||||
22786,
|
||||
22787,
|
||||
22788
|
||||
};
|
||||
|
||||
private static final NpcStringId[] CHEF_FSTRINGS =
|
||||
{
|
||||
NpcStringId.I_BROUGHT_THE_FOOD,
|
||||
NpcStringId.COME_AND_EAT
|
||||
};
|
||||
|
||||
private static final int FIRE_EFFECT_BURN = 1;
|
||||
private static final int FIRE_EFFECT_NONE = 2;
|
||||
|
||||
private static final int MAHUM_EFFECT_EAT = 1;
|
||||
private static final int MAHUM_EFFECT_SLEEP = 2;
|
||||
private static final int MAHUM_EFFECT_NONE = 3;
|
||||
|
||||
private SelMahumSquad()
|
||||
{
|
||||
super(SelMahumSquad.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
addAttackId(CHEF);
|
||||
addAttackId(SQUAD_LEADERS);
|
||||
addEventReceivedId(CHEF, FIRE, STOVE);
|
||||
addEventReceivedId(SQUAD_LEADERS);
|
||||
addFactionCallId(SQUAD_LEADERS);
|
||||
addKillId(CHEF);
|
||||
addMoveFinishedId(SQUAD_LEADERS);
|
||||
addNodeArrivedId(CHEF);
|
||||
addSkillSeeId(STOVE);
|
||||
addSpawnId(CHEF, FIRE);
|
||||
addSpawnId(SQUAD_LEADERS);
|
||||
addSpellFinishedId(CHEF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "chef_disable_reward":
|
||||
{
|
||||
npc.getVariables().set("REWARD_TIME_GONE", 1);
|
||||
break;
|
||||
}
|
||||
case "chef_heal_player":
|
||||
{
|
||||
healPlayer(npc, player);
|
||||
break;
|
||||
}
|
||||
case "chef_remove_invul":
|
||||
{
|
||||
if (npc.isMonster())
|
||||
{
|
||||
npc.setIsInvul(false);
|
||||
npc.getVariables().remove("INVUL_REMOVE_TIMER_STARTED");
|
||||
if ((player != null) && !player.isDead() && npc.getKnownList().knowsThePlayer(player))
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "chef_set_invul":
|
||||
{
|
||||
if (!npc.isDead())
|
||||
{
|
||||
npc.setIsInvul(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "fire":
|
||||
{
|
||||
startQuestTimer("fire", 30000 + getRandom(5000), npc, null);
|
||||
npc.setDisplayEffect(FIRE_EFFECT_NONE);
|
||||
|
||||
if (getRandom(GameTimeController.getInstance().isNight() ? 2 : 4) < 1)
|
||||
{
|
||||
npc.setDisplayEffect(FIRE_EFFECT_BURN); // fire burns
|
||||
npc.broadcastEvent("SCE_CAMPFIRE_START", 600, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setDisplayEffect(FIRE_EFFECT_NONE); // fire goes out
|
||||
npc.broadcastEvent("SCE_CAMPFIRE_END", 600, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "fire_arrived":
|
||||
{
|
||||
// myself.i_quest0 = 1;
|
||||
npc.setIsRunning(false);
|
||||
npc.setTarget(npc);
|
||||
|
||||
if (npc.isNoRndWalk())
|
||||
{
|
||||
npc.doCast(SkillData.getInstance().getSkill(6331, 1));
|
||||
npc.setDisplayEffect(MAHUM_EFFECT_SLEEP);
|
||||
}
|
||||
if (npc.getVariables().getInt("BUSY_STATE") == 1) // Eating
|
||||
{
|
||||
npc.doCast(SkillData.getInstance().getSkill(6332, 1));
|
||||
npc.setDisplayEffect(MAHUM_EFFECT_EAT);
|
||||
}
|
||||
|
||||
startQuestTimer("remove_effects", 300000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "notify_dinner":
|
||||
{
|
||||
npc.broadcastEvent("SCE_DINNER_EAT", 600, null);
|
||||
break;
|
||||
}
|
||||
case "remove_effects":
|
||||
{
|
||||
// myself.i_quest0 = 0;
|
||||
npc.setIsRunning(true);
|
||||
npc.setDisplayEffect(MAHUM_EFFECT_NONE);
|
||||
break;
|
||||
}
|
||||
case "reset_full_bottle_prize":
|
||||
{
|
||||
npc.getVariables().remove("FULL_BARREL_REWARDING_PLAYER");
|
||||
break;
|
||||
}
|
||||
case "return_from_fire":
|
||||
{
|
||||
if (npc.isMonster() && !npc.isDead())
|
||||
{
|
||||
((L2MonsterInstance) npc).returnHome();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if ((npc.getId() == CHEF) && (npc.getVariables().getInt("BUSY_STATE") == 0))
|
||||
{
|
||||
if (npc.getVariables().getInt("INVUL_REMOVE_TIMER_STARTED") == 0)
|
||||
{
|
||||
startQuestTimer("chef_remove_invul", 180000, npc, attacker);
|
||||
startQuestTimer("chef_disable_reward", 60000, npc, null);
|
||||
npc.getVariables().set("INVUL_REMOVE_TIMER_STARTED", 1);
|
||||
}
|
||||
startQuestTimer("chef_heal_player", 1000, npc, attacker);
|
||||
startQuestTimer("chef_set_invul", 60000, npc, null);
|
||||
npc.getVariables().set("BUSY_STATE", 1);
|
||||
}
|
||||
else if (Util.contains(SQUAD_LEADERS, npc.getId()))
|
||||
{
|
||||
handlePreAttackMotion(npc);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon)
|
||||
{
|
||||
handlePreAttackMotion(npc);
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "SCE_DINNER_CHECK":
|
||||
{
|
||||
if (receiver.getId() == FIRE)
|
||||
{
|
||||
receiver.setDisplayEffect(FIRE_EFFECT_BURN);
|
||||
final L2Npc stove = addSpawn(STOVE, receiver.getX(), receiver.getY(), receiver.getZ() + 100, 0, false, 0);
|
||||
stove.setSummoner(receiver);
|
||||
startQuestTimer("notify_dinner", 2000, receiver, null); // @SCE_DINNER_EAT
|
||||
broadcastNpcSay(sender, Say2.NPC_ALL, CHEF_FSTRINGS[getRandom(2)], 1250);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_CAMPFIRE_START":
|
||||
{
|
||||
if (!receiver.isNoRndWalk() && !receiver.isDead() && (receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
receiver.setIsNoRndWalk(true); // Moving to fire - i_ai0 = 1
|
||||
receiver.setIsRunning(true);
|
||||
final Location loc = sender.getPointInRange(100, 200);
|
||||
loc.setHeading(receiver.getHeading());
|
||||
receiver.stopMove(null);
|
||||
receiver.getVariables().set("DESTINATION_X", loc.getX());
|
||||
receiver.getVariables().set("DESTINATION_Y", loc.getY());
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, loc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_CAMPFIRE_END":
|
||||
{
|
||||
if ((receiver.getId() == STOVE) && (receiver.getSummoner() == sender))
|
||||
{
|
||||
receiver.deleteMe();
|
||||
}
|
||||
else if ((receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
receiver.setIsNoRndWalk(false);
|
||||
receiver.getVariables().remove("BUSY_STATE");
|
||||
receiver.setRHandId(THS_Weapon);
|
||||
startQuestTimer("return_from_fire", 3000, receiver, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_DINNER_EAT":
|
||||
{
|
||||
if (!receiver.isDead() && (receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && (receiver.getVariables().getInt("BUSY_STATE", 0) == 0) && Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
if (receiver.isNoRndWalk()) // i_ai0 == 1
|
||||
{
|
||||
receiver.setRHandId(THS_Weapon);
|
||||
}
|
||||
receiver.setIsNoRndWalk(true); // Moving to fire - i_ai0 = 1
|
||||
receiver.getVariables().set("BUSY_STATE", 1); // Eating - i_ai3 = 1
|
||||
receiver.setIsRunning(true);
|
||||
broadcastNpcSay(receiver, Say2.NPC_ALL, (getRandom(3) < 1) ? NpcStringId.LOOKS_DELICIOUS : NpcStringId.LET_S_GO_EAT);
|
||||
final Location loc = sender.getPointInRange(100, 200);
|
||||
loc.setHeading(receiver.getHeading());
|
||||
receiver.stopMove(null);
|
||||
receiver.getVariables().set("DESTINATION_X", loc.getX());
|
||||
receiver.getVariables().set("DESTINATION_Y", loc.getY());
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, loc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_SOUP_FAILURE":
|
||||
{
|
||||
if (Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
receiver.getVariables().set("FULL_BARREL_REWARDING_PLAYER", reference.getObjectId()); // TODO: Use it in 289 quest
|
||||
startQuestTimer("reset_full_bottle_prize", 180000, receiver, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.isMonster() && (npc.getVariables().getInt("REWARD_TIME_GONE") == 0))
|
||||
{
|
||||
((L2MonsterInstance) npc).dropItem(killer, 15492, 1);
|
||||
}
|
||||
cancelQuestTimer("chef_remove_invul", npc, null);
|
||||
cancelQuestTimer("chef_disable_reward", npc, null);
|
||||
cancelQuestTimer("chef_heal_player", npc, null);
|
||||
cancelQuestTimer("chef_set_invul", npc, null);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveFinished(L2Npc npc)
|
||||
{
|
||||
// Npc moves to fire
|
||||
if (npc.isNoRndWalk() && (npc.getX() == npc.getVariables().getInt("DESTINATION_X")) && (npc.getY() == npc.getVariables().getInt("DESTINATION_Y")))
|
||||
{
|
||||
npc.setRHandId(OHS_Weapon);
|
||||
startQuestTimer("fire_arrived", 3000, npc, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNodeArrived(L2Npc npc)
|
||||
{
|
||||
npc.broadcastEvent("SCE_DINNER_CHECK", 300, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if ((npc.getId() == STOVE) && (skill.getId() == 9075) && Util.contains(targets, npc))
|
||||
{
|
||||
npc.doCast(SkillData.getInstance().getSkill(6688, 1));
|
||||
npc.broadcastEvent("SCE_SOUP_FAILURE", 600, caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == CHEF)
|
||||
{
|
||||
npc.setIsInvul(false);
|
||||
}
|
||||
else if (npc.getId() == FIRE)
|
||||
{
|
||||
startQuestTimer("fire", 1000, npc, null);
|
||||
}
|
||||
else if (Util.contains(SQUAD_LEADERS, npc.getId()))
|
||||
{
|
||||
npc.setDisplayEffect(3);
|
||||
npc.setIsNoRndWalk(false);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((skill != null) && (skill.getId() == 6330))
|
||||
{
|
||||
healPlayer(npc, player);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void healPlayer(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((player != null) && !player.isDead() && (npc.getVariables().getInt("INVUL_REMOVE_TIMER_STARTED") != 1) && ((npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ATTACK) || (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST)))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(SkillData.getInstance().getSkill(6330, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelQuestTimer("chef_set_invul", npc, null);
|
||||
npc.getVariables().remove("BUSY_STATE");
|
||||
npc.getVariables().remove("INVUL_REMOVE_TIMER_STARTED");
|
||||
npc.setIsRunning(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePreAttackMotion(L2Npc attacked)
|
||||
{
|
||||
cancelQuestTimer("remove_effects", attacked, null);
|
||||
attacked.getVariables().remove("BUSY_STATE");
|
||||
attacked.setIsNoRndWalk(false);
|
||||
attacked.setDisplayEffect(MAHUM_EFFECT_NONE);
|
||||
if (attacked.getRightHandItem() == OHS_Weapon)
|
||||
{
|
||||
attacked.setRHandId(THS_Weapon);
|
||||
}
|
||||
// TODO: Check about i_quest0
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SelMahumSquad();
|
||||
}
|
||||
}
|
210
trunk/dist/game/data/scripts/ai/group_template/SilentValley.java
vendored
Normal file
210
trunk/dist/game/data/scripts/ai/group_template/SilentValley.java
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Silent Valley AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class SilentValley extends AbstractNpcAI
|
||||
{
|
||||
// Skills
|
||||
private static final SkillHolder BETRAYAL = new SkillHolder(6033, 1); // Treasure Seeker's Betrayal
|
||||
private static final SkillHolder BLAZE = new SkillHolder(4157, 10); // NPC Blaze - Magic
|
||||
// Item
|
||||
private static final int SACK = 13799; // Treasure Sack of the Ancient Giants
|
||||
// Chance
|
||||
private static final int SPAWN_CHANCE = 2;
|
||||
private static final int CHEST_DIE_CHANCE = 5;
|
||||
// Monsters
|
||||
private static final int CHEST = 18693; // Treasure Chest of the Ancient Giants
|
||||
private static final int GUARD1 = 18694; // Treasure Chest Guard
|
||||
private static final int GUARD2 = 18695; // Treasure Chest Guard
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
20965, // Chimera Piece
|
||||
20966, // Changed Creation
|
||||
20967, // Past Creature
|
||||
20968, // Nonexistent Man
|
||||
20969, // Giant's Shadow
|
||||
20970, // Soldier of Ancient Times
|
||||
20971, // Warrior of Ancient Times
|
||||
20972, // Shaman of Ancient Times
|
||||
20973, // Forgotten Ancient People
|
||||
};
|
||||
|
||||
private SilentValley()
|
||||
{
|
||||
super(SilentValley.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBS);
|
||||
addAttackId(CHEST, GUARD1, GUARD2);
|
||||
addEventReceivedId(GUARD1, GUARD2);
|
||||
addKillId(MOBS);
|
||||
addSeeCreatureId(MOBS);
|
||||
addSeeCreatureId(GUARD1, GUARD2);
|
||||
addSpawnId(CHEST, GUARD2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "CLEAR":
|
||||
npc.doDie(null);
|
||||
break;
|
||||
case "CLEAR_EVENT":
|
||||
npc.broadcastEvent("CLEAR_ALL_INSTANT", 2000, null);
|
||||
npc.doDie(null);
|
||||
break;
|
||||
case "SPAWN_CHEST":
|
||||
addSpawn(CHEST, npc.getX() - 100, npc.getY(), npc.getZ() - 100, 0, false, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case CHEST:
|
||||
{
|
||||
if (!isSummon && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_WILL_BE_CURSED_FOR_SEEKING_THE_TREASURE);
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BETRAYAL.getSkill());
|
||||
}
|
||||
else if (isSummon || (getRandom(100) < CHEST_DIE_CHANCE))
|
||||
{
|
||||
npc.dropItem(player, SACK, 1);
|
||||
npc.broadcastEvent("CLEAR_ALL", 2000, null);
|
||||
npc.doDie(null);
|
||||
cancelQuestTimer("CLEAR_EVENT", npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUARD1:
|
||||
case GUARD2:
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BLAZE.getSkill());
|
||||
addAttackPlayerDesire(npc, player);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (isSummon)
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (getRandom(1000) < SPAWN_CHANCE)
|
||||
{
|
||||
final int newZ = npc.getZ() + 100;
|
||||
addSpawn(GUARD2, npc.getX() + 100, npc.getY(), newZ, 0, false, 0);
|
||||
addSpawn(GUARD1, npc.getX() - 100, npc.getY(), newZ, 0, false, 0);
|
||||
addSpawn(GUARD1, npc.getX(), npc.getY() + 100, newZ, 0, false, 0);
|
||||
addSpawn(GUARD1, npc.getX(), npc.getY() - 100, newZ, 0, false, 0);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayable())
|
||||
{
|
||||
final L2PcInstance player = (isSummon) ? ((L2Summon) creature).getOwner() : creature.getActingPlayer();
|
||||
if ((npc.getId() == GUARD1) || (npc.getId() == GUARD2))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BLAZE.getSkill());
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
else if (creature.isAffectedBySkill(BETRAYAL.getSkillId()))
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == CHEST)
|
||||
{
|
||||
npc.setIsInvul(true);
|
||||
startQuestTimer("CLEAR_EVENT", 300000, npc, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("SPAWN_CHEST", 10000, npc, null);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
if ((receiver != null) && !receiver.isDead())
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "CLEAR_ALL":
|
||||
startQuestTimer("CLEAR", 60000, receiver, null);
|
||||
break;
|
||||
case "CLEAR_ALL_INSTANT":
|
||||
receiver.doDie(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SilentValley();
|
||||
}
|
||||
}
|
244
trunk/dist/game/data/scripts/ai/group_template/StakatoNest.java
vendored
Normal file
244
trunk/dist/game/data/scripts/ai/group_template/StakatoNest.java
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jserver.gameserver.util.Broadcast;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Stakato Nest AI.
|
||||
* @author Gnacik
|
||||
*/
|
||||
public final class StakatoNest extends AbstractNpcAI
|
||||
{
|
||||
// @formatter:off
|
||||
// List of all mobs just for register
|
||||
private static final int[] STAKATO_MOBS =
|
||||
{
|
||||
18793, 18794, 18795, 18796, 18797, 18798, 22617, 22618, 22619, 22620,
|
||||
22621, 22622, 22623, 22624, 22625, 22626, 22627, 22628, 22629, 22630,
|
||||
22631, 22632, 22633, 25667
|
||||
};
|
||||
// Coocons
|
||||
private static final int[] COCOONS =
|
||||
{
|
||||
18793, 18794, 18795, 18796, 18797, 18798
|
||||
};
|
||||
// @formatter:on
|
||||
// Cannibalistic Stakato Leader
|
||||
private static final int STAKATO_LEADER = 22625;
|
||||
|
||||
// Spike Stakato Nurse
|
||||
private static final int STAKATO_NURSE = 22630;
|
||||
// Spike Stakato Nurse (Changed)
|
||||
private static final int STAKATO_NURSE_2 = 22631;
|
||||
// Spiked Stakato Baby
|
||||
private static final int STAKATO_BABY = 22632;
|
||||
// Spiked Stakato Captain
|
||||
private static final int STAKATO_CAPTAIN = 22629;
|
||||
|
||||
// Female Spiked Stakato
|
||||
private static final int STAKATO_FEMALE = 22620;
|
||||
// Male Spiked Stakato
|
||||
private static final int STAKATO_MALE = 22621;
|
||||
// Male Spiked Stakato (Changed)
|
||||
private static final int STAKATO_MALE_2 = 22622;
|
||||
// Spiked Stakato Guard
|
||||
private static final int STAKATO_GUARD = 22619;
|
||||
|
||||
// Cannibalistic Stakato Chief
|
||||
private static final int STAKATO_CHIEF = 25667;
|
||||
// Growth Accelerator
|
||||
private static final int GROWTH_ACCELERATOR = 2905;
|
||||
// Small Stakato Cocoon
|
||||
private static final int SMALL_COCOON = 14833;
|
||||
// Large Stakato Cocoon
|
||||
private static final int LARGE_COCOON = 14834;
|
||||
|
||||
private StakatoNest()
|
||||
{
|
||||
super(StakatoNest.class.getSimpleName(), "ai/group_template");
|
||||
registerMobs(STAKATO_MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
|
||||
if ((mob.getId() == STAKATO_LEADER) && (getRandom(1000) < 100) && (mob.getCurrentHp() < (mob.getMaxHp() * 0.3)))
|
||||
{
|
||||
final L2MonsterInstance _follower = checkMinion(npc);
|
||||
|
||||
if (_follower != null)
|
||||
{
|
||||
double _hp = _follower.getCurrentHp();
|
||||
|
||||
if (_hp > (_follower.getMaxHp() * 0.3))
|
||||
{
|
||||
mob.abortAttack();
|
||||
mob.abortCast();
|
||||
mob.setHeading(Util.calculateHeadingFrom(mob, _follower));
|
||||
mob.doCast(SkillData.getInstance().getSkill(4484, 1));
|
||||
mob.setCurrentHp(mob.getCurrentHp() + _hp);
|
||||
_follower.doDie(_follower);
|
||||
_follower.deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final L2MonsterInstance monster;
|
||||
switch (npc.getId())
|
||||
{
|
||||
case STAKATO_NURSE:
|
||||
monster = checkMinion(npc);
|
||||
if (monster != null)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayers(npc, new MagicSkillUse(npc, 2046, 1, 1000, 0));
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
L2Npc spawned = addSpawn(STAKATO_CAPTAIN, monster, true);
|
||||
addAttackPlayerDesire(spawned, killer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STAKATO_BABY:
|
||||
monster = ((L2MonsterInstance) npc).getLeader();
|
||||
if ((monster != null) && !monster.isDead())
|
||||
{
|
||||
startQuestTimer("nurse_change", 5000, monster, killer);
|
||||
}
|
||||
break;
|
||||
case STAKATO_MALE:
|
||||
monster = checkMinion(npc);
|
||||
if (monster != null)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayers(npc, new MagicSkillUse(npc, 2046, 1, 1000, 0));
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
L2Npc spawned = addSpawn(STAKATO_GUARD, monster, true);
|
||||
addAttackPlayerDesire(spawned, killer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STAKATO_FEMALE:
|
||||
monster = ((L2MonsterInstance) npc).getLeader();
|
||||
if ((monster != null) && !monster.isDead())
|
||||
{
|
||||
startQuestTimer("male_change", 5000, monster, killer);
|
||||
}
|
||||
break;
|
||||
case STAKATO_CHIEF:
|
||||
if (killer.isInParty())
|
||||
{
|
||||
List<L2PcInstance> party = killer.getParty().getMembers();
|
||||
for (L2PcInstance member : party)
|
||||
{
|
||||
giveCocoon(member, npc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
giveCocoon(killer, npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (Util.contains(COCOONS, npc.getId()) && Util.contains(targets, npc) && (skill.getId() == GROWTH_ACCELERATOR))
|
||||
{
|
||||
npc.doDie(caster);
|
||||
final L2Npc spawned = addSpawn(STAKATO_CHIEF, npc.getX(), npc.getY(), npc.getZ(), Util.calculateHeadingFrom(npc, caster), false, 0, true);
|
||||
addAttackPlayerDesire(spawned, caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((npc == null) || (player == null) || npc.isDead())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int npcId = 0;
|
||||
switch (event)
|
||||
{
|
||||
case "nurse_change":
|
||||
npcId = STAKATO_NURSE_2;
|
||||
break;
|
||||
case "male_change":
|
||||
npcId = STAKATO_MALE_2;
|
||||
break;
|
||||
}
|
||||
if (npcId > 0)
|
||||
{
|
||||
npc.getSpawn().decreaseCount(npc);
|
||||
npc.deleteMe();
|
||||
final L2Npc spawned = addSpawn(npcId, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), false, 0, true);
|
||||
addAttackPlayerDesire(spawned, player);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
private static L2MonsterInstance checkMinion(L2Npc npc)
|
||||
{
|
||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
if (mob.hasMinions())
|
||||
{
|
||||
final List<L2MonsterInstance> minion = mob.getMinionList().getSpawnedMinions();
|
||||
if ((minion != null) && !minion.isEmpty() && (minion.get(0) != null) && !minion.get(0).isDead())
|
||||
{
|
||||
return minion.get(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void giveCocoon(L2PcInstance player, L2Npc npc)
|
||||
{
|
||||
player.addItem("StakatoCocoon", ((getRandom(100) > 80) ? LARGE_COCOON : SMALL_COCOON), 1, npc, true);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new StakatoNest();
|
||||
}
|
||||
}
|
106
trunk/dist/game/data/scripts/ai/group_template/SummonPc.java
vendored
Normal file
106
trunk/dist/game/data/scripts/ai/group_template/SummonPc.java
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Summon Pc AI.<br>
|
||||
* Summon the player to the NPC on attack.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class SummonPc extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int PORTA = 20213;
|
||||
private static final int PERUM = 20221;
|
||||
// Skill
|
||||
private static final SkillHolder SUMMON_PC = new SkillHolder(4161, 1);
|
||||
|
||||
private SummonPc()
|
||||
{
|
||||
super(SummonPc.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(PORTA, PERUM);
|
||||
addSpellFinishedId(PORTA, PERUM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final int chance = getRandom(100);
|
||||
final boolean attacked = npc.getVariables().getBoolean("attacked", false);
|
||||
if ((npc.calculateDistance(attacker, true, false) > 300) && !attacked)
|
||||
{
|
||||
if (chance < 50)
|
||||
{
|
||||
if ((SUMMON_PC.getSkill().getMpConsume() < npc.getCurrentMp()) && (SUMMON_PC.getSkill().getHpConsume() < npc.getCurrentHp()) && !npc.isSkillDisabled(SUMMON_PC.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SUMMON_PC.getSkill());
|
||||
}
|
||||
|
||||
if ((SUMMON_PC.getSkill().getMpConsume() < npc.getCurrentMp()) && (SUMMON_PC.getSkill().getHpConsume() < npc.getCurrentHp()) && !npc.isSkillDisabled(SUMMON_PC.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SUMMON_PC.getSkill());
|
||||
npc.getVariables().set("attacked", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((npc.calculateDistance(attacker, true, false) > 100) && !attacked)
|
||||
{
|
||||
final L2Attackable monster = (L2Attackable) npc;
|
||||
if (monster.getMostHated() != null)
|
||||
{
|
||||
if (((monster.getMostHated() == attacker) && (chance < 50)) || (chance < 10))
|
||||
{
|
||||
if ((SUMMON_PC.getSkill().getMpConsume() < npc.getCurrentMp()) && (SUMMON_PC.getSkill().getHpConsume() < npc.getCurrentHp()) && !npc.isSkillDisabled(SUMMON_PC.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SUMMON_PC.getSkill());
|
||||
npc.getVariables().set("attacked", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((skill.getId() == SUMMON_PC.getSkillId()) && !npc.isDead() && npc.getVariables().getBoolean("attacked", false))
|
||||
{
|
||||
player.teleToLocation(npc);
|
||||
npc.getVariables().set("attacked", false);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SummonPc();
|
||||
}
|
||||
}
|
138
trunk/dist/game/data/scripts/ai/group_template/TurekOrcs.java
vendored
Normal file
138
trunk/dist/game/data/scripts/ai/group_template/TurekOrcs.java
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2World;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
|
||||
/**
|
||||
* Turek Orcs AI - flee and return with assistance
|
||||
* @author GKR
|
||||
*/
|
||||
|
||||
public final class TurekOrcs extends AbstractNpcAI
|
||||
{
|
||||
// NPC's
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
20494, // Turek War Hound
|
||||
20495, // Turek Orc Warlord
|
||||
20497, // Turek Orc Skirmisher
|
||||
20498, // Turek Orc Supplier
|
||||
20499, // Turek Orc Footman
|
||||
20500, // Turek Orc Sentinel
|
||||
};
|
||||
|
||||
private TurekOrcs()
|
||||
{
|
||||
super(TurekOrcs.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBS);
|
||||
addEventReceivedId(MOBS);
|
||||
addMoveFinishedId(MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("checkState") && !npc.isDead() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK))
|
||||
{
|
||||
if ((npc.getCurrentHp() > (npc.getMaxHp() * 0.7)) && (npc.getVariables().getInt("state") == 2))
|
||||
{
|
||||
npc.getVariables().set("state", 3);
|
||||
((L2Attackable) npc).returnHome();
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getVariables().remove("state");
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (!npc.getVariables().hasVariable("isHit"))
|
||||
{
|
||||
npc.getVariables().set("isHit", 1);
|
||||
}
|
||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) && (npc.getCurrentHp() > (npc.getMaxHp() * 0.3)) && (attacker.getCurrentHp() > (attacker.getMaxHp() * 0.25)) && npc.hasAIValue("fleeX") && npc.hasAIValue("fleeY") && npc.hasAIValue("fleeZ") && (npc.getVariables().getInt("state") == 0) && (getRandom(100) < 10))
|
||||
{
|
||||
// Say and flee
|
||||
broadcastNpcSay(npc, 0, NpcStringId.getNpcStringId(getRandom(1000007, 1000027)));
|
||||
npc.disableCoreAI(true); // to avoid attacking behaviour, while flee
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getAIValue("fleeX"), npc.getAIValue("fleeY"), npc.getAIValue("fleeZ")));
|
||||
npc.getVariables().set("state", 1);
|
||||
npc.getVariables().set("attacker", attacker.getObjectId());
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
if (eventName.equals("WARNING") && !receiver.isDead() && (receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && (reference != null) && (reference.getActingPlayer() != null) && !reference.getActingPlayer().isDead())
|
||||
{
|
||||
receiver.getVariables().set("state", 3);
|
||||
receiver.setIsRunning(true);
|
||||
((L2Attackable) receiver).addDamageHate(reference.getActingPlayer(), 0, 99999);
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, reference.getActingPlayer());
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveFinished(L2Npc npc)
|
||||
{
|
||||
// NPC reaches flee point
|
||||
if (npc.getVariables().getInt("state") == 1)
|
||||
{
|
||||
if ((npc.getX() == npc.getAIValue("fleeX")) && (npc.getY() == npc.getAIValue("fleeY")))
|
||||
{
|
||||
npc.disableCoreAI(false);
|
||||
startQuestTimer("checkState", 15000, npc, null);
|
||||
npc.getVariables().set("state", 2);
|
||||
npc.broadcastEvent("WARNING", 400, L2World.getInstance().getPlayer(npc.getVariables().getInt("attacker")));
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getAIValue("fleeX"), npc.getAIValue("fleeY"), npc.getAIValue("fleeZ")));
|
||||
}
|
||||
}
|
||||
else if ((npc.getVariables().getInt("state") == 3) && npc.staysInSpawnLoc())
|
||||
{
|
||||
npc.disableCoreAI(false);
|
||||
npc.getVariables().remove("state");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new TurekOrcs();
|
||||
}
|
||||
}
|
218
trunk/dist/game/data/scripts/ai/group_template/VarkaKetra.java
vendored
Normal file
218
trunk/dist/game/data/scripts/ai/group_template/VarkaKetra.java
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import quests.Q00605_AllianceWithKetraOrcs.Q00605_AllianceWithKetraOrcs;
|
||||
import quests.Q00606_BattleAgainstVarkaSilenos.Q00606_BattleAgainstVarkaSilenos;
|
||||
import quests.Q00607_ProveYourCourageKetra.Q00607_ProveYourCourageKetra;
|
||||
import quests.Q00608_SlayTheEnemyCommanderKetra.Q00608_SlayTheEnemyCommanderKetra;
|
||||
import quests.Q00609_MagicalPowerOfWaterPart1.Q00609_MagicalPowerOfWaterPart1;
|
||||
import quests.Q00610_MagicalPowerOfWaterPart2.Q00610_MagicalPowerOfWaterPart2;
|
||||
import quests.Q00611_AllianceWithVarkaSilenos.Q00611_AllianceWithVarkaSilenos;
|
||||
import quests.Q00612_BattleAgainstKetraOrcs.Q00612_BattleAgainstKetraOrcs;
|
||||
import quests.Q00613_ProveYourCourageVarka.Q00613_ProveYourCourageVarka;
|
||||
import quests.Q00614_SlayTheEnemyCommanderVarka.Q00614_SlayTheEnemyCommanderVarka;
|
||||
import quests.Q00615_MagicalPowerOfFirePart1.Q00615_MagicalPowerOfFirePart1;
|
||||
import quests.Q00616_MagicalPowerOfFirePart2.Q00616_MagicalPowerOfFirePart2;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
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.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Varka Silenos Barracks and Ketra Orc Outpost AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public class VarkaKetra extends AbstractNpcAI
|
||||
{
|
||||
// Monsters
|
||||
private static final int[] KETRA =
|
||||
{
|
||||
21324, // Ketra Orc Footman
|
||||
21325, // Ketra's War Hound
|
||||
21327, // Ketra Orc Raider
|
||||
21328, // Ketra Orc Scout
|
||||
21329, // Ketra Orc Shaman
|
||||
21331, // Ketra Orc Warrior
|
||||
21332, // Ketra Orc Lieutenant
|
||||
21334, // Ketra Orc Medium
|
||||
21336, // Ketra Orc White Captain
|
||||
21338, // Ketra Orc Seer
|
||||
21339, // Ketra Orc General
|
||||
21340, // Ketra Orc Battalion Commander
|
||||
21342, // Ketra Orc Grand Seer
|
||||
21343, // Ketra Commander
|
||||
21344, // Ketra Elite Guard
|
||||
21345, // Ketra's Head Shaman
|
||||
21346, // Ketra's Head Guard
|
||||
21347, // Ketra Prophet
|
||||
21348, // Prophet's Guard
|
||||
21349, // Prophet's Aide
|
||||
25299, // Ketra's Hero Hekaton (Raid Boss)
|
||||
25302, // Ketra's Commander Tayr (Raid Boss)
|
||||
25305, // Ketra's Chief Brakki (Raid Boss)
|
||||
25306, // Soul of Fire Nastron (Raid Boss)
|
||||
};
|
||||
private static final int[] VARKA =
|
||||
{
|
||||
21350, // Varka Silenos Recruit
|
||||
21351, // Varka Silenos Footman
|
||||
21353, // Varka Silenos Scout
|
||||
21354, // Varka Silenos Hunter
|
||||
21355, // Varka Silenos Shaman
|
||||
21357, // Varka Silenos Priest
|
||||
21358, // Varka Silenos Warrior
|
||||
21360, // Varka Silenos Medium
|
||||
21361, // Varka Silenos Magus
|
||||
21362, // Varka Silenos Officer
|
||||
21364, // Varka Silenos Seer
|
||||
21365, // Varka Silenos Great Magus
|
||||
21366, // Varka Silenos General
|
||||
21368, // Varka Silenos Great Seer
|
||||
21369, // Varka's Commander
|
||||
21370, // Varka's Elite Guard
|
||||
21371, // Varka's Head Magus
|
||||
21372, // Varka's Head Guard
|
||||
21373, // Varka's Prophet
|
||||
21374, // Prophet's Guard
|
||||
21375, // Disciple of Prophet
|
||||
25309, // Varka's Hero Shadith (Raid Boss)
|
||||
25312, // Varka's Commander Mos (Raid Boss)
|
||||
25315, // Varka's Chief Horus (Raid Boss)
|
||||
25316, // Soul of Water Ashutar (Raid Boss)
|
||||
};
|
||||
// Items
|
||||
private static final int[] KETRA_MARKS =
|
||||
{
|
||||
7211, // Mark of Ketra's Alliance - Level 1
|
||||
7212, // Mark of Ketra's Alliance - Level 2
|
||||
7213, // Mark of Ketra's Alliance - Level 3
|
||||
7214, // Mark of Ketra's Alliance - Level 4
|
||||
7215, // Mark of Ketra's Alliance - Level 5
|
||||
};
|
||||
private static final int[] VARKA_MARKS =
|
||||
{
|
||||
7221, // Mark of Varka's Alliance - Level 1
|
||||
7222, // Mark of Varka's Alliance - Level 2
|
||||
7223, // Mark of Varka's Alliance - Level 3
|
||||
7224, // Mark of Varka's Alliance - Level 4
|
||||
7225, // Mark of Varka's Alliance - Level 5
|
||||
};
|
||||
// Quests
|
||||
private static final String[] KETRA_QUESTS =
|
||||
{
|
||||
Q00605_AllianceWithKetraOrcs.class.getSimpleName(),
|
||||
Q00606_BattleAgainstVarkaSilenos.class.getSimpleName(),
|
||||
Q00607_ProveYourCourageKetra.class.getSimpleName(),
|
||||
Q00608_SlayTheEnemyCommanderKetra.class.getSimpleName(),
|
||||
Q00609_MagicalPowerOfWaterPart1.class.getSimpleName(),
|
||||
Q00610_MagicalPowerOfWaterPart2.class.getSimpleName()
|
||||
};
|
||||
private static final String[] VARKA_QUESTS =
|
||||
{
|
||||
Q00611_AllianceWithVarkaSilenos.class.getSimpleName(),
|
||||
Q00612_BattleAgainstKetraOrcs.class.getSimpleName(),
|
||||
Q00613_ProveYourCourageVarka.class.getSimpleName(),
|
||||
Q00614_SlayTheEnemyCommanderVarka.class.getSimpleName(),
|
||||
Q00615_MagicalPowerOfFirePart1.class.getSimpleName(),
|
||||
Q00616_MagicalPowerOfFirePart2.class.getSimpleName()
|
||||
};
|
||||
|
||||
private VarkaKetra()
|
||||
{
|
||||
super(VarkaKetra.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(KETRA);
|
||||
addKillId(VARKA);
|
||||
addNpcHateId(KETRA);
|
||||
addNpcHateId(VARKA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionForEachPlayer(L2PcInstance player, L2Npc npc, boolean isSummon)
|
||||
{
|
||||
if (Util.checkIfInRange(1500, player, npc, false))
|
||||
{
|
||||
if (Util.contains(KETRA, npc.getId()) && hasAtLeastOneQuestItem(player, KETRA_MARKS))
|
||||
{
|
||||
decreaseAlliance(player, KETRA_MARKS);
|
||||
exitQuests(player, KETRA_QUESTS);
|
||||
}
|
||||
else if (Util.contains(VARKA, npc.getId()) && hasAtLeastOneQuestItem(player, VARKA_MARKS))
|
||||
{
|
||||
decreaseAlliance(player, VARKA_MARKS);
|
||||
exitQuests(player, VARKA_QUESTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void decreaseAlliance(L2PcInstance player, int[] marks)
|
||||
{
|
||||
for (int i = 0; i < marks.length; i++)
|
||||
{
|
||||
if (hasQuestItems(player, marks[i]))
|
||||
{
|
||||
takeItems(player, marks[i], -1);
|
||||
if (i > 0)
|
||||
{
|
||||
giveItems(player, marks[i - 1], 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void exitQuests(L2PcInstance player, String[] quests)
|
||||
{
|
||||
for (String quest : quests)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(quest);
|
||||
if ((qs != null) && qs.isStarted())
|
||||
{
|
||||
qs.exitQuest(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
executeForEachPlayer(killer, npc, isSummon, true, false);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return stopAttack(player, mob) ? false : super.onNpcHate(mob, player, isSummon);
|
||||
}
|
||||
|
||||
private final boolean stopAttack(L2PcInstance player, L2Character monster)
|
||||
{
|
||||
return (Util.contains(KETRA, monster.getId()) && hasAtLeastOneQuestItem(player, KETRA_MARKS)) || (Util.contains(VARKA, monster.getId()) && hasAtLeastOneQuestItem(player, VARKA_MARKS));
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new VarkaKetra();
|
||||
}
|
||||
}
|
142
trunk/dist/game/data/scripts/ai/group_template/WarriorFishingBlock.java
vendored
Normal file
142
trunk/dist/game/data/scripts/ai/group_template/WarriorFishingBlock.java
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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 ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlEvent;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Warrior Fishing Block AI.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class WarriorFishingBlock extends AbstractNpcAI
|
||||
{
|
||||
// Monsters
|
||||
private static final int[] MONSTERS =
|
||||
{
|
||||
18319, // Caught Frog
|
||||
18320, // Caught Undine
|
||||
18321, // Caught Rakul
|
||||
18322, // Caught Sea Giant
|
||||
18323, // Caught Sea Horse Soldier
|
||||
18324, // Caught Homunculus
|
||||
18325, // Caught Flava
|
||||
18326, // Caught Gigantic Eye
|
||||
};
|
||||
// NPC Strings
|
||||
private static final NpcStringId[] NPC_STRINGS_ON_SPAWN =
|
||||
{
|
||||
NpcStringId.CROAK_CROAK_FOOD_LIKE_S1_IN_THIS_PLACE,
|
||||
NpcStringId.S1_HOW_LUCKY_I_AM,
|
||||
NpcStringId.PRAY_THAT_YOU_CAUGHT_A_WRONG_FISH_S1
|
||||
};
|
||||
private static final NpcStringId[] NPC_STRINGS_ON_ATTACK =
|
||||
{
|
||||
NpcStringId.DO_YOU_KNOW_WHAT_A_FROG_TASTES_LIKE,
|
||||
NpcStringId.I_WILL_SHOW_YOU_THE_POWER_OF_A_FROG,
|
||||
NpcStringId.I_WILL_SWALLOW_AT_A_MOUTHFUL
|
||||
};
|
||||
private static final NpcStringId[] NPC_STRINGS_ON_KILL =
|
||||
{
|
||||
NpcStringId.UGH_NO_CHANCE_HOW_COULD_THIS_ELDER_PASS_AWAY_LIKE_THIS,
|
||||
NpcStringId.CROAK_CROAK_A_FROG_IS_DYING,
|
||||
NpcStringId.A_FROG_TASTES_BAD_YUCK
|
||||
};
|
||||
// Misc
|
||||
private static final int CHANCE_TO_SHOUT_ON_ATTACK = 33;
|
||||
private static final int DESPAWN_TIME = 50; // 50 seconds to despawn
|
||||
|
||||
public WarriorFishingBlock()
|
||||
{
|
||||
super(WarriorFishingBlock.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MONSTERS);
|
||||
addKillId(MONSTERS);
|
||||
addSpawnId(MONSTERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SPAWN":
|
||||
{
|
||||
final L2Object obj = npc.getTarget();
|
||||
if ((obj == null) || !obj.isPlayer())
|
||||
{
|
||||
npc.decayMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
final L2PcInstance target = obj.getActingPlayer();
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NPC_STRINGS_ON_SPAWN[getRandom(NPC_STRINGS_ON_SPAWN.length)], target.getName());
|
||||
((L2Attackable) npc).addDamageHate(target, 0, 2000);
|
||||
npc.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, target);
|
||||
npc.addAttackerToAttackByList(target);
|
||||
|
||||
startQuestTimer("DESPAWN", DESPAWN_TIME * 1000, npc, target);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "DESPAWN":
|
||||
{
|
||||
npc.decayMe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (getRandom(100) < CHANCE_TO_SHOUT_ON_ATTACK)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NPC_STRINGS_ON_ATTACK[getRandom(NPC_STRINGS_ON_ATTACK.length)]);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NPC_STRINGS_ON_KILL[getRandom(NPC_STRINGS_ON_KILL.length)]);
|
||||
cancelQuestTimer("DESPAWN", npc, killer);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAWN", 2000, npc, null);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new WarriorFishingBlock();
|
||||
}
|
||||
}
|
12
trunk/dist/game/data/scripts/ai/group_template/documentation.txt
vendored
Normal file
12
trunk/dist/game/data/scripts/ai/group_template/documentation.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Group Template AI:
|
||||
This folder contains AI scripts for group templates. That is, if many different mobs share the same behaviour,
|
||||
a group AI script can be created for all of them. Such group templates ought to be here.
|
||||
|
||||
Group templates can be subclassed. In other words, a group may inherit from another group. For example,
|
||||
one group template might define mobs that cast spells. Another template may then define the AI for mobs
|
||||
that cast spells AND use shots. In that case, instead of rewriting all the attack and spell-use AI, we can
|
||||
inherit from the first group template, then add the new behaviours, and split up the NPC registrations appropriately.
|
||||
|
||||
"NPC registrations" refers to the addition of NPCs in the various events of the scripts, such as onAttack, onKill, etc
|
||||
Those are done by using keywords such as "addKillId" etc. For more details on registrations, see
|
||||
"scripts/quests/documentation.txt"
|
37
trunk/dist/game/data/scripts/ai/group_template/package-info.java
vendored
Normal file
37
trunk/dist/game/data/scripts/ai/group_template/package-info.java
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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 DataPack 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Group Template AI:<br>
|
||||
* This folder contains AI scripts for group templates.<br>
|
||||
* That is, if many different mobs share the same behavior, a group AI script can be created for all of them.<br>
|
||||
* Such group templates ought to be here.<br>
|
||||
* <br>
|
||||
* Group templates can be sub-classed.<br>
|
||||
* In other words, a group may inherit from another group.<br>
|
||||
* For example, one group template might define mobs that cast spells.<br>
|
||||
* Another template may then define the AI for mobs that cast spells AND use shots.<br>
|
||||
* In that case, instead of rewriting all the attack and spell-use AI, we can inherit from the first group template, then add the new behaviors, and split up the NPC registrations appropriately.<br>
|
||||
* <br>
|
||||
* "NPC registrations" refers to the addition of NPCs in the various events of the scripts, such as onAttack, onKill, etc.<br>
|
||||
* Those are done by using methods such as addKillId(..) etc.<br>
|
||||
* @see quests
|
||||
* @author Fulminus, Zoey76
|
||||
*/
|
||||
package ai.group_template;
|
Reference in New Issue
Block a user