Merged with released L2J-Unity files.

This commit is contained in:
mobiusdev
2016-06-12 01:34:09 +00:00
parent e003e87887
commit 635557f5da
18352 changed files with 3245113 additions and 2892959 deletions

View File

@@ -0,0 +1,8 @@
<html><body>Rumiese:<br>
Here's the plan. You weaken Istina as much as you can, while I prepare the magical Ballista. Have you seen one of those? They're rather impressive. They are powered by soulshots and can do a great deal of damage. Their main drawback is that they require a lot of energy to recharge, so please tell your team to push yourselves to collect as much magical power as you can, as quickly as possible.<br>
That is all the advice I can give; the rest of it is up to you.<br>
Oh, I once gave you an <font color="LEVEL">Energy Control Device</font>, didn't I? You will most certainly need it for your fight with Istina, so shall I give it to you now?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern leaveInstance">"No, I have somewhere else to be."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern giveDevice">"Please give me a Control Device."</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,7 @@
<html><body>Rumiese:<br>
Somebody is already fighting with Istina. If you want, I can let you in.<br>
Oh, I once gave you an <font color="LEVEL">Energy Control Device</font>, didn't I? You will most certainly need it for your fight with Istina, so shall I give it to you now?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern battleTeleport">"Please let me in."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern leaveInstance">"No, I have somewhere else to be."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern giveDevice">"Please give me a Control Device."</Button>
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Rumiese:<br>
If you time things right, you can deal a critical blow to Istina with the magical power Ballista. Use all the power you have at your disposal to fully charge magical power within the time limit. If you can manage this--and with a little bit of luck--you'll really hurt Istina. Good luck!
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Rumiese:<br>
What an achievement! I am truly in awe of you and your cohorts. Now, let me give you something in recognition of your work. It's not much, compared to your great accomplishments, but I have a chest containing the strength of Istina's soul stone. The soul stone itself sometimes changes materials. Please, accept this with our thanks.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern giveReward">"Can I get a chest imbued with soul stone power?"</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Rumiese:<br>
Unfortunately, either our skill or our luck was not enough to meet the challenge. Istina has retreated, cowed but undefeated. It is only a matter of time before it returns.<br>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Rumiese:<br>
Here we go. Please do not forget you use this when you need it!<br>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Rumiese:<br>
This item can't be sold. But you already have one; you don't need another.<br>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,4 @@
<html><body>Rumiese:<br>
You have quite excellent abilities, but you are also greedy. Shouldn't we give someone else a chance?<br>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
</body></html>

View File

