Fafurion changes.
Source: Liamxroy
This commit is contained in:
parent
2d0d0643ba
commit
801ec5b839
5
L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Fafurion/34488-03.html
vendored
Normal file
5
L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Fafurion/34488-03.html
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<html><body>Heart of Tsunami:<br>
|
||||
(A thundering voice speaks in your head.)<br>
|
||||
Maximum of 200 player can enter.<br>
|
||||
(You cannot challenge Fafurion at this time.)<br>
|
||||
</body></html>
|
175
L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Fafurion/EliteWizard.java
vendored
Normal file
175
L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Fafurion/EliteWizard.java
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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.bosses.Fafurion;
|
||||
|
||||
import org.l2jmobius.commons.util.CommonUtil;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||
import org.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
import org.l2jmobius.gameserver.model.variables.NpcVariables;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* @author NviX
|
||||
*/
|
||||
public class EliteWizard extends AbstractNpcAI
|
||||
{
|
||||
// Npc
|
||||
private static final int ELITE_WIZARD = 29373;
|
||||
// Skills
|
||||
private static final SkillHolder WATER_ARROW = new SkillHolder(32740, 1);
|
||||
private static final SkillHolder ARROW_FLUSH = new SkillHolder(32741, 1);
|
||||
|
||||
private EliteWizard()
|
||||
{
|
||||
registerMobs(ELITE_WIZARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "MANAGE_SKILLS":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
manageSkills(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if (npc.getId() == ELITE_WIZARD)
|
||||
{
|
||||
if (skill == null)
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 1000));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 100));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 20));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 20));
|
||||
}
|
||||
manageSkills(npc);
|
||||
}
|
||||
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage)
|
||||
{
|
||||
refreshAiParams(attacker, npc, damage, damage);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro)
|
||||
{
|
||||
final int newAggroVal = damage + getRandom(3000);
|
||||
final int aggroVal = aggro + 1000;
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (attacker == vars.getObject("c_quest" + i, Creature.class))
|
||||
{
|
||||
if (vars.getInt("i_quest" + i) < aggroVal)
|
||||
{
|
||||
vars.set("i_quest" + i, newAggroVal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
vars.set("i_quest" + index, newAggroVal);
|
||||
vars.set("c_quest" + index, attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill)
|
||||
{
|
||||
startQuestTimer("MANAGE_SKILLS", 1000, npc, null);
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void manageSkills(Npc npc)
|
||||
{
|
||||
if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
final Creature attacker = vars.getObject("c_quest" + i, Creature.class);
|
||||
if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead()))
|
||||
{
|
||||
vars.set("i_quest" + i, 0);
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
final Creature player = vars.getObject("c_quest" + index, Creature.class);
|
||||
final int i2 = vars.getInt("i_quest" + index);
|
||||
if ((i2 > 0) && (getRandom(100) < 70))
|
||||
{
|
||||
vars.set("i_quest" + index, 500);
|
||||
}
|
||||
|
||||
SkillHolder skillToCast = null;
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
if (getRandom(100) < 30)
|
||||
{
|
||||
skillToCast = ARROW_FLUSH;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = WATER_ARROW;
|
||||
}
|
||||
}
|
||||
|
||||
if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skillToCast.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EliteWizard();
|
||||
}
|
||||
}
|
@ -14,19 +14,22 @@
|
||||
* 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.bosses.Fafurion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.enums.Movie;
|
||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||
import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
|
||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.Party;
|
||||
import org.l2jmobius.gameserver.model.StatSet;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.model.zone.type.NoRestartZone;
|
||||
import org.l2jmobius.gameserver.network.NpcStringId;
|
||||
@ -42,59 +45,76 @@ public class Fafurion extends AbstractNpcAI
|
||||
// NPCs
|
||||
private static final int HEART_OF_TSUNAMI = 34488;
|
||||
private static final int FAFURION_GRANDBOSS_ID = 19740;
|
||||
private static final int FAFURION_FINAL_FORM = 29367;
|
||||
private static final int FAFURION_STAGE_1 = 29361;
|
||||
private static final int FAFURION_STAGE_2 = 29362;
|
||||
private static final int FAFURION_STAGE_3 = 29363;
|
||||
private static final int FAFURION_STAGE_4 = 29364;
|
||||
private static final int FAFURION_STAGE_5 = 29365;
|
||||
private static final int FAFURION_STAGE_6 = 29366;
|
||||
private static final int FAFURION_STAGE_7 = 29367;
|
||||
private static final int EMERALD_DRAGON = 29368;
|
||||
private static final int BLUE_WATER_DRAGON = 29369;
|
||||
private static final int FAFURION_DEFENDER = 29370;
|
||||
// Item
|
||||
private static final int FONDUS_STONE = 80322;
|
||||
// Zone
|
||||
private static final NoRestartZone FAFURION_ZONE = ZoneManager.getInstance().getZoneById(85002, NoRestartZone.class);
|
||||
// Locations
|
||||
private static final Location ENTER_NPC_LOC = new Location(190856, 257112, -3328);
|
||||
private static final Location RAID_ENTER_LOC = new Location(180059, 212896, -14727);
|
||||
private static final Location FAFURION_SPAWN_LOC = new Location(180712, 210664, -14823, 22146);
|
||||
// Zone
|
||||
private static final NoRestartZone zone = ZoneManager.getInstance().getZoneById(85002, NoRestartZone.class); // Fafurion Nest zone
|
||||
// Status
|
||||
private static final int ALIVE = 0;
|
||||
private static final int WAITING = 1;
|
||||
private static final int FIGHTING = 2;
|
||||
private static final int DEAD = 3;
|
||||
// Misc
|
||||
private static final int MAX_PEOPLE = 200;
|
||||
private static final int RAID_DURATION = 5; // hours
|
||||
private static GrandBossInstance _fafurion;
|
||||
private int _stage;
|
||||
|
||||
private Fafurion()
|
||||
{
|
||||
addStartNpc(HEART_OF_TSUNAMI);
|
||||
addTalkId(HEART_OF_TSUNAMI);
|
||||
addFirstTalkId(HEART_OF_TSUNAMI);
|
||||
addKillId(FAFURION_FINAL_FORM);
|
||||
final StatSet info = GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID);
|
||||
final long respawnTime = info.getLong("respawn_time");
|
||||
addKillId(FAFURION_STAGE_1, FAFURION_STAGE_2, FAFURION_STAGE_3, FAFURION_STAGE_4, FAFURION_STAGE_5, FAFURION_STAGE_6, FAFURION_STAGE_7);
|
||||
// Unlock
|
||||
if (getStatus() == DEAD)
|
||||
final StatSet info = GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID);
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
if (status == DEAD)
|
||||
{
|
||||
final long time = respawnTime - System.currentTimeMillis();
|
||||
final long time = info.getLong("respawn_time") - System.currentTimeMillis();
|
||||
if (time > 0)
|
||||
{
|
||||
startQuestTimer("unlock_fafurion", time, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
final GrandBossInstance fafurion = (GrandBossInstance) addSpawn(FAFURION_GRANDBOSS_ID, -113360, -244676, -15536, 0, false, 0);
|
||||
GrandBossManager.getInstance().addBoss(fafurion);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
}
|
||||
}
|
||||
else if (getStatus() != ALIVE)
|
||||
else
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
final GrandBossInstance fafurion = (GrandBossInstance) addSpawn(FAFURION_GRANDBOSS_ID, -113360, -244676, -15536, 0, false, 0);
|
||||
GrandBossManager.getInstance().addBoss(fafurion);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final String htmltext = null;
|
||||
String htmltext = null;
|
||||
switch (event)
|
||||
{
|
||||
case "unlock_fafurion":
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
final GrandBossInstance fafurion = (GrandBossInstance) addSpawn(FAFURION_GRANDBOSS_ID, -113360, -244676, -15536, 0, false, 0);
|
||||
GrandBossManager.getInstance().addBoss(fafurion);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
break;
|
||||
}
|
||||
case "warning":
|
||||
@ -111,106 +131,94 @@ public class Fafurion extends AbstractNpcAI
|
||||
}
|
||||
case "beginning":
|
||||
{
|
||||
if (getStatus() == WAITING)
|
||||
if (GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID) == WAITING)
|
||||
{
|
||||
setStatus(FIGHTING);
|
||||
final Npc bossInstance = addSpawn(FAFURION_FINAL_FORM, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
startQuestTimer("resetRaid", RAID_DURATION * 60 * 60 * 1000, bossInstance, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SKIP_WAITING":
|
||||
{
|
||||
if (getStatus() == WAITING)
|
||||
{
|
||||
cancelQuestTimer("warning", null, null);
|
||||
cancelQuestTimer("beginning", null, null);
|
||||
notifyEvent("beginning", null, null);
|
||||
player.sendMessage(getClass().getSimpleName() + ": Skipping waiting time ...");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You can't skip waiting time right now!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "RESPAWN_FAFURION":
|
||||
{
|
||||
if (getStatus() == DEAD)
|
||||
{
|
||||
setRespawn(0);
|
||||
cancelQuestTimer("unlock_fafurion", null, null);
|
||||
notifyEvent("unlock_fafurion", null, null);
|
||||
player.sendMessage(getClass().getSimpleName() + ": Fafurion has been respawned.");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You can't respawn Fafurion while he is alive!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ABORT_FIGHT":
|
||||
{
|
||||
if (getStatus() == FIGHTING)
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
cancelQuestTimer("resetRaid", npc, null);
|
||||
for (Creature creature : zone.getCharactersInside())
|
||||
// checking fafurion stage.
|
||||
_stage = GlobalVariablesManager.getInstance().getInt("Fafurion_Stage", 1);
|
||||
FAFURION_ZONE.getPlayersInside().forEach(p ->
|
||||
{
|
||||
if (creature != null)
|
||||
playMovie(p, Movie.SC_FAFURION_INTRO);
|
||||
});
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, FIGHTING);
|
||||
switch (_stage)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (creature.isNpc())
|
||||
{
|
||||
if (creature.getId() == FAFURION_FINAL_FORM)
|
||||
{
|
||||
creature.teleToLocation(FAFURION_SPAWN_LOC);
|
||||
}
|
||||
else
|
||||
{
|
||||
creature.deleteMe();
|
||||
}
|
||||
}
|
||||
else if (creature.isPlayer() && !creature.isGM())
|
||||
{
|
||||
creature.teleToLocation(ENTER_NPC_LOC);
|
||||
}
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_1, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_2, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_3, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_4, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_5, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_6, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_7, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.sendMessage(getClass().getSimpleName() + ": Fight has been aborted!");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You can't abort fight right now!");
|
||||
startQuestTimer("resetRaid", RAID_DURATION * 60 * 60 * 1000, _fafurion, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "resetRaid":
|
||||
{
|
||||
if ((getStatus() > ALIVE) && (getStatus() < DEAD))
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
if ((status > ALIVE) && (status < DEAD))
|
||||
{
|
||||
for (PlayerInstance plr : World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 5000))
|
||||
{
|
||||
plr.sendPacket(new ExShowScreenMessage(NpcStringId.EXCEEDED_THE_FAFURION_S_NEST_RAID_TIME_LIMIT, ExShowScreenMessage.TOP_CENTER, 10000, true));
|
||||
}
|
||||
setStatus(ALIVE);
|
||||
setRespawn(0);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
FAFURION_ZONE.oustAllPlayers();
|
||||
npc.deleteMe();
|
||||
|
||||
if (_stage > 1)
|
||||
{
|
||||
_stage--;
|
||||
}
|
||||
GlobalVariablesManager.getInstance().set("Fafurion_Stage", _stage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "enter_area":
|
||||
{
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
if (player.isGM())
|
||||
{
|
||||
player.teleToLocation(RAID_ENTER_LOC, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((getStatus() > ALIVE) && (getStatus() < DEAD)) || (getStatus() == DEAD))
|
||||
if (((status > ALIVE) && (status < DEAD)) || (status == DEAD))
|
||||
{
|
||||
return "34488-02.html";
|
||||
}
|
||||
if (FAFURION_ZONE.getPlayersInside().size() >= MAX_PEOPLE)
|
||||
{
|
||||
return "34488-03.html";
|
||||
}
|
||||
if (!player.isInParty())
|
||||
{
|
||||
return "34488-01.html";
|
||||
@ -227,6 +235,10 @@ public class Fafurion extends AbstractNpcAI
|
||||
{
|
||||
return "34488-01.html";
|
||||
}
|
||||
if (members.size() > (MAX_PEOPLE - FAFURION_ZONE.getPlayersInside().size()))
|
||||
{
|
||||
return "34488-03.html";
|
||||
}
|
||||
for (PlayerInstance member : members)
|
||||
{
|
||||
if (member.getLevel() < Config.FAFURION_MIN_PLAYER_LVL)
|
||||
@ -249,9 +261,9 @@ public class Fafurion extends AbstractNpcAI
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getStatus() == ALIVE)
|
||||
if (status == ALIVE)
|
||||
{
|
||||
setStatus(WAITING);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, WAITING);
|
||||
startQuestTimer("beginning", Config.FAFURION_WAIT_TIME * 60000, null, null);
|
||||
startQuestTimer("warning", Config.FAFURION_WAIT_TIME > 0 ? (Config.FAFURION_WAIT_TIME * 60000) - 30000 : 0, null, player);
|
||||
}
|
||||
@ -261,36 +273,195 @@ public class Fafurion extends AbstractNpcAI
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == _fafurion.getId())
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
// TODO: Manage Rage and feature do decrease rage in rooms.
|
||||
case FAFURION_STAGE_1:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_2:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_3:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_4:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_5:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_6:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_7:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
|
||||
{
|
||||
for (PlayerInstance player : World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 5000))
|
||||
if (npc.getId() == _fafurion.getId())
|
||||
{
|
||||
player.sendPacket(new ExShowScreenMessage(NpcStringId.HONORED_WARRIORS_HAVE_DEFEATED_THE_WATER_DRAGON_FAFURION, ExShowScreenMessage.TOP_CENTER, 10000, true));
|
||||
FAFURION_ZONE.getPlayersInside().forEach(p ->
|
||||
{
|
||||
playMovie(p, Movie.SC_FAFURION_ENDING);
|
||||
FAFURION_ZONE.getCharactersInside().forEach(m ->
|
||||
{
|
||||
if (m.isMonster())
|
||||
{
|
||||
m.deleteMe();
|
||||
}
|
||||
});
|
||||
p.sendPacket(new ExShowScreenMessage(NpcStringId.HONORED_WARRIORS_HAVE_DEFEATED_THE_WATER_DRAGON_FAFURION, ExShowScreenMessage.TOP_CENTER, 20000, true));
|
||||
});
|
||||
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, DEAD);
|
||||
final long respawnTime = (Config.FAFURION_SPAWN_INTERVAL + getRandom(-Config.FAFURION_SPAWN_RANDOM, Config.FAFURION_SPAWN_RANDOM)) * 3600000;
|
||||
final StatSet info = GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatSet(FAFURION_GRANDBOSS_ID, info);
|
||||
startQuestTimer("unlock_fafurion", respawnTime, null, null);
|
||||
if (_stage < 7)
|
||||
{
|
||||
_stage++;
|
||||
}
|
||||
GlobalVariablesManager.getInstance().set("Fafurion_Stage", _stage);
|
||||
}
|
||||
|
||||
setStatus(DEAD);
|
||||
final long respawnTime = (Config.FAFURION_SPAWN_INTERVAL + getRandom(-Config.FAFURION_SPAWN_RANDOM, Config.FAFURION_SPAWN_RANDOM)) * 3600000;
|
||||
startQuestTimer("unlock_fafurion", respawnTime, null, null);
|
||||
setRespawn(respawnTime);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private int getStatus()
|
||||
{
|
||||
return GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
}
|
||||
|
||||
private void setStatus(int status)
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, status);
|
||||
}
|
||||
|
||||
private void setRespawn(long respawnTime)
|
||||
{
|
||||
GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID).set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(Npc npc, PlayerInstance player)
|
||||
{
|
||||
@ -301,4 +472,4 @@ public class Fafurion extends AbstractNpcAI
|
||||
{
|
||||
new Fafurion();
|
||||
}
|
||||
}
|
||||
}
|
281
L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Fafurion/FafurionBoss.java
vendored
Normal file
281
L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Fafurion/FafurionBoss.java
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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.bosses.Fafurion;
|
||||
|
||||
import org.l2jmobius.commons.util.CommonUtil;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||
import org.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
import org.l2jmobius.gameserver.model.variables.NpcVariables;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* @author NviX
|
||||
*/
|
||||
public class FafurionBoss extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int FAFURION_STAGE_1 = 29361;
|
||||
private static final int FAFURION_STAGE_2 = 29362;
|
||||
private static final int FAFURION_STAGE_3 = 29363;
|
||||
private static final int FAFURION_STAGE_4 = 29364;
|
||||
private static final int FAFURION_STAGE_5 = 29365;
|
||||
private static final int FAFURION_STAGE_6 = 29366;
|
||||
private static final int FAFURION_STAGE_7 = 29367;
|
||||
// Skills
|
||||
private static final SkillHolder FAFURION_NORMAL_ATTACK = new SkillHolder(32705, 1);
|
||||
private static final SkillHolder FAFURION_BITE = new SkillHolder(32706, 1);
|
||||
private static final SkillHolder FAFURION_WATER_BLAST = new SkillHolder(32708, 1);
|
||||
private static final SkillHolder FAFURION_WATER_SPIRAL = new SkillHolder(32709, 1);
|
||||
private static final SkillHolder FAFURION_HYDRO_BLAST = new SkillHolder(32711, 1);
|
||||
private static final SkillHolder FAFURION_HYDRO_SPIRAL = new SkillHolder(32712, 1);
|
||||
private static final SkillHolder FAFURION_TAIL_STRIKE_1 = new SkillHolder(32713, 1);
|
||||
private static final SkillHolder FAFURION_TAIL_STRIKE_2 = new SkillHolder(32714, 1);
|
||||
private static final SkillHolder FAFURION_WATER_WAVE = new SkillHolder(32715, 1);
|
||||
private static final SkillHolder FAFURION_BREATH = new SkillHolder(32716, 1);
|
||||
private static final SkillHolder FAFURION_FEAR = new SkillHolder(32717, 1);
|
||||
private static final SkillHolder FAFURION_TIDAL_WAVE = new SkillHolder(32723, 1);
|
||||
|
||||
private FafurionBoss()
|
||||
{
|
||||
registerMobs(FAFURION_STAGE_1, FAFURION_STAGE_2, FAFURION_STAGE_3, FAFURION_STAGE_4, FAFURION_STAGE_5, FAFURION_STAGE_6, FAFURION_STAGE_7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "MANAGE_SKILLS":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
manageSkills(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if ((npc.getId() == FAFURION_STAGE_1) || (npc.getId() == FAFURION_STAGE_2) || (npc.getId() == FAFURION_STAGE_3) || (npc.getId() == FAFURION_STAGE_4) || (npc.getId() == FAFURION_STAGE_5) || (npc.getId() == FAFURION_STAGE_6) || (npc.getId() == FAFURION_STAGE_7))
|
||||
{
|
||||
if (skill == null)
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 1000));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 100));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 20));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 20));
|
||||
}
|
||||
manageSkills(npc);
|
||||
}
|
||||
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage)
|
||||
{
|
||||
refreshAiParams(attacker, npc, damage, damage);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro)
|
||||
{
|
||||
final int newAggroVal = damage + getRandom(3000);
|
||||
final int aggroVal = aggro + 1000;
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (attacker == vars.getObject("c_quest" + i, Creature.class))
|
||||
{
|
||||
if (vars.getInt("i_quest" + i) < aggroVal)
|
||||
{
|
||||
vars.set("i_quest" + i, newAggroVal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
vars.set("i_quest" + index, newAggroVal);
|
||||
vars.set("c_quest" + index, attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill)
|
||||
{
|
||||
startQuestTimer("MANAGE_SKILLS", 1000, npc, null);
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void manageSkills(Npc npc)
|
||||
{
|
||||
if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
final Creature attacker = vars.getObject("c_quest" + i, Creature.class);
|
||||
if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead()))
|
||||
{
|
||||
vars.set("i_quest" + i, 0);
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
final Creature player = vars.getObject("c_quest" + index, Creature.class);
|
||||
final int i2 = vars.getInt("i_quest" + index);
|
||||
if ((i2 > 0) && (getRandom(100) < 70))
|
||||
{
|
||||
vars.set("i_quest" + index, 500);
|
||||
}
|
||||
|
||||
SkillHolder skillToCast = null;
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
int chance = getRandom(100);
|
||||
if (npc.getCurrentHp() > (npc.getMaxHp() * 0.8))
|
||||
{
|
||||
if (chance < 30)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_BLAST;
|
||||
}
|
||||
else if (chance < 40)
|
||||
{
|
||||
skillToCast = FAFURION_FEAR;
|
||||
}
|
||||
else if (chance < 60)
|
||||
{
|
||||
skillToCast = FAFURION_BREATH;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = FAFURION_NORMAL_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
if (chance < 15)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_BLAST;
|
||||
}
|
||||
else if (chance < 10)
|
||||
{
|
||||
skillToCast = FAFURION_FEAR;
|
||||
}
|
||||
else if (chance < 35)
|
||||
{
|
||||
skillToCast = FAFURION_BREATH;
|
||||
}
|
||||
else if (chance < 50)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_1;
|
||||
}
|
||||
else if (chance < 65)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = FAFURION_NORMAL_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
if (chance < 5)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_BLAST;
|
||||
}
|
||||
else if (chance < 10)
|
||||
{
|
||||
skillToCast = FAFURION_FEAR;
|
||||
}
|
||||
else if (chance < 15)
|
||||
{
|
||||
skillToCast = FAFURION_BREATH;
|
||||
}
|
||||
else if (chance < 20)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_1;
|
||||
}
|
||||
else if (chance < 30)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_2;
|
||||
}
|
||||
else if (chance < 40)
|
||||
{
|
||||
skillToCast = FAFURION_BITE;
|
||||
}
|
||||
else if (chance < 50)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_SPIRAL;
|
||||
}
|
||||
else if (chance < 60)
|
||||
{
|
||||
skillToCast = FAFURION_HYDRO_BLAST;
|
||||
}
|
||||
else if (chance < 70)
|
||||
{
|
||||
skillToCast = FAFURION_HYDRO_SPIRAL;
|
||||
}
|
||||
else if (chance < 80)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_WAVE;
|
||||
}
|
||||
else if (chance < 90)
|
||||
{
|
||||
skillToCast = FAFURION_TIDAL_WAVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = FAFURION_NORMAL_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skillToCast.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FafurionBoss();
|
||||
}
|
||||
}
|
@ -142,6 +142,8 @@ public enum Movie
|
||||
SC_INZONE_KAIN_INTRO(147, true),
|
||||
SC_INZONE_HELIOS_TRANS_A(148, true),
|
||||
SC_INZONE_HELIOS_TRANS_B(149, true),
|
||||
SC_FAFURION_INTRO(150, true),
|
||||
SC_FAFURION_ENDING(151, true),
|
||||
LAND_KSERTH_A(1000, true),
|
||||
LAND_KSERTH_B(1001, true),
|
||||
LAND_UNDEAD_A(1002, true),
|
||||
|
5
L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Fafurion/34488-03.html
vendored
Normal file
5
L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Fafurion/34488-03.html
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<html><body>Heart of Tsunami:<br>
|
||||
(A thundering voice speaks in your head.)<br>
|
||||
Maximum of 200 player can enter.<br>
|
||||
(You cannot challenge Fafurion at this time.)<br>
|
||||
</body></html>
|
175
L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Fafurion/EliteWizard.java
vendored
Normal file
175
L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Fafurion/EliteWizard.java
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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.bosses.Fafurion;
|
||||
|
||||
import org.l2jmobius.commons.util.CommonUtil;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||
import org.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
import org.l2jmobius.gameserver.model.variables.NpcVariables;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* @author NviX
|
||||
*/
|
||||
public class EliteWizard extends AbstractNpcAI
|
||||
{
|
||||
// Npc
|
||||
private static final int ELITE_WIZARD = 29373;
|
||||
// Skills
|
||||
private static final SkillHolder WATER_ARROW = new SkillHolder(32740, 1);
|
||||
private static final SkillHolder ARROW_FLUSH = new SkillHolder(32741, 1);
|
||||
|
||||
private EliteWizard()
|
||||
{
|
||||
registerMobs(ELITE_WIZARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "MANAGE_SKILLS":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
manageSkills(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if (npc.getId() == ELITE_WIZARD)
|
||||
{
|
||||
if (skill == null)
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 1000));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 100));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 20));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 20));
|
||||
}
|
||||
manageSkills(npc);
|
||||
}
|
||||
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage)
|
||||
{
|
||||
refreshAiParams(attacker, npc, damage, damage);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro)
|
||||
{
|
||||
final int newAggroVal = damage + getRandom(3000);
|
||||
final int aggroVal = aggro + 1000;
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (attacker == vars.getObject("c_quest" + i, Creature.class))
|
||||
{
|
||||
if (vars.getInt("i_quest" + i) < aggroVal)
|
||||
{
|
||||
vars.set("i_quest" + i, newAggroVal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
vars.set("i_quest" + index, newAggroVal);
|
||||
vars.set("c_quest" + index, attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill)
|
||||
{
|
||||
startQuestTimer("MANAGE_SKILLS", 1000, npc, null);
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void manageSkills(Npc npc)
|
||||
{
|
||||
if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
final Creature attacker = vars.getObject("c_quest" + i, Creature.class);
|
||||
if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead()))
|
||||
{
|
||||
vars.set("i_quest" + i, 0);
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
final Creature player = vars.getObject("c_quest" + index, Creature.class);
|
||||
final int i2 = vars.getInt("i_quest" + index);
|
||||
if ((i2 > 0) && (getRandom(100) < 70))
|
||||
{
|
||||
vars.set("i_quest" + index, 500);
|
||||
}
|
||||
|
||||
SkillHolder skillToCast = null;
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
if (getRandom(100) < 30)
|
||||
{
|
||||
skillToCast = ARROW_FLUSH;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = WATER_ARROW;
|
||||
}
|
||||
}
|
||||
|
||||
if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skillToCast.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EliteWizard();
|
||||
}
|
||||
}
|
@ -14,19 +14,22 @@
|
||||
* 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.bosses.Fafurion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.enums.Movie;
|
||||
import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||
import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
|
||||
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.Party;
|
||||
import org.l2jmobius.gameserver.model.StatSet;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.model.zone.type.NoRestartZone;
|
||||
import org.l2jmobius.gameserver.network.NpcStringId;
|
||||
@ -42,59 +45,76 @@ public class Fafurion extends AbstractNpcAI
|
||||
// NPCs
|
||||
private static final int HEART_OF_TSUNAMI = 34488;
|
||||
private static final int FAFURION_GRANDBOSS_ID = 19740;
|
||||
private static final int FAFURION_FINAL_FORM = 29367;
|
||||
private static final int FAFURION_STAGE_1 = 29361;
|
||||
private static final int FAFURION_STAGE_2 = 29362;
|
||||
private static final int FAFURION_STAGE_3 = 29363;
|
||||
private static final int FAFURION_STAGE_4 = 29364;
|
||||
private static final int FAFURION_STAGE_5 = 29365;
|
||||
private static final int FAFURION_STAGE_6 = 29366;
|
||||
private static final int FAFURION_STAGE_7 = 29367;
|
||||
private static final int EMERALD_DRAGON = 29368;
|
||||
private static final int BLUE_WATER_DRAGON = 29369;
|
||||
private static final int FAFURION_DEFENDER = 29370;
|
||||
// Item
|
||||
private static final int FONDUS_STONE = 80322;
|
||||
// Zone
|
||||
private static final NoRestartZone FAFURION_ZONE = ZoneManager.getInstance().getZoneById(85002, NoRestartZone.class);
|
||||
// Locations
|
||||
private static final Location ENTER_NPC_LOC = new Location(190856, 257112, -3328);
|
||||
private static final Location RAID_ENTER_LOC = new Location(180059, 212896, -14727);
|
||||
private static final Location FAFURION_SPAWN_LOC = new Location(180712, 210664, -14823, 22146);
|
||||
// Zone
|
||||
private static final NoRestartZone zone = ZoneManager.getInstance().getZoneById(85002, NoRestartZone.class); // Fafurion Nest zone
|
||||
// Status
|
||||
private static final int ALIVE = 0;
|
||||
private static final int WAITING = 1;
|
||||
private static final int FIGHTING = 2;
|
||||
private static final int DEAD = 3;
|
||||
// Misc
|
||||
private static final int MAX_PEOPLE = 200;
|
||||
private static final int RAID_DURATION = 5; // hours
|
||||
private static GrandBossInstance _fafurion;
|
||||
private int _stage;
|
||||
|
||||
private Fafurion()
|
||||
{
|
||||
addStartNpc(HEART_OF_TSUNAMI);
|
||||
addTalkId(HEART_OF_TSUNAMI);
|
||||
addFirstTalkId(HEART_OF_TSUNAMI);
|
||||
addKillId(FAFURION_FINAL_FORM);
|
||||
final StatSet info = GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID);
|
||||
final long respawnTime = info.getLong("respawn_time");
|
||||
addKillId(FAFURION_STAGE_1, FAFURION_STAGE_2, FAFURION_STAGE_3, FAFURION_STAGE_4, FAFURION_STAGE_5, FAFURION_STAGE_6, FAFURION_STAGE_7);
|
||||
// Unlock
|
||||
if (getStatus() == DEAD)
|
||||
final StatSet info = GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID);
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
if (status == DEAD)
|
||||
{
|
||||
final long time = respawnTime - System.currentTimeMillis();
|
||||
final long time = info.getLong("respawn_time") - System.currentTimeMillis();
|
||||
if (time > 0)
|
||||
{
|
||||
startQuestTimer("unlock_fafurion", time, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
final GrandBossInstance fafurion = (GrandBossInstance) addSpawn(FAFURION_GRANDBOSS_ID, -113360, -244676, -15536, 0, false, 0);
|
||||
GrandBossManager.getInstance().addBoss(fafurion);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
}
|
||||
}
|
||||
else if (getStatus() != ALIVE)
|
||||
else
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
final GrandBossInstance fafurion = (GrandBossInstance) addSpawn(FAFURION_GRANDBOSS_ID, -113360, -244676, -15536, 0, false, 0);
|
||||
GrandBossManager.getInstance().addBoss(fafurion);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
|
||||
{
|
||||
final String htmltext = null;
|
||||
String htmltext = null;
|
||||
switch (event)
|
||||
{
|
||||
case "unlock_fafurion":
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
final GrandBossInstance fafurion = (GrandBossInstance) addSpawn(FAFURION_GRANDBOSS_ID, -113360, -244676, -15536, 0, false, 0);
|
||||
GrandBossManager.getInstance().addBoss(fafurion);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
break;
|
||||
}
|
||||
case "warning":
|
||||
@ -111,106 +131,94 @@ public class Fafurion extends AbstractNpcAI
|
||||
}
|
||||
case "beginning":
|
||||
{
|
||||
if (getStatus() == WAITING)
|
||||
if (GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID) == WAITING)
|
||||
{
|
||||
setStatus(FIGHTING);
|
||||
final Npc bossInstance = addSpawn(FAFURION_FINAL_FORM, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
startQuestTimer("resetRaid", RAID_DURATION * 60 * 60 * 1000, bossInstance, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SKIP_WAITING":
|
||||
{
|
||||
if (getStatus() == WAITING)
|
||||
{
|
||||
cancelQuestTimer("warning", null, null);
|
||||
cancelQuestTimer("beginning", null, null);
|
||||
notifyEvent("beginning", null, null);
|
||||
player.sendMessage(getClass().getSimpleName() + ": Skipping waiting time ...");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You can't skip waiting time right now!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "RESPAWN_FAFURION":
|
||||
{
|
||||
if (getStatus() == DEAD)
|
||||
{
|
||||
setRespawn(0);
|
||||
cancelQuestTimer("unlock_fafurion", null, null);
|
||||
notifyEvent("unlock_fafurion", null, null);
|
||||
player.sendMessage(getClass().getSimpleName() + ": Fafurion has been respawned.");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You can't respawn Fafurion while he is alive!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ABORT_FIGHT":
|
||||
{
|
||||
if (getStatus() == FIGHTING)
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
cancelQuestTimer("resetRaid", npc, null);
|
||||
for (Creature creature : zone.getCharactersInside())
|
||||
// checking fafurion stage.
|
||||
_stage = GlobalVariablesManager.getInstance().getInt("Fafurion_Stage", 1);
|
||||
FAFURION_ZONE.getPlayersInside().forEach(p ->
|
||||
{
|
||||
if (creature != null)
|
||||
playMovie(p, Movie.SC_FAFURION_INTRO);
|
||||
});
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, FIGHTING);
|
||||
switch (_stage)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (creature.isNpc())
|
||||
{
|
||||
if (creature.getId() == FAFURION_FINAL_FORM)
|
||||
{
|
||||
creature.teleToLocation(FAFURION_SPAWN_LOC);
|
||||
}
|
||||
else
|
||||
{
|
||||
creature.deleteMe();
|
||||
}
|
||||
}
|
||||
else if (creature.isPlayer() && !creature.isGM())
|
||||
{
|
||||
creature.teleToLocation(ENTER_NPC_LOC);
|
||||
}
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_1, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_2, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_3, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_4, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_5, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_6, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
_fafurion = (GrandBossInstance) addSpawn(FAFURION_STAGE_7, FAFURION_SPAWN_LOC.getX(), FAFURION_SPAWN_LOC.getY(), FAFURION_SPAWN_LOC.getZ(), FAFURION_SPAWN_LOC.getHeading(), false, 0, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
player.sendMessage(getClass().getSimpleName() + ": Fight has been aborted!");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You can't abort fight right now!");
|
||||
startQuestTimer("resetRaid", RAID_DURATION * 60 * 60 * 1000, _fafurion, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "resetRaid":
|
||||
{
|
||||
if ((getStatus() > ALIVE) && (getStatus() < DEAD))
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
if ((status > ALIVE) && (status < DEAD))
|
||||
{
|
||||
for (PlayerInstance plr : World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 5000))
|
||||
{
|
||||
plr.sendPacket(new ExShowScreenMessage(NpcStringId.EXCEEDED_THE_FAFURION_S_NEST_RAID_TIME_LIMIT, ExShowScreenMessage.TOP_CENTER, 10000, true));
|
||||
}
|
||||
setStatus(ALIVE);
|
||||
setRespawn(0);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, ALIVE);
|
||||
FAFURION_ZONE.oustAllPlayers();
|
||||
npc.deleteMe();
|
||||
|
||||
if (_stage > 1)
|
||||
{
|
||||
_stage--;
|
||||
}
|
||||
GlobalVariablesManager.getInstance().set("Fafurion_Stage", _stage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "enter_area":
|
||||
{
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
if (player.isGM())
|
||||
{
|
||||
player.teleToLocation(RAID_ENTER_LOC, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((getStatus() > ALIVE) && (getStatus() < DEAD)) || (getStatus() == DEAD))
|
||||
if (((status > ALIVE) && (status < DEAD)) || (status == DEAD))
|
||||
{
|
||||
return "34488-02.html";
|
||||
}
|
||||
if (FAFURION_ZONE.getPlayersInside().size() >= MAX_PEOPLE)
|
||||
{
|
||||
return "34488-03.html";
|
||||
}
|
||||
if (!player.isInParty())
|
||||
{
|
||||
return "34488-01.html";
|
||||
@ -227,6 +235,10 @@ public class Fafurion extends AbstractNpcAI
|
||||
{
|
||||
return "34488-01.html";
|
||||
}
|
||||
if (members.size() > (MAX_PEOPLE - FAFURION_ZONE.getPlayersInside().size()))
|
||||
{
|
||||
return "34488-03.html";
|
||||
}
|
||||
for (PlayerInstance member : members)
|
||||
{
|
||||
if (member.getLevel() < Config.FAFURION_MIN_PLAYER_LVL)
|
||||
@ -249,9 +261,9 @@ public class Fafurion extends AbstractNpcAI
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getStatus() == ALIVE)
|
||||
if (status == ALIVE)
|
||||
{
|
||||
setStatus(WAITING);
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, WAITING);
|
||||
startQuestTimer("beginning", Config.FAFURION_WAIT_TIME * 60000, null, null);
|
||||
startQuestTimer("warning", Config.FAFURION_WAIT_TIME > 0 ? (Config.FAFURION_WAIT_TIME * 60000) - 30000 : 0, null, player);
|
||||
}
|
||||
@ -261,36 +273,195 @@ public class Fafurion extends AbstractNpcAI
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == _fafurion.getId())
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
// TODO: Manage Rage and feature do decrease rage in rooms.
|
||||
case FAFURION_STAGE_1:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_2:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_3:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_4:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_5:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_6:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAFURION_STAGE_7:
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
addSpawn(EMERALD_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(BLUE_WATER_DRAGON, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
addSpawn(FAFURION_DEFENDER, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), true, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(Npc npc, PlayerInstance killer, boolean isSummon)
|
||||
{
|
||||
for (PlayerInstance player : World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 5000))
|
||||
if (npc.getId() == _fafurion.getId())
|
||||
{
|
||||
player.sendPacket(new ExShowScreenMessage(NpcStringId.HONORED_WARRIORS_HAVE_DEFEATED_THE_WATER_DRAGON_FAFURION, ExShowScreenMessage.TOP_CENTER, 10000, true));
|
||||
FAFURION_ZONE.getPlayersInside().forEach(p ->
|
||||
{
|
||||
playMovie(p, Movie.SC_FAFURION_ENDING);
|
||||
FAFURION_ZONE.getCharactersInside().forEach(m ->
|
||||
{
|
||||
if (m.isMonster())
|
||||
{
|
||||
m.deleteMe();
|
||||
}
|
||||
});
|
||||
p.sendPacket(new ExShowScreenMessage(NpcStringId.HONORED_WARRIORS_HAVE_DEFEATED_THE_WATER_DRAGON_FAFURION, ExShowScreenMessage.TOP_CENTER, 20000, true));
|
||||
});
|
||||
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, DEAD);
|
||||
final long respawnTime = (Config.FAFURION_SPAWN_INTERVAL + getRandom(-Config.FAFURION_SPAWN_RANDOM, Config.FAFURION_SPAWN_RANDOM)) * 3600000;
|
||||
final StatSet info = GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatSet(FAFURION_GRANDBOSS_ID, info);
|
||||
startQuestTimer("unlock_fafurion", respawnTime, null, null);
|
||||
if (_stage < 7)
|
||||
{
|
||||
_stage++;
|
||||
}
|
||||
GlobalVariablesManager.getInstance().set("Fafurion_Stage", _stage);
|
||||
}
|
||||
|
||||
setStatus(DEAD);
|
||||
final long respawnTime = (Config.FAFURION_SPAWN_INTERVAL + getRandom(-Config.FAFURION_SPAWN_RANDOM, Config.FAFURION_SPAWN_RANDOM)) * 3600000;
|
||||
startQuestTimer("unlock_fafurion", respawnTime, null, null);
|
||||
setRespawn(respawnTime);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private int getStatus()
|
||||
{
|
||||
return GrandBossManager.getInstance().getBossStatus(FAFURION_GRANDBOSS_ID);
|
||||
}
|
||||
|
||||
private void setStatus(int status)
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(FAFURION_GRANDBOSS_ID, status);
|
||||
}
|
||||
|
||||
private void setRespawn(long respawnTime)
|
||||
{
|
||||
GrandBossManager.getInstance().getStatSet(FAFURION_GRANDBOSS_ID).set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(Npc npc, PlayerInstance player)
|
||||
{
|
||||
@ -301,4 +472,4 @@ public class Fafurion extends AbstractNpcAI
|
||||
{
|
||||
new Fafurion();
|
||||
}
|
||||
}
|
||||
}
|
281
L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Fafurion/FafurionBoss.java
vendored
Normal file
281
L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Fafurion/FafurionBoss.java
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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.bosses.Fafurion;
|
||||
|
||||
import org.l2jmobius.commons.util.CommonUtil;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
|
||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import org.l2jmobius.gameserver.model.skills.Skill;
|
||||
import org.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
import org.l2jmobius.gameserver.model.variables.NpcVariables;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* @author NviX
|
||||
*/
|
||||
public class FafurionBoss extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int FAFURION_STAGE_1 = 29361;
|
||||
private static final int FAFURION_STAGE_2 = 29362;
|
||||
private static final int FAFURION_STAGE_3 = 29363;
|
||||
private static final int FAFURION_STAGE_4 = 29364;
|
||||
private static final int FAFURION_STAGE_5 = 29365;
|
||||
private static final int FAFURION_STAGE_6 = 29366;
|
||||
private static final int FAFURION_STAGE_7 = 29367;
|
||||
// Skills
|
||||
private static final SkillHolder FAFURION_NORMAL_ATTACK = new SkillHolder(32705, 1);
|
||||
private static final SkillHolder FAFURION_BITE = new SkillHolder(32706, 1);
|
||||
private static final SkillHolder FAFURION_WATER_BLAST = new SkillHolder(32708, 1);
|
||||
private static final SkillHolder FAFURION_WATER_SPIRAL = new SkillHolder(32709, 1);
|
||||
private static final SkillHolder FAFURION_HYDRO_BLAST = new SkillHolder(32711, 1);
|
||||
private static final SkillHolder FAFURION_HYDRO_SPIRAL = new SkillHolder(32712, 1);
|
||||
private static final SkillHolder FAFURION_TAIL_STRIKE_1 = new SkillHolder(32713, 1);
|
||||
private static final SkillHolder FAFURION_TAIL_STRIKE_2 = new SkillHolder(32714, 1);
|
||||
private static final SkillHolder FAFURION_WATER_WAVE = new SkillHolder(32715, 1);
|
||||
private static final SkillHolder FAFURION_BREATH = new SkillHolder(32716, 1);
|
||||
private static final SkillHolder FAFURION_FEAR = new SkillHolder(32717, 1);
|
||||
private static final SkillHolder FAFURION_TIDAL_WAVE = new SkillHolder(32723, 1);
|
||||
|
||||
private FafurionBoss()
|
||||
{
|
||||
registerMobs(FAFURION_STAGE_1, FAFURION_STAGE_2, FAFURION_STAGE_3, FAFURION_STAGE_4, FAFURION_STAGE_5, FAFURION_STAGE_6, FAFURION_STAGE_7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, Npc npc, PlayerInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "MANAGE_SKILLS":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
manageSkills(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if ((npc.getId() == FAFURION_STAGE_1) || (npc.getId() == FAFURION_STAGE_2) || (npc.getId() == FAFURION_STAGE_3) || (npc.getId() == FAFURION_STAGE_4) || (npc.getId() == FAFURION_STAGE_5) || (npc.getId() == FAFURION_STAGE_6) || (npc.getId() == FAFURION_STAGE_7))
|
||||
{
|
||||
if (skill == null)
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 1000));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 100));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 20));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 20));
|
||||
}
|
||||
manageSkills(npc);
|
||||
}
|
||||
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage)
|
||||
{
|
||||
refreshAiParams(attacker, npc, damage, damage);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro)
|
||||
{
|
||||
final int newAggroVal = damage + getRandom(3000);
|
||||
final int aggroVal = aggro + 1000;
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (attacker == vars.getObject("c_quest" + i, Creature.class))
|
||||
{
|
||||
if (vars.getInt("i_quest" + i) < aggroVal)
|
||||
{
|
||||
vars.set("i_quest" + i, newAggroVal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
vars.set("i_quest" + index, newAggroVal);
|
||||
vars.set("c_quest" + index, attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(Npc npc, PlayerInstance player, Skill skill)
|
||||
{
|
||||
startQuestTimer("MANAGE_SKILLS", 1000, npc, null);
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void manageSkills(Npc npc)
|
||||
{
|
||||
if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
final Creature attacker = vars.getObject("c_quest" + i, Creature.class);
|
||||
if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead()))
|
||||
{
|
||||
vars.set("i_quest" + i, 0);
|
||||
}
|
||||
}
|
||||
final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
final Creature player = vars.getObject("c_quest" + index, Creature.class);
|
||||
final int i2 = vars.getInt("i_quest" + index);
|
||||
if ((i2 > 0) && (getRandom(100) < 70))
|
||||
{
|
||||
vars.set("i_quest" + index, 500);
|
||||
}
|
||||
|
||||
SkillHolder skillToCast = null;
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
int chance = getRandom(100);
|
||||
if (npc.getCurrentHp() > (npc.getMaxHp() * 0.8))
|
||||
{
|
||||
if (chance < 30)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_BLAST;
|
||||
}
|
||||
else if (chance < 40)
|
||||
{
|
||||
skillToCast = FAFURION_FEAR;
|
||||
}
|
||||
else if (chance < 60)
|
||||
{
|
||||
skillToCast = FAFURION_BREATH;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = FAFURION_NORMAL_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.6))
|
||||
{
|
||||
if (chance < 15)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_BLAST;
|
||||
}
|
||||
else if (chance < 10)
|
||||
{
|
||||
skillToCast = FAFURION_FEAR;
|
||||
}
|
||||
else if (chance < 35)
|
||||
{
|
||||
skillToCast = FAFURION_BREATH;
|
||||
}
|
||||
else if (chance < 50)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_1;
|
||||
}
|
||||
else if (chance < 65)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = FAFURION_NORMAL_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.3))
|
||||
{
|
||||
if (chance < 5)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_BLAST;
|
||||
}
|
||||
else if (chance < 10)
|
||||
{
|
||||
skillToCast = FAFURION_FEAR;
|
||||
}
|
||||
else if (chance < 15)
|
||||
{
|
||||
skillToCast = FAFURION_BREATH;
|
||||
}
|
||||
else if (chance < 20)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_1;
|
||||
}
|
||||
else if (chance < 30)
|
||||
{
|
||||
skillToCast = FAFURION_TAIL_STRIKE_2;
|
||||
}
|
||||
else if (chance < 40)
|
||||
{
|
||||
skillToCast = FAFURION_BITE;
|
||||
}
|
||||
else if (chance < 50)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_SPIRAL;
|
||||
}
|
||||
else if (chance < 60)
|
||||
{
|
||||
skillToCast = FAFURION_HYDRO_BLAST;
|
||||
}
|
||||
else if (chance < 70)
|
||||
{
|
||||
skillToCast = FAFURION_HYDRO_SPIRAL;
|
||||
}
|
||||
else if (chance < 80)
|
||||
{
|
||||
skillToCast = FAFURION_WATER_WAVE;
|
||||
}
|
||||
else if (chance < 90)
|
||||
{
|
||||
skillToCast = FAFURION_TIDAL_WAVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = FAFURION_NORMAL_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skillToCast.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FafurionBoss();
|
||||
}
|
||||
}
|
@ -142,6 +142,8 @@ public enum Movie
|
||||
SC_INZONE_KAIN_INTRO(147, true),
|
||||
SC_INZONE_HELIOS_TRANS_A(148, true),
|
||||
SC_INZONE_HELIOS_TRANS_B(149, true),
|
||||
SC_FAFURION_INTRO(150, true),
|
||||
SC_FAFURION_ENDING(151, true),
|
||||
LAND_KSERTH_A(1000, true),
|
||||
LAND_KSERTH_B(1001, true),
|
||||
LAND_UNDEAD_A(1002, true),
|
||||
|
Loading…
Reference in New Issue
Block a user