Some syncs with l2jserver.

Also QuestState cleanup.
This commit is contained in:
MobiusDev
2017-08-15 12:36:39 +00:00
parent 84f82612cf
commit c4f94bcc0f
652 changed files with 12410 additions and 4435 deletions

View File

@@ -0,0 +1,122 @@
/*
* 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.individual;
import com.l2jmobius.gameserver.ai.CtrlIntention;
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.holders.SkillHolder;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Blackdagger Wing AI.
* @author Zoey76
* @since 2.6.0.0
*/
public class BlackdaggerWing extends AbstractNpcAI
{
// NPCs
private static final int BLACKDAGGER_WING = 25721;
// Skills
private static final SkillHolder POWER_STRIKE = new SkillHolder(6833, 1);
private static final SkillHolder RANGE_MAGIC_ATTACK = new SkillHolder(6834, 1);
// Variables
private static final String MID_HP_FLAG = "MID_HP_FLAG";
private static final String POWER_STRIKE_CAST_COUNT = "POWER_STRIKE_CAST_COUNT";
// Timers
private static final String DAMAGE_TIMER = "DAMAGE_TIMER";
// Misc
private static final int MAX_CHASE_DIST = 2500;
private static final double MID_HP_PERCENTAGE = 0.50;
public BlackdaggerWing()
{
super(BlackdaggerWing.class.getSimpleName(), "ai/individual");
addAttackId(BLACKDAGGER_WING);
addSeeCreatureId(BLACKDAGGER_WING);
addSpellFinishedId(BLACKDAGGER_WING);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
{
if (Util.calculateDistance(npc, npc.getSpawn(), false, false) > MAX_CHASE_DIST)
{
npc.teleToLocation(npc.getSpawn().getX(), npc.getSpawn().getY(), npc.getSpawn().getZ());
}
if ((npc.getCurrentHp() < (npc.getMaxHp() * MID_HP_PERCENTAGE)) && !npc.getVariables().getBoolean(MID_HP_FLAG, false))
{
npc.getVariables().set(MID_HP_FLAG, true);
startQuestTimer(DAMAGE_TIMER, 10000, npc, attacker);
}
return super.onAttack(npc, attacker, damage, isSummon);
}
@Override
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
{
if (npc.getVariables().getBoolean(MID_HP_FLAG, false))
{
final L2Character mostHated = ((L2Attackable) npc).getMostHated();
if ((mostHated != null) && mostHated.isPlayer() && (mostHated != creature))
{
if (getRandom(5) < 1)
{
addSkillCastDesire(npc, creature, RANGE_MAGIC_ATTACK, 99999);
}
}
}
return super.onSeeCreature(npc, creature, isSummon);
}
@Override
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
{
if (skill.getId() == POWER_STRIKE.getSkillId())
{
npc.getVariables().set(POWER_STRIKE_CAST_COUNT, npc.getVariables().getInt(POWER_STRIKE_CAST_COUNT) + 1);
if (npc.getVariables().getInt(POWER_STRIKE_CAST_COUNT) > 3)
{
addSkillCastDesire(npc, player, RANGE_MAGIC_ATTACK, 99999);
npc.getVariables().set(POWER_STRIKE_CAST_COUNT, 0);
}
}
return super.onSpellFinished(npc, player, skill);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (DAMAGE_TIMER.equals(event))
{
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK);
startQuestTimer(DAMAGE_TIMER, 30000, npc, player);
}
return super.onAdvEvent(event, npc, player);
}
public static void main(String[] args)
{
new BlackdaggerWing();
}
}

View File