@@ -0,0 +1,694 @@
/*
* 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 instances.IstinaCavern;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.enums.Movie;
import com.l2jmobius.gameserver.model.AggroInfo;
import com.l2jmobius.gameserver.model.DamageDoneInfo;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.StatsSet;
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.L2DoorInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.instancezone.Instance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.NpcStringId;
import com.l2jmobius.gameserver.network.serverpackets.ExSendUIEvent;
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
import com.l2jmobius.gameserver.network.serverpackets.PlaySound;
import com.l2jmobius.gameserver.util.Util;
import instances.AbstractInstance;
/**
* Istina Cavern instance zone.
* @author St3eT
*/
public final class IstinaCavern extends AbstractInstance
{
// NPCs
private static final int RUMIESE = 33151;
private static final int RUMIESE_INSTANCE = 33293;
private static final int INVISIBLE_NPC = 18919;
private static final int BALLISTA = 19021;
private static final int EXTREME_MINION = 23125;
private static final int[] ISTINA =
{
29195, // Istina (Common)
29196, // Istina (Extreme)
};
// Skills
private static final SkillHolder ERUPTION_1 = new SkillHolder(14222, 1);
private static final SkillHolder ERUPTION_2 = new SkillHolder(14223, 1);
private static final SkillHolder ISTINA_ERUPTION_SKILL = new SkillHolder(14221, 1);
// Items
private static final int CONTROL_DEVICE = 17608; // Energy Control Device
private static final int REWARD_BOX_COMMON = 30371; // Box Containing Magic Power
private static final int REWARD_BOX_EXTREME = 30374; // Magic Filled Box
// Locations
private static final Location DEFEAT_ISTINA_LOC = new Location(-177120, 148782, -11384, 49140);
private static final Location RUMIESE_LOC = new Location(-177001, 147844, -11380, 47684);
private static final Location BATTLE_LOC = new Location(-177111, 146802, -11384);
// Misc
private static final int PERFECT_SCORE_1 = 30000000;
private static final int PERFECT_SCORE_2 = 300000000;
private static final int TEMPLATE_ID_COMMON = 169;
private static final int TEMPLATE_ID_EXTREME = 170;
public IstinaCavern()
{
addStartNpc(RUMIESE);
addTalkId(RUMIESE, RUMIESE_INSTANCE);
addFirstTalkId(RUMIESE_INSTANCE);
addAttackId(ISTINA);
addAttackId(BALLISTA);
addSpellFinishedId(ISTINA);
addSpellFinishedId(INVISIBLE_NPC);
addSpawnId(INVISIBLE_NPC, BALLISTA);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
final Instance instance = npc.getInstanceWorld();
if (isIstinaInstance(instance))
{
switch (event)
{
case "leaveInstance":
{
teleportPlayerOut(player, instance);
break;
}
case "battleTeleport":
{
player.teleToLocation(BATTLE_LOC);
break;
}
case "giveDevice":
{
if (!hasQuestItems(player, CONTROL_DEVICE))
{
giveItems(player, CONTROL_DEVICE, 1);
htmltext = "33293-06.html";
}
else
{
htmltext = "33293-07.html";
}
}
case "giveReward":
{
if (instance.isStatus(3))
{
if (npc.getVariables().getBoolean("PLAYER_" + player.getObjectId(), true))
{
giveItems(player, (isExtremeMode(instance) ? REWARD_BOX_EXTREME : REWARD_BOX_COMMON), 1);
npc.getVariables().set("PLAYER_" + player.getObjectId(), false);
}
else
{
htmltext = "33293-08.html";
}
}
break;
}
}
}
else
{
if (event.equals("enterInstanceCommon"))
{
enterInstance(player, npc, TEMPLATE_ID_COMMON);
}
else if (event.equals("enterInstanceExtreme"))
{
enterInstance(player, npc, TEMPLATE_ID_EXTREME);
}
}
return htmltext;
}
@Override
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
{
final Instance instance = npc.getInstanceWorld();
if (isIstinaInstance(instance))
{
final StatsSet npcParams = npc.getParameters();
final StatsSet npcVars = npc.getVariables();
switch (event)
{
case "DEATH_TIMER":
{
final L2Character mostHated = ((L2Attackable) npc).getMostHated();
if ((mostHated != null) && npc.isInsideRadius(mostHated, 15000, false, true))
{
final SkillHolder death1 = npcParams.getSkillHolder("Istina_Death_Skill01");
final SkillHolder death2 = npcParams.getSkillHolder("Istina_Death_Skill02");
if (mostHated.isInCategory(CategoryType.TANKER_GROUP))
{
addSkillCastDesire(npc, mostHated, (mostHated.isAffectedBySkill(death1) ? death2 : death1), 23);
}
else
{
addSkillCastDesire(npc, mostHated, death2, 23);
}
}
getTimers().addTimer("DEATH_TIMER", 35000, npc, null);
break;
}
case "DEATH_CHECK_TIMER":
{
final SkillHolder death1 = npcParams.getSkillHolder("Istina_Death_Skill01");
final SkillHolder death2 = npcParams.getSkillHolder("Istina_Death_Skill02");
final L2Character mostHated = ((L2Attackable) npc).getMostHated();
if ((mostHated != null) && npc.isInsideRadius(mostHated, 15000, false, true) && mostHated.isInCategory(CategoryType.TANKER_GROUP) && mostHated.isAffectedBySkill(death1))
{
addSkillCastDesire(npc, mostHated, death2, 23);
}
break;
}
case "REFLECT_TIMER":
{
if (!isExtremeMode(instance))
{
showOnScreenMsg(instance, NpcStringId.ISTINA_SPREADS_THE_REFLECTING_PROTECTIVE_SHEET, ExShowScreenMessage.TOP_CENTER, 4000);
}
final SkillHolder reflect = npcParams.getSkillHolder("Istina_Refraction_Skill");
npc.setTarget(npc);
npc.doCast(reflect.getSkill());
instance.broadcastPacket(new PlaySound(1, "Npcdialog1.istina_voice_02", 0, 0, 0, 0, 0));
getTimers().addTimer("REFLECT_TIMER", 90000 + getRandom(15000), npc, null);
break;
}
case "REFLECT_CHECK_TIMER":
{
if (npc.isAffectedBySkill(npcParams.getSkillHolder("Istina_Refraction_Skill")))
{
getTimers().addTimer("REFLECT_CHECK_TIMER", 1000, npc, null);
}
else
{
npc.setDisplayEffect(2);
}
break;
}
case "LOW_ERUPTION_TIMER":
{
final L2Attackable istina = (L2Attackable) npc;
if ((istina.getHateList() != null) && (istina.getHateList().size() > 0))
{
final L2Character target = istina.getHateList().stream().sorted((o1, o2) -> (int) o1.calculateDistance(o2, true, false)).findFirst().orElse(null);
if (target != null)
{
final L2Npc eruption = addSpawn(INVISIBLE_NPC, Util.getRandomPosition(target, 50, 50), false, 0, false, instance.getId());
eruption.getVariables().set("ERUPTION_TARGET", target);
}
}
getTimers().addTimer("LOW_ERUPTION_TIMER", 15000, npc, null);
break;
}
case "ERUPTION_TIMER":
{
addSkillCastDesire(npc, npc, ISTINA_ERUPTION_SKILL, 23);
showOnScreenMsg(instance, NpcStringId.POWERFUL_ACIDIC_ENERGY_IS_ERUPTING_FROM_ISTINA_S_BODY, ExShowScreenMessage.TOP_CENTER, 6000);
getTimers().addTimer("ERUPTION_TIMER", 50000 + getRandom(15000), npc, null);
break;
}
case "BALLISTA_START_TIMER":
{
final int helpCountDown = npcVars.getInt("HELP_COUNT_DOWN", 5);
if (helpCountDown == 0)
{
getTimers().addTimer("BALLISTA_CHECK_TIMER", 1000, npc, null);
npc.setTargetable(true);
npc.setIsInvul(false);
npcVars.set("COUNTING_ENABLED", true);
showOnScreenMsg(instance, NpcStringId.START_CHARGING_MANA_BALLISTA, ExShowScreenMessage.MIDDLE_CENTER, 4000);
}
else
{
showOnScreenMsg(instance, NpcStringId.AFTER_S1_SECONDS_THE_CHARGING_MAGIC_BALLISTAS_STARTS, ExShowScreenMessage.MIDDLE_CENTER, 4000, Integer.toString(helpCountDown));
npcVars.set("HELP_COUNT_DOWN", helpCountDown - 1);
getTimers().addTimer("BALLISTA_START_TIMER", 1000, npc, null);
}
break;
}
case "BALLISTA_CHECK_TIMER":
{
if (npcVars.getBoolean("COUNTING_ENABLED", false))
{
final int countDown = npcVars.getInt("COUNT_DOWN", 30);
final int charged = getChargedPercent(npcVars.getInt("SCORE_VAL", 0), isExtremeMode(instance));
if (countDown == 0)
{
npcVars.set("COUNTING_ENABLED", false);
npc.setTargetable(false);
npc.setIsInvul(true);
getTimers().addTimer("BALLISTA_END_TIMER", 1000, npc, null);
instance.getPlayers().forEach(temp -> temp.sendPacket(new ExSendUIEvent(temp, 2, countDown, charged, 0, 2042, 0, NpcStringId.REPLENISH_BALLISTA_MAGIC_POWER.getId())));
}
npcVars.set("HELP_COUNT_DOWN", npcVars.getInt("HELP_COUNT_DOWN", 0) + 1);
if (npcVars.getInt("HELP_COUNT_DOWN", 0) == 2)
{
npcVars.set("COUNT_DOWN", countDown - 1);
npcVars.set("HELP_COUNT_DOWN", 0);
instance.getPlayers().forEach(temp -> temp.sendPacket(new ExSendUIEvent(temp, 2, countDown, charged, 0, 2042, 0, NpcStringId.REPLENISH_BALLISTA_MAGIC_POWER.getId())));
}
getTimers().addTimer("BALLISTA_CHECK_TIMER", 500, npc, null);
}
break;
}
case "BALLISTA_END_TIMER":
{
if (getChargedPercent(npcVars.getInt("SCORE_VAL", 0), isExtremeMode(instance)) >= getRandom(100))
{
playMovie(instance, Movie.SC_ISTINA_ENDING_A);
instance.setStatus(3);
getTimers().addTimer("INSTANCE_FINISH_TIMER", 23000, npc, null);
}
else
{
playMovie(instance, Movie.SC_ISTINA_ENDING_B);
instance.setStatus(4);
getTimers().addTimer("INSTANCE_FINISH_TIMER", 22000, npc, null);
}
instance.getAliveNpcs(ISTINA).forEach(istina ->
{
istina.teleToLocation(instance.getEnterLocation());
istina.setInvisible(true);
});
break;
}
case "INSTANCE_FINISH_TIMER":
{
getTimers().addTimer("NPC_DELETE", 3000, evnt -> npc.deleteMe());
instance.finishInstance();
instance.getAliveNpcs(L2Attackable.class, ISTINA).forEach(istina ->
{
istina.teleToLocation(DEFEAT_ISTINA_LOC);
istina.setInvisible(false);
istina.setUndying(false);
istina.reduceCurrentHp(istina.getVariables().getInt("REWARD_DAMAGE", 1000000), istina.getVariables().getObject("REWARD_PLAYER", L2PcInstance.class), null);
});
break;
}
case "AUTHORITY_TIMER":
{
final int random = getRandom(1, 3);
final SkillHolder authoritySkill = npcParams.getSkillHolder("Istina_Authority_Skill0" + random);
if (authoritySkill != null)
{
addSkillCastDesire(npc, npc, authoritySkill, 23);
instance.broadcastPacket(new PlaySound(1, "Npcdialog1.istina_voice_01", 0, 0, 0, 0, 0));
switch (random)
{
case 1:
showOnScreenMsg(instance, NpcStringId.ISTINA_S_SOUL_STONE_STARTS_POWERFULLY_ILLUMINATING_IN_RED, ExShowScreenMessage.TOP_CENTER, 6000);
break;
case 2:
showOnScreenMsg(instance, NpcStringId.ISTINA_S_SOUL_STONE_STARTS_POWERFULLY_ILLUMINATING_IN_BLUE, ExShowScreenMessage.TOP_CENTER, 6000);
break;
case 3:
showOnScreenMsg(instance, NpcStringId.ISTINA_S_SOUL_STONE_STARTS_POWERFULLY_ILLUMINATING_IN_GREEN, ExShowScreenMessage.TOP_CENTER, 6000);
break;
}
}
getTimers().addTimer("AUTHORITY_TIMER", 70000 + getRandom(25000), npc, null);
break;
}
case "AUTHORITY_END_TIMER":
{
// gg->Area_SetOnOffEx(Istina_Authority_AreaData1, @OFF, myself->InstantZone_GetId());
// gg->Area_SetOnOffEx(Istina_Authority_AreaData2, @OFF, myself->InstantZone_GetId());
// gg->Area_SetOnOffEx(Istina_Authority_AreaData3, @OFF, myself->InstantZone_GetId());
break;
}
}
}
}
@Override
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
{
final Instance instance = npc.getInstanceWorld();
if ((skill != null) && isIstinaInstance(instance))
{
final int skillId = skill.getId();
if (npc.getId() == INVISIBLE_NPC)
{
if (skillId == ERUPTION_1.getSkillId())
{
npc.setTarget(npc);
npc.doCast(ERUPTION_2.getSkill());
}
else if (skillId == ERUPTION_2.getSkillId())
{
getTimers().addTimer("NPC_DELETE", 2000, event -> npc.deleteMe());
if (isExtremeMode(instance) && (getRandom(100) < 30))
{
addAttackPlayerDesire(addSpawn(EXTREME_MINION, npc, false, 0, false, instance.getId()), npc.getVariables().getObject("ERUPTION_TARGET", L2PcInstance.class), 23);
}
}
}
else
{
final StatsSet npcParams = npc.getParameters();
if (skillId == npcParams.getSkillHolder("Istina_Death_Skill01").getSkillId())
{
showOnScreenMsg(player, NpcStringId.ISTINA_S_MARK_SHINES_ABOVE_THE_HEAD, ExShowScreenMessage.TOP_CENTER, 4000);
getTimers().addTimer("DEATH_CHECK_TIMER", 10000, npc, null);
}
else if (skillId == npcParams.getSkillHolder("Istina_Refraction_Skill").getSkillId())
{
npc.setDisplayEffect(1);
getTimers().addTimer("REFLECT_CHECK_TIMER", 1000, npc, null);
}
else if (skillId == ISTINA_ERUPTION_SKILL.getSkillId())
{
((L2Attackable) npc).getAggroList().values().stream().sorted(Comparator.comparingInt(AggroInfo::getHate)).map(AggroInfo::getAttacker).limit(5).forEach(character ->
{
final L2Npc eruption = addSpawn(INVISIBLE_NPC, Util.getRandomPosition(character, 150, 150), false, 0, false, instance.getId());
eruption.getVariables().set("ERUPTION_TARGET", character);
});
}
else if (skillId == npcParams.getSkillHolder("Istina_Authority_Skill01").getSkillId())
{
// gg->Area_SetOnOffEx(Istina_Authority_AreaData2, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
// gg->Area_SetOnOffEx(Istina_Authority_AreaData3, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
getTimers().addTimer("AUTHORITY_END_TIMER", 15000, npc, null);
}
else if (skillId == npcParams.getSkillHolder("Istina_Authority_Skill02").getSkillId())
{
// gg->Area_SetOnOffEx(Istina_Authority_AreaData1, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
// gg->Area_SetOnOffEx(Istina_Authority_AreaData3, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
getTimers().addTimer("AUTHORITY_END_TIMER", 15000, npc, null);
}
else if (skillId == npcParams.getSkillHolder("Istina_Authority_Skill03").getSkillId())
{
// gg->Area_SetOnOffEx(Istina_Authority_AreaData1, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
// gg->Area_SetOnOffEx(Istina_Authority_AreaData2, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
getTimers().addTimer("AUTHORITY_END_TIMER", 15000, npc, null);
}
}
}
return super.onSpellFinished(npc, player, skill);
}
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
{
final Instance instance = npc.getInstanceWorld();
if (isIstinaInstance(instance))
{
final StatsSet npcVars = npc.getVariables();
final int stage = npcVars.getInt("ISTINA_STAGE", -1);
if (npc.getId() == BALLISTA)
{
if (npcVars.getBoolean("COUNTING_ENABLED", false))
{
final int score = npcVars.getInt("SCORE_VAL", 0);
if (getChargedPercent(score, isExtremeMode(instance)) < 100)
{
int addScore = damage;
if (skill != null)
{
if (skill.getEffectPoint() < 0)
{
addScore *= 1.5;
}
addScore *= 1.5;
}
if (attacker.isInCategory(CategoryType.FIGHTER_GROUP))
{
addScore *= 2;
}
npcVars.set("SCORE_VAL", score + addScore);
}
}
}
else
{
switch (stage)
{
case -1:
{
instance.setStatus(1);
npcVars.set("ISTINA_STAGE", 1);
instance.getDoors().forEach(L2DoorInstance::closeMe);
npc.setUndying(true);
((L2Attackable) npc).setCanReturnToSpawnPoint(false);
getTimers().addTimer("DEATH_TIMER", 3500, npc, null);
getTimers().addTimer("REFLECT_TIMER", 3500, npc, null);
getTimers().addTimer("LOW_ERUPTION_TIMER", 15000, npc, null);
break;
}
case 1:
{
if (npc.getCurrentHpPercent() < 85)
{
npcVars.set("ISTINA_STAGE", 2);
getTimers().addTimer("AUTHORITY_TIMER", 3000, npc, null);
}
break;
}
case 2:
{
if (npc.getCurrentHpPercent() < 70)
{
npcVars.set("ISTINA_STAGE", 3);
if (isExtremeMode(instance))
{
// myself->AddTimerEx(Seal_Timer, (3 * 1000));
}
// myself->AddTimerEx(Overcrowding_Timer, (10 * 1000));
}
break;
}
case 3:
{
if (npc.getCurrentHpPercent() < 55)
{
npcVars.set("ISTINA_STAGE", 4);
getTimers().addTimer("ERUPTION_TIMER", 50000, npc, null);
// myself->AddTimerEx(Creation_Timer, (Creation_Timer_Interval * 1000));
}
break;
}
case 4:
{
if (npc.getCurrentHpPercent() < 40)
{
npcVars.set("ISTINA_STAGE", 5);
if (isExtremeMode(instance))
{
// myself->AddTimerEx(Order_Timer, (Order_Timer_Interval * 100));
}
}
break;
}
case 5:
{
if (npc.getCurrentHpPercent() < 0.01)
{
setPlayerRewardInfo(npc);
npcVars.set("ISTINA_STAGE", 6);
getTimers().cancelTimer("DEATH_TIMER", npc, null);
getTimers().cancelTimer("DEATH_CHECK_TIMER", npc, null);
getTimers().cancelTimer("REFLECT_TIMER", npc, null);
getTimers().cancelTimer("REFLECT_CHECK_TIMER", npc, null);
getTimers().cancelTimer("AUTHORITY_TIMER", npc, null);
getTimers().cancelTimer("ERUPTION_TIMER", npc, null);
getTimers().cancelTimer("LOW_ERUPTION_TIMER", npc, null);
// myself->BlockTimer(Overcrowding_Timer);
if (isExtremeMode(instance))
{
// myself->BlockTimer(Seal_Timer);
// myself->BlockTimer(Order_Timer);
}
instance.getAliveNpcs(EXTREME_MINION, INVISIBLE_NPC).forEach(L2Npc::deleteMe);
instance.spawnGroup("BALLISTA");
instance.setStatus(2);
instance.getAliveNpcs(RUMIESE_INSTANCE).forEach(rumiese -> rumiese.teleToLocation(RUMIESE_LOC));
instance.getDoors().forEach(L2DoorInstance::openMe);
// myself->AddTimerEx(Broadcast_Timer, (2 * 1000));
onTimerEvent("AUTHORITY_END_TIMER", null, npc, null);
// myself->AddTimerEx(Location_Check_Timer, (4 * 1000));
npc.disableCoreAI(true);
npc.teleToLocation(DEFEAT_ISTINA_LOC);
npc.setDisplayEffect(3);
npc.setTargetable(false);
playMovie(instance, Movie.SC_ISTINA_BRIDGE);
instance.finishInstance(15);
}
break;
}
}
}
}
return super.onAttack(npc, attacker, damage, isSummon, skill);
}
@Override
public String onSpawn(L2Npc npc)
{
final Instance instance = npc.getInstanceWorld();
if (isIstinaInstance(instance))
{
if (npc.getId() == INVISIBLE_NPC)
{
npc.setTarget(npc);
npc.doCast(ERUPTION_1.getSkill());
}
else if (npc.getId() == BALLISTA)
{
npc.disableCoreAI(true);
npc.setUndying(true);
npc.setIsInvul(true);
npc.setTargetable(false);
getTimers().addTimer("BALLISTA_START_TIMER", 10000, npc, null);
}
}
return super.onSpawn(npc);
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
String htmltext = null;
final Instance instance = npc.getInstanceWorld();
if (isIstinaInstance(instance))
{
switch (instance.getStatus())
{
case 0:
htmltext = "33293-01.html";
break;
case 1:
htmltext = "33293-02.html";
break;
case 2:
htmltext = "33293-03.html";
break;
case 3:
htmltext = "33293-04.html";
break;
case 4:
htmltext = "33293-05.html";
break;
}
}
return htmltext;
}
private boolean isExtremeMode(Instance instance)
{
return instance.getTemplateId() == TEMPLATE_ID_EXTREME;
}
private boolean isIstinaInstance(Instance instance)
{
return (instance != null) && ((instance.getTemplateId() == TEMPLATE_ID_COMMON) || (instance.getTemplateId() == TEMPLATE_ID_EXTREME));
}
private int getChargedPercent(int score, boolean isExtreme)
{
final int charged;
if (score >= (isExtreme ? PERFECT_SCORE_2 : PERFECT_SCORE_1))
{
charged = 100;
}
else
{
charged = (score * 100) / (isExtreme ? PERFECT_SCORE_2 : PERFECT_SCORE_1);
}
return charged;
}
private L2PcInstance setPlayerRewardInfo(L2Npc npc)
{
final Map<L2PcInstance, DamageDoneInfo> rewards = new ConcurrentHashMap<>();
final StatsSet npcVars = npc.getVariables();
L2PcInstance maxDealer = null;
int maxDamage = 0;
int totalDamage = 0;
for (AggroInfo info : ((L2Attackable) npc).getAggroList().values())
{
if (info == null)
{
continue;
}
final L2PcInstance attacker = info.getAttacker().getActingPlayer();
if (attacker != null)
{
final int damage = info.getDamage();
if (damage > 1)
{
if (!Util.checkIfInRange(Config.ALT_PARTY_RANGE, npc, attacker, true))
{
continue;
}
final DamageDoneInfo reward = rewards.computeIfAbsent(attacker, DamageDoneInfo::new);
reward.addDamage(damage);
if (reward.getDamage() > maxDamage)
{
maxDealer = attacker;
maxDamage = reward.getDamage();
}
totalDamage += damage;
}
}
}
npcVars.set("REWARD_PLAYER", maxDealer);
npcVars.set("REWARD_DAMAGE", totalDamage);
return maxDealer;
}
public static void main(String[] args)
{
new IstinaCavern();
}
}