Merged with released L2J-Unity files.
This commit is contained in:
85
trunk/dist/game/data/scripts/ai/group/AltarOfEvil.java
vendored
Normal file
85
trunk/dist/game/data/scripts/ai/group/AltarOfEvil.java
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Altar of Evil AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class AltarOfEvil extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int RIFTER = 23179; // Dimensional Rifter
|
||||
// Skill
|
||||
private static final SkillHolder SKILL = new SkillHolder(14643, 1); // Summon
|
||||
|
||||
public AltarOfEvil()
|
||||
{
|
||||
addAttackId(RIFTER);
|
||||
addNpcHateId(RIFTER);
|
||||
addSpellFinishedId(RIFTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
teleportPlayer(mob, player);
|
||||
return super.onNpcHate(mob, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
teleportPlayer(npc, attacker);
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (skill.getId() == SKILL.getSkillId())
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.DIMENSIONAL_RIFTER_SUMMONED_YOU, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
player.teleToLocation(npc);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void teleportPlayer(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc.isScriptValue(0) && (npc.calculateDistance(player, true, false) > 200))
|
||||
{
|
||||
addSkillCastDesire(npc, player, SKILL, 23);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new AltarOfEvil();
|
||||
}
|
||||
}
|
149
trunk/dist/game/data/scripts/ai/group/AreaSkillNpc.java
vendored
Normal file
149
trunk/dist/game/data/scripts/ai/group/AreaSkillNpc.java
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Area Skill Npc AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class AreaSkillNpc extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] BASIC = // area_skill_npc
|
||||
{
|
||||
13018, // Maximum Defense
|
||||
13019, // Anti-Music
|
||||
13020, // Maximum Resist Status
|
||||
13021, // Maximum Recovery
|
||||
13022, // Recover Force
|
||||
13023, // Maximize long-range weapon use
|
||||
13024, // Smokescreen
|
||||
13028, // Day of Doom
|
||||
13030, // Anti-Summoning Field
|
||||
13323, // Whisper of Fear
|
||||
13324, // Whisper of Fear
|
||||
13325, // Whisper of Fear
|
||||
13458, // Whisper of Fear
|
||||
13459, // Whisper of Fear
|
||||
13460, // Whisper of Fear
|
||||
13310, // Solo Dance
|
||||
13377, // Solo Dance
|
||||
13378, // Solo Dance
|
||||
13379, // Solo Dance
|
||||
13380, // Solo Dance
|
||||
13381, // Solo Dance
|
||||
13452, // Solo Dance
|
||||
13453, // Solo Dance
|
||||
13454, // Solo Dance
|
||||
};
|
||||
private static final int[] TOTEMS = // ai_totem_of_body
|
||||
{
|
||||
143, // Totem of Body
|
||||
144, // Totem of Spirit
|
||||
145, // Totem of Bravery
|
||||
146, // Totem of Fortitude
|
||||
};
|
||||
private static final int[] DECOY = // ai_decoy
|
||||
{
|
||||
13071, // Virtual Image
|
||||
13072, // Virtual Image
|
||||
13073, // Virtual Image
|
||||
13074, // Virtual Image
|
||||
13075, // Virtual Image
|
||||
13076, // Virtual Image
|
||||
13257, // Virtual Image
|
||||
13258, // Virtual Image
|
||||
13259, // Virtual Image
|
||||
13260, // Virtual Image
|
||||
13261, // Virtual Image
|
||||
13262, // Virtual Image
|
||||
13263, // Virtual Image
|
||||
13264, // Virtual Image
|
||||
13265, // Virtual Image
|
||||
13266, // Virtual Image
|
||||
13267, // Virtual Image
|
||||
13328, // Decoy
|
||||
};
|
||||
|
||||
private AreaSkillNpc()
|
||||
{
|
||||
addSpawnId(BASIC);
|
||||
addSpawnId(TOTEMS);
|
||||
addSpawnId(DECOY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final L2Character summoner = npc.getSummoner();
|
||||
if ((summoner != null) && summoner.isPlayer())
|
||||
{
|
||||
final L2PcInstance player = summoner.getActingPlayer();
|
||||
|
||||
if (CommonUtil.contains(BASIC, npc.getId()) || CommonUtil.contains(TOTEMS, npc.getId()))
|
||||
{
|
||||
final int despawnTime = npc.getTemplate().getParameters().getInt("despawn_time", 7);
|
||||
getTimers().addTimer("SKILL_CAST_BASIC", 100, npc, player);
|
||||
getTimers().addTimer("DELETE_ME", (despawnTime * 1000), npc, player);
|
||||
}
|
||||
else if (CommonUtil.contains(DECOY, npc.getId()))
|
||||
{
|
||||
final int castTime = npc.getTemplate().getParameters().getInt("i_use_term_time", 5000);
|
||||
final int despawnTime = npc.getTemplate().getParameters().getInt("i_despawn_time", 30000);
|
||||
onTimerEvent("SKILL_CAST_BASIC", null, npc, player); // Trigger cast instantly
|
||||
getTimers().addTimer("SKILL_CAST_BASIC", castTime, npc, player);
|
||||
getTimers().addTimer("DELETE_ME", despawnTime, npc, player);
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SKILL_CAST_BASIC"))
|
||||
{
|
||||
final SkillHolder skill = npc.getParameters().getSkillHolder(CommonUtil.contains(DECOY, npc.getId()) ? "decoy_skill" : "union_skill");
|
||||
final int skillDelay = npc.getParameters().getInt("skill_delay", 2);
|
||||
|
||||
if (skill != null)
|
||||
{
|
||||
npc.doCast(skill.getSkill());
|
||||
getTimers().addTimer("SKILL_CAST_BASIC", skillDelay * 1000, npc, player);
|
||||
}
|
||||
}
|
||||
else if (event.equals("DELETE_ME"))
|
||||
{
|
||||
getTimers().cancelTimer("SKILL_CAST_BASIC", npc, player);
|
||||
npc.deleteMe();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new AreaSkillNpc();
|
||||
}
|
||||
}
|
125
trunk/dist/game/data/scripts/ai/group/BabyPets.java
vendored
Normal file
125
trunk/dist/game/data/scripts/ai/group/BabyPets.java
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Baby Pets AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class BabyPets extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] BABY_PETS =
|
||||
{
|
||||
12780, // Baby Buffalo
|
||||
12781, // Baby Kookaburra
|
||||
12782, // Baby Cougar
|
||||
};
|
||||
// Skills
|
||||
private static final int HEAL_1 = 4717; // Heal Trick
|
||||
private static final int HEAL_2 = 4718; // Greater Heal Trick
|
||||
|
||||
private BabyPets()
|
||||
{
|
||||
addSummonSpawnId(BABY_PETS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("HEAL") && (player != null))
|
||||
{
|
||||
final L2Summon summon = player.getPet();
|
||||
|
||||
if (summon != null)
|
||||
{
|
||||
if (getRandom(100) <= 25)
|
||||
{
|
||||
castHeal(summon, new SkillHolder(HEAL_1, getHealLv(summon)), 80);
|
||||
}
|
||||
|
||||
if (getRandom(100) <= 75)
|
||||
{
|
||||
castHeal(summon, new SkillHolder(HEAL_2, getHealLv(summon)), 15);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelQuestTimer("HEAL", null, player);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_PLAYER_LOGOUT)
|
||||
@RegisterType(ListenerRegisterType.GLOBAL)
|
||||
public void OnPlayerLogout(OnPlayerLogout event)
|
||||
{
|
||||
cancelQuestTimer("HEAL", null, event.getActiveChar());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonSpawn(L2Summon summon)
|
||||
{
|
||||
startQuestTimer("HEAL", 5000, null, summon.getOwner(), true);
|
||||
}
|
||||
|
||||
private int getHealLv(L2Summon summon)
|
||||
{
|
||||
final int summonLv = summon.getLevel();
|
||||
return CommonUtil.constrain(summonLv < 70 ? (summonLv / 10) : (7 + ((summonLv - 70) / 5)), 1, 12);
|
||||
}
|
||||
|
||||
private void castHeal(L2Summon summon, SkillHolder skill, int maxHpPer)
|
||||
{
|
||||
final boolean previousFollowStatus = summon.getFollowStatus();
|
||||
final L2PcInstance owner = summon.getOwner();
|
||||
|
||||
if (!owner.isDead() && (((owner.getCurrentHp() / owner.getMaxHp()) * 100) < maxHpPer) && !summon.isHungry() && SkillCaster.checkUseConditions(summon, skill.getSkill()))
|
||||
{
|
||||
summon.getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill.getSkill(), owner);
|
||||
summon.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_PET_USES_S1).addSkillName(skill.getSkill()));
|
||||
|
||||
if (previousFollowStatus != summon.getFollowStatus())
|
||||
{
|
||||
summon.setFollowStatus(previousFollowStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BabyPets();
|
||||
}
|
||||
}
|
481
trunk/dist/game/data/scripts/ai/group/BeastFarm.java
vendored
Normal file
481
trunk/dist/game/data/scripts/ai/group/BeastFarm.java
vendored
Normal file
@ -0,0 +1,481 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2TamedBeastInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcInfo;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
|
||||
|
||||
/**
|
||||
* 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, GrowthCapableMob> GROWTH_CAPABLE_MOBS = new HashMap<>();
|
||||
private static List<TamedBeast> TAMED_BEAST_DATA = new ArrayList<>();
|
||||
private final Map<Integer, Integer> _feedInfo = new ConcurrentHashMap<>();
|
||||
|
||||
private BeastFarm()
|
||||
{
|
||||
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);
|
||||
GROWTH_CAPABLE_MOBS.put(18873, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18876);
|
||||
GROWTH_CAPABLE_MOBS.put(18874, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18877);
|
||||
GROWTH_CAPABLE_MOBS.put(18875, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18878);
|
||||
GROWTH_CAPABLE_MOBS.put(18876, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18879);
|
||||
GROWTH_CAPABLE_MOBS.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);
|
||||
GROWTH_CAPABLE_MOBS.put(18880, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18883);
|
||||
GROWTH_CAPABLE_MOBS.put(18881, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18884);
|
||||
GROWTH_CAPABLE_MOBS.put(18882, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18885);
|
||||
GROWTH_CAPABLE_MOBS.put(18883, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18886);
|
||||
GROWTH_CAPABLE_MOBS.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);
|
||||
GROWTH_CAPABLE_MOBS.put(18887, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18890);
|
||||
GROWTH_CAPABLE_MOBS.put(18888, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18891);
|
||||
GROWTH_CAPABLE_MOBS.put(18889, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18892);
|
||||
GROWTH_CAPABLE_MOBS.put(18890, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18893);
|
||||
GROWTH_CAPABLE_MOBS.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);
|
||||
GROWTH_CAPABLE_MOBS.put(18894, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18897);
|
||||
GROWTH_CAPABLE_MOBS.put(18895, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18898);
|
||||
GROWTH_CAPABLE_MOBS.put(18896, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18899);
|
||||
GROWTH_CAPABLE_MOBS.put(18897, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18900);
|
||||
GROWTH_CAPABLE_MOBS.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 (CommonUtil.contains(TAMED_BEASTS, nextNpcId))
|
||||
{
|
||||
final L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(nextNpcId, player, food, npc.getX(), npc.getY(), npc.getZ(), true);
|
||||
|
||||
final 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();
|
||||
|
||||
final 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?!)
|
||||
final 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 (!CommonUtil.contains(targets, npc))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
// gather some values on local variables
|
||||
final int npcId = npc.getId();
|
||||
final int skillId = skill.getId();
|
||||
// check if the npc and skills used are valid for this script. Exit if invalid.
|
||||
if (!CommonUtil.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
|
||||
final 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 (GROWTH_CAPABLE_MOBS.containsKey(npcId))
|
||||
{
|
||||
growthLevel = GROWTH_CAPABLE_MOBS.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 (GROWTH_CAPABLE_MOBS.containsKey(npcId))
|
||||
{
|
||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
||||
final int newNpcId = GROWTH_CAPABLE_MOBS.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 ConcurrentHashMap<>();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
53
trunk/dist/game/data/scripts/ai/group/BloodySwampland.java
vendored
Normal file
53
trunk/dist/game/data/scripts/ai/group/BloodySwampland.java
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Bloody Swampland AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class BloodySwampland extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int COLLECTOR = 23171; // Corpse Collector
|
||||
|
||||
public BloodySwampland()
|
||||
{
|
||||
addAttackId(COLLECTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.3)))
|
||||
{
|
||||
addSkillCastDesire(npc, attacker, npc.getParameters().getSkillHolder("Skill01_ID"), 23);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BloodySwampland();
|
||||
}
|
||||
}
|
91
trunk/dist/game/data/scripts/ai/group/CrumaTower.java
vendored
Normal file
91
trunk/dist/game/data/scripts/ai/group/CrumaTower.java
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.Id;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDamageReceived;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Cruma Tower AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class CrumaTower extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int CARSUS = 30483;
|
||||
private static final int TELEPORT_DEVICE = 33157;
|
||||
|
||||
public CrumaTower()
|
||||
{
|
||||
addSpawnId(CARSUS);
|
||||
addAttackId(TELEPORT_DEVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("MESSAGE") && (npc != null))
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.YOU_CAN_GO_TO_UNDERGROUND_LV_3_USING_THE_ELEVATOR_IN_THE_BACK);
|
||||
getTimers().addTimer(event, 15000, npc, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onTimerEvent(event, params, npc, player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
getTimers().addTimer("MESSAGE", 15000, npc, null);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_CREATURE_DAMAGE_RECEIVED)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(TELEPORT_DEVICE)
|
||||
public void onCreatureDamageReceived(OnCreatureDamageReceived event)
|
||||
{
|
||||
try
|
||||
{
|
||||
final L2Npc npc = (L2Npc) event.getTarget();
|
||||
final int[] location = npc.getParameters().getIntArray("teleport", ";");
|
||||
event.getAttacker().teleToLocation(location[0], location[1], location[2]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.warning("Invalid location for Cruma Tower teleport device.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new CrumaTower();
|
||||
}
|
||||
}
|
235
trunk/dist/game/data/scripts/ai/group/DenOfEvil.java
vendored
Normal file
235
trunk/dist/game/data/scripts/ai/group/DenOfEvil.java
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2EffectZone;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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);
|
||||
final 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;
|
||||
}
|
||||
final int skillId = getSkillIdByNpcId(npc.getId());
|
||||
final 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);
|
||||
final 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;
|
||||
}
|
||||
final int skillId = getSkillIdByNpcId(npc.getId());
|
||||
final 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())
|
||||
{
|
||||
final Skill skill = SkillData.getInstance().getSkill(6149, 1);
|
||||
skill.applyEffects(character, character);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (character.doDie(null)) // mobs die
|
||||
{
|
||||
if (character.isNpc())
|
||||
{
|
||||
// respawn eye
|
||||
final L2Npc npc = (L2Npc) character;
|
||||
if (CommonUtil.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();
|
||||
}
|
||||
}
|
73
trunk/dist/game/data/scripts/ai/group/EventShrines.java
vendored
Normal file
73
trunk/dist/game/data/scripts/ai/group/EventShrines.java
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.instancemanager.EventShrineManager;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.quest.Quest;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.OnEventTrigger;
|
||||
|
||||
/**
|
||||
* @author hlwrave, Mobius
|
||||
* @Add in event config.xml enableShrines="true" after event name to enable them.
|
||||
*/
|
||||
final public class EventShrines extends Quest
|
||||
{
|
||||
private static final Map<Integer, Integer> ZONE_TRIGGERS = new HashMap<>();
|
||||
static
|
||||
{
|
||||
ZONE_TRIGGERS.put(11030, 23206292); // Hunter
|
||||
ZONE_TRIGGERS.put(11031, 24186292); // Aden
|
||||
ZONE_TRIGGERS.put(11032, 24166292); // Goddard
|
||||
ZONE_TRIGGERS.put(11035, 22136292); // Shuttgard
|
||||
ZONE_TRIGGERS.put(11028, 20226292); // Dion
|
||||
ZONE_TRIGGERS.put(11029, 22196292); // Oren
|
||||
ZONE_TRIGGERS.put(11020, 22226292); // Giran
|
||||
ZONE_TRIGGERS.put(11027, 19216292); // Gludio
|
||||
ZONE_TRIGGERS.put(11034, 23246292); // Heine
|
||||
ZONE_TRIGGERS.put(11025, 17226292); // Gluddin
|
||||
ZONE_TRIGGERS.put(11033, 21166292); // Rune
|
||||
ZONE_TRIGGERS.put(11042, 17256292); // Faeron
|
||||
ZONE_TRIGGERS.put(11043, 26206292); // Arcan
|
||||
ZONE_TRIGGERS.put(11022, 16256292); // Talking Island
|
||||
}
|
||||
|
||||
public EventShrines()
|
||||
{
|
||||
super(-1);
|
||||
addEnterZoneId(ZONE_TRIGGERS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (character.isPlayer() && EventShrineManager.getInstance().areShrinesEnabled())
|
||||
{
|
||||
character.sendPacket(new OnEventTrigger(ZONE_TRIGGERS.get(zone.getId()), true));
|
||||
}
|
||||
return super.onEnterZone(character, zone);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EventShrines();
|
||||
}
|
||||
}
|
610
trunk/dist/game/data/scripts/ai/group/FeedableBeasts.java
vendored
Normal file
610
trunk/dist/game/data/scripts/ai/group/FeedableBeasts.java
vendored
Normal file
@ -0,0 +1,610 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2TamedBeastInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
// Tamed Wild Beasts
|
||||
private static final int TRAINED_BUFFALO1 = 16013;
|
||||
private static final int TRAINED_BUFFALO2 = 16014;
|
||||
private static final int TRAINED_COUGAR1 = 16015;
|
||||
private static final int TRAINED_COUGAR2 = 16016;
|
||||
private static final int TRAINED_KOOKABURRA1 = 16017;
|
||||
private static final int TRAINED_KOOKABURRA2 = 16018;
|
||||
// private static final int TRAINED_TINY_BABY_BUFFALO = 16020; // TODO: Implement.
|
||||
// private static final int TRAINED_TINY_BABY_COUGAR = 16022; // TODO: Implement.
|
||||
// private static final int TRAINED_TINY_BABY_KOOKABURRA = 16024; // TODO: Implement.
|
||||
// @formatter:off
|
||||
private static final int[] TAMED_BEASTS =
|
||||
{
|
||||
TRAINED_BUFFALO1, TRAINED_BUFFALO2, TRAINED_COUGAR1, TRAINED_COUGAR2, TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2
|
||||
};
|
||||
// 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, TRAINED_BUFFALO1, TRAINED_BUFFALO2, TRAINED_COUGAR1, TRAINED_COUGAR2, TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
private static final Map<Integer, Integer> MAD_COW_POLYMORPH = new HashMap<>(6);
|
||||
|
||||
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 final Map<Integer, Integer> _feedInfo = new ConcurrentHashMap<>();
|
||||
private static Map<Integer, GrowthCapableMob> GROWTH_CAPABLE_MOBS = new HashMap<>();
|
||||
|
||||
// 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 ConcurrentHashMap<>();
|
||||
|
||||
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);
|
||||
final int rand = getRandom(temp[0].length);
|
||||
return temp[0][rand];
|
||||
}
|
||||
|
||||
public Integer getChance()
|
||||
{
|
||||
return _chance;
|
||||
}
|
||||
|
||||
public Integer getGrowthLevel()
|
||||
{
|
||||
return _growthLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private FeedableBeasts()
|
||||
{
|
||||
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}, { TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2 }};
|
||||
final int[][] Kookabura_2_2 = {{ 21469, 21825}, { TRAINED_KOOKABURRA1, TRAINED_KOOKABURRA2 }};
|
||||
|
||||
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}, {TRAINED_BUFFALO1, TRAINED_BUFFALO2 }};
|
||||
final int[][] Buffalo_2_2 = {{ 21488, 21827}, {TRAINED_BUFFALO1, TRAINED_BUFFALO2 }};
|
||||
|
||||
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 }, { TRAINED_COUGAR1, TRAINED_COUGAR2 }};
|
||||
final int[][] Cougar_2_2 = {{ 21507, 21829 }, { TRAINED_COUGAR1, TRAINED_COUGAR2 }};
|
||||
//@formatter:on
|
||||
|
||||
// Alpen Kookabura
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_0_Crystal);
|
||||
GROWTH_CAPABLE_MOBS.put(21451, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21452, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21454, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21453, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21455, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21456, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21458, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21457, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21459, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21460, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21462, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21461, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21463, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21464, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21466, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21465, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21467, temp);
|
||||
|
||||
// Alpen Buffalo
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_0_Crystal);
|
||||
GROWTH_CAPABLE_MOBS.put(21470, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21471, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21473, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21472, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21474, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21475, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21477, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21476, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21478, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21479, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21481, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21480, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21482, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21483, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21485, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21484, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21486, temp);
|
||||
|
||||
// Alpen Cougar
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_0_Crystal);
|
||||
GROWTH_CAPABLE_MOBS.put(21489, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21490, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21492, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21491, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21493, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21494, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21496, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21495, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21497, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21498, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21500, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21499, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21501, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_1);
|
||||
GROWTH_CAPABLE_MOBS.put(21502, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21504, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_2);
|
||||
GROWTH_CAPABLE_MOBS.put(21503, temp);
|
||||
GROWTH_CAPABLE_MOBS.put(21505, temp);
|
||||
}
|
||||
|
||||
private void spawnNext(L2Npc npc, int growthLevel, L2PcInstance player, int food)
|
||||
{
|
||||
final 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 = GROWTH_CAPABLE_MOBS.get(npcId).getMob(food, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNpcId = GROWTH_CAPABLE_MOBS.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 = GROWTH_CAPABLE_MOBS.get(npcId).getMob(food, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNpcId = GROWTH_CAPABLE_MOBS.get(npcId).getMob(food, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// all other levels of growth are straight-forward
|
||||
nextNpcId = GROWTH_CAPABLE_MOBS.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 (CommonUtil.contains(TAMED_BEASTS, nextNpcId))
|
||||
{
|
||||
if ((player.getTrainedBeasts() != null) && !player.getTrainedBeasts().isEmpty())
|
||||
{
|
||||
for (L2TamedBeastInstance oldTrained : player.getTrainedBeasts())
|
||||
{
|
||||
oldTrained.deleteMe();
|
||||
}
|
||||
}
|
||||
|
||||
final L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(nextNpcId, player, food - FOODSKILLDIFF, npc.getX(), npc.getY(), npc.getZ());
|
||||
nextNpc.setRunning();
|
||||
Q00020_BringUpWithLove.checkJewelOfInnocence(player);
|
||||
|
||||
// Support for A Grand Plan for Taming Wild Beasts (655) quest.
|
||||
// Q00655_AGrandPlanForTamingWildBeasts.reward(player, nextNpc); TODO: Replace me?
|
||||
|
||||
// also, perform a rare random chat
|
||||
if (getRandom(20) == 0)
|
||||
{
|
||||
final NpcStringId message = NpcStringId.getNpcStringId(getRandom(2024, 2029));
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, message, message.getParamCount() > 0 ? player.getName() : null);
|
||||
}
|
||||
// @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?!)
|
||||
final L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
|
||||
|
||||
if (MAD_COW_POLYMORPH.containsKey(nextNpcId))
|
||||
{
|
||||
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
|
||||
final 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 (!CommonUtil.contains(targets, npc))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
// gather some values on local variables
|
||||
final int npcId = npc.getId();
|
||||
final 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
|
||||
final 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 (GROWTH_CAPABLE_MOBS.containsKey(npcId))
|
||||
{
|
||||
growthLevel = GROWTH_CAPABLE_MOBS.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 (GROWTH_CAPABLE_MOBS.containsKey(npcId))
|
||||
{
|
||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
||||
if (GROWTH_CAPABLE_MOBS.get(npcId).getMob(food, 0, 0) == null)
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// rare random talk...
|
||||
if (getRandom(20) == 0)
|
||||
{
|
||||
final NpcStringId message = TEXT[growthLevel][getRandom(TEXT[growthLevel].length)];
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, message, message.getParamCount() > 0 ? caster.getName() : null);
|
||||
}
|
||||
|
||||
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) < GROWTH_CAPABLE_MOBS.get(npcId).getChance())
|
||||
{
|
||||
spawnNext(npc, growthLevel, caster, food);
|
||||
}
|
||||
}
|
||||
else if (CommonUtil.contains(TAMED_BEASTS, npcId) && (npc instanceof L2TamedBeastInstance))
|
||||
{
|
||||
final L2TamedBeastInstance beast = ((L2TamedBeastInstance) npc);
|
||||
if (skillId == beast.getFoodType())
|
||||
{
|
||||
beast.onReceiveFood();
|
||||
final NpcStringId message = TAMED_TEXT[getRandom(TAMED_TEXT.length)];
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, message, message.getParamCount() > 0 ? caster.getName() : null);
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
68
trunk/dist/game/data/scripts/ai/group/FrozenLabyrinth.java
vendored
Normal file
68
trunk/dist/game/data/scripts/ai/group/FrozenLabyrinth.java
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
112
trunk/dist/game/data/scripts/ai/group/GiantsCave.java
vendored
Normal file
112
trunk/dist/game/data/scripts/ai/group/GiantsCave.java
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.INTRUDER_DETECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_SHOUT, NpcStringId.OH_GIANTS_AN_INTRUDER_HAS_BEEN_DISCOVERED);
|
||||
}
|
||||
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Attackable.class, 450, characters ->
|
||||
{
|
||||
if ((getRandomBoolean()))
|
||||
{
|
||||
addAttackPlayerDesire(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())
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.YOU_GUYS_ARE_DETECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, 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();
|
||||
}
|
||||
}
|
107
trunk/dist/game/data/scripts/ai/group/HotSprings.java
vendored
Normal file
107
trunk/dist/game/data/scripts/ai/group/HotSprings.java
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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) && SkillCaster.checkUseConditions(npc, skill))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skill);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new HotSprings();
|
||||
}
|
||||
}
|
211
trunk/dist/game/data/scripts/ai/group/ImprovedBabyPets.java
vendored
Normal file
211
trunk/dist/game/data/scripts/ai/group/ImprovedBabyPets.java
vendored
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerLogout;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Improved Baby Pets AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class ImprovedBabyPets extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] BABY_PETS =
|
||||
{
|
||||
16034, // Improved Baby Buffalo
|
||||
16035, // Improved Baby Kookaburra
|
||||
16036, // Improved Baby Cougar
|
||||
};
|
||||
// Skills
|
||||
private static final int PET_CONTROL = 5771;
|
||||
|
||||
private ImprovedBabyPets()
|
||||
{
|
||||
addSummonSpawnId(BABY_PETS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
final L2Summon summon = player.getPet();
|
||||
|
||||
if (summon == null)
|
||||
{
|
||||
cancelQuestTimer("HEAL", null, player);
|
||||
cancelQuestTimer("BUFF", null, player);
|
||||
}
|
||||
else if (event.equals("HEAL") && player.isInCombat() && !summon.isHungry())
|
||||
{
|
||||
final double hpPer = (player.getCurrentHp() / player.getMaxHp()) * 100;
|
||||
final double mpPer = (player.getCurrentMp() / player.getMaxMp()) * 100;
|
||||
final int healType = summon.getTemplate().getParameters().getInt("heal_type", 0);
|
||||
final int skillLv = (int) Math.floor((summon.getLevel() / 5) - 11);
|
||||
|
||||
if (healType == 1)
|
||||
{
|
||||
final int stepLv = CommonUtil.constrain(skillLv, 0, 3);
|
||||
|
||||
if ((hpPer >= 30) && (hpPer < 70))
|
||||
{
|
||||
castHeal(summon, stepLv, 1);
|
||||
}
|
||||
else if (hpPer < 30)
|
||||
{
|
||||
castHeal(summon, stepLv, 2);
|
||||
}
|
||||
}
|
||||
else if (healType == 0)
|
||||
{
|
||||
if (hpPer < 30)
|
||||
{
|
||||
castHeal(summon, CommonUtil.constrain(skillLv, 0, 3), 2);
|
||||
}
|
||||
else if (mpPer < 60)
|
||||
{
|
||||
castHeal(summon, CommonUtil.constrain(skillLv, 0, 5), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equals("BUFF") && !summon.isAffectedBySkill(PET_CONTROL) && !summon.isHungry())
|
||||
{
|
||||
final int buffStep = (int) CommonUtil.constrain(Math.floor((summon.getLevel() / 5) - 11), 0, 3);
|
||||
|
||||
for (int i = 1; i <= (2 * (1 + buffStep)); i++)
|
||||
{
|
||||
if (castBuff(summon, buffStep, i))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonSpawn(L2Summon summon)
|
||||
{
|
||||
startQuestTimer("HEAL", 5000, null, summon.getOwner(), true);
|
||||
startQuestTimer("BUFF", 10000, null, summon.getOwner(), true);
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_PLAYER_LOGOUT)
|
||||
@RegisterType(ListenerRegisterType.GLOBAL)
|
||||
public void OnPlayerLogout(OnPlayerLogout event)
|
||||
{
|
||||
cancelQuestTimer("HEAL", null, event.getActiveChar());
|
||||
cancelQuestTimer("BUFF", null, event.getActiveChar());
|
||||
}
|
||||
|
||||
private boolean castBuff(L2Summon summon, int stepNumber, int buffNumber)
|
||||
{
|
||||
final L2PcInstance owner = summon.getOwner();
|
||||
final StatsSet parameters = summon.getTemplate().getParameters();
|
||||
final SkillHolder skill = parameters.getObject("step" + stepNumber + "_buff0" + buffNumber, SkillHolder.class);
|
||||
|
||||
if ((skill != null) && (owner != null))
|
||||
{
|
||||
final boolean previousFollowStatus = summon.getFollowStatus();
|
||||
final SkillHolder mergedSkill = parameters.getObject("step" + stepNumber + "_merged_buff0" + buffNumber, SkillHolder.class);
|
||||
final int targetType = parameters.getInt("step" + stepNumber + "_buff_target0" + buffNumber, 0);
|
||||
|
||||
if (!owner.hasAbnormalType(skill.getSkill().getAbnormalType()) && SkillCaster.checkUseConditions(summon, skill.getSkill()) && !owner.isDead())
|
||||
{
|
||||
if (mergedSkill != null)
|
||||
{
|
||||
if (owner.hasAbnormalType(mergedSkill.getSkill().getAbnormalType()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!previousFollowStatus && !summon.isInsideRadius(owner, skill.getSkill().getCastRange(), true, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((targetType >= 0) && (targetType <= 2))
|
||||
{
|
||||
summon.getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill.getSkill(), (targetType == 1) ? summon : owner);
|
||||
summon.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_PET_USES_S1).addSkillName(skill.getSkill()));
|
||||
|
||||
if (previousFollowStatus != summon.getFollowStatus())
|
||||
{
|
||||
summon.setFollowStatus(previousFollowStatus);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void castHeal(L2Summon summon, int stepNumber, int healNumber)
|
||||
{
|
||||
final boolean previousFollowStatus = summon.getFollowStatus();
|
||||
final L2PcInstance owner = summon.getOwner();
|
||||
final StatsSet parameters = summon.getTemplate().getParameters();
|
||||
final SkillHolder skill = parameters.getObject("step" + stepNumber + "_heal0" + healNumber, SkillHolder.class);
|
||||
final int targetType = parameters.getInt("step" + stepNumber + "_heal_target0" + healNumber, 0);
|
||||
|
||||
if ((skill != null) && (owner != null) && SkillCaster.checkUseConditions(summon, skill.getSkill()) && !owner.isDead())
|
||||
{
|
||||
if (!previousFollowStatus && !summon.isInsideRadius(owner, skill.getSkill().getCastRange(), true, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!owner.hasAbnormalType(skill.getSkill().getAbnormalType()))
|
||||
{
|
||||
if ((targetType >= 0) && (targetType <= 2))
|
||||
{
|
||||
summon.getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill.getSkill(), (targetType == 1) ? summon : owner);
|
||||
summon.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_PET_USES_S1).addSkillName(skill.getSkill()));
|
||||
|
||||
if (previousFollowStatus != summon.getFollowStatus())
|
||||
{
|
||||
summon.setFollowStatus(previousFollowStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new ImprovedBabyPets();
|
||||
}
|
||||
}
|
81
trunk/dist/game/data/scripts/ai/group/IsleOfPrayer.java
vendored
Normal file
81
trunk/dist/game/data/scripts/ai/group/IsleOfPrayer.java
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
139
trunk/dist/game/data/scripts/ai/group/LairOfAntharas.java
vendored
Normal file
139
trunk/dist/game/data/scripts/ai/group/LairOfAntharas.java
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
npc.broadcastSay(ChatType.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();
|
||||
newKnight.broadcastSay(ChatType.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();
|
||||
eliteKnight.broadcastSay(ChatType.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)
|
||||
{
|
||||
if ((npc.getId() == DRAGON_GUARD) || (npc.getId() == DRAGON_MAGE))
|
||||
{
|
||||
npc.setRandomWalking(true);
|
||||
startQuestTimer("CHECK_HOME", 10000, npc, null, true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new LairOfAntharas();
|
||||
}
|
||||
}
|
293
trunk/dist/game/data/scripts/ai/group/MonasteryOfSilence.java
vendored
Normal file
293
trunk/dist/game/data/scripts/ai/group/MonasteryOfSilence.java
vendored
Normal file
@ -0,0 +1,293 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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":
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Npc.class, 400, character ->
|
||||
{
|
||||
if ((getRandom(100) < 30) && !character.isDead() && !character.isInCombat())
|
||||
{
|
||||
if ((character.getId() == CAPTAIN) && (getRandom(100) < 10) && npc.isScriptValue(0))
|
||||
{
|
||||
character.broadcastSay(ChatType.NPC_GENERAL, SOLINA_KNIGHTS_MSG[getRandom(SOLINA_KNIGHTS_MSG.length)]);
|
||||
character.setScriptValue(1);
|
||||
startQuestTimer("TIMER", 10000, character, 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 (SkillCaster.checkUseConditions(npc, 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) && SkillCaster.checkUseConditions(mob, 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 (SkillCaster.checkUseConditions(npc, KNIGHT_BLESS.getSkill()))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(KNIGHT_BLESS.getSkill());
|
||||
}
|
||||
npc.setScriptValue(1);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.FOR_THE_GLORY_OF_SOLINA);
|
||||
addAttackPlayerDesire(addSpawn(KNIGHT, npc), player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUIDE:
|
||||
{
|
||||
if ((getRandom(100) < 3) && (mob.getMostHated() == player) && SkillCaster.checkUseConditions(npc, ORDEAL_STRIKE.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(ORDEAL_STRIKE.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SEEKER:
|
||||
{
|
||||
if ((getRandom(100) < 33) && (mob.getMostHated() == player) && SkillCaster.checkUseConditions(npc, 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) && SkillCaster.checkUseConditions(npc, skill.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skill.getSkill());
|
||||
}
|
||||
|
||||
if (!npc.isInCombat())
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, 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))
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, 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();
|
||||
}
|
||||
}
|
65
trunk/dist/game/data/scripts/ai/group/OrbisTemple.java
vendored
Normal file
65
trunk/dist/game/data/scripts/ai/group/OrbisTemple.java
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Orbis Temple AI.
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class OrbisTemple extends AbstractNpcAI
|
||||
{
|
||||
private static final Map<Integer, Location> TELEPORT_DATA = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
TELEPORT_DATA.put(12036, new Location(213983, 53250, -8176));
|
||||
TELEPORT_DATA.put(12037, new Location(198022, 90032, -192));
|
||||
TELEPORT_DATA.put(12038, new Location(213799, 53253, -14432));
|
||||
TELEPORT_DATA.put(12039, new Location(215056, 50467, -8416));
|
||||
TELEPORT_DATA.put(12040, new Location(211641, 115547, -12736));
|
||||
TELEPORT_DATA.put(12041, new Location(211137, 50501, -14624));
|
||||
}
|
||||
|
||||
public OrbisTemple()
|
||||
{
|
||||
addEnterZoneId(TELEPORT_DATA.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character creature, L2ZoneType zone)
|
||||
{
|
||||
if (creature.isPlayer() && (creature.getInstanceWorld() == null))
|
||||
{
|
||||
creature.teleToLocation(TELEPORT_DATA.get(zone.getId()));
|
||||
}
|
||||
return super.onEnterZone(creature, zone);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new OrbisTemple();
|
||||
}
|
||||
}
|
91
trunk/dist/game/data/scripts/ai/group/OrcBarracks.java
vendored
Normal file
91
trunk/dist/game/data/scripts/ai/group/OrcBarracks.java
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Orc Barracks AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class OrcBarracks extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int TUREK_ORC_FOOTMAN = 20499;
|
||||
private static final int TUREK_WAR_HOUND = 20494;
|
||||
private static final int CHERTUBA_MIRAGE = 23421;
|
||||
private static final int CHERTUBA_ILLUSION = 23422;
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
20495, // Turek Orc Prefect
|
||||
20496, // Turek Orc Archer
|
||||
20497, // Turek Orc Skirmisher
|
||||
20498, // Turek Orc Supplier
|
||||
20500, // Turek Orc Sentinel
|
||||
20501, // Turek Orc Priest
|
||||
20546, // Turek Orc Elder
|
||||
23418, // Marionette Spirit
|
||||
};
|
||||
// Misc
|
||||
private static final int MINION_COUNT = 2;
|
||||
private static final int SPAWN_RATE = 80;
|
||||
|
||||
public OrcBarracks()
|
||||
{
|
||||
addSpawnId(TUREK_ORC_FOOTMAN);
|
||||
addKillId(TUREK_ORC_FOOTMAN);
|
||||
addKillId(MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final boolean hasMinions = npc.getParameters().getBoolean("hasMinions", false);
|
||||
if (hasMinions)
|
||||
{
|
||||
for (int i = 0; i < MINION_COUNT; i++)
|
||||
{
|
||||
addMinion((L2MonsterInstance) npc, TUREK_WAR_HOUND);
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (killer.getRace().equals(Race.ERTHEIA) && (SPAWN_RATE > getRandom(100)))
|
||||
{
|
||||
final int npcId = (killer.isMageClass()) ? CHERTUBA_ILLUSION : CHERTUBA_MIRAGE;
|
||||
showOnScreenMsg(killer, NpcStringId.A_POWERFUL_MONSTER_HAS_COME_TO_FACE_YOU, ExShowScreenMessage.TOP_CENTER, 5000);
|
||||
addSpawn(npcId, npc, false, 180000);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new OrcBarracks();
|
||||
}
|
||||
}
|
59
trunk/dist/game/data/scripts/ai/group/PavelArchaic.java
vendored
Normal file
59
trunk/dist/game/data/scripts/ai/group/PavelArchaic.java
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
96
trunk/dist/game/data/scripts/ai/group/PlainsOfDion.java
vendored
Normal file
96
trunk/dist/game/data/scripts/ai/group/PlainsOfDion.java
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.GeoData;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, MONSTERS_MSG[i], player.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, MONSTERS_MSG[i]);
|
||||
}
|
||||
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2MonsterInstance.class, npc.getTemplate().getClanHelpRange(), obj ->
|
||||
{
|
||||
if (CommonUtil.contains(DELU_LIZARDMEN, obj.getId()) && !obj.isAttackingNow() && !obj.isDead() && GeoData.getInstance().canSeeTarget(npc, obj))
|
||||
{
|
||||
addAttackPlayerDesire(obj, player);
|
||||
obj.broadcastSay(ChatType.NPC_GENERAL, MONSTERS_ASSIST_MSG[getRandom(3)]);
|
||||
}
|
||||
});
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PlainsOfDion();
|
||||
}
|
||||
}
|
233
trunk/dist/game/data/scripts/ai/group/PlainsOfLizardman.java
vendored
Normal file
233
trunk/dist/game/data/scripts/ai/group/PlainsOfLizardman.java
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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());
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Attackable.class, 200, monster ->
|
||||
{
|
||||
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);
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Attackable.class, 1000, monster ->
|
||||
{
|
||||
if ((monster.getId() == TANTA_MAGICIAN) || (monster.getId() == TANTA_SCOUT))
|
||||
{
|
||||
monster.setIsRunning(true);
|
||||
monster.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();
|
||||
}
|
||||
}
|
513
trunk/dist/game/data/scripts/ai/group/PrimevalIsle.java
vendored
Normal file
513
trunk/dist/game/data/scripts/ai/group/PrimevalIsle.java
vendored
Normal file
@ -0,0 +1,513 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.GeoData;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.handler.IItemHandler;
|
||||
import com.l2jmobius.gameserver.handler.ItemHandler;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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 (CommonUtil.contains(MONSTERS, npc.getId()))
|
||||
{
|
||||
if (creature.isPlayer())
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final int ag_type = npc.getParameters().getInt("ag_type", 0);
|
||||
final int probPhysicalSpecial1 = npc.getParameters().getInt("ProbPhysicalSpecial1", 0);
|
||||
final int probPhysicalSpecial2 = npc.getParameters().getInt("ProbPhysicalSpecial2", 0);
|
||||
final SkillHolder physicalSpecial1 = npc.getParameters().getObject("PhysicalSpecial1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial2 = npc.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.getInstanceWorld());
|
||||
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.getSkill()))
|
||||
{
|
||||
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 (CommonUtil.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);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, "?");
|
||||
((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.getServitors().values().stream().findFirst().orElse(attacker.getPet()) : attacker;
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Attackable.class, 500, monster ->
|
||||
{
|
||||
if ((getRandomBoolean()))
|
||||
{
|
||||
addAttackPlayerDesire(monster, playable);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (CommonUtil.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.getParameters().getInt("ProbPhysicalSpecial1", 0);
|
||||
final int probPhysicalSpecial2 = npc.getParameters().getInt("ProbPhysicalSpecial2", 0);
|
||||
final SkillHolder selfRangeBuff1 = npc.getParameters().getObject("SelfRangeBuff1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial1 = npc.getParameters().getObject("PhysicalSpecial1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial2 = npc.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.getSkill()))
|
||||
{
|
||||
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.isInventoryUnder80(false))
|
||||
{
|
||||
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 (CommonUtil.contains(SPRIGNANT, npc.getId()))
|
||||
{
|
||||
startQuestTimer("USE_SKILL", 15000, npc, null);
|
||||
}
|
||||
else if (CommonUtil.contains(TREX, npc.getId()))
|
||||
{
|
||||
final int collectGhost = npc.getParameters().getInt("CollectGhost", 0);
|
||||
final int collectDespawn = npc.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();
|
||||
}
|
||||
}
|
78
trunk/dist/game/data/scripts/ai/group/RuinsOfYeSagira.java
vendored
Normal file
78
trunk/dist/game/data/scripts/ai/group/RuinsOfYeSagira.java
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Ruins Of Ye Sagira AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class RuinsOfYeSagira extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int GUARD = 33119;
|
||||
// Locations
|
||||
private static final Location GUARD_LOC = new Location(-115201, 237363, -3088);
|
||||
// Misc
|
||||
private static final String ROUTE_NAME1 = "ye_segira_guard1";
|
||||
private static final String ROUTE_NAME2 = "ye_segira_guard2";
|
||||
|
||||
private RuinsOfYeSagira()
|
||||
{
|
||||
addRouteFinishedId(GUARD);
|
||||
startQuestTimer("SPAWN_FIRST", 15000, null, null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SPAWN_FIRST":
|
||||
{
|
||||
final L2Npc guard = addSpawn(GUARD, GUARD_LOC);
|
||||
WalkingManager.getInstance().startMoving(guard, ROUTE_NAME1);
|
||||
startQuestTimer("SPAWN_SECOND", 4000, null, null);
|
||||
break;
|
||||
}
|
||||
case "SPAWN_SECOND":
|
||||
{
|
||||
final L2Npc guard = addSpawn(GUARD, GUARD_LOC);
|
||||
WalkingManager.getInstance().startMoving(guard, ROUTE_NAME2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRouteFinished(L2Npc npc)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RuinsOfYeSagira();
|
||||
}
|
||||
}
|
371
trunk/dist/game/data/scripts/ai/group/SeedOfAnnihilation.java
vendored
Normal file
371
trunk/dist/game/data/scripts/ai/group/SeedOfAnnihilation.java
vendored
Normal file
@ -0,0 +1,371 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2EffectZone;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Seed Of Annihilation AI.
|
||||
* @author Gigiikun
|
||||
*/
|
||||
public final class SeedOfAnnihilation extends AbstractNpcAI
|
||||
{
|
||||
private static final Map<Integer, Location> TELEPORT_ZONES = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
TELEPORT_ZONES.put(60002, new Location(-213175, 182648, -10992));
|
||||
TELEPORT_ZONES.put(60003, new Location(-181217, 186711, -10528));
|
||||
TELEPORT_ZONES.put(60004, new Location(-180211, 182984, -15152));
|
||||
TELEPORT_ZONES.put(60005, new Location(-179275, 186802, -10720));
|
||||
}
|
||||
|
||||
private static final int ANNIHILATION_FURNACE = 18928;
|
||||
|
||||
// Strength, Agility, Wisdom
|
||||
private static final int[] ZONE_BUFFS =
|
||||
{
|
||||
0,
|
||||
6443,
|
||||
6444,
|
||||
6442
|
||||
};
|
||||
|
||||
//@formatter:off
|
||||
private static final int[][] ZONE_BUFFS_LIST =
|
||||
{
|
||||
{1, 2, 3},
|
||||
{1, 3, 2},
|
||||
{2, 1, 3},
|
||||
{2, 3, 1},
|
||||
{3, 2, 1},
|
||||
{3, 1, 2}
|
||||
};
|
||||
//@formatter:on
|
||||
|
||||
// 0: Bistakon, 1: Reptilikon, 2: Cokrakon
|
||||
private final SeedRegion[] _regionsData = new SeedRegion[3];
|
||||
private Long _seedsNextStatusChange;
|
||||
|
||||
public SeedOfAnnihilation()
|
||||
{
|
||||
loadSeedRegionData();
|
||||
for (int i : TELEPORT_ZONES.keySet())
|
||||
{
|
||||
addEnterZoneId(i);
|
||||
}
|
||||
for (SeedRegion element : _regionsData)
|
||||
{
|
||||
for (int elite_mob_id : element.elite_mob_ids)
|
||||
{
|
||||
addSpawnId(elite_mob_id);
|
||||
}
|
||||
}
|
||||
addStartNpc(32739);
|
||||
addTalkId(32739);
|
||||
startEffectZonesControl();
|
||||
}
|
||||
|
||||
public void loadSeedRegionData()
|
||||
{
|
||||
// Bistakon data
|
||||
_regionsData[0] = new SeedRegion(new int[]
|
||||
{
|
||||
22750,
|
||||
22751,
|
||||
22752,
|
||||
22753
|
||||
}, new int[][]
|
||||
{
|
||||
{
|
||||
22746,
|
||||
22746,
|
||||
22746
|
||||
},
|
||||
{
|
||||
22747,
|
||||
22747,
|
||||
22747
|
||||
},
|
||||
{
|
||||
22748,
|
||||
22748,
|
||||
22748
|
||||
},
|
||||
{
|
||||
22749,
|
||||
22749,
|
||||
22749
|
||||
}
|
||||
}, 60006, new int[][]
|
||||
{
|
||||
{
|
||||
-180450,
|
||||
185507,
|
||||
-10544,
|
||||
11632
|
||||
},
|
||||
{
|
||||
-180005,
|
||||
185489,
|
||||
-10544,
|
||||
11632
|
||||
}
|
||||
});
|
||||
|
||||
// Reptilikon data
|
||||
_regionsData[1] = new SeedRegion(new int[]
|
||||
{
|
||||
22757,
|
||||
22758,
|
||||
22759
|
||||
}, new int[][]
|
||||
{
|
||||
{
|
||||
22754,
|
||||
22755,
|
||||
22756
|
||||
}
|
||||
}, 60007, new int[][]
|
||||
{
|
||||
{
|
||||
-179600,
|
||||
186998,
|
||||
-10704,
|
||||
11632
|
||||
},
|
||||
{
|
||||
-179295,
|
||||
186444,
|
||||
-10704,
|
||||
11632
|
||||
}
|
||||
});
|
||||
|
||||
// Cokrakon data
|
||||
_regionsData[2] = new SeedRegion(new int[]
|
||||
{
|
||||
22763,
|
||||
22764,
|
||||
22765
|
||||
}, new int[][]
|
||||
{
|
||||
{
|
||||
22760,
|
||||
22760,
|
||||
22761
|
||||
},
|
||||
{
|
||||
22760,
|
||||
22760,
|
||||
22762
|
||||
},
|
||||
{
|
||||
22761,
|
||||
22761,
|
||||
22760
|
||||
},
|
||||
{
|
||||
22761,
|
||||
22761,
|
||||
22762
|
||||
},
|
||||
{
|
||||
22762,
|
||||
22762,
|
||||
22760
|
||||
},
|
||||
{
|
||||
22762,
|
||||
22762,
|
||||
22761
|
||||
}
|
||||
}, 60008, new int[][]
|
||||
{
|
||||
{
|
||||
-180971,
|
||||
186361,
|
||||
-10528,
|
||||
11632
|
||||
},
|
||||
{
|
||||
-180758,
|
||||
186739,
|
||||
-10528,
|
||||
11632
|
||||
}
|
||||
});
|
||||
|
||||
int buffsNow = 0;
|
||||
final String var = loadGlobalQuestVar("SeedNextStatusChange");
|
||||
if (var.equalsIgnoreCase("") || (Long.parseLong(var) < System.currentTimeMillis()))
|
||||
{
|
||||
buffsNow = getRandom(ZONE_BUFFS_LIST.length);
|
||||
saveGlobalQuestVar("SeedBuffsList", String.valueOf(buffsNow));
|
||||
_seedsNextStatusChange = getNextSeedsStatusChangeTime();
|
||||
saveGlobalQuestVar("SeedNextStatusChange", String.valueOf(_seedsNextStatusChange));
|
||||
}
|
||||
else
|
||||
{
|
||||
_seedsNextStatusChange = Long.parseLong(var);
|
||||
buffsNow = Integer.parseInt(loadGlobalQuestVar("SeedBuffsList"));
|
||||
}
|
||||
for (int i = 0; i < _regionsData.length; i++)
|
||||
{
|
||||
_regionsData[i].activeBuff = ZONE_BUFFS_LIST[buffsNow][i];
|
||||
}
|
||||
}
|
||||
|
||||
private Long getNextSeedsStatusChangeTime()
|
||||
{
|
||||
final Calendar reenter = Calendar.getInstance();
|
||||
reenter.set(Calendar.SECOND, 0);
|
||||
reenter.set(Calendar.MINUTE, 0);
|
||||
reenter.set(Calendar.HOUR_OF_DAY, 13);
|
||||
reenter.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||
if (reenter.getTimeInMillis() <= System.currentTimeMillis())
|
||||
{
|
||||
reenter.add(Calendar.DAY_OF_MONTH, 7);
|
||||
}
|
||||
return reenter.getTimeInMillis();
|
||||
}
|
||||
|
||||
private void startEffectZonesControl()
|
||||
{
|
||||
for (int i = 0; i < _regionsData.length; i++)
|
||||
{
|
||||
for (int j = 0; j < _regionsData[i].af_spawns.length; j++)
|
||||
{
|
||||
_regionsData[i].af_npcs[j] = addSpawn(ANNIHILATION_FURNACE, _regionsData[i].af_spawns[j][0], _regionsData[i].af_spawns[j][1], _regionsData[i].af_spawns[j][2], _regionsData[i].af_spawns[j][3], false, 0);
|
||||
_regionsData[i].af_npcs[j].setDisplayEffect(_regionsData[i].activeBuff);
|
||||
}
|
||||
ZoneManager.getInstance().getZoneById(_regionsData[i].buff_zone, L2EffectZone.class).addSkill(ZONE_BUFFS[_regionsData[i].activeBuff], 1);
|
||||
}
|
||||
startQuestTimer("ChangeSeedsStatus", _seedsNextStatusChange - System.currentTimeMillis(), null, null);
|
||||
}
|
||||
|
||||
private void spawnGroupOfMinion(L2MonsterInstance npc, int[] mobIds)
|
||||
{
|
||||
for (int mobId : mobIds)
|
||||
{
|
||||
addMinion(npc, mobId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
for (SeedRegion element : _regionsData)
|
||||
{
|
||||
if (CommonUtil.contains(element.elite_mob_ids, npc.getId()))
|
||||
{
|
||||
spawnGroupOfMinion((L2MonsterInstance) npc, element.minion_lists[getRandom(element.minion_lists.length)]);
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("ChangeSeedsStatus"))
|
||||
{
|
||||
final int buffsNow = getRandom(ZONE_BUFFS_LIST.length);
|
||||
saveGlobalQuestVar("SeedBuffsList", String.valueOf(buffsNow));
|
||||
_seedsNextStatusChange = getNextSeedsStatusChangeTime();
|
||||
saveGlobalQuestVar("SeedNextStatusChange", String.valueOf(_seedsNextStatusChange));
|
||||
for (int i = 0; i < _regionsData.length; i++)
|
||||
{
|
||||
_regionsData[i].activeBuff = ZONE_BUFFS_LIST[buffsNow][i];
|
||||
|
||||
for (L2Npc af : _regionsData[i].af_npcs)
|
||||
{
|
||||
af.setDisplayEffect(_regionsData[i].activeBuff);
|
||||
}
|
||||
|
||||
final L2EffectZone zone = ZoneManager.getInstance().getZoneById(_regionsData[i].buff_zone, L2EffectZone.class);
|
||||
zone.clearSkills();
|
||||
zone.addSkill(ZONE_BUFFS[_regionsData[i].activeBuff], 1);
|
||||
}
|
||||
startQuestTimer("ChangeSeedsStatus", _seedsNextStatusChange - System.currentTimeMillis(), null, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("transform"))
|
||||
{
|
||||
if (player.isAffectedBySkill(6408))
|
||||
{
|
||||
npc.showChatWindow(player, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(SkillData.getInstance().getSkill(6408, 1));
|
||||
npc.doCast(SkillData.getInstance().getSkill(6649, 1));
|
||||
npc.showChatWindow(player, 1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (TELEPORT_ZONES.containsKey(zone.getId()))
|
||||
{
|
||||
final Location teleLoc = TELEPORT_ZONES.get(zone.getId());
|
||||
character.teleToLocation(teleLoc, false);
|
||||
}
|
||||
return super.onEnterZone(character, zone);
|
||||
}
|
||||
|
||||
private static class SeedRegion
|
||||
{
|
||||
public int[] elite_mob_ids;
|
||||
public int[][] minion_lists;
|
||||
public int buff_zone;
|
||||
public int[][] af_spawns;
|
||||
public L2Npc[] af_npcs = new L2Npc[2];
|
||||
public int activeBuff = 0;
|
||||
|
||||
public SeedRegion(int[] emi, int[][] ml, int bz, int[][] as)
|
||||
{
|
||||
elite_mob_ids = emi;
|
||||
minion_lists = ml;
|
||||
buff_zone = bz;
|
||||
af_spawns = as;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SeedOfAnnihilation();
|
||||
}
|
||||
}
|
207
trunk/dist/game/data/scripts/ai/group/SilentValley.java
vendored
Normal file
207
trunk/dist/game/data/scripts/ai/group/SilentValley.java
vendored
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, 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();
|
||||
}
|
||||
}
|
242
trunk/dist/game/data/scripts/ai/group/StakatoNest.java
vendored
Normal file
242
trunk/dist/game/data/scripts/ai/group/StakatoNest.java
vendored
Normal file
@ -0,0 +1,242 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.util.Broadcast;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
final 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++)
|
||||
{
|
||||
final 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++)
|
||||
{
|
||||
final 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())
|
||||
{
|
||||
final 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 (CommonUtil.contains(COCOONS, npc.getId()) && CommonUtil.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();
|
||||
}
|
||||
}
|
337
trunk/dist/game/data/scripts/ai/group/Wastelands.java
vendored
Normal file
337
trunk/dist/game/data/scripts/ai/group/Wastelands.java
vendored
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2QuestGuardInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.Id;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jmobius.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Wastelands AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Wastelands extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int JOEL = 33516;
|
||||
private static final int SCHUAZEN = 33517;
|
||||
private static final int COMMANDER = 33434;
|
||||
private static final int GUARD = 33437;
|
||||
private static final int DECO_GUARD = 19140; // Antharas Decoration 5
|
||||
private static final int DECO_GUARD2 = 19163; // Wastelands Decoration 1
|
||||
private static final int REGENERATED_KANILOV = 27459;
|
||||
private static final int REGENERATED_POSLOF = 27460;
|
||||
private static final int SAKUM = 27453;
|
||||
private static final int COMMANDO = 19126;
|
||||
private static final int COMMANDO_CAPTAIN = 19127;
|
||||
// Locations
|
||||
private static final Location GUARD_POSLOF_LOC = new Location(-29474, 187083, -3912);
|
||||
private static final Location[] COMMANDO_SAKUM_LOC =
|
||||
{
|
||||
new Location(-36525, 192032, -3640),
|
||||
new Location(-36160, 191912, -3640),
|
||||
new Location(-36371, 191370, -3632),
|
||||
new Location(-36765, 191759, -3632),
|
||||
};
|
||||
private static final Location[] COMMANDO_CAPTAIN_SAKUM_LOC =
|
||||
{
|
||||
new Location(-36683, 191475, -3632),
|
||||
new Location(-36131, 191574, -3632),
|
||||
};
|
||||
|
||||
private Wastelands()
|
||||
{
|
||||
addSpawnId(COMMANDER, GUARD, DECO_GUARD, REGENERATED_KANILOV, REGENERATED_POSLOF, SAKUM);
|
||||
addSeeCreatureId(JOEL, SCHUAZEN, COMMANDO, COMMANDO_CAPTAIN);
|
||||
addKillId(REGENERATED_POSLOF, SAKUM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SOCIAL_SHOW":
|
||||
{
|
||||
npc.broadcastSocialAction(4);
|
||||
|
||||
L2World.getInstance().getVisibleObjects(npc, L2Npc.class, 500).stream().filter(n -> n.getId() == GUARD).forEach(guard ->
|
||||
{
|
||||
startQuestTimer("SOCIAL_ACTION", getRandom(2500, 3500), guard, null);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "SOCIAL_ACTION":
|
||||
{
|
||||
npc.broadcastSocialAction(4);
|
||||
break;
|
||||
}
|
||||
case "START_ATTACK":
|
||||
{
|
||||
final L2Attackable guard = (L2Attackable) npc;
|
||||
final int attackId;
|
||||
|
||||
switch (guard.getId())
|
||||
{
|
||||
case JOEL:
|
||||
{
|
||||
attackId = REGENERATED_KANILOV;
|
||||
break;
|
||||
}
|
||||
case SCHUAZEN:
|
||||
{
|
||||
attackId = REGENERATED_POSLOF;
|
||||
break;
|
||||
}
|
||||
case COMMANDO:
|
||||
case COMMANDO_CAPTAIN:
|
||||
{
|
||||
attackId = SAKUM;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
attackId = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (attackId > 0)
|
||||
{
|
||||
//@formatter:off
|
||||
final L2Npc monster = L2World.getInstance().getVisibleObjects(guard, L2Npc.class, 1000)
|
||||
.stream()
|
||||
.filter(obj -> (obj.getId() == attackId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//@formatter:on
|
||||
|
||||
if (monster != null)
|
||||
{
|
||||
guard.reduceCurrentHp(1, monster, null); // TODO: Find better way for attack
|
||||
monster.reduceCurrentHp(1, guard, null);
|
||||
guard.setCanStopAttackByTime(false);
|
||||
|
||||
if ((guard.getId() != COMMANDO) && (guard.getId() != COMMANDO_CAPTAIN))
|
||||
{
|
||||
guard.setIsInvul(true);
|
||||
}
|
||||
|
||||
if (guard.getId() == SCHUAZEN)
|
||||
{
|
||||
//@formatter:off
|
||||
final L2QuestGuardInstance decoGuard = (L2QuestGuardInstance) L2World.getInstance().getVisibleObjects(guard, L2Npc.class, 500)
|
||||
.stream()
|
||||
.filter(obj -> (obj.getId() == DECO_GUARD2))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//@formatter:on
|
||||
|
||||
if (decoGuard != null)
|
||||
{
|
||||
decoGuard.reduceCurrentHp(0, monster, null); // TODO: Find better way for attack
|
||||
monster.reduceCurrentHp(1, decoGuard, null);
|
||||
decoGuard.setCanStopAttackByTime(false);
|
||||
decoGuard.setIsInvul(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("START_ATTACK", 250, guard, null);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK))
|
||||
{
|
||||
startQuestTimer("START_ATTACK", 250, npc, null);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case COMMANDER:
|
||||
{
|
||||
startQuestTimer("SOCIAL_SHOW", 13000, npc, null, true);
|
||||
npc.setRandomAnimation(false);
|
||||
break;
|
||||
}
|
||||
case REGENERATED_KANILOV:
|
||||
case REGENERATED_POSLOF:
|
||||
{
|
||||
final int guardId = npc.getId() == REGENERATED_KANILOV ? JOEL : SCHUAZEN;
|
||||
//@formatter:off
|
||||
final L2QuestGuardInstance guard = (L2QuestGuardInstance) L2World.getInstance().getVisibleObjects(npc, L2Npc.class, 500)
|
||||
.stream()
|
||||
.filter(obj -> (obj.getId() == guardId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//@formatter:on
|
||||
|
||||
if (guard != null)
|
||||
{
|
||||
if (guard.getId() == SCHUAZEN)
|
||||
{
|
||||
addSpawn(DECO_GUARD2, GUARD_POSLOF_LOC);
|
||||
}
|
||||
guard.broadcastSay(ChatType.NPC_GENERAL, guard.getId() == JOEL ? NpcStringId.AH_REGENERATOR_POSLOF_APPEARED_AGAIN : NpcStringId.AH_REGENERATOR_KANILOV_APPEARED_AGAIN);
|
||||
notifyEvent("START_ATTACK", guard, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SAKUM:
|
||||
{
|
||||
manageCommando((L2Attackable) npc);
|
||||
break;
|
||||
}
|
||||
case GUARD:
|
||||
case DECO_GUARD:
|
||||
{
|
||||
npc.setRandomAnimation(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == REGENERATED_POSLOF)
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Attackable.class, 1000, guard ->
|
||||
{
|
||||
if ((guard.getId() == DECO_GUARD2))
|
||||
{
|
||||
guard.deleteMe();
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (npc.getId() == SAKUM)
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Attackable.class, 1000, guard ->
|
||||
{
|
||||
if ((guard.getId() == COMMANDO) || (guard.getId() == COMMANDO_CAPTAIN))
|
||||
{
|
||||
guard.deleteMe();
|
||||
}
|
||||
});
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_CREATURE_DEATH)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(COMMANDO)
|
||||
@Id(COMMANDO_CAPTAIN)
|
||||
public void onCreatureKill(OnCreatureDeath event)
|
||||
{
|
||||
final L2Attackable guard = (L2Attackable) event.getTarget();
|
||||
|
||||
//@formatter:off
|
||||
final L2Attackable sakum = L2World.getInstance().getVisibleObjects(guard, L2Attackable.class, 1000)
|
||||
.stream()
|
||||
.filter(obj -> (obj.getId() == SAKUM))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//@formatter:on
|
||||
|
||||
if (sakum != null)
|
||||
{
|
||||
manageCommando(sakum);
|
||||
}
|
||||
}
|
||||
|
||||
private void manageCommando(L2Attackable sakum)
|
||||
{
|
||||
int guardCount = sakum.getVariables().getInt("GUARD_COUNT", 0);
|
||||
guardCount--;
|
||||
|
||||
if (guardCount <= 0)
|
||||
{
|
||||
if (sakum.getVariables().getBoolean("GUARD_CAPTAIN", false))
|
||||
{
|
||||
sakum.getVariables().set("GUARD_COUNT", COMMANDO_CAPTAIN_SAKUM_LOC.length);
|
||||
sakum.getVariables().set("GUARD_CAPTAIN", false);
|
||||
|
||||
for (Location loc : COMMANDO_CAPTAIN_SAKUM_LOC)
|
||||
{
|
||||
final L2Attackable commander = (L2Attackable) addSpawn(COMMANDO_CAPTAIN, loc);
|
||||
commander.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.HOW_DARE_YOU_ATTACK);
|
||||
|
||||
commander.reduceCurrentHp(1, sakum, null); // TODO: Find better way for attack
|
||||
sakum.reduceCurrentHp(1, commander, null);
|
||||
commander.setCanStopAttackByTime(false);
|
||||
|
||||
notifyEvent("START_ATTACK", commander, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sakum.getVariables().set("GUARD_COUNT", COMMANDO_SAKUM_LOC.length);
|
||||
sakum.getVariables().set("GUARD_CAPTAIN", true);
|
||||
|
||||
for (Location loc : COMMANDO_SAKUM_LOC)
|
||||
{
|
||||
final L2Attackable commander = (L2Attackable) addSpawn(COMMANDO, loc);
|
||||
|
||||
commander.reduceCurrentHp(1, sakum, null); // TODO: Find better way for attack
|
||||
sakum.reduceCurrentHp(1, commander, null);
|
||||
commander.setCanStopAttackByTime(false);
|
||||
|
||||
notifyEvent("START_ATTACK", commander, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sakum.getVariables().set("GUARD_COUNT", guardCount);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Wastelands();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user