@@ -0,0 +1,136 @@
/*
* 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.individual;
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.util.Util;
import ai.AbstractNpcAI;
/**
* Bleeding Fly AI.
* @author Zoey76
* @since 2.6.0.0
*/
public class BleedingFly extends AbstractNpcAI
{
// NPCs
private static final int BLEEDING_FLY = 25720;
private static final int PARASITIC_LEECH = 25734;
// Skills
private static final SkillHolder SUMMON_PARASITE_LEECH = new SkillHolder(6832, 1);
private static final SkillHolder NPC_ACUMEN_LVL_3 = new SkillHolder(6915, 3);
// Variables
private static final String MID_HP_FLAG = "MID_HP_FLAG";
private static final String LOW_HP_FLAG = "LOW_HP_FLAG";
private static final String MID_HP_MINION_COUNT = "MID_HP_MINION_COUNT";
private static final String LOW_HP_MINION_COUNT = "LOW_HP_MINION_COUNT";
// Timers
private static final String TIMER_MID_HP = "TIMER_MID_HP";
private static final String TIMER_LOW_HP = "TIMER_LOW_HP";
// Misc
private static final int MAX_CHASE_DIST = 2500;
private static final double MID_HP_PERCENTAGE = 0.50;
private static final double MIN_HP_PERCENTAGE = 0.25;
public BleedingFly()
{
super(BleedingFly.class.getSimpleName(), "ai/individual");
addAttackId(BLEEDING_FLY);
addSpawnId(BLEEDING_FLY);
}
@Override
public String onSpawn(L2Npc npc)
{
npc.getVariables().set(MID_HP_MINION_COUNT, 5);
npc.getVariables().set(LOW_HP_MINION_COUNT, 10);
return super.onSpawn(npc);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
{
if (Util.calculateDistance(npc, npc.getSpawn(), false, false) > MAX_CHASE_DIST)
{
npc.teleToLocation(npc.getSpawn().getX(), npc.getSpawn().getY(), npc.getSpawn().getZ());
}
if ((npc.getCurrentHp() < (npc.getMaxHp() * MID_HP_PERCENTAGE)) && !npc.getVariables().getBoolean(MID_HP_FLAG, false))
{
npc.getVariables().set(MID_HP_FLAG, true);
startQuestTimer(TIMER_MID_HP, 1000, npc, null);
}
if ((npc.getCurrentHp() < (npc.getMaxHp() * MIN_HP_PERCENTAGE)) && !npc.getVariables().getBoolean(LOW_HP_FLAG, false))
{
npc.getVariables().set(MID_HP_FLAG, false);
npc.getVariables().set(LOW_HP_FLAG, true);
startQuestTimer(TIMER_LOW_HP, 1000, npc, null);
}
return super.onAttack(npc, attacker, damage, isSummon);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (npc.isDead())
{
return super.onAdvEvent(event, npc, player);
}
if (TIMER_MID_HP.equals(event))
{
if (npc.getVariables().getInt(MID_HP_MINION_COUNT) > 0)
{
npc.getVariables().set(MID_HP_MINION_COUNT, npc.getVariables().getInt(MID_HP_MINION_COUNT) - 1);
addSkillCastDesire(npc, npc, SUMMON_PARASITE_LEECH, 99999);
addSpawn(PARASITIC_LEECH, npc.getX() + getRandom(150), npc.getY() + getRandom(150), npc.getZ(), npc.getHeading(), false, 0);
addSpawn(PARASITIC_LEECH, npc.getX() + getRandom(150), npc.getY() + getRandom(150), npc.getZ(), npc.getHeading(), false, 0);
if (npc.getVariables().getBoolean(MID_HP_FLAG, false))
{
startQuestTimer(TIMER_MID_HP, 140000, npc, null);
}
}
}
else if (TIMER_LOW_HP.equals(event))
{
if (npc.getVariables().getInt(LOW_HP_MINION_COUNT) > 0)
{
npc.getVariables().set(LOW_HP_MINION_COUNT, npc.getVariables().getInt(LOW_HP_MINION_COUNT) - 1);
addSkillCastDesire(npc, npc, SUMMON_PARASITE_LEECH, 99999);
addSkillCastDesire(npc, npc, NPC_ACUMEN_LVL_3, 99999);
addSpawn(PARASITIC_LEECH, npc.getX() + getRandom(150), npc.getY() + getRandom(150), npc.getZ(), npc.getHeading(), false, 0);
addSpawn(PARASITIC_LEECH, npc.getX() + getRandom(150), npc.getY() + getRandom(150), npc.getZ(), npc.getHeading(), false, 0);
if (npc.getVariables().getBoolean(LOW_HP_FLAG, false))
{
startQuestTimer(TIMER_LOW_HP, 80000, npc, null);
}
}
}
return super.onAdvEvent(event, npc, player);
}
public static void main(String[] args)
{
new BleedingFly();
}
}

View 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.individual;
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.util.Util;
import ai.AbstractNpcAI;
/**
* Dust Rider AI.
* @author Zoey76
* @since 2.6.0.0
*/
public class DustRider extends AbstractNpcAI
{
private static final int DUST_RIDER = 25719;
// Skills
private static final SkillHolder NPC_HASTE_LVL_3 = new SkillHolder(6914, 3);
// Variables
private static final String CAST_FLAG = "CAST_FLAG";
// Misc
private static final int MAX_CHASE_DIST = 2500;
private static final double MIN_HP_PERCENTAGE = 0.30;
public DustRider()
{
super(DustRider.class.getSimpleName(), "ai/individual");
addAttackId(DUST_RIDER);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
{
if (Util.calculateDistance(npc, npc.getSpawn(), false, false) > MAX_CHASE_DIST)
{
npc.teleToLocation(npc.getSpawn().getX(), npc.getSpawn().getY(), npc.getSpawn().getZ());
}
if (!npc.getVariables().getBoolean(CAST_FLAG, false) && (npc.getCurrentHp() < (npc.getMaxHp() * MIN_HP_PERCENTAGE)))
{
npc.getVariables().set(CAST_FLAG, true);
addSkillCastDesire(npc, npc, NPC_HASTE_LVL_3, 99999);
}
return super.onAttack(npc, attacker, damage, isSummon);
}
public static void main(String[] args)
{
new DustRider();
}
}

View File

@@ -0,0 +1,134 @@
/*
* 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.individual;
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.holders.SkillHolder;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Emerald Horn AI.
* @author Zoey76
* @since 2.6.0.0
*/
public class EmeraldHorn extends AbstractNpcAI
{
private static final int EMERALD_HORN = 25718;
// Skills
private static final SkillHolder REFLECT_ATTACK = new SkillHolder(6823, 1);
private static final SkillHolder PIERCING_STORM = new SkillHolder(6824, 1);
private static final SkillHolder BLEED_LVL_1 = new SkillHolder(6825, 1);
private static final SkillHolder BLEED_LVL_2 = new SkillHolder(6825, 2);
// Variables
private static final String HIGH_DAMAGE_FLAG = "HIGH_DAMAGE_FLAG";
private static final String TOTAL_DAMAGE_COUNT = "TOTAL_DAMAGE_COUNT";
private static final String CAST_FLAG = "CAST_FLAG";
// Timers
private static final String DAMAGE_TIMER_15S = "DAMAGE_TIMER_15S";
// Misc
private static final int MAX_CHASE_DIST = 2500;
public EmeraldHorn()
{
super(EmeraldHorn.class.getSimpleName(), "ai/individual");
addAttackId(EMERALD_HORN);
addSpellFinishedId(EMERALD_HORN);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
{
if (Util.calculateDistance(npc, npc.getSpawn(), false, false) > MAX_CHASE_DIST)
{
npc.teleToLocation(npc.getSpawn().getX(), npc.getSpawn().getY(), npc.getSpawn().getZ());
}
if (npc.isAffectedBySkill(REFLECT_ATTACK.getSkillId()))
{
if (npc.getVariables().getBoolean(CAST_FLAG, false))
{
npc.getVariables().set(TOTAL_DAMAGE_COUNT, npc.getVariables().getInt(TOTAL_DAMAGE_COUNT) + damage);
}
}
if (npc.getVariables().getInt(TOTAL_DAMAGE_COUNT) > 5000)
{
addSkillCastDesire(npc, attacker, BLEED_LVL_2, 99999);
npc.getVariables().set(TOTAL_DAMAGE_COUNT, 0);
npc.getVariables().set(CAST_FLAG, false);
npc.getVariables().set(HIGH_DAMAGE_FLAG, true);
}
if (npc.getVariables().getInt(TOTAL_DAMAGE_COUNT) > 10000)
{
addSkillCastDesire(npc, attacker, BLEED_LVL_1, 99999);
npc.getVariables().set(TOTAL_DAMAGE_COUNT, 0);
npc.getVariables().set(CAST_FLAG, false);
npc.getVariables().set(HIGH_DAMAGE_FLAG, true);
}
return super.onAttack(npc, attacker, damage, isSummon);
}
@Override
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
{
if (getRandom(5) < 1)
{
npc.getVariables().set(TOTAL_DAMAGE_COUNT, 0);
npc.getVariables().set(CAST_FLAG, true);
addSkillCastDesire(npc, npc, REFLECT_ATTACK, 99999);
startQuestTimer(DAMAGE_TIMER_15S, 15 * 1000, npc, player);
}
return super.onSpellFinished(npc, player, skill);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (DAMAGE_TIMER_15S.equals(event))
{
if (!npc.getVariables().getBoolean(HIGH_DAMAGE_FLAG, false))
{
final L2Character mostHated = ((L2Attackable) npc).getMostHated();
if (mostHated != null)
{
if (mostHated.isDead())
{
((L2Attackable) npc).stopHating(mostHated);
}
else
{
addSkillCastDesire(npc, mostHated, PIERCING_STORM, 99999);
}
}
}
npc.getVariables().set(CAST_FLAG, false);
}
return super.onAdvEvent(event, npc, player);
}
public static void main(String[] args)
{
new EmeraldHorn();
}
}

View 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.individual;
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.util.Util;
import ai.AbstractNpcAI;
/**
* Muscle Bomber AI.
* @author Zoey76
* @since 2.6.0.0
*/
public class MuscleBomber extends AbstractNpcAI
{
// NPC
private static final int MUSCLE_BOMBER = 25724;
private static final int DRAKOS_ASSASSIN = 22823;
// Skills
private static final SkillHolder ENHANCE_LVL_1 = new SkillHolder(6842, 1);
private static final SkillHolder ENHANCE_LVL_2 = new SkillHolder(6842, 2);
// Variables
private static final String HIGH_HP_FLAG = "HIGH_HP_FLAG";
private static final String MED_HP_FLAG = "MED_HP_FLAG";
private static final String LIMIT_FLAG = "LIMIT_FLAG";
// Timers
private static final String TIMER_SUMMON = "TIMER_SUMMON";
private static final String TIMER_LIMIT = "TIMER_LIMIT";
// Misc
private static final int MAX_CHASE_DIST = 2500;
private static final double HIGH_HP_PERCENTAGE = 0.80;
private static final double MED_HP_PERCENTAGE = 0.50;
public MuscleBomber()
{
super(MuscleBomber.class.getSimpleName(), "ai/individual");
addAttackId(MUSCLE_BOMBER);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
{
if (Util.calculateDistance(npc, npc.getSpawn(), false, false) > MAX_CHASE_DIST)
{
npc.teleToLocation(npc.getSpawn().getX(), npc.getSpawn().getY(), npc.getSpawn().getZ());
}
if ((npc.getCurrentHp() < (npc.getMaxHp() * HIGH_HP_PERCENTAGE)) && !npc.getVariables().getBoolean(HIGH_HP_FLAG, false))
{
npc.getVariables().set(HIGH_HP_FLAG, true);
addSkillCastDesire(npc, npc, ENHANCE_LVL_1, 99999);
}
if ((npc.getCurrentHp() < (npc.getMaxHp() * MED_HP_PERCENTAGE)) && !npc.getVariables().getBoolean(MED_HP_FLAG, false))
{
npc.getVariables().set(MED_HP_FLAG, true);
addSkillCastDesire(npc, npc, ENHANCE_LVL_2, 99999);
startQuestTimer(TIMER_SUMMON, 60000, npc, attacker);
startQuestTimer(TIMER_LIMIT, 300000, npc, attacker);
}
return super.onAttack(npc, attacker, damage, isSummon);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
switch (event)
{
case TIMER_LIMIT:
{
npc.getVariables().set(LIMIT_FLAG, true);
break;
}
case TIMER_SUMMON:
{
if (!npc.isDead() && !npc.getVariables().getBoolean(LIMIT_FLAG, false))
{
if (player != null)
{
addAttackDesire(addSpawn(DRAKOS_ASSASSIN, npc.getX() + getRandom(100), npc.getY() + getRandom(10), npc.getZ(), npc.getHeading(), false, 0), player);
addAttackDesire(addSpawn(DRAKOS_ASSASSIN, npc.getX() + getRandom(100), npc.getY() + getRandom(10), npc.getZ(), npc.getHeading(), false, 0), player);
}
startQuestTimer(TIMER_SUMMON, 60000, npc, player);
}
break;
}
}
return super.onAdvEvent(event, npc, player);
}
public static void main(String[] args)
{
new MuscleBomber();
}
}

View File

@@ -0,0 +1,134 @@
/*
* 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.individual;
import com.l2jmobius.gameserver.ai.CtrlIntention;
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.holders.SkillHolder;
import com.l2jmobius.gameserver.util.Util;
import ai.AbstractNpcAI;
/**
* Shadow Summoner AI.
* @author Zoey76
* @since 2.6.0.0
*/
public class ShadowSummoner extends AbstractNpcAI
{
// NPCs
private static final int SHADOW_SUMMONER = 25722;
private static final int DEMONS_BANQUET_1 = 25730;
private static final int DEMONS_BANQUET_2 = 25731;
// Skills
private static final SkillHolder SUMMON_SKELETON = new SkillHolder(6835, 1);
// Variables
private static final String LOW_HP_FLAG = "LOW_HP_FLAG";
private static final String LIMIT_FLAG = "LIMIT_FLAG";
// Timers
private static final String SUMMON_TIMER = "SUMMON_TIMER";
private static final String FEED_TIMER = "FEED_TIMER";
private static final String LIMIT_TIMER = "LIMIT_TIMER";
private static final String DELAY_TIMER = "DELAY_TIMER";
// Misc
private static final int MAX_CHASE_DIST = 2500;
private static final double MIN_HP_PERCENTAGE = 0.25;
public ShadowSummoner()
{
super(ShadowSummoner.class.getSimpleName(), "ai/individual");
addAttackId(SHADOW_SUMMONER);
addSeeCreatureId(SHADOW_SUMMONER);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
{
if (Util.calculateDistance(npc, npc.getSpawn(), false, false) > MAX_CHASE_DIST)
{
npc.teleToLocation(npc.getSpawn().getX(), npc.getSpawn().getY(), npc.getSpawn().getZ());
}
if ((npc.getCurrentHp() < (npc.getMaxHp() * MIN_HP_PERCENTAGE)) && !npc.getVariables().getBoolean(LOW_HP_FLAG, false))
{
npc.getVariables().set(LOW_HP_FLAG, true);
startQuestTimer(SUMMON_TIMER, 1000, npc, attacker);
startQuestTimer(FEED_TIMER, 30000, npc, attacker);
startQuestTimer(LIMIT_TIMER, 600000, npc, attacker);
}
return super.onAttack(npc, attacker, damage, isSummon);
}
@Override
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
{
if (!creature.isPlayer())
{
if (creature.getId() == DEMONS_BANQUET_2)
{
((L2Attackable) npc).clearAggroList();
addAttackDesire(npc, creature, 99999);
}
}
return super.onSeeCreature(npc, creature, isSummon);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (npc.isDead())
{
return super.onAdvEvent(event, npc, player);
}
if (SUMMON_TIMER.equals(event))
{
if (!npc.getVariables().getBoolean(LIMIT_FLAG, false))
{
startQuestTimer(DELAY_TIMER, 5000, npc, player);
startQuestTimer(SUMMON_TIMER, 30000, npc, player);
}
}
else if (FEED_TIMER.equals(event))
{
if (!npc.getVariables().getBoolean(LIMIT_FLAG, false))
{
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK);
startQuestTimer(FEED_TIMER, 30000, npc, player);
}
}
else if (LIMIT_TIMER.equals(event))
{
npc.getVariables().set(LIMIT_FLAG, true);
}
else if (DELAY_TIMER.equals(event))
{
addSkillCastDesire(npc, npc, SUMMON_SKELETON, 99999);
final L2Npc demonsBanquet = addSpawn(getRandom(2) < 1 ? DEMONS_BANQUET_1 : DEMONS_BANQUET_2, npc.getX() + 150, npc.getY() + 150, npc.getZ(), npc.getHeading(), false, 0);
addAttackDesire(demonsBanquet, player, 10000);
}
return super.onAdvEvent(event, npc, player);
}
public static void main(String[] args)
{
new ShadowSummoner();
}
}

View File

@@ -39,13 +39,13 @@ public final class Alexandria extends AbstractNpcAI
// Items
private static final ItemHolder[] REQUIRED_ITEMS = new ItemHolder[]
{
new ItemHolder(57, 3550000),
new ItemHolder(5094, 400),
new ItemHolder(6471, 200),
new ItemHolder(9814, 40),
new ItemHolder(9815, 30),
new ItemHolder(9816, 50),
new ItemHolder(9817, 50),
new ItemHolder(57, 7500000),
new ItemHolder(5094, 50),
new ItemHolder(6471, 25),
new ItemHolder(9814, 4),
new ItemHolder(9815, 3),
new ItemHolder(9816, 5),
new ItemHolder(9817, 5),
};
// Agathions
private static final QuestItemHolder[] LITTLE_DEVILS = new QuestItemHolder[]
@@ -97,7 +97,7 @@ public final class Alexandria extends AbstractNpcAI
for (QuestItemHolder agathion : AGATHIONS.get(event))
{
chance3 += agathion.getChance();
if ((chance >= chance2) && (chance2 < chance3))
if ((chance2 <= chance) && (chance < chance3))
{
if (takeAllItems(player, REQUIRED_ITEMS))
{

View File

@@ -0,0 +1,8 @@
<html><body>Asamah:<br>
I am Asamah, son of Mushika, chief of the Elroki tribe. These are our lands. In them lies perhaps our last hope to return to our ancient ancestral home. But these days are evil, and our hope is waning before this threat.<br>
Our strength has run out like water from a broken pot, and although my ancestors would be shamed to ask for aid, I believe only an outsider like yourself can save us now.<br>
<a action="bypass -h npc_%objectId%_Quest">Quest</a><br>
<a action="bypass -h Quest Asamah 32115-03.htm">Find out how to use the capture skill.</a><br>
<a action="bypass -h npc_%objectId%_multisell 577">Equip the trap.</a><br>
<a action="bypass -h npc_%objectId%_multisell 578">Buy</a>
</body></html>

View File

@@ -0,0 +1,7 @@
<html><body>Asamah:<br>
I am Asamah, son of Mushika, chief of the Elroki tribe. These are our lands. In them lies perhaps our last hope to return to our ancient ancestral home. But these days are evil, and our hope is waning before this threat.<br>
Our strength has run out like water from a broken pot, and although my ancestors would be shamed to ask for aid, I believe only an outsider like yourself can save us now.<br>
<a action="bypass -h npc_%objectId%_Quest">Quest</a><br>
<a action="bypass -h Quest Asamah 32115-03.htm">Find out how to use the capture skill.</a><br>
<a action="bypass -h npc_%objectId%_multisell 578">Buy</a>
</body></html>

View File

@@ -0,0 +1,6 @@
<html><body>Asamah:<br>
If you have a trap, then you may use at least 3 types of capture skills. You can only use a capture skill on the predatory Tyrannosaurus.<br>
If you are capturing a Tyrannosaurus for the first time, you will use the <font color="LEVEL">Kabokula</font> technique most among the three capture skills. But you cannot completely capture this powerful predatory dinosaur with just one skill type!<br>
At this point, watch the Tyrannosaurus' reactions and use the proper skill to maintain its state of captivity. Nothing is a better teacher than your own experience, but since you have come all this way, I will tell you the traditional capture method of the Elkrohki. Listen carefully.<br>
<a action="bypass -h Quest Asamah 32115-04.htm">Next.</a>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Asamah:<br>
You must know which action to use when a Tyrannosaurus tries to cancel a capture skill. When the beast <font color="LEVEL">roars, shakes and writhes</font>, the appropriate capture skills to use are <font color="LEVEL">kabokula, tapirawa and shabonoba</font>. Watch each action of the Tyrannosaurus carefully and respond with the correct skill.<br>
Remember that using a capture skill consumes both capture stones and MP. Be sure to prepare enough of them both! May Shilen bless your efforts!
</body></html>

View 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.npc.Asamah;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.quest.QuestState;
import ai.AbstractNpcAI;
import quests.Q00111_ElrokianHuntersProof.Q00111_ElrokianHuntersProof;
/**
* Asamah AI.
* @author Adry_85
* @since 2.6.0.0
*/
public final class Asamah extends AbstractNpcAI
{
// NPC
private static final int ASAMAH = 32115;
public Asamah()
{
super(Asamah.class.getSimpleName(), "ai/npc");
addFirstTalkId(ASAMAH);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
if (event.equals("32115-03.htm") || event.equals("32115-04.htm"))
{
htmltext = event;
}
return htmltext;
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
final QuestState st = player.getQuestState(Q00111_ElrokianHuntersProof.class.getSimpleName());
return ((st != null) && (st.isCompleted())) ? "32115-01.htm" : "32115-02.htm";
}
public static void main(String[] args)
{
new Asamah();
}
}

View File

@@ -0,0 +1,3 @@
<html><body>Dragon Vortex:<br>
You can't summon the monster this soon. Please wait a little.
</body></html>

View File

@@ -1,3 +0,0 @@
<html><body>Dragon Vortex:<br>
No high commanding dragon can be summoned at this time, since they are already summoned.
</body></html>

View File

@@ -1,5 +1,6 @@
<html><body>Dragon Vortex:<br>
A mysterious vortex which has the power to summon one of Antharas's high commanding dragons. To call forth one of these creatures you must use a <font color="LEVEL">Large Dragon Bone</font> to entice it.<br>
Summoned Dragons: <font color="LEVEL">Emerald Horn, Dust Rider, Bleeding Fly, Blackdagger Wing, Shadow Summoner, Spike Slasher, & Muscle Bomber</font><br>
<a action="bypass -h Quest DragonVortex Spawn">Use a Large Dragon Bone</a>
A mysterious vortex which has the power to summon one of Antharas' high commanding dragons.<br>
To call forth one of these creatures, you must use a <font color="LEVEL">Large Dragon Bone</font>.<br>
Dragons to be summoned: <font color="LEVEL">Emerald Horn Dust Rider Bleeding Fly Blackdagger Wing Shadow Summoner Spike Slasher Muscle Bomber</font><br>
<a action="bypass -h Quest DragonVortex RAIDBOSS">Use a Large Dragon Bone</a>
</body></html>

View File

@@ -16,11 +16,7 @@
*/
package ai.npc.DragonVortex;
import java.util.ArrayList;
import java.util.List;
import com.l2jmobius.gameserver.datatables.SpawnTable;
import com.l2jmobius.gameserver.model.L2Spawn;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
@@ -28,158 +24,131 @@ import ai.AbstractNpcAI;
/**
* Dragon Vortex AI.
* @author UnAfraid, improved by Adry_85 & DreamStage
* @author Adry_85
* @since 2.6.0.0
*/
public final class DragonVortex extends AbstractNpcAI
{
// NPC
private static final int VORTEX = 32871;
private static final int DRAGON_VORTEX = 32871;
// Raids
private static final int[][] RAIDS =
{
{
25718, // Emerald Horn 29.2%
292
},
{
25719, // Dust Rider 22.4%
224
},
{
25720, // Bleeding Fly 17.6%
176
},
{
25721, // Blackdagger Wing 11.6%
116
},
{
25723, // Spike Slasher 9.2%
92
},
{
25722, // Shadow Summoner 5.6%
56
},
{
25724, // Muscle Bomber 4.4%
44
}
};
private static final int EMERALD_HORN = 25718;
private static final int DUST_RIDER = 25719;
private static final int BLEEDING_FLY = 25720;
private static final int BLACKDAGGER_WING = 25721;
private static final int SHADOW_SUMMONER = 25722;
private static final int SPIKE_SLASHER = 25723;
private static final int MUSCLE_BOMBER = 25724;
// Item
private static final int LARGE_DRAGON_BONE = 17248;
// Misc
private static final int DESPAWN_DELAY = 1800000; // 30min
// Variables
private static final String I_QUEST0 = "I_QUEST0";
// Locations
private static final Location SPOT_1 = new Location(92744, 114045, -3072);
private static final Location SPOT_2 = new Location(110112, 124976, -3624);
private static final Location SPOT_3 = new Location(121637, 113657, -3792);
private static final Location SPOT_4 = new Location(109346, 111849, -3040);
private DragonVortex()
{
super(DragonVortex.class.getSimpleName(), "ai/npc");
addStartNpc(VORTEX);
addFirstTalkId(VORTEX);
addTalkId(VORTEX);
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
return "32871.html";
addStartNpc(DRAGON_VORTEX);
addFirstTalkId(DRAGON_VORTEX);
addTalkId(DRAGON_VORTEX);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if ("Spawn".equals(event))
switch (event)
{
if (hasQuestItems(player, LARGE_DRAGON_BONE))
case "RAIDBOSS":
{
final int chance = getRandom(1000);
final List<int[]> unspawnedRaids = new ArrayList<>();
final List<int[]> unspawnedCandidates = new ArrayList<>();
int raidChanceIncrease = 0;
// Iterate over all Raids and check which ones are currently spawned, sum spawned Raids chance for unspawnedRaids List distribution
for (int[] raidsList : RAIDS)
if (hasQuestItems(player, LARGE_DRAGON_BONE))
{
final int raidChance = raidsList[1];
if (checkIfNpcSpawned(raidsList[0]))
if (!npc.getVariables().getBoolean(I_QUEST0, false))
{
raidChanceIncrease += raidChance;
takeItems(player, LARGE_DRAGON_BONE, 1);
final int random = getRandom(100);
int raid = 0;
if (random < 3)
{
raid = MUSCLE_BOMBER;
}
else if (random < 8)
{
raid = SHADOW_SUMMONER;
}
else if (random < 15)
{
raid = SPIKE_SLASHER;
}
else if (random < 25)
{
raid = BLACKDAGGER_WING;
}
else if (random < 45)
{
raid = BLEEDING_FLY;
}
else if (random < 67)
{
raid = DUST_RIDER;
}
else
{
raid = EMERALD_HORN;
}
Location LOC = null;
switch (npc.getX())
{
case 92225:
{
LOC = SPOT_1;
break;
}
case 110116:
{
LOC = SPOT_2;
break;
}
case 121172:
{
LOC = SPOT_3;
break;
}
case 108924:
{
LOC = SPOT_4;
break;
}
}
npc.getVariables().set(I_QUEST0, true);
addSpawn(raid, LOC, false, 0, true);
startQuestTimer("CANSPAWN", 60000, npc, null);
}
else
{
unspawnedRaids.add(new int[]
{
raidsList[0],
raidChance
});
return "32871-02.html";
}
}
// If there are unspawnedRaids onto the new List, distribute the amount of increased chances for each one and spawn a new Raid from the new chances
if (!unspawnedRaids.isEmpty())
else
{
final int unspawnedRaidsSize = unspawnedRaids.size();
final int chanceIncrease = (raidChanceIncrease / unspawnedRaidsSize);
int raidChanceValue = 0;
for (int[] unspawnedRaidsList : unspawnedRaids)
{
raidChanceValue += unspawnedRaidsList[1] + chanceIncrease;
unspawnedCandidates.add(new int[]
{
unspawnedRaidsList[0],
raidChanceValue
});
}
for (int[] unspawnedCandidatesList : unspawnedCandidates)
{
if (chance <= unspawnedCandidatesList[1])
{
spawnRaid(unspawnedCandidatesList[0], npc, player);
break;
}
}
return null;
return "32871-01.html";
}
return "32871-noboss.html";
break;
}
case "CANSPAWN":
{
npc.getVariables().set(I_QUEST0, false);
break;
}
return "32871-no.html";
}
return super.onAdvEvent(event, npc, player);
}
/**
* Method used for spawning a Dragon Vortex Raid and take a Large Dragon Bone from the Player
* @param raidId
* @param npc
* @param player
*/
public void spawnRaid(int raidId, L2Npc npc, L2PcInstance player)
{
final L2Spawn spawnDat = addSpawn(raidId, npc.getX() + getRandom(-500, 500), npc.getY() + getRandom(-500, 500), npc.getZ() + 10, 0, false, DESPAWN_DELAY, true).getSpawn();
SpawnTable.getInstance().addNewSpawn(spawnDat, false);
takeItems(player, LARGE_DRAGON_BONE, 1);
}
/**
* Method used for checking if npc is spawned
* @param npcId
* @return if npc is spawned
*/
public boolean checkIfNpcSpawned(int npcId)
{
for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(npcId))
{
final L2Npc spawnedWarpgate = spawn.getLastSpawn();
if ((spawnedWarpgate != null))
{
return true;
}
}
return false;
}
public static void main(String[] args)
{
new DragonVortex();

View File

@@ -0,0 +1,4 @@
<html><body>
(This one is different than the ones I saw before. This one is isolated, and somehow sad looking.<br>
<a action="bypass -h npc_%objectId%_Quest">Look around.</a>
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>
(It's a stone statue that looks like a human being. Otherwise it looks normal.)
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>
(This is Kier, a member of Jinia Guild who was turned into an ice sculpture by the Ice Queen Freya.)<br>
<a action="bypass -h npc_%objectId%_Quest">Look around the ice sculpture.</a>
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>
(A former member of the Jinia Guild. Now he's an ice sculpture of Kier by the Ice Queen.)
</body></html>

View File

@@ -0,0 +1,76 @@
/*
* 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.npc.Kier;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.quest.QuestState;
import ai.AbstractNpcAI;
import quests.Q00115_TheOtherSideOfTruth.Q00115_TheOtherSideOfTruth;
import quests.Q10283_RequestOfIceMerchant.Q10283_RequestOfIceMerchant;
/**
* Kier AI.
* @author Adry_85
* @since 2.6.0.0
*/
public final class Kier extends AbstractNpcAI
{
// NPC
private static final int KIER = 32022;
private Kier()
{
super(Kier.class.getSimpleName(), "ai/npc");
addFirstTalkId(KIER);
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
String htmltext = null;
final QuestState st_Q00115 = player.getQuestState(Q00115_TheOtherSideOfTruth.class.getSimpleName());
if (st_Q00115 == null)
{
htmltext = "32022-02.html";
}
else if (!st_Q00115.isCompleted())
{
htmltext = "32022-01.html";
}
final QuestState st_Q10283 = player.getQuestState(Q10283_RequestOfIceMerchant.class.getSimpleName());
if (st_Q10283 != null)
{
if (st_Q10283.isMemoState(2))
{
htmltext = "32022-03.html";
}
else if (st_Q10283.isCompleted())
{
htmltext = "32022-04.html";
}
}
return htmltext;
}
public static void main(String[] args)
{
new Kier();
}
}

View File

@@ -0,0 +1,4 @@
<html><body>Gatekeeper Asher:<br>
Since the the seal was broken, various trees on the island have begun to "leak" large amounts of Mana, drawing it out from reserves far underground.<br>
It is now possible to regenerate MP simply by standing near some of these large trees!
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Gatekeeper Asher:<br>
You don't have enough money.<br>
Teleporting to Rune Township requires 50,000 Adena.
</body></html>

View File

@@ -0,0 +1,7 @@
<html><body>Gatekeeper Asher:<br>
For thousands of years, Primeval Isle had been sealed to prevent its inhabitants from leaving through this Gate. Now, however, adventurers' activities seem to have finally weakened the seal enough to permit departures.<br>
You may now teleport to the mainland, but only to Rune Township. Would you like to do so?<br>
<a action="bypass -h Quest Asher teleport">Teleport to Rune Township (50,000 Adena).</a><br>
<a action="bypass -h Quest Asher 32714-01.html">Ask about the effects of the weakened seal.</a><br>
<a action="bypass -h npc_%objectId%_Quest">Quest</a>
</body></html>

View 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.npc.Teleports.Asher;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import ai.AbstractNpcAI;
/**
* Asher AI.
* @author Adry_85
* @since 2.6.0.0
*/
public class Asher extends AbstractNpcAI
{
// NPC
private static final int ASHER = 32714;
// Location
private static final Location LOCATION = new Location(43835, -47749, -792);
// Misc
private static final int ADENA = 50000;
private Asher()
{
super(Asher.class.getSimpleName(), "ai/npc/Teleports");
addFirstTalkId(ASHER);
addStartNpc(ASHER);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
if (event.equals("teleport"))
{
if (player.getAdena() >= ADENA)
{
player.teleToLocation(LOCATION);
takeItems(player, Inventory.ADENA_ID, ADENA);
}
else
{
return "32714-02.html";
}
}
else if (event.equals("32714-01.html"))
{
return event;
}
return super.onAdvEvent(event, npc, player);
}
public static void main(String[] args)
{
new Asher();
}
}