Sync with L2JServer Feb 3rd 2015.

This commit is contained in:
mobius 2015-02-03 21:11:57 +00:00
parent 9cf1a6d6e5
commit fe25f74122
169 changed files with 3379 additions and 5414 deletions

View File

@ -218,6 +218,10 @@ FeeDeleteTransferSkills = 10000000
# Default: 10000000
FeeDeleteSubClassSkills = 10000000
# Fee to remove Dual-Class skills.
# Default: 20000000
FeeDeleteDualClassSkills = 20000000
# Need Seize your destiny quest, to awaken
# Default: true
NeedSeizeYourDestinyForAwaken = false
@ -766,21 +770,6 @@ OffsetOnTeleportEnabled = True
# Default: 50
MaxOffsetOnTeleport = 50
# Restores the player to their previous instance (ie. an instanced area/dungeon) on EnterWorld.
# Default: False
RestorePlayerInstance = False
# Set whether summon skills can be used to summon players inside an instance.
# When enabled individual instances can have summoning disabled in instance xml's.
# DEFAULT NEEDS TO BE VERIFIED, MUST BE CHANGED HERE AND IN CONFIG.JAVA IF NOT CORRECT
# Default: ?
AllowSummonToInstance = True
# When a player dies, is removed from instance after a fixed period of time.
# Time in seconds.
# Default: 60
EjectDeadPlayerTime = 60
# This option is to enable or disable the use of in game petitions.
# The MaxPetitionsPerPlayer is the amount of petitions a player can make.
# The MaximumPendingPetitions is the total amount of petitions in the server.

View File

@ -462,6 +462,31 @@ WearDelay = 5
WearPrice = 10
# ---------------------------------------------------------------------------
# Instances
# ---------------------------------------------------------------------------
# Restores the player to their previous instance (ie. an instanced area/dungeon) on EnterWorld.
# Default: False
RestorePlayerInstance = False
# Set whether summon skills can be used to summon players inside an instance.
# When enabled individual instances can have summoning disabled in instance xml's.
# DEFAULT NEEDS TO BE VERIFIED, MUST BE CHANGED HERE AND IN CONFIG.JAVA IF NOT CORRECT
# Default: False
AllowSummonInInstance = False
# When a player dies, is removed from instance after a fixed period of time.
# Time in seconds.
# Default: 60
EjectDeadPlayerTime = 60
# When is instance finished, is set time to destruction currency instance.
# Time in seconds.
# Default: 300
DefaultFinishTime = 300
# ---------------------------------------------------------------------------
# Misc Settings
# ---------------------------------------------------------------------------
@ -881,6 +906,10 @@ AllowReportsFromSameClanMembers = False
# Default: False
Debug = False
# Instances debugging
# Default: False
InstanceDebug = False
# Html action cache debugging
# Default: False
HtmlActionCacheDebug = False

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../data/xsd/SecondaryAuth.xsd">
<enabled>false</enabled> <!-- Enable Secondary Authentication on Character Select -->
<enabled>true</enabled> <!-- Enable Secondary Authentication on Character Select -->
<maxAttempts>5</maxAttempts> <!-- Max Attempts for Second Auth Password (0 to disable) -->
<banTime>480</banTime> <!-- Ban time if user reach maxAttempts (in minutes) -->
<recoveryLink>http://www.google.com</recoveryLink> <!-- Password Recovery Link -->

View File

@ -1,53 +0,0 @@
# ---------------------------------------------------------------------------
# TerritoryWar Settings
# ---------------------------------------------------------------------------
# The defaults are set to be retail-like. If you modify any of these settings your server will deviate from being retail-like.
# Warning:
# Please take extreme caution when changing anything. Also please understand what you are changing before you do so on a live server.
# ---------------------------------------------------------------------------
# Standard Settings
# ---------------------------------------------------------------------------
# Length of siege before the count down (in minutes).
# Default: 120
WarLength = 120
# Clan Minimum level to register.
# Default: 0
ClanMinLevel = 0
# Player Minimum level to register.
# Default: 40
PlayerMinLevel = 40
# Max number of clans and players that can register for a side.
# Default: 500
DefenderMaxClans = 500
# Default: 500
DefenderMaxPlayers = 500
# Is Ward holding players can be attacked and killed in peace zone
# Default: False
PlayerWithWardCanBeKilledInPeaceZone = False
# Spawn wards in Castles when Territory War is not in progress
# Default: False
SpawnWardsWhenTWIsNotInProgress = False
# Return all wards to their own castle when Territory War starts
# Default: False
ReturnWardsWhenTWStarts = False
# Territory Badge needed to change nobless
# default: 100
MinTerritoryBadgeForNobless = 100
# Territory Badge needed to buy Strider
# default: 50
MinTerritoryBadgeForStriders = 50
# Territory Badge needed to buy Guardian's Strider
# default: 80
MinTerritoryBadgeForBigStrider = 80

View File

@ -1,4 +1,4 @@
<html><body>Pathfinder Agent:<br>
<html><body>Pathfinder Worker:<br>
Nighttime Zaken was able to rid himself of all weakness. He is basically immortal, except that he can still be attacked through his daytime counterpart...<br>
Since it is a part of Pailaka, the mirror dimension world of dreams, it is possible to mount an attack there. If you go as part of a major force...say, the <font color="LEVEL">union of at least 8 parties</font>, it may be possible to confront him even in this incarnation.<br>
Do you wish to try?<br>

View File

@ -1,8 +1,8 @@
<html><body>Pathfinder Agent:<br>
<html><body>Pathfinder Worker:<br>
Daytime Zaken is another aspect of Zaken.<br>
Unlike his nighttime counterpart, he hides himself because he knows he is weak...<br>
But there is a way to find him. Light a <font color="LEVEL">candle on a barrel</font> and it will show you the way.<br>
But be careful! The candlelight may also alert his subordinates to your location.<br>
Compared to Nighttime Zaken, Daytime Zaken is not that strong -- you should be able to attack him with a combined force of <font color="LEVEL">1 to 3 parties</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest CavernOfThePirateCaptain enter60">Challenge Daytime Zaken.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest CavernOfThePirateCaptain enter60">Challenge Daytime Zaken. </Button>
</body></html>

View File

@ -1,6 +1,6 @@
<html><body>Pathfinder Worker:<br>
We have found out that Zaken has a way to manifest his Daytime presence to be even stronger than before.<br>
Our reports indicate that you can face him just like the regular Daytime Zaken, but it won't be easy.<br>
(Only level 78-85 can enter.)<br>
(Only levels 78 - 99 can enter.)<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest CavernOfThePirateCaptain enter83">Challenge Daytime Zaken (Difficult).</Button>
</body></html>
</body></html>

View File

@ -1,8 +1,8 @@
<html><body>Pathfinder Agent:<br>
<html><body>Pathfinder Worker:<br>
Pirate King Zaken once lived here. But it's been said that he may have allied himself with the invaders from the Dream World, which is why adventurers seeking to challenge him now cannot find him.<br>
We believe that he has now created a giant Dream Dimension by drawing on the power of night.<br>
Because of that, Zaken was separated into two individuals, one corporeal during the day and the other at night. He is more powerful now than ever, and he has been attacking the real world from the Dream Dimension.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Chat 1">Ask how to fight Nighttime Zaken.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Chat 2">Ask how to fight Daytime Zaken.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Chat 3">Ask how to fight Daytime Zaken (Difficult).</Button>
Because of that, Zaken was separated into two individuals, a corporeal one during the day and the other one during the night. He is more powerful now than ever, and he has been attacking the real world from the Dream Dimension.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Chat 1">Ask how to fight Nighttime Zaken</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Chat 2">Ask how to fight Daytime Zaken</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Chat 3">Ask how to fight Daytime Zaken (Difficult)</Button>
</body></html>

View File

@ -1,5 +1,5 @@
<html><body>Somulita:<br>
The power of strong and spiteful soul can felt on Devil's Isle. Something is trying to break into this world to wreak havoc on it.<br>
Adventurer, do you wish to prove your bravery in such a dangerous place?<br>
<Button ALIGN=LEFT ICON="TELEPORT" action="bypass -h npc_%objectId%_goto 200921">Teleport to the entry of the Pirate's Palace.</Button>
<html><body>Somulitan:<br>
The power of a malevolent and spiteful soul can be felt on Devil's Isle. Something or someone is trying to break through the boundaries of our world. And should that happen, havoc and devastation are sure to follow.<br>
Adventurer, do you really wish to face such a unknown and dangerous adversary?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_goto 200921"> Teleport to the entrance of Zaken's ship. </Button>
</body></html>

View File

@ -4,4 +4,9 @@
<allowSummon val="false"/>
<showTimer val="true" increase="true" text="Elapsed Time :" />
<spawnPoint spawnX="52212" spawnY="218998" spawnZ="-3208" />
<reenter additionStyle="ON_INSTANCE_FINISH" >
<reset day="Monday" hour="6" minute="30" />
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Friday" hour="6" minute="30" />
</reenter>
</instance>

View File

@ -4,4 +4,9 @@
<allowSummon val="false"/>
<showTimer val="true" increase="true" text="Elapsed Time :" />
<spawnPoint spawnX="52212" spawnY="218998" spawnZ="-3208" />
</instance>
<reenter additionStyle="ON_INSTANCE_FINISH" >
<reset day="Monday" hour="6" minute="30" />
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Friday" hour="6" minute="30" />
</reenter>
</instance>

View File

@ -4,4 +4,9 @@
<allowSummon val="false"/>
<showTimer val="true" increase="true" text="Elapsed Time :" />
<spawnPoint spawnX="52212" spawnY="218998" spawnZ="-3208" />
<reenter additionStyle="ON_INSTANCE_FINISH" >
<reset day="Monday" hour="6" minute="30" />
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Friday" hour="6" minute="30" />
</reenter>
</instance>

View File

@ -4,6 +4,9 @@
<allowSummon val="false" />
<emptyDestroyTime val="1200" />
<spawnPoint spawnX="149442" spawnY="173520" spawnZ="-5024" />
<reenter additionStyle="ON_INSTANCE_ENTER" >
<reset time="86400000" />
</reenter>
<doorlist>
<door doorId="24220001" />
<door doorId="24220002" />

View File

@ -4,6 +4,10 @@
<allowSummon val="false" />
<emptyDestroyTime val="600" />
<spawnPoint spawnX="-22213" spawnY="277138" spawnZ="-9930" />
<reenter additionStyle="ON_INSTANCE_FINISH" >
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Saturday" hour="6" minute="30" />
</reenter>
<spawnlist>
<group name="general">
<spawn npcId="25540" x="-22199" y="278407" z="-8264" heading="0" respawn="0" />

View File

@ -4,6 +4,7 @@
<allowSummon val="false" />
<emptyDestroyTime val="900" />
<spawnPoint spawnX="171895" spawnY="-17501" spawnZ="-4903" />
<removeBuffs type="ALL" />
<doorlist>
<door doorId="17240101" />
<door doorId="17240102" />

View File

@ -4,6 +4,10 @@
<allowSummon val="false" />
<emptyDestroyTime val="1800" />
<spawnPoint spawnX="181381" spawnY="-80883" spawnZ="-2730" />
<reenter additionStyle="NONE" >
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Saturday" hour="6" minute="30" />
</reenter>
<doorlist>
<door doorId="17130045" />
<door doorId="17130051" />

View File

@ -4,6 +4,7 @@
<allowSummon val="false" />
<emptyDestroyTime val="30" />
<spawnPoint spawnX="147072" spawnY="23743" spawnZ="-1984" />
<removeBuffs type="ALL" />
<spawnlist>
<group name="general">
<!-- Franz -->

View File

@ -4,6 +4,10 @@
<allowSummon val="false" />
<emptyDestroyTime val="600" />
<spawnPoint spawnX="115717" spawnY="-125734" spawnZ="-3392" />
<reenter additionStyle="ON_INSTANCE_FINISH" >
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Saturday" hour="6" minute="30" />
</reenter>
<doorlist>
<door doorId="23140101" />
</doorlist>

View File

@ -4,6 +4,10 @@
<allowSummon val="false" />
<emptyDestroyTime val="600" />
<spawnPoint spawnX="115717" spawnY="-125734" spawnZ="-3392" />
<reenter additionStyle="ON_INSTANCE_FINISH" >
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Saturday" hour="6" minute="30" />
</reenter>
<doorlist>
<door doorId="23140101" />
</doorlist>

View File

@ -4,29 +4,7 @@
<allowSummon val="false" />
<emptyDestroyTime val="1" />
<spawnPoint spawnX="115983" spawnY="-87351" spawnZ="-3397" />
<doorlist>
<door doorId="21100001" /><!-- opened="true"-->
<door doorId="21100002" /><!-- opened="true"-->
<door doorId="21100003" /><!-- opened="true"-->
<door doorId="21100004" /><!-- opened="true"-->
<door doorId="21100005" /><!-- opened="true"-->
<door doorId="21100006" /><!-- opened="true"-->
<door doorId="21100007" /><!-- opened="true"-->
<door doorId="21100008" /><!-- opened="true"-->
<door doorId="21100009" /><!-- opened="true"-->
<door doorId="21100010" /><!-- opened="true"-->
<door doorId="21100011" /><!-- opened="true"-->
<door doorId="21100012" /><!-- opened="true"-->
<door doorId="21100013" /><!-- opened="true"-->
<door doorId="21100014" /><!-- opened="true"-->
<door doorId="21100015" /><!-- opened="true"-->
<door doorId="21100016" /><!-- opened="true"-->
<door doorId="21100018" /><!-- opened="false"-->
<door doorId="21100101" /><!-- opened="false"-->
<door doorId="21100102" /><!-- opened="false"-->
<door doorId="21100103" /><!-- opened="false"-->
<door doorId="21100104" /><!-- opened="false"-->
</doorlist>
<removeBuffs type="ALL" />
<spawnlist>
<group name="general">
<!-- Eris's Evil Thoughts -->
@ -60,91 +38,6 @@
<spawn npcId="32834" x="86888" y="-246734" z="-8320" heading="0" respawn="0" />
<spawn npcId="32835" x="85793" y="-245640" z="-8320" heading="0" respawn="0" />
<spawn npcId="32836" x="84705" y="-246730" z="-8320" heading="0" respawn="0" />
<!-- Spawn: Seven Signs, Solina's Tomb -->
<spawn npcId="18949" x="76625" y="-240824" z="-10832" heading="0" respawn="0"/>
<spawn npcId="18956" x="55498" y="-252781" z="-6760" heading="0" respawn="0"/>
<spawn npcId="18957" x="55520" y="-252160" z="-6760" heading="0" respawn="0"/>
<spawn npcId="18958" x="56635" y="-252776" z="-6760" heading="0" respawn="0"/>
<spawn npcId="18959" x="56672" y="-252156" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="44269" y="-251082" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="43811" y="-248086" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="44314" y="-250726" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="44246" y="-248658" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="44197" y="-251121" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="44371" y="-248136" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="44314" y="-250726" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27407" x="44210" y="-248554" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27409" x="46844" y="-248629" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27409" x="46933" y="-248040" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27410" x="46412" y="-248590" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27410" x="46376" y="-248447" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27410" x="46952" y="-248499" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27410" x="47053" y="-248080" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27410" x="46933" y="-248180" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27410" x="46613" y="-248050" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="43590" y="-249404" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45280" y="-251316" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45285" y="-247479" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="43584" y="-249935" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45469" y="-247502" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45584" y="-251289" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="47438" y="-249349" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="43356" y="-249461" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45218" y="-251733" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="47142" y="-249793" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45183" y="-247956" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="43254" y="-249948" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45548" y="-251690" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="47582" y="-249770" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27412" x="45533" y="-247983" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="47224" y="-249486" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="43710" y="-249384" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45220" y="-251386" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45255" y="-247569" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45554" y="-251309" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="47458" y="-249439" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45519" y="-247442" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="43326" y="-249451" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45258" y="-251763" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="47222" y="-249823" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45203" y="-247896" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45568" y="-251690" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="47522" y="-249920" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="45563" y="-247923" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="43724" y="-249935" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27413" x="43214" y="-249908" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27414" x="44125" y="-251134" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27414" x="43945" y="-251134" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27414" x="44331" y="-248096" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27414" x="44211" y="-248106" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27414" x="43994" y="-250706" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27414" x="44154" y="-250736" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27414" x="44210" y="-250736" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27417" x="47005" y="-250679" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27417" x="46365" y="-250819" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27417" x="46872" y="-251280" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27417" x="46368" y="-251176" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27418" x="46405" y="-250739" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27418" x="46725" y="-250809" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27418" x="46728" y="-251267" z="-6760" heading="0" respawn="0"/>
<spawn npcId="27418" x="46512" y="-251072" z="-6760" heading="0" respawn="0"/>
<spawn npcId="32793" x="56097" y="-250576" z="-6757" heading="0" respawn="0"/>
<spawn npcId="32794" x="56430" y="-239226" z="-7224" heading="0" respawn="0"/>
<spawn npcId="32795" x="56379" y="-239233" z="-7224" heading="0" respawn="0"/>
<spawn npcId="32796" x="56495" y="-239445" z="-7224" heading="0" respawn="0"/>
<spawn npcId="32797" x="56347" y="-239448" z="-7224" heading="0" respawn="0"/>
<spawn npcId="32820" x="85792" y="-248739" z="-8296" heading="0" respawn="0"/>
<spawn npcId="32837" x="45398" y="-249639" z="-6728" heading="0" respawn="0"/>
<spawn npcId="32838" x="45413" y="-251556" z="-6744" heading="0" respawn="0"/>
<spawn npcId="32839" x="47333" y="-249648" z="-6744" heading="0" respawn="0"/>
<spawn npcId="32840" x="45392" y="-247720" z="-6744" heading="0" respawn="0"/>
<spawn npcId="32841" x="43472" y="-249632" z="-6744" heading="0" respawn="0"/>
<spawn npcId="32842" x="56080" y="-251648" z="-6760" heading="0" respawn="0"/>
<spawn npcId="32843" x="56116" y="-252480" z="-6736" heading="0" respawn="0"/>
<spawn npcId="32857" x="44123" y="-248367" z="-6720" heading="0" respawn="0"/>
<spawn npcId="32858" x="46672" y="-248368" z="-6720" heading="0" respawn="0"/>
<spawn npcId="32859" x="44114" y="-250912" z="-6720" heading="0" respawn="0"/>
<spawn npcId="32860" x="46672" y="-250915" z="-6720" heading="0" respawn="0"/>
</group>
</spawnlist>
</instance>

View File

@ -4,6 +4,7 @@
<allowSummon val="false" />
<emptyDestroyTime val="3000" />
<spawnPoint spawnX="-84757" spawnY="60009" spawnZ="-2581" />
<removeBuffs type="ALL" />
<doorlist>
<door doorId="16200001" />
<door doorId="16200002" />

View File

@ -4,6 +4,10 @@
<allowSummon val="false" />
<emptyDestroyTime val="600" />
<spawnPoint spawnX="-19006" spawnY="277065" spawnZ="-13383" />
<reenter additionStyle="ON_INSTANCE_FINISH" >
<reset day="Wednesday" hour="6" minute="30" />
<reset day="Saturday" hour="6" minute="30" />
</reenter>
<spawnlist>
<group name="general">
<spawn npcId="25542" x="-19056" y="278732" z="-15000" heading="0" respawn="0" />

View File

@ -60,7 +60,6 @@ ai/npc/Raina/Raina.java
ai/npc/RemembranceTower/RemembranceTower.java
ai/npc/Scarecrow/Scarecrow.java
ai/npc/Sirra/Sirra.java
ai/npc/SubclassCertification/SubclassCertification.java
ai/npc/Summons/MerchantGolem/GolemTrader.java
ai/npc/SupportUnitCaptain/SupportUnitCaptain.java
ai/npc/SymbolMaker/SymbolMaker.java
@ -85,6 +84,7 @@ ai/npc/Teleports/TeleportWithCharm/TeleportWithCharm.java
ai/npc/Teleports/ToIVortex/ToIVortex.java
ai/npc/TownPets/TownPets.java
ai/npc/Trainers/HealerTrainer/HealerTrainer.java
ai/npc/Trandon/Trandon.java
ai/npc/Tunatun/Tunatun.java
ai/npc/VarkaSilenosSupport/VarkaSilenosSupport.java
ai/npc/VillageMasters/FirstClassTransferTalk/FirstClassTransferTalk.java
@ -173,39 +173,8 @@ village_master/Alliance/Alliance.java
village_master/ProofOfCourage/ProofOfCourage.java
village_master/ProofOfJustice/ProofOfJustice.java
# Instance Dungeons Section
instances/CavernOfThePirateCaptain/CavernOfThePirateCaptain.java
instances/ChambersOfDelusion/ChamberOfDelusionEast.java
instances/ChambersOfDelusion/ChamberOfDelusionNorth.java
instances/ChambersOfDelusion/ChamberOfDelusionSouth.java
instances/ChambersOfDelusion/ChamberOfDelusionWest.java
instances/ChambersOfDelusion/ChamberOfDelusionSquare.java
instances/ChambersOfDelusion/ChamberOfDelusionTower.java
instances/CrystalCaverns/CrystalCaverns.java
instances/DarkCloudMansion/DarkCloudMansion.java
instances/DisciplesNecropolisPast/DisciplesNecropolisPast.java
instances/ElcadiasTent/ElcadiasTent.java
instances/FaeronTrainingGrounds1/FaeronTrainingGrounds1.java
instances/FaeronTrainingGrounds2/FaeronTrainingGrounds2.java
instances/FinalEmperialTomb/FinalEmperialTomb.java
instances/HarnakUndergroundRuins/HarnakUndergroundRuins.java
instances/HideoutOfTheDawn/HideoutOfTheDawn.java
instances/IceQueensCastle/IceQueensCastle.java
instances/IceQueensCastleHardBattle/IceQueensCastleHardBattle.java
instances/IceQueensCastleNormalBattle/IceQueensCastleNormalBattle.java
instances/JiniaGuildHideout1/JiniaGuildHideout1.java
instances/JiniaGuildHideout2/JiniaGuildHideout2.java
instances/JiniaGuildHideout3/JiniaGuildHideout3.java
instances/JiniaGuildHideout4/JiniaGuildHideout4.java
instances/LibraryOfSages/LibraryOfSages.java
instances/Kamaloka/Kamaloka.java
instances/MithrilMine/MithrilMine.java
instances/MonasteryOfSilence1/MonasteryOfSilence1.java
instances/MonasteryOfSilence2/MonasteryOfSilence2.java
instances/NornilsGarden/NornilsGarden.java
instances/PailakaDevilsLegacy/PailakaDevilsLegacy.java
instances/PailakaSongOfIceAndFire/PailakaSongOfIceAndFire.java
instances/SanctumOftheLordsOfDawn/SanctumOftheLordsOfDawn.java
# Instance Section
instances/InstanceLoader.java
# Gracia Section
gracia/GraciaLoader.java
@ -224,7 +193,6 @@ custom/ShadowWeapons/ShadowWeapons.java
custom/NewbieCoupons/NewbieCoupons.java
custom/RaidbossInfo/RaidbossInfo.java
custom/NpcLocationInfo/NpcLocationInfo.java
custom/Validators/SubClassSkills.java
custom/FactionManager/FactionManager.java
# Custom Events

View File

@ -125,16 +125,16 @@ public final class SelMahumSquad extends AbstractNpcAI
case "fire":
{
startQuestTimer("fire", 30000 + getRandom(5000), npc, null);
npc.setDisplayEffect(FIRE_EFFECT_NONE);
npc.setState(FIRE_EFFECT_NONE);
if (getRandom(GameTimeController.getInstance().isNight() ? 2 : 4) < 1)
{
npc.setDisplayEffect(FIRE_EFFECT_BURN); // fire burns
npc.setState(FIRE_EFFECT_BURN); // fire burns
npc.broadcastEvent("SCE_CAMPFIRE_START", 600, null);
}
else
{
npc.setDisplayEffect(FIRE_EFFECT_NONE); // fire goes out
npc.setState(FIRE_EFFECT_NONE); // fire goes out
npc.broadcastEvent("SCE_CAMPFIRE_END", 600, null);
}
break;
@ -148,12 +148,12 @@ public final class SelMahumSquad extends AbstractNpcAI
if (npc.isNoRndWalk())
{
npc.doCast(SkillData.getInstance().getSkill(6331, 1));
npc.setDisplayEffect(MAHUM_EFFECT_SLEEP);
npc.setState(MAHUM_EFFECT_SLEEP);
}
if (npc.getVariables().getInt("BUSY_STATE") == 1) // Eating
{
npc.doCast(SkillData.getInstance().getSkill(6332, 1));
npc.setDisplayEffect(MAHUM_EFFECT_EAT);
npc.setState(MAHUM_EFFECT_EAT);
}
startQuestTimer("remove_effects", 300000, npc, null);
@ -168,7 +168,7 @@ public final class SelMahumSquad extends AbstractNpcAI
{
// myself.i_quest0 = 0;
npc.setIsRunning(true);
npc.setDisplayEffect(MAHUM_EFFECT_NONE);
npc.setState(MAHUM_EFFECT_NONE);
break;
}
case "reset_full_bottle_prize":
@ -226,7 +226,7 @@ public final class SelMahumSquad extends AbstractNpcAI
{
if (receiver.getId() == FIRE)
{
receiver.setDisplayEffect(FIRE_EFFECT_BURN);
receiver.setState(FIRE_EFFECT_BURN);
final L2Npc stove = addSpawn(STOVE, receiver.getX(), receiver.getY(), receiver.getZ() + 100, 0, false, 0);
stove.setSummoner(receiver);
startQuestTimer("notify_dinner", 2000, receiver, null); // @SCE_DINNER_EAT
@ -353,7 +353,7 @@ public final class SelMahumSquad extends AbstractNpcAI
}
else if (Util.contains(SQUAD_LEADERS, npc.getId()))
{
npc.setDisplayEffect(3);
npc.setState(3);
npc.setIsNoRndWalk(false);
}
return super.onSpawn(npc);
@ -390,7 +390,7 @@ public final class SelMahumSquad extends AbstractNpcAI
cancelQuestTimer("remove_effects", attacked, null);
attacked.getVariables().remove("BUSY_STATE");
attacked.setIsNoRndWalk(false);
attacked.setDisplayEffect(MAHUM_EFFECT_NONE);
attacked.setState(MAHUM_EFFECT_NONE);
if (attacked.getRightHandItem() == OHS_Weapon)
{
attacked.setRHandId(THS_Weapon);

View File

@ -60,7 +60,7 @@ public final class Anais extends AbstractNpcAI
private void burnerOnAttack(int pot, L2Npc anais)
{
L2Npc npc = _divineBurners.get(pot);
npc.setDisplayEffect(1);
npc.setState(1);
npc.setIsRunning(false);
if (pot < 4)
{
@ -99,7 +99,7 @@ public final class Anais extends AbstractNpcAI
}
final L2Npc b = _divineBurners.get(_pot);
_pot = _pot + 1;
b.setDisplayEffect(1);
b.setState(1);
b.setIsRunning(false);
L2Npc ward = addSpawn(GRAIL_WARD, new Location(b.getX(), b.getY(), b.getZ()), true, 0);
((L2Attackable) ward).addDamageHate(_nextTarget, 0, 999);
@ -134,7 +134,7 @@ public final class Anais extends AbstractNpcAI
cancelQuestTimer("GUARD_ATTACK", npc, _nextTarget);
if (_current != null)
{
_current.setDisplayEffect(2);
_current.setState(2);
_current.setIsRunning(false);
_current = null;
}
@ -186,7 +186,7 @@ public final class Anais extends AbstractNpcAI
cancelQuestTimer("CHECK", npc, null);
if (_current != null)
{
_current.setDisplayEffect(2);
_current.setState(2);
_current.setIsRunning(false);
_current = null;
}

View File

@ -2,9 +2,8 @@
I am Avant-Garde, the Transformation Wizard. I have long wandered through the land and only recently settled here.<br>
In fact, my young friend, I am not a wizard of the Ivory Tower. You look surprised! Heh. Think of me as a wanderer who acquired a special power quite by chance... My magic, however, requires some very specialized items.<br>
If you have acquired these unique items from the dark wizard in Hardin's Academy, then perhaps I can help you.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest AvantGarde 32323-02.html">Ask about transformation.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest AvantGarde LearnTransformationSkill">Learn transformation.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest AvantGarde BuyTransformationItems">Purchase items related to transformation.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest AvantGarde 32323-05a.html">Learn about subclass certification.</Button>
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest.</Button>
<a action="bypass -h Quest AvantGarde 32323-02.html">Ask about transformation.</a><br>
<a action="bypass -h Quest AvantGarde LearnTransformationSkill">Learn transformation.</a><br>
<a action="bypass -h Quest AvantGarde BuyTransformationItems">Purchase items related to transformation.</a><br>
<a action="bypass -h npc_%objectId%_Quest">Quest.</a>
</body></html>

View File

@ -22,25 +22,17 @@ import java.util.List;
import ai.npc.AbstractNpcAI;
import com.l2jserver.Config;
import com.l2jserver.gameserver.data.xml.impl.MultisellData;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.instancemanager.QuestManager;
import com.l2jserver.gameserver.model.L2SkillLearn;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.base.AcquireSkillType;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.clientpackets.RequestAcquireSkill;
import com.l2jserver.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.util.Util;
import custom.Validators.SubClassSkills;
/**
* Avant-Garde AI.<br>
@ -52,21 +44,6 @@ public final class AvantGarde extends AbstractNpcAI
{
// NPC
private static final int AVANT_GARDE = 32323;
// Items
// @formatter:off
private static final int[] ITEMS =
{
10280, 10281, 10282, 10283, 10284, 10285, 10286, 10287, 10288, 10289, 10290, 10291, 10292, 10293, 10294, 10612
};
// @formatter:on
// Misc
private static final String[] QUEST_VAR_NAMES =
{
"EmergentAbility65-",
"EmergentAbility70-",
"ClassAbility75-",
"ClassAbility80-"
};
public AvantGarde()
{
@ -80,18 +57,9 @@ public final class AvantGarde extends AbstractNpcAI
@Override
public String onAcquireSkill(L2Npc npc, L2PcInstance player, Skill skill, AcquireSkillType type)
{
switch (type)
if (type.equals(AcquireSkillType.TRANSFORM))
{
case TRANSFORM:
{
showTransformSkillList(player);
break;
}
case SUBCLASS:
{
showSubClassSkillList(player);
break;
}
showTransformSkillList(player);
}
return null;
}
@ -107,7 +75,6 @@ public final class AvantGarde extends AbstractNpcAI
case "32323-02b.html":
case "32323-02c.html":
case "32323-05.html":
case "32323-05a.html":
case "32323-05no.html":
case "32323-06.html":
case "32323-06no.html":
@ -139,153 +106,6 @@ public final class AvantGarde extends AbstractNpcAI
}
break;
}
case "LearnSubClassSkill":
{
if (!RequestAcquireSkill.canTransform(player))
{
htmltext = "32323-04.html";
}
if (player.isSubClassActive())
{
htmltext = "32323-08.html";
}
else
{
boolean hasItems = false;
for (int id : ITEMS)
{
if (player.getInventory().getItemByItemId(id) != null)
{
hasItems = true;
break;
}
}
if (hasItems)
{
showSubClassSkillList(player);
}
else
{
htmltext = "32323-08.html";
}
}
break;
}
case "CancelCertification":
{
if (player.getSubClasses().size() == 0)
{
htmltext = "32323-07.html";
}
else if (player.isSubClassActive())
{
htmltext = "32323-08.html";
}
else if (player.getAdena() < Config.FEE_DELETE_SUBCLASS_SKILLS)
{
htmltext = "32323-08no.html";
}
else
{
QuestState st = player.getQuestState(SubClassSkills.class.getSimpleName());
if (st == null)
{
st = QuestManager.getInstance().getQuest(SubClassSkills.class.getSimpleName()).newQuestState(player);
}
int activeCertifications = 0;
for (String varName : QUEST_VAR_NAMES)
{
for (int i = 1; i <= Config.MAX_SUBCLASS; i++)
{
String qvar = st.getGlobalQuestVar(varName + i);
if (!qvar.isEmpty() && (qvar.endsWith(";") || !qvar.equals("0")))
{
activeCertifications++;
}
}
}
if (activeCertifications == 0)
{
htmltext = "32323-10no.html";
}
else
{
for (String varName : QUEST_VAR_NAMES)
{
for (int i = 1; i <= Config.MAX_SUBCLASS; i++)
{
final String qvarName = varName + i;
final String qvar = st.getGlobalQuestVar(qvarName);
if (qvar.endsWith(";"))
{
final String skillIdVar = qvar.replace(";", "");
if (Util.isDigit(skillIdVar))
{
int skillId = Integer.parseInt(skillIdVar);
final Skill sk = SkillData.getInstance().getSkill(skillId, 1);
if (sk != null)
{
player.removeSkill(sk);
st.saveGlobalQuestVar(qvarName, "0");
}
}
else
{
_log.warning("Invalid Sub-Class Skill Id: " + skillIdVar + " for player " + player.getName() + "!");
}
}
else if (!qvar.isEmpty() && !qvar.equals("0"))
{
if (Util.isDigit(qvar))
{
final int itemObjId = Integer.parseInt(qvar);
L2ItemInstance itemInstance = player.getInventory().getItemByObjectId(itemObjId);
if (itemInstance != null)
{
player.destroyItem("CancelCertification", itemObjId, 1, player, false);
}
else
{
itemInstance = player.getWarehouse().getItemByObjectId(itemObjId);
if (itemInstance != null)
{
_log.warning("Somehow " + player.getName() + " put a certification book into warehouse!");
player.getWarehouse().destroyItem("CancelCertification", itemInstance, 1, player, false);
}
else
{
_log.warning("Somehow " + player.getName() + " deleted a certification book!");
}
}
st.saveGlobalQuestVar(qvarName, "0");
}
else
{
_log.warning("Invalid item object Id: " + qvar + " for player " + player.getName() + "!");
}
}
}
}
player.reduceAdena("Cleanse", Config.FEE_DELETE_SUBCLASS_SKILLS, npc, true);
htmltext = "32323-09no.html";
player.sendSkillList();
}
// Let's consume all certification books, even those not present in database.
for (int itemId : ITEMS)
{
L2ItemInstance item = player.getInventory().getItemByItemId(itemId);
if (item != null)
{
_log.warning(getClass().getName() + ": player " + player + " had 'extra' certification skill books while cancelling sub-class certifications!");
player.destroyItem("CancelCertificationExtraBooks", item, npc, false);
}
}
}
break;
}
}
return htmltext;
}
@ -302,24 +122,6 @@ public final class AvantGarde extends AbstractNpcAI
return "32323-01.html";
}
/**
* Display the Sub-Class Skill list to the player.
* @param player the player
*/
public static void showSubClassSkillList(L2PcInstance player)
{
final List<L2SkillLearn> subClassSkills = SkillTreesData.getInstance().getAvailableSubClassSkills(player);
if (subClassSkills.isEmpty())
{
player.sendPacket(SystemMessageId.THERE_ARE_NO_OTHER_SKILLS_TO_LEARN);
}
else
{
player.sendPacket(new ExAcquirableSkillListByClass(subClassSkills, AcquireSkillType.TRANSFORM));
}
}
/**
* This displays Transformation Skill List to the player.
* @param player the active character.

View File

@ -21,7 +21,6 @@ package ai.npc.AwakeningMaster;
import quests.Q10338_SeizeYourDestiny.Q10338_SeizeYourDestiny;
import ai.npc.AbstractNpcAI;
import com.l2jserver.Config;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.data.xml.impl.SkillTreesData;
import com.l2jserver.gameserver.enums.CategoryType;
@ -86,14 +85,13 @@ public final class AwakeningMaster extends AbstractNpcAI
{
return null;
}
String htmltext = null;
switch (event)
{
case "awakening":
{
final QuestState st2 = player.getQuestState(Q10338_SeizeYourDestiny.class.getSimpleName());
if ((!Config.NEED_SCROLL_OF_AFTERLIFE_FOR_AWAKEN || st.hasQuestItems(SCROLL_OF_AFTERLIFE)) && (player.getLevel() > 84) && (!player.isSubClassActive() || player.isDualClassActive()) && player.isInCategory(CategoryType.FOURTH_CLASS_GROUP) && (!Config.NEED_SEIZE_YOUR_DESTINY_FOR_AWAKEN || ((st2 != null) && st2.isCompleted())))
if (st.hasQuestItems(SCROLL_OF_AFTERLIFE) && (player.getLevel() > 84) && (!player.isSubClassActive() || player.isDualClassActive()) && player.isInCategory(CategoryType.FOURTH_CLASS_GROUP) && (st2 != null) && st2.isCompleted())
{
switch (npc.getId())
{
@ -194,14 +192,11 @@ public final class AwakeningMaster extends AbstractNpcAI
return;
}
if (Config.NEED_SEIZE_YOUR_DESTINY_FOR_AWAKEN)
final QuestState st = player.getQuestState(Q10338_SeizeYourDestiny.class.getSimpleName());
if ((st == null) || !st.isCompleted())
{
final QuestState st = player.getQuestState(Q10338_SeizeYourDestiny.class.getSimpleName());
if ((st == null) || !st.isCompleted())
{
return;
}
return;
}
if (player.isHero() || Hero.getInstance().isUnclaimedHero(player.getObjectId()))
@ -222,23 +217,28 @@ public final class AwakeningMaster extends AbstractNpcAI
return;
}
if (Config.NEED_SCROLL_OF_AFTERLIFE_FOR_AWAKEN)
final L2ItemInstance item = player.getInventory().getItemByItemId(SCROLL_OF_AFTERLIFE);
if (item == null)
{
final L2ItemInstance item = player.getInventory().getItemByItemId(SCROLL_OF_AFTERLIFE);
if (item == null)
{
return;
}
if (!player.destroyItem("Awakening", item, player, true))
{
return;
}
return;
}
if (!player.destroyItem("Awakening", item, player, true))
{
return;
}
for (ClassId newClass : player.getClassId().getNextClassIds())
{
player.setClassId(newClass.getId());
if (player.isDualClassActive())
{
player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
}
else
{
player.setBaseClass(player.getActiveClass());
}
player.sendPacket(SystemMessageId.CONGRATULATIONS_YOU_VE_COMPLETED_A_CLASS_TRANSFER);
final UserInfo ui = new UserInfo(player, false);
ui.addComponentType(UserInfoType.BASIC_INFO);

View File

@ -112,14 +112,14 @@ public final class Minigame extends AbstractNpcAI
{
if (npc.getId() == BURNER)
{
npc.setDisplayEffect(2);
npc.setState(2);
npc.setIsRunning(false);
}
else
{
for (L2Npc burner : room.getBurners())
{
burner.setDisplayEffect(2);
burner.setState(2);
burner.setIsRunning(false);
}
}
@ -147,7 +147,7 @@ public final class Minigame extends AbstractNpcAI
if (room.getCurrentPot() < 9)
{
L2Npc b = room.getBurners()[room.getOrder()[room.getCurrentPot()]];
b.setDisplayEffect(1);
b.setState(1);
b.setIsRunning(false);
startQuestTimer("off", 2000, b, null); // Stopping burning each pot 2s after
startQuestTimer("timer", TIMER_INTERVAL * 1000, npc, null);
@ -279,7 +279,7 @@ public final class Minigame extends AbstractNpcAI
{
if (room.getCurrentPot() < 8)
{
npc.setDisplayEffect(1);
npc.setState(1);
npc.setIsRunning(false);
startQuestTimer("off", 2000, npc, null);
room.setCurrentPot(room.getCurrentPot() + 1);
@ -427,7 +427,7 @@ public final class Minigame extends AbstractNpcAI
{
for (L2Npc burner : _burners)
{
burner.setDisplayEffect(1);
burner.setState(1);
burner.setIsRunning(false);
}
}

View File

@ -1,10 +0,0 @@
<html><body>Subclass Skill Certification:<br>
Depending on your level, I may be able to certify your subclass.<br>
Take this certification to <font color="LEVEL">Avant-Garde, the Wizard of Transformation in the Ivory Tower</font>, for more information on which skills you will be able to acquire.<br>
Additionally, you will receive the Transformation Sealbook in lieu of ultimate skills.<br>
Now, what level of certification do you want to obtain?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification Obtain65">Level 65 Emergent Skill certification.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification Obtain70">Level 70 Emergent Skill certification.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification Obtain75">Level 75 Master or class-specific Skill certification.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification Obtain80">Level 80 Divine Transformation certification.</Button>
</body></html>

View File

@ -1,7 +0,0 @@
<html><body>Subclass Skill Certification:<br>
You are trying to obtain level 75 certification of %class%, common skill or special skill. Remember that once this subclass is certified, it cannot be re-certified -- even if you delete this class and develop another one -- without a special and expensive cancellation process.<br>
Do you still want to be certified?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification lvl75Class">Obtain class specific skill certification.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification lvl75Master">Obtain master skill certification.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification NotObtain.html">Do not obtain certification.</Button>
</body></html>

View File

@ -1,6 +0,0 @@
<html><body>Subclass Skill Certification:<br>
You are trying to obtain level %level% certification of %class%, %skilltype%. Remember that once this subclass is certified, it cannot be re-certified -- even if you delete this class and develop another one -- without a special and expensive cancellation process.<br>
Do you still want to be certified?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification %event%">Obtain certification.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification NotObtain.html">Do not obtain certification.</Button>
</body></html>

View File

@ -1,6 +0,0 @@
<html><body>Subclass Skill Certification:<br>
You can be certified at levels 65, 70, 75 and 80. You can practice common skills at Level 65 and 70, common or special skills at Level 75, and ultimate skills at level 80.<br>
Common skills are not occupation specific. They can be learned regardless of class. Special skills and ultimate skills are specific to your occupation.<br>
The effects of skills learned through this certification can overlap each other, even if they are the same kind of skill.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification Main.html">Back.</Button>
</body></html>

View File

@ -1,5 +0,0 @@
<html><body>Subclass Skill Certification:<br>
This certifies that you has reached the required level.<br>
Take it to <font color="LEVEL">Transformation Wizard Avant-Garde</font>, and you will be able to learn some new skills.<br>
To cancel this certification, simply ask her.
</body></html>

View File

@ -1,7 +0,0 @@
<html><body>Subclass Skill Certification:<br>
Once you reach a certain level of skill in your subclass, your skills can be certified. As a result, you will be able to learn some special skills which you can use in your main class.<br>
However, each subclass slot can have only <font color="LEVEL">one certification</font>. That means that even if you come back with a different occupation for the subclass, you cannot obtain another certification unless you first spend a <font color="LEVEL">huge amount to cancel the first certification</font>.<br>
If you want to obtain a certification, <font color="LEVEL">your current occupation should be that of the subclass you want to be certified, and you should be above level 65</font>. Now, do you wish to be certified for this subclass?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification Explanation.html">Listen to a detailed explanation about subclass certification.</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest SubclassCertification GetCertified">Get certified.</Button>
</body></html>

View File

@ -1,4 +0,0 @@
<html><body>Subclass Ability Validation:<br>
Your skill level is not yet sufficient to obtain a certificate.<br>
You can get Skill Certificate once you have reached level 65, 70, 75 or 80.
</body></html>

View File

@ -1,3 +0,0 @@
<html><body>Subclass Ability Validation:<br>
If you want to obtain the certificate, you should come as a form of subclass you wish to apply.
</body></html>

View File

@ -1,283 +0,0 @@
/*
* Copyright (C) 2004-2015 L2J DataPack
*
* This file is part of L2J DataPack.
*
* L2J DataPack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J DataPack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ai.npc.SubclassCertification;
import java.util.HashMap;
import java.util.Map;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.data.xml.impl.ClassListData;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2VillageMasterInstance;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.model.quest.State;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
/**
* Subclass certification
* @author xban1x, jurchiks
*/
public final class SubclassCertification extends AbstractNpcAI
{
// @formatter:off
private static final int[] NPCS =
{
30026, 30031, 30037, 30066, 30070, 30109, 30115, 30120, 30154, 30174,
30175, 30176, 30187, 30191, 30195, 30288, 30289, 30290, 30297, 30358,
30373, 30462, 30474, 30498, 30499, 30500, 30503, 30504, 30505, 30508,
30511, 30512, 30513, 30520, 30525, 30565, 30594, 30595, 30676, 30677,
30681, 30685, 30687, 30689, 30694, 30699, 30704, 30845, 30847, 30849,
30854, 30857, 30862, 30865, 30894, 30897, 30900, 30905, 30910, 30913,
31269, 31272, 31276, 31279, 31285, 31288, 31314, 31317, 31321, 31324,
31326, 31328, 31331, 31334, 31336, 31755, 31958, 31961, 31965, 31968,
31974, 31977, 31996, 32092, 32093, 32094, 32095, 32096, 32097, 32098,
32145, 32146, 32147, 32150, 32153, 32154, 32157, 32158, 32160, 32171,
32193, 32199, 32202, 32213, 32214, 32221, 32222, 32229, 32230, 32233,
32234
};
// @formatter:on
private static final int CERTIFICATE_EMERGENT_ABILITY = 10280;
private static final int CERTIFICATE_MASTER_ABILITY = 10612;
private static final Map<Integer, Integer> ABILITY_CERTIFICATES = new HashMap<>();
private static final Map<Integer, Integer> TRANSFORMATION_SEALBOOKS = new HashMap<>();
static
{
ABILITY_CERTIFICATES.put(0, 10281); // Certificate - Warrior Ability
ABILITY_CERTIFICATES.put(1, 10283); // Certificate - Rogue Ability
ABILITY_CERTIFICATES.put(2, 10282); // Certificate - Knight Ability
ABILITY_CERTIFICATES.put(3, 10286); // Certificate - Summoner Ability
ABILITY_CERTIFICATES.put(4, 10284); // Certificate - Wizard Ability
ABILITY_CERTIFICATES.put(5, 10285); // Certificate - Healer Ability
ABILITY_CERTIFICATES.put(6, 10287); // Certificate - Enchanter Ability
TRANSFORMATION_SEALBOOKS.put(0, 10289); // Transformation Sealbook: Divine Warrior
TRANSFORMATION_SEALBOOKS.put(1, 10290); // Transformation Sealbook: Divine Rogue
TRANSFORMATION_SEALBOOKS.put(2, 10288); // Transformation Sealbook: Divine Knight
TRANSFORMATION_SEALBOOKS.put(3, 10294); // Transformation Sealbook: Divine Summoner
TRANSFORMATION_SEALBOOKS.put(4, 10292); // Transformation Sealbook: Divine Wizard
TRANSFORMATION_SEALBOOKS.put(5, 10291); // Transformation Sealbook: Divine Healer
TRANSFORMATION_SEALBOOKS.put(6, 10293); // Transformation Sealbook: Divine Enchanter
}
private static final int MIN_LVL = 65;
private SubclassCertification()
{
super(SubclassCertification.class.getSimpleName(), "ai/npc");
addStartNpc(NPCS);
addTalkId(NPCS);
}
@Override
public String onTalk(L2Npc npc, L2PcInstance player)
{
final QuestState st = player.getQuestState(getName());
String htmltext = getNoQuestMsg(player);
if (st != null)
{
st.setState(State.STARTED);
htmltext = "Main.html";
}
return htmltext;
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
String htmltext = null;
final QuestState st = player.getQuestState(getName());
if (st == null)
{
return htmltext;
}
switch (event)
{
case "GetCertified":
{
if (!player.isSubClassActive())
{
htmltext = "NotSubclass.html";
}
else if (player.getLevel() < MIN_LVL)
{
htmltext = "NotMinLevel.html";
}
else if (((L2VillageMasterInstance) npc).checkVillageMaster(player.getActiveClass()))
{
htmltext = "CertificationList.html";
}
else
{
htmltext = "WrongVillageMaster.html";
}
break;
}
case "Obtain65":
{
htmltext = replaceHtml(player, "EmergentAbility.html", true, null).replace("%level%", "65").replace("%skilltype%", "common skill").replace("%event%", "lvl65Emergent");
break;
}
case "Obtain70":
{
htmltext = replaceHtml(player, "EmergentAbility.html", true, null).replace("%level%", "70").replace("%skilltype%", "common skill").replace("%event%", "lvl70Emergent");
break;
}
case "Obtain75":
{
htmltext = replaceHtml(player, "ClassAbility.html", true, null);
break;
}
case "Obtain80":
{
htmltext = replaceHtml(player, "EmergentAbility.html", true, null).replace("%level%", "80").replace("%skilltype%", "transformation skill").replace("%event%", "lvl80Class");
break;
}
case "lvl65Emergent":
{
htmltext = doCertification(player, st, "EmergentAbility", CERTIFICATE_EMERGENT_ABILITY, 65);
break;
}
case "lvl70Emergent":
{
htmltext = doCertification(player, st, "EmergentAbility", CERTIFICATE_EMERGENT_ABILITY, 70);
break;
}
case "lvl75Master":
{
htmltext = doCertification(player, st, "ClassAbility", CERTIFICATE_MASTER_ABILITY, 75);
break;
}
case "lvl75Class":
{
htmltext = doCertification(player, st, "ClassAbility", ABILITY_CERTIFICATES.get(getClassIndex(player)), 75);
break;
}
case "lvl80Class":
{
htmltext = doCertification(player, st, "ClassAbility", TRANSFORMATION_SEALBOOKS.get(getClassIndex(player)), 80);
break;
}
case "Main.html":
case "Explanation.html":
case "NotObtain.html":
{
htmltext = event;
break;
}
}
return htmltext;
}
private String replaceHtml(L2PcInstance player, String htmlFile, boolean replaceClass, String levelToReplace)
{
String htmltext = getHtm(player.getHtmlPrefix(), htmlFile);
if (replaceClass)
{
htmltext = htmltext.replace("%class%", String.valueOf(ClassListData.getInstance().getClass(player.getActiveClass()).getClientCode()));
}
if (levelToReplace != null)
{
htmltext = htmltext.replace("%level%", levelToReplace);
}
return htmltext;
}
private static int getClassIndex(L2PcInstance player)
{
if (player.isInCategory(CategoryType.SUB_GROUP_WARRIOR))
{
return 0;
}
else if (player.isInCategory(CategoryType.SUB_GROUP_ROGUE))
{
return 1;
}
else if (player.isInCategory(CategoryType.SUB_GROUP_KNIGHT))
{
return 2;
}
else if (player.isInCategory(CategoryType.SUB_GROUP_SUMMONER))
{
return 3;
}
else if (player.isInCategory(CategoryType.SUB_GROUP_WIZARD))
{
return 4;
}
else if (player.isInCategory(CategoryType.SUB_GROUP_HEALER))
{
return 5;
}
else if (player.isInCategory(CategoryType.SUB_GROUP_ENCHANTER))
{
return 6;
}
return -1;
}
private String doCertification(L2PcInstance player, QuestState qs, String variable, Integer itemId, int level)
{
if (itemId == null)
{
return null;
}
String htmltext;
String tmp = variable + level + "-" + player.getClassIndex();
String globalVariable = qs.getGlobalQuestVar(tmp);
if (!globalVariable.equals("") && !globalVariable.equals("0"))
{
htmltext = "AlreadyReceived.html";
}
else if (player.getLevel() < level)
{
htmltext = replaceHtml(player, "LowLevel.html", false, Integer.toString(level));
}
else
{
// Add items to player's inventory
final L2ItemInstance item = player.getInventory().addItem("Quest", itemId, 1, player, player.getTarget());
if (item == null)
{
return null;
}
final SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1);
smsg.addItemName(item);
player.sendPacket(smsg);
qs.saveGlobalQuestVar(tmp, String.valueOf(item.getObjectId()));
htmltext = "GetAbility.html";
}
return htmltext;
}
public static void main(String[] args)
{
new SubclassCertification();
}
}

View File

@ -1,4 +0,0 @@
<html><body>Subclass Ability Validation:<br>
I'm sorry, but I cannot give you a certificate for your current occupation.<br>
You should go and look for the subclass master for your current occupation.
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Subclass certification occurs at levels 65, 70, 75, and 80. New skills can be learned at each level.<br>
You can learn skills regardless of your occupation.<br>
Effects of the skills you learn through this certification can stack, even if you use the same skills.<br>
<Button ALIGN=LEFT ICON="RETURN" action="bypass -h Quest Trandon 33490.html">Back</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Dual class certification can be done when <font color="LEVEL">your main and dual class levels both hit 85, 90, 95, and 99</font>. You can get certificates by getting certified for each of them, and with the certificates, you get to learn skills.<br>
Remember; <font color="LEVEL">skills you learned through dual certification only apply to main class and dual class</font>.<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490.html">"Okay, I see."</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
So what do you want to know about subclass certification?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-04.html">"I want to learn skills for certified subclasses."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-05.html">"I want to give up on skills and certification for certified subclasses."</Button>
</body></html>

View File

@ -0,0 +1,8 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
If your subclass is strong enough, that class' power can be transferred to your main class.<br>
But this is a dangerous feat. Your power must be proven through certification.<br>
If you have a certificate, I will do a partial transfer on you.<br>
Now, will you learn the subclass skills transferred onto the main class? <br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon learnSubSkill">"Of course!"</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-07.html">"No, I want to give up."</Button>
</body></html>

View File

@ -0,0 +1,7 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Subclass skill certification and learning actually require tons of effort. Not just effort - it's more fundamental than that. The enormous pressure it puts on your soul... a normal person wouldn't be able to survive it.<br>
Not that it's completely impossible if you use special herbs. Except that those herbs cost about <font color="LEVEL">10 million Adena</font> each. But I have the herbs handy, so as long as you pay up, I can cancel that certification for you.<br>
If you cancel the certification, <font color="LEVEL">your current certification status disappears, and all the certificates and sealbooks you didn't learn skills with will be deleted</font>. So...what do you want to do?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon deleteSubSkill">"Yeah, I'll go ahead and cancel the certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-06.html">"I want to quit."</Button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Good idea. Those herbs aren't the easiest to come by. And that nasty black wizard in the Dragon Valley is the only one who knows how to formulate the thing, so I wasn't too excited about this either.<br>
And everything you got certified for... it's kind of a waste, right?
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Well, I guess I'm not one to stop you if you want to give up.<br>
After all, it's no easy feat to use the power of a subclass in a main class.
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
So what do you want to do about dual class certification?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-09.html">"I want to learn certified dual class skills."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-10.html">"Actually, I'll just give up on the whole certification deal."</Button>
</body></html>

View File

@ -0,0 +1,8 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
You can obtain new powers if <font color="LEVEL">your main class and dual class both exceed level 85</font>.<br1>
You can't get these powers unless you are certified with your dual class and main class. i<br1>
<font color="LEVEL">I'll help you obtain new powers if you have the certificates</font>.<br1>
So, will you give me that dual class certificate and acquire the power contained within? <br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon learnDualSkill">"Of course!"</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-11.html">"Whoa, wait a minute. Give me some time to get ready."</Button>
</body></html>

View File

@ -0,0 +1,10 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Dual class certification and skill learning are actually incredible feats.<br1>
As you may know from the subclass experience you had before, but it's not just about effort. The enormous pressure it puts on your soul is beyond your imagination.<br1>
I will be usin the special herbs again to seal the certified skills you learned.<br1>
This time though, the herb will cost you about <font color="LEVEL">20 million Adena</font>. I have them handy, so just pay up and I can cancel that certification for you. <br1>
If you cancel the certification, <font color="LEVEL">your current certification status disappears, and all the certificates and sealbooks you didn't learn skills with will be deleted</font>.<br1>
So...what do you want to do?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon deleteDualSkill">"Yeah, I'll go ahead and cancel the certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-06.html">"I want to quit."</Button>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Well, if you're not ready...I can't push you.<br1>
Come again after you <font color="LEVEL">get your main and dual class levels to 85, 90, 95, and 99 and get certified</font>.
</body></html>

View File

@ -0,0 +1,9 @@
<html><body>Subclass Skill Certification:<br>
Subclass certification is handled at various different levels. If your skills are good enough, I can certify you.<br>
When you are ready, bring the certification to me and I will help you learn new skills.<br>
Now, what level of certification do you want?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon subCertify 0">"Level 65 Skill Certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon subCertify 1">"Level 70 Skill Certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon subCertify 2">"Level 75 Skill Certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon subCertify 3">"Level 80 Skill Certification."</Button>
</body></html>

View File

@ -0,0 +1,3 @@
<html><body>Subclass Skill Certification:<br>
To receive a subclass certification, you must come to me in the subclass state.
</body></html>

View File

@ -0,0 +1,3 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
I wanted to give you your certificate once your subclass certification was completed, but you don't have sufficient free weight and inventory space. Return to me when 80% of your weight and inventory is free.
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Subclass Skill Certification:<br>
You have already received the certificate for this occupation.<br>
I cannot give you any more certificates for your current occupation. If you wish to obtain another certificate, please come back as an occupation from another slot.<br>
However, Ertheia are still connected to gods. So it would be meaningless for them to start a new life as a subclass, which also means that subclass certificates are meaningless for them.<br>
(Ertheia cannot add a subclass or get a subclass certificate.)
</body></html>

View File

@ -1,3 +1,3 @@
<html><body>Subclass Skill Certification:<br>
<html><body>Subclass Ability Validation:<br>
You are not yet ready to receive your level %level% certification. Work hard and come back later.
</body></html>

View File

@ -1,3 +1,3 @@
<html><body>Subclass Skill Certification:<br>
<html><body>Subclass Ability Validation:<br>
You have already received the certificate for this skill.
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Subclass Skill Certification:<br>
You want to be certified for Level %level%? Once you are certified, you can't be recertified unless you cancel the certification by jumping through some hoops first. Even if you delete the class and build up your skill, it's a no go. You OK with that?<br>
Do you still want to receive certification?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon giveSubCertify %index%">"Yes."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-19.html">"Not really."</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Subclass Skill Certification:<br>
This certification is to verify that your subclass has exceeded the required level.<br>
When your mind is clear and you've decided how to proceed, come and see me and I'll provide you with an appropriate skill.<br>
If you would like to cancel this certification, please let me know and I can cancel it.
</body></html>

View File

@ -0,0 +1,3 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
To draw the power of a subclass, you must <font color="LEVEL">set your current class the main class, and bring the certificate to me.</font> Also, if you want to change any subclass certified skill you have acquired, you must abandon the skills and certification of the certified subclass. <font color="LEVEL">To abandon the subclass skills and certification, come and talk to me while you're in your main class.</font>
</body></html>

View File

@ -0,0 +1,3 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Sorry, but you need 10 million adena. You don't seem to have that much money.
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Hmm... you have neither a certified certificate, nor any skills you've learned from certification. What are you trying to cancel?<br>
This herb is very rare and expensive, you don't want to use it unless it's necessary.
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Sub/Dual Class Certificate Manager Trandon:<br>
<font color="LEVEL">To get dual class certification, don't you think you should come as a dual class?</font><br>
Please come back as a dual class.
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Sub/Dual Class Certificate Manager Trandon:<br>
Your inventory and weight slots are still full.<br>
<font color="LEVEL">Come back when your inventory and weight slots are less than 80% full.</font>
</body></html>

View File

@ -0,0 +1,9 @@
<html><body>Subclass/Dual Class Skill Certification:<br>
You have to be at a <font color="LEVEL">high enough level for both main and subclass.</font> I can give you the certificate if you're strong enough.<br>
After I give you the certificate, bring it back to me and I'll tell you about skills you can learn.<br>
Now, what level of certification do you want?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon dualCertify 0">"Level 85 Skill Certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon dualCertify 1">"Level 90 Skill Certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon dualCertify 2">"Level 95 Skill Certification."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon dualCertify 3">"Level 99 Skill Certification."</Button>
</body></html>

View File

@ -0,0 +1,5 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Haven't you already been certified for level <font color="LEVEL">%level%?</font><br1>
Young ones these days...listen carefully.<br1>
You can get <font color="LEVEL">certified a total of 4 times for the dual class - when your main and dual class levels are at 85, 90, 95, and 99.</font>
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Sub/Dual Class Certificate Manager Trandon:<br>
It seems <font color="LEVEL">you are not yet qualified to get dual class certification for level %level%</font>.<br>
You can get certified only when <font color="LEVEL">both your main class and dual class are level %level% or above</font>. So, come back after leveling up.
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Sub/Dual Class Certificate Manager Trandon:<br>
Congratulations.<br1>
Let me give you a <font color="LEVEL">dual class certificate for level %level%.<br1>
Come back with this certificate when you want to learn a dual certification skill.</font><br1>
Keep in mind that <font color="LEVEL">you have to come back as your main class</font> to learn a dual certification skill.
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Sub/Dual Class Certificate Manager Trandon:<br>
Just like subclass certification skills, you <font color="LEVEL">have to be your main class to learn dual certification skills</font>.<br1>
Please come back as your main class.
</body></html>

View File

@ -0,0 +1,6 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Hmm... You don't have a dual class certificate.<br1>
<font color="LEVEL">To learn a dual certification skill, you need a dual class certificate</font>. Get certified!<br1>
Luckily for you, I'm the person to talk to. Would you like to get certified?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-26.html">"Yes, I'll try it."</Button>
</body></html>

View File

@ -0,0 +1,7 @@
<html><body>Sub/Dual Class Certificate Manager Trandon:<br>
To re-seal the power of the dual certification skill you learned, I need herbs.<br1>
I need more herbs for this than for sealing subclass certification skills.<br1>
Let me see how much it will cost...<br>
Hmm... Just the herbs cost <font color="LEVEL">20 million Adena</font>.<br1>
Bring me <font color="LEVEL">20 million Adena</font>.
</body></html>

View File

@ -0,0 +1,4 @@
<html><body>Sub/Dual Class Certificate Manager Trandon:<br>
You don't have any unsealed certification skills yet.<br1>
Come back when you want to seal the power of unsealed certification skills.
</body></html>

View File

@ -0,0 +1,12 @@
<html><body>Subclass/Dual Class Certificate Manager Trandon:<br>
Discipline and endless training to bring your subclass up to a certain level open your eyes to new powers.<br1>
Now, let's see how much your training has taught you.<br1>
By the way, to receive this certification, <font color="LEVEL">your current class must be the class of the subclass or dual class you want to be certified for; you also need to be level 65 or above, and in the case of the dual class, level 85 or above</font>.<br1>
So, do you want to be certified? Or do you want to learn skills with the certification you received?<br>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-01.html">"Wait...care to explain more about the subclass certification?"</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-12.html">"Certify me on the subclass."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-03.html">"I need to learn or forget a subclass skill."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-02.html">"So, uh, about this dual class certification..."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-26.html">"I need a dual class certification, please."</Button>
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Trandon 33490-08.html">"I need to learn or forget a dual class skill, actually."</Button>
</body></html>

View File

@ -0,0 +1,463 @@
/*
* Copyright (C) 2004-2015 L2J DataPack
*
* This file is part of L2J DataPack.
*
* L2J DataPack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J DataPack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ai.npc.Trandon;
import java.util.Set;
import ai.npc.AbstractNpcAI;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.events.EventType;
import com.l2jserver.gameserver.model.events.ListenerRegisterType;
import com.l2jserver.gameserver.model.events.annotations.RegisterEvent;
import com.l2jserver.gameserver.model.events.annotations.RegisterType;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogin;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSubChange;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.variables.PlayerVariables;
import com.l2jserver.gameserver.network.clientpackets.RequestAcquireSkill;
/**
* Trandon AI.
* @author malyelfik
*/
public final class Trandon extends AbstractNpcAI
{
// NPC
private static final int NPC_ID = 33490;
// Items
private static final int SUB_CERTIFICATE = 10280;
private static final int DUAL_CERTIFICATE = 36078;
// Misc @formatter:off
private static final int[] SUB_SKILL_LEVELS = {65, 70, 75, 80};
private static final int[] DUAL_SKILL_LEVELS = {85, 90, 95, 99};
// @formatter:on
private Trandon()
{
super(Trandon.class.getSimpleName(), "ai/npc");
addStartNpc(NPC_ID);
addFirstTalkId(NPC_ID);
addTalkId(NPC_ID);
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
final String[] substrings = event.split(" ");
if (substrings.length < 1)
{
return null;
}
String htmltext = substrings[0];
switch (htmltext)
{
case "33490.html":
case "33490-01.html":
case "33490-02.html":
case "33490-03.html":
case "33490-04.html":
case "33490-05.html":
case "33490-06.html":
case "33490-07.html":
case "33490-08.html":
case "33490-09.html":
case "33490-10.html":
case "33490-11.html":
case "33490-19.html":
break;
case "33490-12.html":
{
if (player.getRace().equals(Race.ERTHEIA) || hasAllSubCertifications(player))
{
htmltext = "33490-15.html";
}
else if (!player.isSubClassActive())
{
htmltext = "33490-13.html";
}
else if (!player.isInventoryUnder90(false) || (player.getWeightPenalty() >= 2))
{
htmltext = "33490-14.html";
}
break;
}
case "subCertify":
{
if ((substrings.length < 2) || !player.isSubClassActive())
{
return null;
}
final int index = Integer.parseInt(substrings[1]);
if ((index < 0) || (index > 3))
{
return null;
}
final int level = SUB_SKILL_LEVELS[index];
if (player.getLevel() < level)
{
htmltext = getHtm(player.getHtmlPrefix(), "33490-16.html").replace("%level%", String.valueOf(level));
}
else if (player.getVariables().hasVariable(getSubSkillVariableName(player, level)))
{
htmltext = "33490-17.html";
}
else
{
htmltext = getHtm(player.getHtmlPrefix(), "33490-18.html");
htmltext = htmltext.replace("%level%", String.valueOf(level));
htmltext = htmltext.replace("%index%", String.valueOf(index));
}
break;
}
case "giveSubCertify":
{
if ((substrings.length < 2) || !player.isSubClassActive() || player.getRace().equals(Race.ERTHEIA))
{
return null;
}
final int index = Integer.parseInt(substrings[1]);
if ((index < 0) || (index > 3))
{
return null;
}
final int level = SUB_SKILL_LEVELS[index];
final PlayerVariables vars = player.getVariables();
if ((player.getLevel() < level) || vars.hasVariable(getSubSkillVariableName(player, level)))
{
htmltext = null;
}
else
{
vars.set(getSubSkillVariableName(player, level), true);
giveItems(player, SUB_CERTIFICATE, 1);
htmltext = "33490-20.html";
}
break;
}
case "learnSubSkill":
{
if (player.getRace().equals(Race.ERTHEIA))
{
htmltext = "33490-15.html";
}
else if (player.isSubClassActive() || !hasQuestItems(player, SUB_CERTIFICATE))
{
htmltext = "33490-21.html";
}
else
{
RequestAcquireSkill.showSubSkillList(player);
htmltext = null;
}
break;
}
case "deleteSubSkill":
{
if (player.getRace().equals(Race.ERTHEIA))
{
htmltext = "33490-15.html";
}
else if (player.isSubClassActive())
{
htmltext = "33490-21.html";
}
else if (player.getAdena() < Config.FEE_DELETE_SUBCLASS_SKILLS)
{
htmltext = "33490-22.html";
}
else if (!hasSubCertificate(player))
{
htmltext = "33490-23.html";
}
else
{
htmltext = null; // TODO: Unknown html
takeItems(player, SUB_CERTIFICATE, -1);
takeItems(player, Inventory.ADENA_ID, Config.FEE_DELETE_SUBCLASS_SKILLS);
final PlayerVariables vars = player.getVariables();
for (int i = 1; i <= 3; i++)
{
for (int lv : SUB_SKILL_LEVELS)
{
vars.remove("SubSkill-" + i + "-" + lv);
}
}
takeSkills(player, "SubSkillList");
}
break;
}
case "33490-26.html":
{
// TODO: What happens when you have all dual certificates?
if (!player.isDualClassActive())
{
htmltext = "33490-24.html";
}
else if (!player.isInventoryUnder90(false) || (player.getWeightPenalty() >= 2))
{
htmltext = "33490-25.html";
}
else if ((player.getLevel() < DUAL_SKILL_LEVELS[0]) || (player.getStat().getBaseLevel() < DUAL_SKILL_LEVELS[0])) // Dual or main class level is lower than 85
{
// TODO: What happens here?
player.sendMessage("Your level is too low.");
htmltext = null;
}
break;
}
case "dualCertify":
{
if ((substrings.length < 2) || !player.isDualClassActive())
{
return null;
}
final int index = Integer.parseInt(substrings[1]);
if ((index < 0) || (index > 3))
{
return null;
}
final int level = DUAL_SKILL_LEVELS[index];
final PlayerVariables vars = player.getVariables();
if (vars.hasVariable(getDualSkillVariableName(level)))
{
htmltext = getHtm(player.getHtmlPrefix(), "33490-27.html");
}
else if ((player.getLevel() < level) || (player.getStat().getBaseLevel() < level))
{
htmltext = getHtm(player.getHtmlPrefix(), "33490-28.html");
}
else
{
vars.set(getDualSkillVariableName(level), true);
giveItems(player, DUAL_CERTIFICATE, 1);
htmltext = getHtm(player.getHtmlPrefix(), "33490-29.html");
}
htmltext = htmltext.replace("%level%", String.valueOf(level));
break;
}
case "learnDualSkill":
{
// TODO: What happens when you have all dual-certificates used?
if (player.isSubClassActive())
{
htmltext = "33490-30.html";
}
else if (!hasQuestItems(player, DUAL_CERTIFICATE))
{
htmltext = "33490-31.html";
}
else if ((player.getLevel() < DUAL_SKILL_LEVELS[0]) || (player.getStat().getBaseLevel() < DUAL_SKILL_LEVELS[0]))
{
// This case should not happen
htmltext = null;
}
else
{
RequestAcquireSkill.showDualSkillList(player);
htmltext = null;
}
break;
}
case "deleteDualSkill":
{
if (player.isSubClassActive())
{
htmltext = "33490-30.html";
}
else if (player.getAdena() < Config.FEE_DELETE_DUALCLASS_SKILLS)
{
htmltext = "33490-32.html";
}
else if (!hasDualCertificate(player))
{
htmltext = "33490-33.html";
}
else
{
htmltext = null; // TODO: Unknown html
takeItems(player, DUAL_CERTIFICATE, -1);
takeItems(player, Inventory.ADENA_ID, Config.FEE_DELETE_DUALCLASS_SKILLS);
final PlayerVariables vars = player.getVariables();
for (int lv : DUAL_SKILL_LEVELS)
{
vars.remove(getDualSkillVariableName(lv));
}
takeSkills(player, "DualSkillList");
}
break;
}
default:
{
htmltext = null;
}
}
return htmltext;
}
// TODO: Move this to char skills
@RegisterEvent(EventType.ON_PLAYER_SUB_CHANGE)
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
public final void onSubChange(OnPlayerSubChange evt)
{
final L2PcInstance player = evt.getActiveChar();
if (player.isDualClassActive() || !player.isSubClassActive())
{
giveSkills(player, "DualSkillList");
}
giveSkills(player, "SubSkillList");
player.sendSkillList();
}
@RegisterEvent(EventType.ON_PLAYER_LOGIN)
@RegisterType(ListenerRegisterType.GLOBAL_PLAYERS)
public final void onLogin(OnPlayerLogin evt)
{
final L2PcInstance player = evt.getActiveChar();
if (player.isDualClassActive() || !player.isSubClassActive())
{
giveSkills(player, "DualSkillList");
}
giveSkills(player, "SubSkillList");
}
/**
* Checks if player has all sub certifications for current subclass
* @param player
* @return
*/
private final boolean hasAllSubCertifications(L2PcInstance player)
{
if (!player.isSubClassActive())
{
return false;
}
final PlayerVariables vars = player.getVariables();
for (int lv : SUB_SKILL_LEVELS)
{
if (!vars.hasVariable(getSubSkillVariableName(player, lv)))
{
return false;
}
}
return true;
}
/**
* Checks if player has any sub certification
* @param player
* @return
*/
private final boolean hasSubCertificate(L2PcInstance player)
{
final PlayerVariables vars = player.getVariables();
final Set<Integer> subs = player.getSubClasses().keySet();
for (int index : subs)
{
for (int lv : SUB_SKILL_LEVELS)
{
if (vars.hasVariable("SubSkill-" + index + "-" + lv))
{
return true;
}
}
}
return false;
}
/**
* Checks if player has any dual certification
* @param player
* @return
*/
private final boolean hasDualCertificate(L2PcInstance player)
{
final PlayerVariables vars = player.getVariables();
for (int lv : DUAL_SKILL_LEVELS)
{
if (vars.hasVariable(getDualSkillVariableName(lv)))
{
return true;
}
}
return false;
}
private final String getSubSkillVariableName(L2PcInstance player, int level)
{
return "SubSkill-" + player.getClassIndex() + "-" + level;
}
private final String getDualSkillVariableName(int level)
{
return "DualSkill-" + level;
}
private final void takeSkills(L2PcInstance player, String type)
{
final PlayerVariables vars = player.getVariables();
final String list = vars.getString(type, "");
if (!list.isEmpty())
{
final String[] skills = list.split(";");
for (String skill : skills)
{
final String[] str = skill.split("-");
final Skill sk = SkillData.getInstance().getSkill(Integer.parseInt(str[0]), Integer.parseInt(str[1]));
player.removeSkill(sk);
}
vars.remove(type);
player.sendSkillList();
}
}
private final void giveSkills(L2PcInstance player, String type)
{
final String list = player.getVariables().getString(type, "");
if (!list.isEmpty())
{
final String[] skills = list.split(";");
for (String skill : skills)
{
final String[] str = skill.split("-");
final Skill sk = SkillData.getInstance().getSkill(Integer.parseInt(str[0]), Integer.parseInt(str[1]));
player.addSkill(sk, false);
}
}
}
public static void main(String[] args)
{
new Trandon();
}
}

View File

@ -1,376 +0,0 @@
/*
* Copyright (C) 2004-2015 L2J DataPack
*
* This file is part of L2J DataPack.
*
* L2J DataPack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J DataPack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package custom.Validators;
import java.util.Arrays;
import javolution.util.FastList;
import com.l2jserver.Config;
import com.l2jserver.gameserver.data.xml.impl.ClassListData;
import com.l2jserver.gameserver.enums.IllegalActionPunishmentType;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.util.Util;
/**
* Sub-class skills validator.<br>
* TODO: Rewrite.
* @author DS
*/
public final class SubClassSkills extends Quest
{
// arrays must be sorted
// @formatter:off
private static final int[] _allCertSkillIds =
{
631, 632, 633, 634, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646,
647, 648, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661,
662, 799, 800, 801, 802, 803, 804, 1489, 1490, 1491
};
private static final int[][] _certSkillsByLevel =
{
{
631, 632, 633, 634
},
{
631, 632, 633, 634
},
{
637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 650,
651, 652, 653, 654, 655, 799, 800, 801, 802, 803, 804, 1489, 1490,
1491
},
{
656, 657, 658, 659, 660, 661, 662
}
};
private static final int[] _allCertItemIds =
{
10280, 10281, 10282, 10283, 10284, 10285, 10286, 10287, 10288, 10289,
10290, 10291, 10292, 10293, 10294, 10612
};
private static final int[][] _certItemsByLevel =
{
{ 10280 },
{ 10280 },
{ 10612, 10281, 10282, 10283, 10284, 10285, 10286, 10287 },
{ 10288, 10289, 10290, 10291, 10292, 10293, 10294 }
};
// @formatter:on
private static final String[] VARS =
{
"EmergentAbility65-",
"EmergentAbility70-",
"ClassAbility75-",
"ClassAbility80-"
};
private SubClassSkills()
{
super(-1, SubClassSkills.class.getSimpleName(), "custom");
setOnEnterWorld(true);
}
@Override
public String onEnterWorld(L2PcInstance player)
{
if (!Config.SKILL_CHECK_ENABLE)
{
return null;
}
if (player.canOverrideCond(PcCondOverride.SKILL_CONDITIONS) && !Config.SKILL_CHECK_GM)
{
return null;
}
final Skill[] certSkills = getCertSkills(player);
if (player.isSubClassActive())
{
if (certSkills != null)
{
for (Skill s : certSkills)
{
Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " has cert skill on subclass :" + s.getName() + "(" + s.getId() + "/" + s.getLevel() + "), class:" + ClassListData.getInstance().getClass(player.getClassId()).getClassName(), IllegalActionPunishmentType.NONE);
if (Config.SKILL_CHECK_REMOVE)
{
player.removeSkill(s);
}
}
}
return null;
}
Skill skill;
int[][] cSkills = null; // skillId/skillLvl
if (certSkills != null)
{
cSkills = new int[certSkills.length][2];
for (int i = certSkills.length; --i >= 0;)
{
skill = certSkills[i];
cSkills[i][0] = skill.getId();
cSkills[i][1] = skill.getLevel();
}
}
L2ItemInstance item;
int[][] cItems = null; // objectId/number
final L2ItemInstance[] certItems = getCertItems(player);
if (certItems != null)
{
cItems = new int[certItems.length][2];
for (int i = certItems.length; --i >= 0;)
{
item = certItems[i];
cItems[i][0] = item.getObjectId();
cItems[i][1] = (int) Math.min(item.getCount(), Integer.MAX_VALUE);
}
}
QuestState st = player.getQuestState("SubClassSkills");
if (st == null)
{
st = newQuestState(player);
}
String qName, qValue;
int id, index;
for (int i = VARS.length; --i >= 0;)
{
for (int j = Config.MAX_SUBCLASS; j > 0; j--)
{
qName = VARS[i] + String.valueOf(j);
qValue = st.getGlobalQuestVar(qName);
if ((qValue == null) || qValue.isEmpty())
{
continue;
}
if (qValue.endsWith(";")) // found skill
{
try
{
id = Integer.parseInt(qValue.replace(";", ""));
skill = null;
if (certSkills != null)
{
// searching skill in test array
if (cSkills != null)
{
for (index = certSkills.length; --index >= 0;)
{
if (cSkills[index][0] == id)
{
skill = certSkills[index];
cSkills[index][1]--;
break;
}
}
}
if (skill != null)
{
if (!Util.contains(_certSkillsByLevel[i], id))
{
// should remove this skill ?
Util.handleIllegalPlayerAction(player, "Invalid cert variable WITH skill:" + qName + "=" + qValue + " - skill does not match certificate level", IllegalActionPunishmentType.NONE);
}
}
else
{
Util.handleIllegalPlayerAction(player, "Invalid cert variable:" + qName + "=" + qValue + " - skill not found", IllegalActionPunishmentType.NONE);
}
}
else
{
Util.handleIllegalPlayerAction(player, "Invalid cert variable:" + qName + "=" + qValue + " - no certified skills found", IllegalActionPunishmentType.NONE);
}
}
catch (NumberFormatException e)
{
Util.handleIllegalPlayerAction(player, "Invalid cert variable:" + qName + "=" + qValue + " - not a number", IllegalActionPunishmentType.NONE);
}
}
else
// found item
{
try
{
id = Integer.parseInt(qValue);
if (id == 0)
{
continue;
}
item = null;
if (certItems != null)
{
// searching item in test array
if (cItems != null)
{
for (index = certItems.length; --index >= 0;)
{
if (cItems[index][0] == id)
{
item = certItems[index];
cItems[index][1]--;
break;
}
}
}
if (item != null)
{
if (!Util.contains(_certItemsByLevel[i], item.getId()))
{
Util.handleIllegalPlayerAction(player, "Invalid cert variable:" + qName + "=" + qValue + " - item found but does not match certificate level", IllegalActionPunishmentType.NONE);
}
}
else
{
Util.handleIllegalPlayerAction(player, "Invalid cert variable:" + qName + "=" + qValue + " - item not found", IllegalActionPunishmentType.NONE);
}
}
else
{
Util.handleIllegalPlayerAction(player, "Invalid cert variable:" + qName + "=" + qValue + " - no cert item found in inventory", IllegalActionPunishmentType.NONE);
}
}
catch (NumberFormatException e)
{
Util.handleIllegalPlayerAction(player, "Invalid cert variable:" + qName + "=" + qValue + " - not a number", IllegalActionPunishmentType.NONE);
}
}
}
}
if ((certSkills != null) && (cSkills != null))
{
for (int i = cSkills.length; --i >= 0;)
{
if (cSkills[i][1] == 0)
{
continue;
}
skill = certSkills[i];
if (cSkills[i][1] > 0)
{
if (cSkills[i][1] == skill.getLevel())
{
Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " has invalid cert skill :" + skill.getName() + "(" + skill.getId() + "/" + skill.getLevel() + ")", IllegalActionPunishmentType.NONE);
}
else
{
Util.handleIllegalPlayerAction(player, "Player " + player.getName() + " has invalid cert skill :" + skill.getName() + "(" + skill.getId() + "/" + skill.getLevel() + "), level too high", IllegalActionPunishmentType.NONE);
}
if (Config.SKILL_CHECK_REMOVE)
{
player.removeSkill(skill);
}
}
else
{
Util.handleIllegalPlayerAction(player, "Invalid cert skill :" + skill.getName() + "(" + skill.getId() + "/" + skill.getLevel() + "), level too low", IllegalActionPunishmentType.NONE);
}
}
}
if ((certItems != null) && (cItems != null))
{
for (int i = cItems.length; --i >= 0;)
{
if (cItems[i][1] == 0)
{
continue;
}
item = certItems[i];
Util.handleIllegalPlayerAction(player, "Invalid cert item without variable or with wrong count:" + item.getObjectId(), IllegalActionPunishmentType.NONE);
}
}
return null;
}
private Skill[] getCertSkills(L2PcInstance player)
{
FastList<Skill> tmp = null;
for (Skill s : player.getAllSkills())
{
if ((s != null) && (Arrays.binarySearch(_allCertSkillIds, s.getId()) >= 0))
{
if (tmp == null)
{
tmp = FastList.newInstance();
}
tmp.add(s);
}
}
if (tmp == null)
{
return null;
}
final Skill[] result = tmp.toArray(new Skill[tmp.size()]);
FastList.recycle(tmp);
return result;
}
private L2ItemInstance[] getCertItems(L2PcInstance player)
{
FastList<L2ItemInstance> tmp = null;
for (L2ItemInstance i : player.getInventory().getItems())
{
if ((i != null) && (Arrays.binarySearch(_allCertItemIds, i.getId()) >= 0))
{
if (tmp == null)
{
tmp = FastList.newInstance();
}
tmp.add(i);
}
}
if (tmp == null)
{
return null;
}
final L2ItemInstance[] result = tmp.toArray(new L2ItemInstance[tmp.size()]);
FastList.recycle(tmp);
return result;
}
public static void main(String[] args)
{
new SubClassSkills();
}
}

View File

@ -121,7 +121,7 @@ public final class Maguen extends AbstractNpcAI
{
npc.getAI().stopFollow();
final int randomEffect = getRandom(1, 3);
npc.setDisplayEffect(randomEffect);
npc.setState(randomEffect);
npc.getVariables().set("NPC_EFFECT", randomEffect);
startQuestTimer("SECOND_TIMER", 5000 + getRandom(300), npc, player);
npc.broadcastSocialAction(getRandom(1, 3));
@ -130,8 +130,7 @@ public final class Maguen extends AbstractNpcAI
case "SECOND_TIMER":
{
final int randomEffect = getRandom(1, 3);
npc.setDisplayEffect(4);
npc.setDisplayEffect(randomEffect);
npc.setState(randomEffect);
npc.getVariables().set("NPC_EFFECT", randomEffect);
startQuestTimer("THIRD_TIMER", 4600 + getRandom(600), npc, player);
npc.broadcastSocialAction(getRandom(1, 3));
@ -140,8 +139,7 @@ public final class Maguen extends AbstractNpcAI
case "THIRD_TIMER":
{
final int randomEffect = getRandom(1, 3);
npc.setDisplayEffect(4);
npc.setDisplayEffect(randomEffect);
npc.setState(randomEffect);
npc.getVariables().set("NPC_EFFECT", randomEffect);
startQuestTimer("FORTH_TIMER", 4200 + getRandom(900), npc, player);
npc.broadcastSocialAction(getRandom(1, 3));
@ -150,7 +148,7 @@ public final class Maguen extends AbstractNpcAI
case "FORTH_TIMER":
{
npc.getVariables().set("NPC_EFFECT", 0);
npc.setDisplayEffect(4);
npc.setState(4);
startQuestTimer("END_TIMER", 500, npc, player);
npc.broadcastSocialAction(getRandom(1, 3));
break;
@ -251,7 +249,7 @@ public final class Maguen extends AbstractNpcAI
{
startQuestTimer("END_TIMER", 1000, npc, player);
}
npc.setDisplayEffect(4);
npc.setState(4);
return super.onSpellFinished(npc, player, skill);
}
@ -376,4 +374,4 @@ public final class Maguen extends AbstractNpcAI
{
return QuestManager.getInstance().getQuest(Nemo.class.getSimpleName());
}
}
}

View File

@ -268,7 +268,7 @@ public class SeedOfAnnihilation extends AbstractNpcAI
for (int j = 0; j < _regionsData[i].af_spawns.length; j++)
{
_regionsData[i].af_npcs[j] = addSpawn(ANNIHILATION_FURNACE, _regionsData[i].af_spawns[j][0], _regionsData[i].af_spawns[j][1], _regionsData[i].af_spawns[j][2], _regionsData[i].af_spawns[j][3], false, 0);
_regionsData[i].af_npcs[j].setDisplayEffect(_regionsData[i].activeBuff);
_regionsData[i].af_npcs[j].setState(_regionsData[i].activeBuff);
}
ZoneManager.getInstance().getZoneById(_regionsData[i].buff_zone, L2EffectZone.class).addSkill(ZONE_BUFFS[_regionsData[i].activeBuff], 1);
}
@ -311,7 +311,7 @@ public class SeedOfAnnihilation extends AbstractNpcAI
for (L2Npc af : _regionsData[i].af_npcs)
{
af.setDisplayEffect(_regionsData[i].activeBuff);
af.setState(_regionsData[i].activeBuff);
}
L2EffectZone zone = ZoneManager.getInstance().getZoneById(_regionsData[i].buff_zone, L2EffectZone.class);

View File

@ -639,7 +639,7 @@ public class AdminEffects implements IAdminCommandHandler
{
String type = st.nextToken();
int diplayeffect = Integer.parseInt(type);
npc.setDisplayEffect(diplayeffect);
npc.setState(diplayeffect);
}
catch (Exception e)
{

View File

@ -155,7 +155,7 @@ public final class CallPc extends AbstractEffect
if (activeChar.getInstanceId() > 0)
{
Instance summonerInstance = InstanceManager.getInstance().getInstance(activeChar.getInstanceId());
if (!Config.ALLOW_SUMMON_TO_INSTANCE || !summonerInstance.isSummonAllowed())
if (!Config.ALLOW_SUMMON_IN_INSTANCE || !summonerInstance.isSummonAllowed())
{
activeChar.sendPacket(SystemMessageId.YOU_MAY_NOT_SUMMON_FROM_YOUR_CURRENT_LOCATION);
return false;

View File

@ -109,11 +109,6 @@ public final class Warpgate extends AbstractNpcAI
private static boolean canEnter(L2PcInstance player)
{
if (player.isFlying())
{
return false;
}
return true;
return !player.isFlying();
}
}

View File

@ -18,14 +18,12 @@
*/
package hellbound.Instances.DemonPrinceFloor;
import java.util.Calendar;
import ai.npc.AbstractNpcAI;
import instances.AbstractInstance;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Instance;
@ -38,7 +36,7 @@ import com.l2jserver.gameserver.util.Util;
* Demon Prince Floor instance zone.
* @author GKR
*/
public final class DemonPrinceFloor extends AbstractNpcAI
public final class DemonPrinceFloor extends AbstractInstance
{
protected class DPFWorld extends InstanceWorld
{
@ -51,20 +49,18 @@ public final class DemonPrinceFloor extends AbstractNpcAI
private static final int DEMON_PRINCE = 25540;
// Item
private static final int SEAL_BREAKER_5 = 15515;
// Misc
private static final int TEMPLATE_ID = 142;
private static final int RESET_HOUR = 6;
private static final int RESET_MIN = 30;
// Locations
private static final Location ENTRY_POINT = new Location(-22208, 277056, -8239);
private static final Location EXIT_POINT = new Location(-19024, 277122, -8256);
// Misc
private static final int TEMPLATE_ID = 142;
private static final int MIN_LV = 78;
public DemonPrinceFloor()
{
super(DemonPrinceFloor.class.getSimpleName(), "hellbound/Instances");
addStartNpc(GK_4);
addStartNpc(CUBE);
addTalkId(GK_4);
addTalkId(CUBE);
addStartNpc(GK_4, CUBE);
addTalkId(GK_4, CUBE);
addKillId(DEMON_PRINCE);
}
@ -74,16 +70,26 @@ public final class DemonPrinceFloor extends AbstractNpcAI
String htmltext = null;
if (npc.getId() == GK_4)
{
htmltext = checkConditions(player);
if (!player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
if (player.getParty() == null)
{
htmltext = "gk-noparty.htm";
}
else if (!player.getParty().isLeader(player))
{
htmltext = "gk-noleader.htm";
}
}
if (htmltext == null)
{
enterInstance(player, "DemonPrince.xml");
enterInstance(player, new DPFWorld(), "DemonPrince.xml", TEMPLATE_ID);
}
}
else if (npc.getId() == CUBE)
{
InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
if (world instanceof DPFWorld)
{
world.removeAllowed(player.getObjectId());
@ -99,51 +105,27 @@ public final class DemonPrinceFloor extends AbstractNpcAI
final int instanceId = npc.getInstanceId();
if (instanceId > 0)
{
Instance inst = InstanceManager.getInstance().getInstance(instanceId);
InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
final InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
inst.setSpawnLoc(EXIT_POINT);
// Terminate instance in 10 min
if ((inst.getInstanceEndTime() - System.currentTimeMillis()) > 600000)
{
inst.setDuration(600000);
}
inst.setEmptyDestroyTime(0);
if (world instanceof DPFWorld)
{
setReenterTime(world);
}
finishInstance(world);
addSpawn(CUBE, -22144, 278744, -8239, 0, false, 0, false, instanceId);
}
return super.onKill(npc, killer, isSummon);
}
private String checkConditions(L2PcInstance player)
@Override
protected boolean checkConditions(L2PcInstance player)
{
if (player.getParty() == null)
if (player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
return "gk-noparty.htm";
}
else if (!player.getParty().isLeader(player))
{
return "gk-noleader.htm";
return true;
}
return null;
}
private boolean checkTeleport(L2PcInstance player)
{
final L2Party party = player.getParty();
if (party == null)
{
return false;
}
if (!party.isLeader(player))
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return false;
@ -151,125 +133,64 @@ public final class DemonPrinceFloor extends AbstractNpcAI
for (L2PcInstance partyMember : party.getMembers())
{
if (partyMember.getLevel() < 78)
if (partyMember.getLevel() < MIN_LV)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY).addPcName(partyMember));
return false;
}
if (!Util.checkIfInRange(500, player, partyMember, true))
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED).addPcName(partyMember));
return false;
}
if (InstanceManager.getInstance().getPlayerWorld(player) != null)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON).addPcName(partyMember));
return false;
}
Long reentertime = InstanceManager.getInstance().getInstanceTime(partyMember.getObjectId(), TEMPLATE_ID);
final Long reentertime = InstanceManager.getInstance().getInstanceTime(partyMember.getObjectId(), TEMPLATE_ID);
if (System.currentTimeMillis() < reentertime)
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_RE_ENTER_YET);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_RE_ENTER_YET).addPcName(partyMember));
return false;
}
if (partyMember.getInventory().getInventoryItemCount(SEAL_BREAKER_5, -1, false) < 1)
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_QUEST_REQUIREMENT_IS_NOT_SUFFICIENT_AND_CANNOT_BE_ENTERED);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_S_QUEST_REQUIREMENT_IS_NOT_SUFFICIENT_AND_CANNOT_BE_ENTERED).addPcName(partyMember));
return false;
}
}
return true;
}
private void enterInstance(L2PcInstance player, String template)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (world instanceof DPFWorld)
if (player.getParty() == null)
{
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
return;
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
}
if (!checkTeleport(player))
{
return;
}
world = new DPFWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.addAllowed(player.getObjectId());
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
_log.info("Tower of Infinitum - Demon Prince floor started " + template + " Instance: " + world.getInstanceId() + " created by player: " + player.getName());
for (L2PcInstance partyMember : player.getParty().getMembers())
{
teleportPlayer(partyMember, ENTRY_POINT, world.getInstanceId());
partyMember.destroyItemByItemId("Quest", SEAL_BREAKER_5, 1, null, true);
world.addAllowed(partyMember.getObjectId());
}
}
public void setReenterTime(InstanceWorld world)
{
if (world instanceof DPFWorld)
{
// Reenter time should be cleared every Wed and Sat at 6:30 AM, so we set next suitable
Calendar reenter;
Calendar now = Calendar.getInstance();
Calendar reenterPointWed = (Calendar) now.clone();
reenterPointWed.set(Calendar.AM_PM, Calendar.AM);
reenterPointWed.set(Calendar.MINUTE, RESET_MIN);
reenterPointWed.set(Calendar.HOUR_OF_DAY, RESET_HOUR);
reenterPointWed.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
Calendar reenterPointSat = (Calendar) reenterPointWed.clone();
reenterPointSat.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
if (now.after(reenterPointSat))
{
reenterPointWed.add(Calendar.WEEK_OF_MONTH, 1);
reenter = (Calendar) reenterPointWed.clone();
player.destroyItemByItemId("Quest", SEAL_BREAKER_5, 1, null, true);
world.addAllowed(player.getObjectId());
}
else
{
reenter = (Calendar) reenterPointSat.clone();
}
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_S_ENTRY_HAS_BEEN_RESTRICTED_YOU_CAN_CHECK_THE_NEXT_POSSIBLE_ENTRY_TIME_BY_USING_THE_COMMAND_INSTANCEZONE);
sm.addInstanceName(world.getTemplateId());
// set instance reenter time for all allowed players
for (int objectId : world.getAllowed())
{
L2PcInstance player = L2World.getInstance().getPlayer(objectId);
if ((player != null) && player.isOnline())
for (L2PcInstance partyMember : player.getParty().getMembers())
{
InstanceManager.getInstance().setInstanceTime(objectId, world.getTemplateId(), reenter.getTimeInMillis());
player.sendPacket(sm);
teleportPlayer(partyMember, ENTRY_POINT, world.getInstanceId());
partyMember.destroyItemByItemId("Quest", SEAL_BREAKER_5, 1, null, true);
world.addAllowed(partyMember.getObjectId());
}
}
}
else
{
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
}
}
}
}

View File

@ -18,14 +18,12 @@
*/
package hellbound.Instances.RankuFloor;
import java.util.Calendar;
import ai.npc.AbstractNpcAI;
import instances.AbstractInstance;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Instance;
@ -38,7 +36,7 @@ import com.l2jserver.gameserver.util.Util;
* Tower of Infinitum (10th Floor) instance zone.
* @author GKR
*/
public final class RankuFloor extends AbstractNpcAI
public final class RankuFloor extends AbstractInstance
{
protected class RFWorld extends InstanceWorld
{
@ -51,20 +49,18 @@ public final class RankuFloor extends AbstractNpcAI
private static final int RANKU = 25542;
// Item
private static final int SEAL_BREAKER_10 = 15516;
// Misc
private static final int TEMPLATE_ID = 143;
private static final int RESET_HOUR = 6;
private static final int RESET_MIN = 30;
// Locations
private static final Location ENTRY_POINT = new Location(-19008, 277024, -15000);
private static final Location EXIT_POINT = new Location(-19008, 277122, -13376);
// Misc
private static final int TEMPLATE_ID = 143;
private static final int MIN_LV = 78;
public RankuFloor()
{
super(RankuFloor.class.getSimpleName(), "hellbound/Instances");
addStartNpc(GK_9);
addStartNpc(CUBE);
addTalkId(GK_9);
addTalkId(CUBE);
addStartNpc(GK_9, CUBE);
addTalkId(GK_9, CUBE);
addKillId(RANKU);
}
@ -75,11 +71,21 @@ public final class RankuFloor extends AbstractNpcAI
if (npc.getId() == GK_9)
{
htmltext = checkConditions(player);
if (!player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
if (player.getParty() == null)
{
htmltext = "gk-noparty.htm";
}
else if (!player.getParty().isLeader(player))
{
htmltext = "gk-noleader.htm";
}
}
if (htmltext == null)
{
enterInstance(player, "Ranku.xml");
enterInstance(player, new RFWorld(), "Ranku.xml", TEMPLATE_ID);
}
}
else if (npc.getId() == CUBE)
@ -87,7 +93,6 @@ public final class RankuFloor extends AbstractNpcAI
final InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
if (world instanceof RFWorld)
{
world.removeAllowed(player.getObjectId());
teleportPlayer(player, EXIT_POINT, 0);
}
}
@ -97,55 +102,29 @@ public final class RankuFloor extends AbstractNpcAI
@Override
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
{
int instanceId = npc.getInstanceId();
final int instanceId = npc.getInstanceId();
if (instanceId > 0)
{
Instance inst = InstanceManager.getInstance().getInstance(instanceId);
InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
final InstanceWorld world = InstanceManager.getInstance().getWorld(npc.getInstanceId());
inst.setSpawnLoc(EXIT_POINT);
// Terminate instance in 10 min
if ((inst.getInstanceEndTime() - System.currentTimeMillis()) > 600000)
{
inst.setDuration(600000);
}
inst.setEmptyDestroyTime(0);
if (world instanceof RFWorld)
{
setReenterTime(world);
}
finishInstance(world);
addSpawn(CUBE, -19056, 278732, -15000, 0, false, 0, false, instanceId);
}
return super.onKill(npc, killer, isSummon);
}
private String checkConditions(L2PcInstance player)
@Override
protected boolean checkConditions(L2PcInstance player)
{
if (player.getParty() == null)
if (player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
return "gk-noparty.htm";
}
else if (player.getParty().getLeaderObjectId() != player.getObjectId())
{
return "gk-noleader.htm";
return true;
}
return null;
}
private boolean checkTeleport(L2PcInstance player)
{
final L2Party party = player.getParty();
if (party == null)
{
return false;
}
if (!party.isLeader(player))
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return false;
@ -153,125 +132,64 @@ public final class RankuFloor extends AbstractNpcAI
for (L2PcInstance partyMember : party.getMembers())
{
if (partyMember.getLevel() < 78)
if (partyMember.getLevel() < MIN_LV)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY).addPcName(partyMember));
return false;
}
if (!Util.checkIfInRange(500, player, partyMember, true))
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED).addPcName(partyMember));
return false;
}
if (InstanceManager.getInstance().getPlayerWorld(player) != null)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON).addPcName(partyMember));
return false;
}
final Long reenterTime = InstanceManager.getInstance().getInstanceTime(partyMember.getObjectId(), TEMPLATE_ID);
if (System.currentTimeMillis() < reenterTime)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_RE_ENTER_YET);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_RE_ENTER_YET).addPcName(partyMember));
return false;
}
if (partyMember.getInventory().getInventoryItemCount(SEAL_BREAKER_10, -1, false) < 1)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_QUEST_REQUIREMENT_IS_NOT_SUFFICIENT_AND_CANNOT_BE_ENTERED);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_S_QUEST_REQUIREMENT_IS_NOT_SUFFICIENT_AND_CANNOT_BE_ENTERED).addPcName(partyMember));
return false;
}
}
return true;
}
private void enterInstance(L2PcInstance player, String template)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (world instanceof RFWorld)
if (player.getParty() == null)
{
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
return;
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
}
if (!checkTeleport(player))
{
return;
}
world = new RFWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.addAllowed(player.getObjectId());
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
_log.info("Tower of Infinitum - Ranku floor started " + template + " Instance: " + world.getInstanceId() + " created by player: " + player.getName());
for (L2PcInstance partyMember : player.getParty().getMembers())
{
teleportPlayer(partyMember, ENTRY_POINT, world.getInstanceId());
partyMember.destroyItemByItemId("Quest", SEAL_BREAKER_10, 1, null, true);
world.addAllowed(partyMember.getObjectId());
}
}
public void setReenterTime(InstanceWorld world)
{
if (world instanceof RFWorld)
{
// Reenter time should be cleared every Wed and Sat at 6:30 AM, so we set next suitable
Calendar reenter;
Calendar now = Calendar.getInstance();
Calendar reenterPointWed = (Calendar) now.clone();
reenterPointWed.set(Calendar.AM_PM, Calendar.AM);
reenterPointWed.set(Calendar.MINUTE, RESET_MIN);
reenterPointWed.set(Calendar.HOUR_OF_DAY, RESET_HOUR);
reenterPointWed.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
Calendar reenterPointSat = (Calendar) reenterPointWed.clone();
reenterPointSat.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
if (now.after(reenterPointSat))
{
reenterPointWed.add(Calendar.WEEK_OF_MONTH, 1);
reenter = (Calendar) reenterPointWed.clone();
player.destroyItemByItemId("Quest", SEAL_BREAKER_10, 1, null, true);
world.addAllowed(player.getObjectId());
}
else
{
reenter = (Calendar) reenterPointSat.clone();
}
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_S_ENTRY_HAS_BEEN_RESTRICTED_YOU_CAN_CHECK_THE_NEXT_POSSIBLE_ENTRY_TIME_BY_USING_THE_COMMAND_INSTANCEZONE);
sm.addInstanceName(world.getTemplateId());
// set instance reenter time for all allowed players
for (int objectId : world.getAllowed())
{
L2PcInstance player = L2World.getInstance().getPlayer(objectId);
if ((player != null) && player.isOnline())
for (L2PcInstance partyMember : player.getParty().getMembers())
{
InstanceManager.getInstance().setInstanceTime(objectId, world.getTemplateId(), reenter.getTimeInMillis());
player.sendPacket(sm);
teleportPlayer(partyMember, ENTRY_POINT, world.getInstanceId());
partyMember.destroyItemByItemId("Quest", SEAL_BREAKER_10, 1, null, true);
world.addAllowed(partyMember.getObjectId());
}
}
}
else
{
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
}
}
}
}

View File

@ -19,15 +19,15 @@
package hellbound.Instances.UrbanArea;
import hellbound.HellboundEngine;
import instances.AbstractInstance;
import java.util.concurrent.ScheduledFuture;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@ -47,15 +47,33 @@ import com.l2jserver.gameserver.util.Util;
* Urban Area instance zone.
* @author GKR
*/
public final class UrbanArea extends AbstractNpcAI
public final class UrbanArea extends AbstractInstance
{
protected class UrbanAreaWorld extends InstanceWorld
{
protected L2MonsterInstance spawnedAmaskari;
protected ScheduledFuture<?> activeAmaskariCall = null;
public boolean isAmaskariDead = false;
protected boolean isAmaskariDead = false;
}
// NPCs
private static final int TOMBSTONE = 32343;
private static final int KANAF = 32346;
private static final int KEYMASTER = 22361;
private static final int AMASKARI = 22449;
private static final int DOWNTOWN_NATIVE = 32358;
private static final int TOWN_GUARD = 22359;
private static final int TOWN_PATROL = 22360;
// Items
private static final int KEY = 9714;
// Skills
private static final SkillHolder STONE = new SkillHolder(4616, 1);
// Locations
private static final Location AMASKARI_SPAWN_POINT = new Location(19424, 253360, -2032, 16860);
private static final Location ENTRY_POINT = new Location(14117, 255434, -2016);
protected static final Location EXIT_POINT = new Location(16262, 283651, -9700);
// Misc
private static final int MIN_LV = 78;
private static final int TEMPLATE_ID = 2;
private static final NpcStringId[] NPCSTRING_ID =
@ -71,35 +89,16 @@ public final class UrbanArea extends AbstractNpcAI
NpcStringId.NOW_I_CAN_ESCAPE_ON_MY_OWN
};
private static final int TOMBSTONE = 32343;
private static final int KANAF = 32346;
private static final int KEYMASTER = 22361;
private static final int AMASKARI = 22449;
private static final int DOWNTOWN_NATIVE = 32358;
private static final int TOWN_GUARD = 22359;
private static final int TOWN_PATROL = 22360;
private static final Location AMASKARI_SPAWN_POINT = new Location(19424, 253360, -2032, 16860);
private static final Location ENTRY_POINT = new Location(14117, 255434, -2016);
protected static final Location EXIT_POINT = new Location(16262, 283651, -9700);
private static final SkillHolder STONE = new SkillHolder(4616, 1);
private static final int KEY = 9714;
public UrbanArea()
{
super(UrbanArea.class.getSimpleName(), "hellbound/Instances");
addFirstTalkId(DOWNTOWN_NATIVE);
addStartNpc(KANAF);
addStartNpc(DOWNTOWN_NATIVE);
addTalkId(KANAF);
addTalkId(DOWNTOWN_NATIVE);
addAttackId(TOWN_GUARD);
addAttackId(KEYMASTER);
addStartNpc(KANAF, DOWNTOWN_NATIVE);
addTalkId(KANAF, DOWNTOWN_NATIVE);
addAttackId(TOWN_GUARD, KEYMASTER);
addAggroRangeEnterId(TOWN_GUARD);
addKillId(AMASKARI);
addSpawnId(DOWNTOWN_NATIVE);
addSpawnId(TOWN_GUARD);
addSpawnId(TOWN_PATROL);
addSpawnId(KEYMASTER);
addSpawnId(DOWNTOWN_NATIVE, TOWN_GUARD, TOWN_PATROL, KEYMASTER);
}
@Override
@ -118,16 +117,27 @@ public final class UrbanArea extends AbstractNpcAI
String htmltext = null;
if (npc.getId() == KANAF)
{
htmltext = checkConditions(player);
if (!player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
if (HellboundEngine.getInstance().getLevel() < 10)
{
htmltext = "32346-lvl.htm";
}
if (player.getParty() == null)
{
htmltext = "32346-party.htm";
}
}
if (htmltext == null)
{
enterInstance(player, "UrbanArea.xml");
enterInstance(player, new UrbanAreaWorld(), "UrbanArea.xml", TEMPLATE_ID);
}
}
else if (npc.getId() == TOMBSTONE)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
if ((tmpworld != null) && (tmpworld instanceof UrbanAreaWorld))
{
final UrbanAreaWorld world = (UrbanAreaWorld) tmpworld;
@ -156,7 +166,7 @@ public final class UrbanArea extends AbstractNpcAI
{
npc.setBusy(true);
// destroy instance after 5 min
Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
inst.setDuration(5 * 60000);
inst.setEmptyDestroyTime(0);
ThreadPoolManager.getInstance().scheduleGeneral(new ExitInstance(party, world), 285000);
@ -190,8 +200,8 @@ public final class UrbanArea extends AbstractNpcAI
{
if (!npc.isAffectedBySkill(STONE.getSkillId()) || world.isAmaskariDead)
{
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NATIVES_NPCSTRING_ID[0]));
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NATIVES_NPCSTRING_ID[2]));
broadcastNpcSay(npc, Say2.NPC_ALL, NATIVES_NPCSTRING_ID[0]);
broadcastNpcSay(npc, Say2.NPC_ALL, NATIVES_NPCSTRING_ID[2]);
}
else
{
@ -201,8 +211,8 @@ public final class UrbanArea extends AbstractNpcAI
npc.stopSkillEffects(false, STONE.getSkillId());
}
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NATIVES_NPCSTRING_ID[0]));
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NATIVES_NPCSTRING_ID[1]));
broadcastNpcSay(npc, Say2.NPC_ALL, NATIVES_NPCSTRING_ID[0]);
broadcastNpcSay(npc, Say2.NPC_ALL, NATIVES_NPCSTRING_ID[1]);
HellboundEngine.getInstance().updateTrust(10, true);
npc.scheduleDespawn(3000);
// Try to call Amaskari
@ -219,7 +229,7 @@ public final class UrbanArea extends AbstractNpcAI
}
}
}
return null;
return super.onAdvEvent(event, npc, player);
}
@Override
@ -237,21 +247,20 @@ public final class UrbanArea extends AbstractNpcAI
npc.setBusy(false);
npc.setBusyMessage("");
}
return super.onSpawn(npc);
}
@Override
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
if ((tmpworld != null) && (tmpworld instanceof UrbanAreaWorld))
{
UrbanAreaWorld world = (UrbanAreaWorld) tmpworld;
final UrbanAreaWorld world = (UrbanAreaWorld) tmpworld;
if (!npc.isBusy())
{
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NPCSTRING_ID[0]));
broadcastNpcSay(npc, Say2.NPC_ALL, NPCSTRING_ID[0]);
npc.setBusy(true);
if ((world.spawnedAmaskari != null) && !world.spawnedAmaskari.isDead() && (getRandom(1000) < 25) && Util.checkIfInRange(1000, npc, world.spawnedAmaskari, false))
@ -260,7 +269,6 @@ public final class UrbanArea extends AbstractNpcAI
{
world.activeAmaskariCall.cancel(true);
}
world.activeAmaskariCall = ThreadPoolManager.getInstance().scheduleGeneral(new CallAmaskari(npc), 25000);
}
}
@ -271,10 +279,10 @@ public final class UrbanArea extends AbstractNpcAI
@Override
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
if ((tmpworld != null) && (tmpworld instanceof UrbanAreaWorld))
{
UrbanAreaWorld world = (UrbanAreaWorld) tmpworld;
final UrbanAreaWorld world = (UrbanAreaWorld) tmpworld;
if (!world.isAmaskariDead && !(npc.getBusyMessage().equalsIgnoreCase("atk") || npc.isBusy()))
{
@ -296,7 +304,7 @@ public final class UrbanArea extends AbstractNpcAI
}
if (msgId >= 0)
{
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NPCSTRING_ID[msgId]));
broadcastNpcSay(npc, Say2.NPC_ALL, NPCSTRING_ID[msgId], range);
}
npc.setBusy(true);
npc.setBusyMessage("atk");
@ -307,7 +315,6 @@ public final class UrbanArea extends AbstractNpcAI
{
world.activeAmaskariCall.cancel(true);
}
world.activeAmaskariCall = ThreadPoolManager.getInstance().scheduleGeneral(new CallAmaskari(npc), 25000);
}
}
@ -318,7 +325,7 @@ public final class UrbanArea extends AbstractNpcAI
@Override
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
if ((tmpworld != null) && (tmpworld instanceof UrbanAreaWorld))
{
UrbanAreaWorld world = (UrbanAreaWorld) tmpworld;
@ -327,30 +334,17 @@ public final class UrbanArea extends AbstractNpcAI
return super.onKill(npc, killer, isSummon);
}
private String checkConditions(L2PcInstance player)
@Override
protected boolean checkConditions(L2PcInstance player)
{
if (HellboundEngine.getInstance().getLevel() < 10)
if (player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
return "32346-lvl.htm";
return true;
}
if (player.getParty() == null)
{
return "32346-party.htm";
}
return null;
}
private boolean checkTeleport(L2PcInstance player)
{
final L2Party party = player.getParty();
if (party == null)
{
return false;
}
if (!party.isLeader(player))
if ((party == null) || !party.isLeader(player))
{
player.sendPacket(SystemMessageId.ONLY_A_PARTY_LEADER_CAN_MAKE_THE_REQUEST_TO_ENTER);
return false;
@ -358,70 +352,51 @@ public final class UrbanArea extends AbstractNpcAI
for (L2PcInstance partyMember : party.getMembers())
{
if (partyMember.getLevel() < 78)
if (partyMember.getLevel() < MIN_LV)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY).addPcName(partyMember));
return false;
}
if (!Util.checkIfInRange(1000, player, partyMember, true))
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED).addPcName(partyMember));
return false;
}
if (InstanceManager.getInstance().getPlayerWorld(player) != null)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
sm.addPcName(partyMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON).addPcName(partyMember));
return false;
}
}
return true;
}
private void enterInstance(L2PcInstance player, String template)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (world instanceof UrbanAreaWorld)
if (player.getParty() == null)
{
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
return;
world.addAllowed(player.getObjectId());
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
else
{
for (L2PcInstance partyMember : player.getParty().getMembers())
{
teleportPlayer(partyMember, ENTRY_POINT, world.getInstanceId());
world.addAllowed(partyMember.getObjectId());
}
}
((UrbanAreaWorld) world).spawnedAmaskari = (L2MonsterInstance) addSpawn(AMASKARI, AMASKARI_SPAWN_POINT, false, 0, false, world.getInstanceId());
}
if (!checkTeleport(player))
else
{
return;
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
}
world = new UrbanAreaWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.addAllowed(player.getObjectId());
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
teleportPlayer(player, ENTRY_POINT, world.getInstanceId());
_log.info("Hellbound Town started " + template + " Instance: " + world.getInstanceId() + " created by player: " + player.getName());
for (L2PcInstance partyMember : player.getParty().getMembers())
{
teleportPlayer(partyMember, ENTRY_POINT, world.getInstanceId());
world.addAllowed(partyMember.getObjectId());
}
((UrbanAreaWorld) world).spawnedAmaskari = (L2MonsterInstance) addSpawn(AMASKARI, AMASKARI_SPAWN_POINT, false, 0, false, world.getInstanceId());
}
private static class CallAmaskari implements Runnable

View File

@ -0,0 +1,329 @@
/*
* Copyright (C) 2004-2015 L2J DataPack
*
* This file is part of L2J DataPack.
*
* L2J DataPack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J DataPack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package instances;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Logger;
import ai.npc.AbstractNpcAI;
import com.l2jserver.Config;
import com.l2jserver.gameserver.enums.InstanceReenterType;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.model.holders.InstanceReenterTimeHolder;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.skills.BuffInfo;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
/**
* Abstract class for Instances.
* @author FallenAngel
*/
public abstract class AbstractInstance extends AbstractNpcAI
{
public final Logger _log = Logger.getLogger(getClass().getSimpleName());
public AbstractInstance(String name, String desc)
{
super(name, desc);
}
public AbstractInstance(String name)
{
super(name, "instances");
}
protected void enterInstance(L2PcInstance player, InstanceWorld instance, String template, int templateId)
{
final InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
{
if (world.getTemplateId() == templateId)
{
onEnterInstance(player, world, false);
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
if (inst.isRemoveBuffEnabled())
{
handleRemoveBuffs(player, world);
}
return;
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
}
if (checkConditions(player))
{
instance.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
instance.setTemplateId(templateId);
instance.setStatus(0);
InstanceManager.getInstance().addWorld(instance);
onEnterInstance(player, instance, true);
final Instance inst = InstanceManager.getInstance().getInstance(instance.getInstanceId());
if (inst.getReenterType() == InstanceReenterType.ON_INSTANCE_ENTER)
{
handleReenterTime(instance);
}
if (inst.isRemoveBuffEnabled())
{
handleRemoveBuffs(instance);
}
if (Config.DEBUG_INSTANCES)
{
_log.info("Instance " + inst.getName() + " (" + instance.getTemplateId() + ") has been created by player " + player.getName());
}
}
}
protected void finishInstance(InstanceWorld world)
{
finishInstance(world, Config.INSTANCE_FINISH_TIME);
}
protected void finishInstance(InstanceWorld world, int duration)
{
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
if (inst.getReenterType() == InstanceReenterType.ON_INSTANCE_FINISH)
{
handleReenterTime(world);
}
if (duration == 0)
{
InstanceManager.getInstance().destroyInstance(inst.getId());
}
else if (duration > 0)
{
inst.setDuration(duration);
inst.setEmptyDestroyTime(0);
}
}
protected void handleReenterTime(InstanceWorld world)
{
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
final List<InstanceReenterTimeHolder> reenterData = inst.getReenterData();
long time = -1;
for (InstanceReenterTimeHolder data : reenterData)
{
if (data.getTime() > 0)
{
time = System.currentTimeMillis() + data.getTime();
break;
}
final Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.AM_PM, data.getHour() >= 12 ? 1 : 0);
calendar.set(Calendar.HOUR, data.getHour());
calendar.set(Calendar.MINUTE, data.getMinute());
calendar.set(Calendar.SECOND, 0);
if (calendar.getTimeInMillis() <= System.currentTimeMillis())
{
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
if (data.getDay() != null)
{
while (calendar.get(Calendar.DAY_OF_WEEK) != (data.getDay().getValue() + 1))
{
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
}
if (time == -1)
{
time = calendar.getTimeInMillis();
}
else if (calendar.getTimeInMillis() < time)
{
time = calendar.getTimeInMillis();
}
}
if (time > 0)
{
setReenterTime(world, time);
}
}
protected void handleRemoveBuffs(InstanceWorld world)
{
for (Integer objId : world.getAllowed())
{
final L2PcInstance player = L2World.getInstance().getPlayer(objId);
if (player != null)
{
handleRemoveBuffs(player, world);
}
}
}
protected abstract void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance);
protected boolean checkConditions(L2PcInstance player)
{
return true;
}
/**
* Spawns group of instance NPC's
* @param groupName - name of group from XML definition to spawn
* @param instanceId - ID of instance
* @return list of spawned NPC's
*/
protected List<L2Npc> spawnGroup(String groupName, int instanceId)
{
return InstanceManager.getInstance().getInstance(instanceId).spawnGroup(groupName);
}
/**
* Save Reenter time for every player in InstanceWorld.
* @param world - the InstanceWorld
* @param time - Time in miliseconds
*/
protected void setReenterTime(InstanceWorld world, long time)
{
for (int objectId : world.getAllowed())
{
InstanceManager.getInstance().setInstanceTime(objectId, world.getTemplateId(), time);
final L2PcInstance player = L2World.getInstance().getPlayer(objectId);
if ((player != null) && player.isOnline())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_S_ENTRY_HAS_BEEN_RESTRICTED_YOU_CAN_CHECK_THE_NEXT_POSSIBLE_ENTRY_TIME_BY_USING_THE_COMMAND_INSTANCEZONE).addString(InstanceManager.getInstance().getInstance(world.getInstanceId()).getName()));
}
}
if (Config.DEBUG_INSTANCES)
{
_log.info("Time restrictions has been set for player in instance ID: " + world.getInstanceId() + " (" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time) + ")");
}
}
private void handleRemoveBuffs(L2PcInstance player, InstanceWorld world)
{
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
final List<BuffInfo> buffToRemove = new ArrayList<>();
switch (inst.getRemoveBuffType())
{
case ALL:
{
final L2Summon pet = player.getPet();
if (pet != null)
{
pet.stopAllEffectsExceptThoseThatLastThroughDeath();
}
player.getServitors().values().forEach(L2Summon::stopAllEffectsExceptThoseThatLastThroughDeath);
break;
}
case WHITELIST:
{
for (BuffInfo info : player.getEffectList().getBuffs().values())
{
if (!inst.getBuffExceptionList().contains(info.getSkill().getId()))
{
buffToRemove.add(info);
}
}
for (L2Summon summon : player.getServitors().values())
{
for (BuffInfo info : summon.getEffectList().getBuffs().values())
{
if (!inst.getBuffExceptionList().contains(info.getSkill().getId()))
{
buffToRemove.add(info);
}
}
}
final L2Summon pet = player.getPet();
if (pet != null)
{
for (BuffInfo info : pet.getEffectList().getBuffs().values())
{
if (!inst.getBuffExceptionList().contains(info.getSkill().getId()))
{
buffToRemove.add(info);
}
}
}
break;
}
case BLACKLIST:
{
for (BuffInfo info : player.getEffectList().getBuffs().values())
{
if (inst.getBuffExceptionList().contains(info.getSkill().getId()))
{
buffToRemove.add(info);
}
}
for (L2Summon summon : player.getServitors().values())
{
for (BuffInfo info : summon.getEffectList().getBuffs().values())
{
if (inst.getBuffExceptionList().contains(info.getSkill().getId()))
{
buffToRemove.add(info);
}
}
}
final L2Summon pet = player.getPet();
if (pet != null)
{
for (BuffInfo info : pet.getEffectList().getBuffs().values())
{
if (inst.getBuffExceptionList().contains(info.getSkill().getId()))
{
buffToRemove.add(info);
}
}
}
break;
}
}
for (BuffInfo info : buffToRemove)
{
info.getEffected().getEffectList().stopSkillEffects(true, info.getSkill());
}
}
}

View File

@ -18,22 +18,18 @@
*/
package instances.CavernOfThePirateCaptain;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import instances.AbstractInstance;
import ai.npc.AbstractNpcAI;
import java.util.ArrayList;
import java.util.List;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.L2Attackable;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
@ -43,22 +39,21 @@ import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
* Cavern Of The Pirate Captain (Day Dream) instance Zone.
* @author St3eT
*/
public class CavernOfThePirateCaptain extends AbstractNpcAI
public final class CavernOfThePirateCaptain extends AbstractInstance
{
protected class CavernOfThePirateCaptainWorld extends InstanceWorld
{
List<L2PcInstance> playersInside = new ArrayList<>();
L2Attackable _zaken;
long storeTime = 0;
boolean _is83;
int _zakenRoom;
int _blueFounded;
protected List<L2PcInstance> playersInside = new ArrayList<>();
protected L2Attackable _zaken;
protected long storeTime = 0;
protected boolean _is83;
protected int _zakenRoom;
protected int _blueFounded;
}
// NPCs
private static final int PATHFINDER = 32713; // Pathfinder Worker
private static final int ZAKEN_60 = 29176; // Zaken
private static final int ZAKEN_60_NIGHT = 29022; // Zaken Night
private static final int ZAKEN_83 = 29181; // Zaken
private static final int CANDLE = 32705; // Zaken's Candle
private static final int DOLL_BLADER_60 = 29023; // Doll Blader
@ -72,9 +67,6 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
// Items
private static final int VORPAL_RING = 15763; // Sealed Vorpal Ring
private static final int VORPAL_EARRING = 15764; // Sealed Vorpal Earring
private static final int FIRE = 15280; // Transparent 1HS (for NPC)
private static final int RED = 15281; // Transparent 1HS (for NPC)
private static final int BLUE = 15302; // Transparent Bow (for NPC)
// Locations
private static final Location[] ENTER_LOC =
{
@ -129,19 +121,10 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
private static final int MIN_LV_83 = 78;
private static final int PLAYERS_60_MIN = 9;
private static final int PLAYERS_60_MAX = 27;
private static final int PLAYERS_60_NIGHT_MIN = 72;
private static final int PLAYERS_60_NIGHT_MAX = 450;
private static final int PLAYERS_83_MIN = 9;
private static final int PLAYERS_83_MAX = 27;
private static final int TEMPLATE_ID_60 = 133;
private static final int TEMPLATE_ID_60_NIGHT = 114;
private static final int TEMPLATE_ID_83 = 135;
private static final int HOURS = 6;
private static final int MINUTES = 30;
private static final int DAY_A = Calendar.MONDAY;
private static final int DAY_B = Calendar.WEDNESDAY;
private static final int DAY_C = Calendar.FRIDAY;
private static boolean isNight = false;
//@formatter:off
private static final int[][] ROOM_DATA =
{
@ -166,39 +149,22 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
};
//@formatter:on
private CavernOfThePirateCaptain()
public CavernOfThePirateCaptain()
{
super(CavernOfThePirateCaptain.class.getSimpleName(), "instances");
super(CavernOfThePirateCaptain.class.getSimpleName());
addStartNpc(PATHFINDER);
addTalkId(PATHFINDER);
addKillId(ZAKEN_60, ZAKEN_60_NIGHT, ZAKEN_83);
addKillId(ZAKEN_60, ZAKEN_83);
addFirstTalkId(CANDLE);
}
private void enterInstance(L2PcInstance player, String template, boolean is83)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (world instanceof CavernOfThePirateCaptainWorld)
{
teleportPlayer(player, ENTER_LOC[getRandom(ENTER_LOC.length)], world.getInstanceId(), false);
return;
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
}
if (checkConditions(player, is83))
{
world = new CavernOfThePirateCaptainWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(is83 ? TEMPLATE_ID_83 : (isNight ? TEMPLATE_ID_60_NIGHT : TEMPLATE_ID_60));
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
final CavernOfThePirateCaptainWorld curworld = (CavernOfThePirateCaptainWorld) world;
curworld._is83 = is83;
curworld._is83 = curworld.getTemplateId() == TEMPLATE_ID_83;
curworld.storeTime = System.currentTimeMillis();
if (!player.isInParty())
@ -221,26 +187,21 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
}
manageNpcSpawn(curworld);
}
else
{
teleportPlayer(player, ENTER_LOC[getRandom(ENTER_LOC.length)], world.getInstanceId(), false);
}
}
private void managePlayerEnter(L2PcInstance player, CavernOfThePirateCaptainWorld world)
{
if (!world._is83)
{
player.stopAllEffectsExceptThoseThatLastThroughDeath();
final L2Summon pet = player.getPet();
if (pet != null)
{
pet.stopAllEffectsExceptThoseThatLastThroughDeath();
}
player.getServitors().values().forEach(L2Summon::stopAllEffectsExceptThoseThatLastThroughDeath);
}
world.playersInside.add(player);
world.addAllowed(player.getObjectId());
teleportPlayer(player, ENTER_LOC[getRandom(ENTER_LOC.length)], world.getInstanceId(), false);
}
private boolean checkConditions(L2PcInstance player, boolean is83)
@Override
protected boolean checkConditions(L2PcInstance player)
{
if (player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
@ -253,6 +214,7 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
return false;
}
final boolean is83 = InstanceManager.getInstance().getPlayerWorld(player).getTemplateId() == TEMPLATE_ID_83 ? true : false;
final L2Party party = player.getParty();
final boolean isInCC = party.isInCommandChannel();
final List<L2PcInstance> members = (isInCC) ? party.getCommandChannel().getMembers() : party.getMembers();
@ -264,7 +226,7 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
return false;
}
if ((members.size() < (is83 ? PLAYERS_83_MIN : (isNight ? PLAYERS_60_NIGHT_MIN : PLAYERS_60_MIN))) || (members.size() > (is83 ? PLAYERS_83_MAX : (isNight ? PLAYERS_60_NIGHT_MAX : PLAYERS_60_MAX))))
if ((members.size() < (is83 ? PLAYERS_83_MIN : PLAYERS_60_MIN)) || (members.size() > (is83 ? PLAYERS_83_MAX : PLAYERS_60_MAX)))
{
broadcastSystemMessage(player, null, SystemMessageId.YOU_CANNOT_ENTER_DUE_TO_THE_PARTY_HAVING_EXCEEDED_THE_LIMIT, false);
return false;
@ -284,7 +246,7 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
return false;
}
final Long reentertime = InstanceManager.getInstance().getInstanceTime(groupMembers.getObjectId(), (is83 ? TEMPLATE_ID_83 : (isNight ? TEMPLATE_ID_60_NIGHT : TEMPLATE_ID_60)));
final Long reentertime = InstanceManager.getInstance().getInstanceTime(groupMembers.getObjectId(), (is83 ? TEMPLATE_ID_83 : TEMPLATE_ID_60));
if (System.currentTimeMillis() < reentertime)
{
broadcastSystemMessage(player, groupMembers, SystemMessageId.C1_MAY_NOT_RE_ENTER_YET, true);
@ -322,16 +284,11 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
{
if (event.equals("enter60"))
{
enterInstance(player, "CavernOfThePirateCaptainWorldDay60.xml", false);
}
else if (event.equals("enter60night"))
{
isNight = true;
enterInstance(player, "CavernOfThePirateCaptainWorldNight60.xml", false);
enterInstance(player, new CavernOfThePirateCaptainWorld(), "CavernOfThePirateCaptainWorldDay60.xml", TEMPLATE_ID_60);
}
else if (event.equals("enter83"))
{
enterInstance(player, "CavernOfThePirateCaptainWorldDay83.xml", true);
enterInstance(player, new CavernOfThePirateCaptainWorld(), "CavernOfThePirateCaptainWorldDay83.xml", TEMPLATE_ID_83);
}
else
{
@ -345,9 +302,9 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
{
case "BURN_BLUE":
{
if (npc.getRightHandItem() == 0)
if (npc.isState(0))
{
npc.setRHandId(FIRE);
npc.setState(1); // Burning
startQuestTimer("BURN_BLUE2", 3000, npc, player);
if (world._blueFounded == 4)
{
@ -358,27 +315,27 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
}
case "BURN_BLUE2":
{
if (npc.getRightHandItem() == FIRE)
if (npc.isState(1)) // Burning
{
npc.setRHandId(BLUE);
npc.setState(3); // Blue glow
}
break;
}
case "BURN_RED":
{
if (npc.getRightHandItem() == 0)
if (npc.isState(0))
{
npc.setRHandId(FIRE);
npc.setState(1); // Burning
startQuestTimer("BURN_RED2", 3000, npc, player);
}
break;
}
case "BURN_RED2":
{
if (npc.getRightHandItem() == FIRE)
if (npc.isState(1)) // Burning
{
final int room = getRoomByCandle(npc);
npc.setRHandId(RED);
npc.setState(2); // Red glow
manageScreenMsg(world, NpcStringId.THE_CANDLES_CAN_LEAD_YOU_TO_ZAKEN_DESTROY_HIM);
spawnNpc(world._is83 ? DOLL_BLADER_83 : DOLL_BLADER_60, room, player, world);
spawnNpc(world._is83 ? VALE_MASTER_83 : VALE_MASTER_60, room, player, world);
@ -414,7 +371,6 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
if ((tmpworld != null) && (tmpworld instanceof CavernOfThePirateCaptainWorld))
{
final CavernOfThePirateCaptainWorld world = (CavernOfThePirateCaptainWorld) tmpworld;
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
if (npc.getId() == ZAKEN_83)
{
@ -447,9 +403,7 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
}
}
}
saveReenterForPlayers(world);
inst.setDuration(300000);
inst.setEmptyDestroyTime(0);
finishInstance(world);
}
return super.onKill(npc, killer, isSummon);
}
@ -514,14 +468,14 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
{
if ((players != null) && (players.getInstanceId() == world.getInstanceId()))
{
showOnScreenMsg(players, stringId, 2, 6000);
showOnScreenMsg(players, stringId, 5, 6000);
}
}
}
private L2Attackable spawnNpc(int npcId, int roomId, L2PcInstance player, CavernOfThePirateCaptainWorld world)
{
if ((player != null) && (npcId != ZAKEN_60) && (npcId != ZAKEN_60_NIGHT) && (npcId != ZAKEN_83))
if ((player != null) && (npcId != ZAKEN_60) && (npcId != ZAKEN_83))
{
final L2Attackable mob = (L2Attackable) addSpawn(npcId, ROOM_DATA[roomId - 1][0] + getRandom(350), ROOM_DATA[roomId - 1][1] + getRandom(350), ROOM_DATA[roomId - 1][2], 0, false, 0, false, world.getInstanceId());
addAttackPlayerDesire(mob, player);
@ -546,60 +500,8 @@ public class CavernOfThePirateCaptain extends AbstractNpcAI
{
candles.get(ROOM_DATA[world._zakenRoom - 1][i] - 1).getVariables().set("isBlue", 1);
}
world._zaken = spawnNpc(world._is83 ? ZAKEN_83 : (isNight ? ZAKEN_60_NIGHT : ZAKEN_60), world._zakenRoom, null, world);
world._zaken = spawnNpc(world._is83 ? ZAKEN_83 : ZAKEN_60, world._zakenRoom, null, world);
world._zaken.setInvisible(true);
world._zaken.setIsParalyzed(true);
}
private void saveReenterForPlayers(InstanceWorld world)
{
final Calendar reenter = Calendar.getInstance();
reenter.set(Calendar.MINUTE, MINUTES);
reenter.set(Calendar.HOUR_OF_DAY, HOURS);
if (reenter.getTimeInMillis() <= System.currentTimeMillis())
{
reenter.add(Calendar.DAY_OF_MONTH, 1);
}
if ((reenter.get(Calendar.DAY_OF_WEEK) <= DAY_A) || (reenter.get(Calendar.DAY_OF_WEEK) > DAY_C))
{
while (reenter.get(Calendar.DAY_OF_WEEK) != DAY_A)
{
reenter.add(Calendar.DAY_OF_MONTH, 1);
}
}
else if (reenter.get(Calendar.DAY_OF_WEEK) <= DAY_B)
{
while (reenter.get(Calendar.DAY_OF_WEEK) != DAY_B)
{
reenter.add(Calendar.DAY_OF_MONTH, 1);
}
}
else
{
while (reenter.get(Calendar.DAY_OF_WEEK) != DAY_C)
{
reenter.add(Calendar.DAY_OF_MONTH, 1);
}
}
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_S_ENTRY_HAS_BEEN_RESTRICTED_YOU_CAN_CHECK_THE_NEXT_POSSIBLE_ENTRY_TIME_BY_USING_THE_COMMAND_INSTANCEZONE);
sm.addString(InstanceManager.getInstance().getInstanceIdName(world.getTemplateId()));
for (int objectId : world.getAllowed())
{
final L2PcInstance player = L2World.getInstance().getPlayer(objectId);
InstanceManager.getInstance().setInstanceTime(objectId, world.getTemplateId(), reenter.getTimeInMillis());
if ((player != null) && player.isOnline())
{
player.sendPacket(sm);
}
}
}
public static void main(String[] args)
{
new CavernOfThePirateCaptain();
}
}
}

View File

@ -18,6 +18,8 @@
*/
package instances.ChambersOfDelusion;
import instances.AbstractInstance;
import java.util.Calendar;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
@ -35,7 +37,6 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.NpcStringId;
@ -50,7 +51,7 @@ import com.l2jserver.gameserver.util.Util;
* Chambers of Delusion superclass.
* @author GKR
*/
public abstract class Chamber extends Quest
public abstract class Chamber extends AbstractInstance
{
protected class CDWorld extends InstanceWorld
{
@ -173,9 +174,9 @@ public abstract class Chamber extends Quest
// Misc
private static final String RETURN = Chamber.class.getSimpleName() + "_return";
protected Chamber(int questId, String name, String descr, int instanceId, String instanceTemplateName, int entranceGKId, int roomGKFirstId, int roomGKLastId, int aenkinelId, int boxId)
protected Chamber(String name, String descr, int instanceId, String instanceTemplateName, int entranceGKId, int roomGKFirstId, int roomGKLastId, int aenkinelId, int boxId)
{
super(questId, name, descr);
super(name, descr);
INSTANCEID = instanceId;
INSTANCE_TEMPLATE = instanceTemplateName;
@ -208,7 +209,8 @@ public abstract class Chamber extends Quest
return (world.currentRoom == (ROOM_ENTER_POINTS.length - 1));
}
private boolean checkConditions(L2PcInstance player)
@Override
protected boolean checkConditions(L2PcInstance player)
{
final L2Party party = player.getParty();
if (party == null)
@ -402,39 +404,18 @@ public abstract class Chamber extends Quest
}
}
protected int enterInstance(L2PcInstance player)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
int instanceId = 0;
// check for existing instances for this player
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
// existing instance
if (world != null)
if (firstEntrance)
{
enter((CDWorld) world);
}
else
{
if (!(world instanceof CDWorld))
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON));
return 0;
}
final CDWorld currentWorld = (CDWorld) world;
teleportPlayer(player, ROOM_ENTER_POINTS[currentWorld.currentRoom], world.getInstanceId());
return instanceId;
}
// New instance
if (!checkConditions(player))
{
return 0;
}
final L2Party party = player.getParty();
instanceId = InstanceManager.getInstance().createDynamicInstance(INSTANCE_TEMPLATE);
world = new CDWorld(party);
world.setInstanceId(instanceId);
world.setTemplateId(INSTANCEID);
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
_log.info("Chamber Of Delusion started " + INSTANCE_TEMPLATE + " Instance: " + instanceId + " created by player: " + player.getName());
enter((CDWorld) world);
return instanceId;
}
protected void exitInstance(L2PcInstance player)
@ -635,7 +616,6 @@ public abstract class Chamber extends Quest
{
npc.doDie(player);
}
return super.onSpellFinished(npc, player, skill);
}
@ -652,7 +632,11 @@ public abstract class Chamber extends Quest
if (npcId == ENTRANCE_GATEKEEPER)
{
enterInstance(player);
if (checkConditions(player))
{
final L2Party party = player.getParty();
enterInstance(player, new CDWorld(party), INSTANCE_TEMPLATE, INSTANCEID);
}
}
return "";

View File

@ -45,14 +45,9 @@ public final class ChamberOfDelusionEast extends Chamber
private static final int INSTANCEID = 127;
private static final String INSTANCE_TEMPLATE = "ChamberOfDelusionEast.xml";
private ChamberOfDelusionEast()
public ChamberOfDelusionEast()
{
super(-1, ChamberOfDelusionEast.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
super(ChamberOfDelusionEast.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
ROOM_ENTER_POINTS = ENTER_POINTS;
}
public static void main(String[] args)
{
new ChamberOfDelusionEast();
}
}

View File

@ -45,14 +45,9 @@ public final class ChamberOfDelusionNorth extends Chamber
private static final int INSTANCEID = 130; // this is the client number
private static final String INSTANCE_TEMPLATE = "ChamberOfDelusionNorth.xml";
private ChamberOfDelusionNorth()
public ChamberOfDelusionNorth()
{
super(-1, ChamberOfDelusionNorth.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
super(ChamberOfDelusionNorth.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
ROOM_ENTER_POINTS = ENTER_POINTS;
}
public static void main(String[] args)
{
new ChamberOfDelusionNorth();
}
}

View File

@ -45,14 +45,9 @@ public final class ChamberOfDelusionSouth extends Chamber
private static final int INSTANCEID = 129; // this is the client number
private static final String INSTANCE_TEMPLATE = "ChamberOfDelusionSouth.xml";
private ChamberOfDelusionSouth()
public ChamberOfDelusionSouth()
{
super(-1, ChamberOfDelusionSouth.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
super(ChamberOfDelusionSouth.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
ROOM_ENTER_POINTS = ENTER_POINTS;
}
public static void main(String[] args)
{
new ChamberOfDelusionSouth();
}
}

View File

@ -49,14 +49,9 @@ public final class ChamberOfDelusionSquare extends Chamber
private static final int INSTANCEID = 131;
private static final String INSTANCE_TEMPLATE = "ChamberOfDelusionSquare.xml";
private ChamberOfDelusionSquare()
public ChamberOfDelusionSquare()
{
super(-1, ChamberOfDelusionSquare.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
super(ChamberOfDelusionSquare.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
ROOM_ENTER_POINTS = ENTER_POINTS;
}
public static void main(String[] args)
{
new ChamberOfDelusionSquare();
}
}

View File

@ -49,14 +49,9 @@ public final class ChamberOfDelusionTower extends Chamber
private static final int INSTANCEID = 132; // this is the client number
private static final String INSTANCE_TEMPLATE = "ChamberOfDelusionTower.xml";
private ChamberOfDelusionTower()
public ChamberOfDelusionTower()
{
super(-1, ChamberOfDelusionTower.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
super(ChamberOfDelusionTower.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
ROOM_ENTER_POINTS = ENTER_POINTS;
}
public static void main(String[] args)
{
new ChamberOfDelusionTower();
}
}

View File

@ -45,14 +45,9 @@ public final class ChamberOfDelusionWest extends Chamber
private static final int INSTANCEID = 128; // this is the client number
private static final String INSTANCE_TEMPLATE = "ChamberOfDelusionWest.xml";
private ChamberOfDelusionWest()
public ChamberOfDelusionWest()
{
super(-1, ChamberOfDelusionWest.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
super(ChamberOfDelusionWest.class.getSimpleName(), "instances", INSTANCEID, INSTANCE_TEMPLATE, ENTRANCE_GATEKEEPER, ROOM_GATEKEEPER_FIRST, ROOM_GATEKEEPER_LAST, AENKINEL, BOX);
ROOM_ENTER_POINTS = ENTER_POINTS;
}
public static void main(String[] args)
{
new ChamberOfDelusionWest();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -18,17 +18,18 @@
*/
package instances.DarkCloudMansion;
import instances.AbstractInstance;
import javolution.util.FastList;
import javolution.util.FastMap;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
@ -40,15 +41,12 @@ import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
/**
* Dark Cloud Mansion instance zone.
*/
public final class DarkCloudMansion extends Quest
public final class DarkCloudMansion extends AbstractInstance
{
private static final int TEMPLATE_ID = 9;
private static boolean debug = false;
private static boolean noRndWalk = true;
// Items
private static int CC = 9690; // Contaminated Crystal
protected class DMCWorld extends InstanceWorld
{
protected FastMap<String, DMCRoom> rooms = new FastMap<>();
}
// NPCs
private static int YIYEN = 32282;
@ -58,7 +56,6 @@ public final class DarkCloudMansion extends Quest
private static int SOTruth = 32291; // Symbol of Truth
private static int BSM = 32324; // Black Stone Monolith
private static int SC = 22402; // Shadow Column
// Mobs
private static int[] CCG =
{
@ -106,7 +103,10 @@ public final class DarkCloudMansion extends Quest
22264
};
// Doors/Walls
// Items
private static int CC = 9690; // Contaminated Crystal
// Misc
private static final int TEMPLATE_ID = 9;
private static int D1 = 24230001; // Starting Room
private static int D2 = 24230002; // First Room
private static int D3 = 24230005; // Second Room
@ -120,7 +120,8 @@ public final class DarkCloudMansion extends Quest
// private static int W5 = 24230011; // Wall 5
// private static int W6 = 24230012; // Wall 6
// private static int W7 = 24230013; // Wall 7
private static boolean debug = false;
private static boolean noRndWalk = true;
private static NpcStringId[] _spawnChat =
{
NpcStringId.I_M_THE_REAL_ONE,
@ -129,14 +130,12 @@ public final class DarkCloudMansion extends Quest
NpcStringId.NOT_THAT_DUDE_I_M_THE_REAL_ONE,
NpcStringId.DON_T_BE_FOOLED_DON_T_BE_FOOLED_I_M_THE_REAL_ONE
};
private static NpcStringId[] _decayChat =
{
NpcStringId.I_M_THE_REAL_ONE_PHEW,
NpcStringId.CAN_T_YOU_EVEN_FIND_OUT,
NpcStringId.FIND_ME
};
private static NpcStringId[] _successChat =
{
NpcStringId.HUH_HOW_DID_YOU_KNOW_IT_WAS_ME,
@ -144,312 +143,74 @@ public final class DarkCloudMansion extends Quest
NpcStringId.YOU_VE_DONE_WELL,
NpcStringId.OH_VERY_SENSIBLE
};
private static NpcStringId[] _faildChat =
{
NpcStringId.YOU_VE_BEEN_FOOLED,
NpcStringId.SORRY_BUT_I_M_THE_FAKE_ONE
};
// @formatter:off
// Second room - random monolith order
private static int[][] MonolithOrder = new int[][]
{
{
1,
2,
3,
4,
5,
6
},
{
6,
5,
4,
3,
2,
1
},
{
4,
5,
6,
3,
2,
1
},
{
2,
6,
3,
5,
1,
4
},
{
4,
1,
5,
6,
2,
3
},
{
3,
5,
1,
6,
2,
4
},
{
6,
1,
3,
4,
5,
2
},
{
5,
6,
1,
2,
4,
3
},
{
5,
2,
6,
3,
4,
1
},
{
1,
5,
2,
6,
3,
4
},
{
1,
2,
3,
6,
5,
4
},
{
6,
4,
3,
1,
5,
2
},
{
3,
5,
2,
4,
1,
6
},
{
3,
2,
4,
5,
1,
6
},
{
5,
4,
3,
1,
6,
2
},
{1, 2, 3, 4, 5, 6},
{6, 5, 4, 3, 2, 1},
{4 ,5, 6, 3, 2, 1},
{2, 6, 3, 5, 1, 4},
{4, 1, 5, 6, 2, 3},
{3, 5, 1, 6, 2, 4},
{6, 1, 3, 4, 5, 2},
{5, 6, 1, 2, 4, 3},
{5, 2, 6, 3, 4, 1},
{1, 5, 2, 6, 3, 4},
{1, 2, 3, 6, 5, 4},
{6, 4, 3, 1, 5, 2},
{3, 5, 2, 4, 1, 6},
{3, 2, 4, 5, 1, 6},
{5, 4, 3, 1, 6, 2},
};
// Second room - golem spawn locatons - random
private static int[][] GolemSpawn = new int[][]
{
{
CCG[0],
148060,
181389
},
{
CCG[1],
147910,
181173
},
{
CCG[0],
147810,
181334
},
{
CCG[1],
147713,
181179
},
{
CCG[0],
147569,
181410
},
{
CCG[1],
147810,
181517
},
{
CCG[0],
147805,
181281
}
{CCG[0], 148060, 181389},
{CCG[1], 147910, 181173},
{CCG[0], 147810, 181334},
{CCG[1], 147713, 181179},
{CCG[0], 147569, 181410},
{CCG[1], 147810, 181517},
{CCG[0], 147805, 181281},
};
// forth room - random shadow column
private static int[][] ColumnRows = new int[][]
{
{
1,
1,
0,
1,
0
},
{
0,
1,
1,
0,
1
},
{
1,
0,
1,
1,
0
},
{
0,
1,
0,
1,
1
},
{
1,
0,
1,
0,
1
}
{1, 1, 0, 1, 0},
{0, 1, 1, 0, 1},
{1, 0, 1, 1, 0},
{0, 1, 0, 1, 1},
{1, 0, 1, 0, 1},
};
// Fifth room - beleth order
private static int[][] Beleths = new int[][]
{
{
1,
0,
1,
0,
1,
0,
0
},
{
0,
0,
1,
0,
1,
1,
0
},
{
0,
0,
0,
1,
0,
1,
1
},
{
1,
0,
1,
1,
0,
0,
0
},
{
1,
1,
0,
0,
0,
1,
0
},
{
0,
1,
0,
1,
0,
1,
0
},
{
0,
0,
0,
1,
1,
1,
0
},
{
1,
0,
1,
0,
0,
1,
0
},
{
0,
1,
1,
0,
0,
0,
1
}
{1, 0, 1, 0, 1, 0, 0},
{0, 0, 1, 0, 1, 1, 0},
{0, 0, 0, 1, 0, 1, 1},
{1, 0, 1, 1, 0, 0, 0},
{1, 1, 0, 0, 0, 1, 0},
{0, 1, 0, 1, 0, 1, 0},
{0, 0, 0, 1, 1, 1, 0},
{1, 0, 1, 0, 0, 1, 0},
{0, 1, 1, 0, 0, 0, 1},
};
// @formatter:on
private DarkCloudMansion()
public DarkCloudMansion()
{
super(-1, DarkCloudMansion.class.getSimpleName(), "instances");
addFirstTalkId(BSM);
addFirstTalkId(SOTruth);
super(DarkCloudMansion.class.getSimpleName());
addFirstTalkId(BSM, SOTruth);
addStartNpc(YIYEN);
addTalkId(YIYEN);
addTalkId(SOTruth);
addTalkId(YIYEN, SOTruth);
addAttackId(SC);
addAttackId(BS);
addAttackId(CCG);
@ -475,19 +236,15 @@ public final class DarkCloudMansion extends Quest
public int[] Order;
}
protected class DMCWorld extends InstanceWorld
@Override
protected boolean checkConditions(L2PcInstance player)
{
public FastMap<String, DMCRoom> rooms = new FastMap<>();
}
private boolean checkConditions(L2PcInstance player)
{
if (debug)
if (debug || player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
return true;
}
L2Party party = player.getParty();
final L2Party party = player.getParty();
if (party == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
@ -524,46 +281,34 @@ public final class DarkCloudMansion extends Quest
return true;
}
protected void enterInstance(L2PcInstance player, String template, Location loc)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (!(world instanceof DMCWorld))
runStartRoom((DMCWorld) world);
// teleport players
if (debug && (player.getParty() == null))
{
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
world.addAllowed(player.getObjectId());
teleportPlayer(player, new Location(146534, 180464, -6117), world.getInstanceId());
}
else
{
for (L2PcInstance partyMember : player.getParty().getMembers())
{
if (partyMember.getQuestState(getName()) == null)
{
newQuestState(partyMember);
}
world.addAllowed(partyMember.getObjectId());
teleportPlayer(partyMember, new Location(146534, 180464, -6117), world.getInstanceId());
}
}
teleportPlayer(player, loc, world.getInstanceId());
return;
}
if (!checkConditions(player))
{
return;
}
L2Party party = player.getParty();
final int instanceId = InstanceManager.getInstance().createDynamicInstance(template);
world = new DMCWorld();
world.setInstanceId(instanceId);
world.setTemplateId(TEMPLATE_ID);
InstanceManager.getInstance().addWorld(world);
_log.info("DarkCloudMansion: started " + template + " Instance: " + instanceId + " created by player: " + player.getName());
runStartRoom((DMCWorld) world);
// teleport players
if (debug && (party == null))
{
world.addAllowed(player.getObjectId());
teleportPlayer(player, loc, instanceId);
}
else
{
for (L2PcInstance partyMember : party.getMembers())
{
getQuestState(partyMember, true);
world.addAllowed(partyMember.getObjectId());
teleportPlayer(partyMember, loc, instanceId);
}
teleportPlayer(player, new Location(146534, 180464, -6117), world.getInstanceId());
}
}
@ -1200,8 +945,8 @@ public final class DarkCloudMansion extends Quest
return "";
}
InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
DMCWorld world;
final InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final DMCWorld world;
if (tmpworld instanceof DMCWorld)
{
world = (DMCWorld) tmpworld;
@ -1262,8 +1007,8 @@ public final class DarkCloudMansion extends Quest
@Override
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
DMCWorld world;
final InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final DMCWorld world;
if (tmpworld instanceof DMCWorld)
{
world = (DMCWorld) tmpworld;
@ -1336,15 +1081,14 @@ public final class DarkCloudMansion extends Quest
killedBelethSample(world, npc);
}
}
return "";
}
@Override
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon, Skill skill)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
DMCWorld world;
final InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
final DMCWorld world;
if (tmpworld instanceof DMCWorld)
{
world = (DMCWorld) tmpworld;
@ -1418,10 +1162,10 @@ public final class DarkCloudMansion extends Quest
@Override
public String onTalk(L2Npc npc, L2PcInstance player)
{
int npcId = npc.getId();
final int npcId = npc.getId();
if (npcId == YIYEN)
{
enterInstance(player, "DarkCloudMansion.xml", new Location(146534, 180464, -6117));
enterInstance(player, new DMCWorld(), "DarkCloudMansion.xml", TEMPLATE_ID);
}
else
{
@ -1458,9 +1202,4 @@ public final class DarkCloudMansion extends Quest
}
return "";
}
public static void main(String[] args)
{
new DarkCloudMansion();
}
}
}

View File

@ -18,6 +18,8 @@
*/
package instances.DisciplesNecropolisPast;
import instances.AbstractInstance;
import java.util.HashMap;
import java.util.Map;
@ -26,13 +28,10 @@ import quests.Q00196_SevenSignsSealOfTheEmperor.Q00196_SevenSignsSealOfTheEmpero
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.L2Summon;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
@ -44,18 +43,15 @@ import com.l2jserver.gameserver.util.Util;
* Disciple's Necropolis Past instance zone.
* @author Adry_85
*/
public final class DisciplesNecropolisPast extends Quest
public final class DisciplesNecropolisPast extends AbstractInstance
{
protected class DNPWorld extends InstanceWorld
{
protected final FastList<L2Npc> anakimGroup = new FastList<>();
protected final FastList<L2Npc> lilithGroup = new FastList<>();
protected long storeTime = 0;
protected int countKill = 0;
}
// Instance
private static final int TEMPLATE_ID = 112;
// NPCs
private static final int SEAL_DEVICE = 27384;
private static final int PROMISE_OF_MAMMON = 32585;
@ -69,20 +65,6 @@ public final class DisciplesNecropolisPast extends Quest
private static final int ANAKIMS_GUARDIAN = 32719;
private static final int ANAKIMS_GUARD = 32720;
private static final int ANAKIMS_EXECUTOR = 32721;
// Doors
private static final int DOOR_1 = 17240102;
private static final int DOOR_2 = 17240104;
private static final int DOOR_3 = 17240106;
private static final int DOOR_4 = 17240108;
private static final int DOOR_5 = 17240110;
private static final int DISCIPLES_NECROPOLIS_DOOR = 17240111;
// Items
private static final int SACRED_SWORD_OF_EINHASAD = 15310;
private static final int SEAL_OF_BINDING = 13846;
// Locations
private static final Location ENTER = new Location(-89554, 216078, -7488, 0, 0);
private static final Location EXIT = new Location(171895, -17501, -4903, 0, 0);
// Monsters
private static final int LILIM_BUTCHER = 27371;
private static final int LILIM_MAGUS = 27372;
private static final int LILIM_KNIGHT_ERRANT = 27373;
@ -92,28 +74,9 @@ public final class DisciplesNecropolisPast extends Quest
private static final int LILIM_SLAYER = 27377;
private static final int LILIM_GREAT_MAGUS = 27378;
private static final int LILIM_GUARD_KNIGHT = 27379;
// NpcStringId
private static final NpcStringId[] LILITH_SHOUT =
{
NpcStringId.HOW_DARE_YOU_TRY_TO_CONTEND_AGAINST_ME_IN_STRENGTH_RIDICULOUS,
NpcStringId.ANAKIM_IN_THE_NAME_OF_GREAT_SHILEN_I_WILL_CUT_YOUR_THROAT,
NpcStringId.YOU_CANNOT_BE_THE_MATCH_OF_LILITH_I_LL_TEACH_YOU_A_LESSON
};
// Bosses Spawn
private static final Map<Integer, Location> LILITH_SPAWN = new HashMap<>();
private static final Map<Integer, Location> ANAKIM_SPAWN = new HashMap<>();
static
{
LILITH_SPAWN.put(LILITH, new Location(-83175, 217021, -7504, 49151));
LILITH_SPAWN.put(LILITHS_STEWARD, new Location(-83327, 216938, -7492, 50768));
LILITH_SPAWN.put(LILITHS_ELITE, new Location(-83003, 216909, -7492, 4827));
ANAKIM_SPAWN.put(ANAKIM, new Location(-83179, 216479, -7504, 16384));
ANAKIM_SPAWN.put(ANAKIMS_GUARDIAN, new Location(-83321, 216507, -7492, 16166));
ANAKIM_SPAWN.put(ANAKIMS_GUARD, new Location(-83086, 216519, -7495, 15910));
ANAKIM_SPAWN.put(ANAKIMS_EXECUTOR, new Location(-83031, 216604, -7492, 17071));
}
// Items
private static final int SACRED_SWORD_OF_EINHASAD = 15310;
private static final int SEAL_OF_BINDING = 13846;
// Skills
private static final SkillHolder SEAL_ISOLATION = new SkillHolder(5980, 3);
private static final Map<Integer, SkillHolder> SKILLS = new HashMap<>();
@ -127,10 +90,40 @@ public final class DisciplesNecropolisPast extends Quest
SKILLS.put(32720, new SkillHolder(6194, 1)); // Presentation - Anakim's Guard Battle
SKILLS.put(32721, new SkillHolder(6195, 1)); // Presentation - Anakim's Executor Battle
}
private DisciplesNecropolisPast()
// Locations
private static final Location ENTER = new Location(-89554, 216078, -7488, 0, 0);
private static final Location EXIT = new Location(171895, -17501, -4903, 0, 0);
// NpcStringId
private static final NpcStringId[] LILITH_SHOUT =
{
super(-1, DisciplesNecropolisPast.class.getSimpleName(), "instances");
NpcStringId.HOW_DARE_YOU_TRY_TO_CONTEND_AGAINST_ME_IN_STRENGTH_RIDICULOUS,
NpcStringId.ANAKIM_IN_THE_NAME_OF_GREAT_SHILEN_I_WILL_CUT_YOUR_THROAT,
NpcStringId.YOU_CANNOT_BE_THE_MATCH_OF_LILITH_I_LL_TEACH_YOU_A_LESSON
};
// Misc
private static final int TEMPLATE_ID = 112;
private static final int DOOR_1 = 17240102;
private static final int DOOR_2 = 17240104;
private static final int DOOR_3 = 17240106;
private static final int DOOR_4 = 17240108;
private static final int DOOR_5 = 17240110;
private static final int DISCIPLES_NECROPOLIS_DOOR = 17240111;
private static final Map<Integer, Location> LILITH_SPAWN = new HashMap<>();
private static final Map<Integer, Location> ANAKIM_SPAWN = new HashMap<>();
static
{
LILITH_SPAWN.put(LILITH, new Location(-83175, 217021, -7504, 49151));
LILITH_SPAWN.put(LILITHS_STEWARD, new Location(-83327, 216938, -7492, 50768));
LILITH_SPAWN.put(LILITHS_ELITE, new Location(-83003, 216909, -7492, 4827));
ANAKIM_SPAWN.put(ANAKIM, new Location(-83179, 216479, -7504, 16384));
ANAKIM_SPAWN.put(ANAKIMS_GUARDIAN, new Location(-83321, 216507, -7492, 16166));
ANAKIM_SPAWN.put(ANAKIMS_GUARD, new Location(-83086, 216519, -7495, 15910));
ANAKIM_SPAWN.put(ANAKIMS_EXECUTOR, new Location(-83031, 216604, -7492, 17071));
}
public DisciplesNecropolisPast()
{
super(DisciplesNecropolisPast.class.getSimpleName());
addAttackId(SEAL_DEVICE);
addFirstTalkId(SHUNAIMAN, LEON, DISCIPLES_GATEKEEPER);
addKillId(LILIM_BUTCHER, LILIM_MAGUS, LILIM_KNIGHT_ERRANT, LILIM_KNIGHT, SHILENS_EVIL_THOUGHTS1, SHILENS_EVIL_THOUGHTS2, LILIM_SLAYER, LILIM_GREAT_MAGUS, LILIM_GUARD_KNIGHT);
@ -144,69 +137,47 @@ public final class DisciplesNecropolisPast extends Quest
{
for (Map.Entry<Integer, Location> entry : LILITH_SPAWN.entrySet())
{
L2Npc npc = addSpawn(entry.getKey(), entry.getValue(), false, 0, false, world.getInstanceId());
final L2Npc npc = addSpawn(entry.getKey(), entry.getValue(), false, 0, false, world.getInstanceId());
world.lilithGroup.add(npc);
}
for (Map.Entry<Integer, Location> entry : ANAKIM_SPAWN.entrySet())
{
L2Npc enpc = addSpawn(entry.getKey(), entry.getValue(), false, 0, false, world.getInstanceId());
final L2Npc enpc = addSpawn(entry.getKey(), entry.getValue(), false, 0, false, world.getInstanceId());
world.anakimGroup.add(enpc);
}
}
private synchronized void checkDoors(L2Npc npc, DNPWorld world)
{
if (world.countKill == 4)
switch (world.countKill)
{
openDoor(DOOR_1, world.getInstanceId());
}
else if (world.countKill == 10)
{
openDoor(DOOR_2, world.getInstanceId());
}
else if (world.countKill == 18)
{
openDoor(DOOR_3, world.getInstanceId());
}
else if (world.countKill == 28)
{
openDoor(DOOR_4, world.getInstanceId());
}
else if (world.countKill == 40)
{
openDoor(DOOR_5, world.getInstanceId());
case 4:
openDoor(DOOR_1, world.getInstanceId());
break;
case 10:
openDoor(DOOR_2, world.getInstanceId());
break;
case 18:
openDoor(DOOR_3, world.getInstanceId());
break;
case 28:
openDoor(DOOR_4, world.getInstanceId());
break;
case 40:
openDoor(DOOR_5, world.getInstanceId());
break;
}
}
protected int enterInstance(L2PcInstance player, String template, Location loc)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
// check for existing instances for this player
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
// existing instance
if (world != null)
if (firstEntrance)
{
if (!(world instanceof DNPWorld))
{
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return 0;
}
teleportPlayer(player, loc, world.getInstanceId());
removeBuffs(player);
return world.getInstanceId();
spawnNPC((DNPWorld) world);
world.addAllowed(player.getObjectId());
}
// New instance
world = new DNPWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.setStatus(0);
((DNPWorld) world).storeTime = System.currentTimeMillis();
InstanceManager.getInstance().addWorld(world);
_log.info("Disciple's Necropolis Past started " + template + " Instance: " + world.getInstanceId() + " created by player: " + player.getName());
// teleport players
teleportPlayer(player, loc, world.getInstanceId());
spawnNPC((DNPWorld) world);
world.addAllowed(player.getObjectId());
return world.getInstanceId();
teleportPlayer(player, ENTER, world.getInstanceId());
}
private void makeCast(L2Npc npc, FastList<L2Npc> targets)
@ -221,10 +192,10 @@ public final class DisciplesNecropolisPast extends Quest
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
if (tmpworld instanceof DNPWorld)
{
DNPWorld world = (DNPWorld) tmpworld;
final DNPWorld world = (DNPWorld) tmpworld;
switch (event)
{
case "FINISH":
@ -398,31 +369,16 @@ public final class DisciplesNecropolisPast extends Quest
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
switch (npc.getId())
{
case SHUNAIMAN:
{
return "32586.htm";
}
case LEON:
{
return "32587.htm";
}
case DISCIPLES_GATEKEEPER:
{
return "32657.htm";
}
}
return super.onFirstTalk(npc, player);
return npc.getId() + ".htm";
}
@Override
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
{
InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
if (tmpworld instanceof DNPWorld)
{
DNPWorld world = (DNPWorld) tmpworld;
final DNPWorld world = (DNPWorld) tmpworld;
world.countKill++;
checkDoors(npc, world);
}
@ -474,7 +430,7 @@ public final class DisciplesNecropolisPast extends Quest
{
if (qs.isCond(3) || qs.isCond(4))
{
enterInstance(talker, "DisciplesNecropolisPast.xml", ENTER);
enterInstance(talker, new DNPWorld(), "DisciplesNecropolisPast.xml", TEMPLATE_ID);
return "";
}
break;
@ -509,18 +465,4 @@ public final class DisciplesNecropolisPast extends Quest
}
return htmltext;
}
private static final void removeBuffs(L2Character ch)
{
ch.stopAllEffectsExceptThoseThatLastThroughDeath();
if (ch.hasSummon())
{
ch.getServitors().values().forEach(L2Summon::stopAllEffectsExceptThoseThatLastThroughDeath);
}
}
public static void main(String[] args)
{
new DisciplesNecropolisPast();
}
}
}

View File

@ -18,11 +18,10 @@
*/
package instances.ElcadiasTent;
import instances.AbstractInstance;
import quests.Q10292_SevenSignsGirlOfDoubt.Q10292_SevenSignsGirlOfDoubt;
import quests.Q10293_SevenSignsForbiddenBookOfTheElmoreAdenKingdom.Q10293_SevenSignsForbiddenBookOfTheElmoreAdenKingdom;
import quests.Q10294_SevenSignsToTheMonasteryOfSilence.Q10294_SevenSignsToTheMonasteryOfSilence;
import quests.Q10296_SevenSignsPowerOfTheSeal.Q10296_SevenSignsPowerOfTheSeal;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.Location;
@ -30,30 +29,30 @@ import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.network.SystemMessageId;
/**
* Elcadia's Tent instance zone.
* @author Adry_85
*/
public final class ElcadiasTent extends AbstractNpcAI
public final class ElcadiasTent extends AbstractInstance
{
protected class ETWorld extends InstanceWorld
{
}
private static final int TEMPLATE_ID = 158;
// NPCs
private static final int ELCADIA = 32784;
private static final int GRUFF_LOOKING_MAN = 32862;
// Locations
private static final Location START_LOC = new Location(89706, -238074, -9632, 0, 0);
private static final Location EXIT_LOC = new Location(43316, -87986, -2832, 0, 0);
// Misc
private static final int TEMPLATE_ID = 158;
private ElcadiasTent()
public ElcadiasTent()
{
super(ElcadiasTent.class.getSimpleName(), "instances");
super(ElcadiasTent.class.getSimpleName());
addFirstTalkId(GRUFF_LOOKING_MAN, ELCADIA);
addStartNpc(GRUFF_LOOKING_MAN, ELCADIA);
addTalkId(GRUFF_LOOKING_MAN, ELCADIA);
@ -67,14 +66,12 @@ public final class ElcadiasTent extends AbstractNpcAI
final QuestState GirlOfDoubt = talker.getQuestState(Q10292_SevenSignsGirlOfDoubt.class.getSimpleName());
final QuestState ForbiddenBook = talker.getQuestState(Q10293_SevenSignsForbiddenBookOfTheElmoreAdenKingdom.class.getSimpleName());
final QuestState Monastery = talker.getQuestState(Q10294_SevenSignsToTheMonasteryOfSilence.class.getSimpleName());
final QuestState Power = talker.getQuestState(Q10296_SevenSignsPowerOfTheSeal.class.getSimpleName());
if (((GirlOfDoubt != null) && GirlOfDoubt.isStarted()) //
|| ((GirlOfDoubt != null) && GirlOfDoubt.isCompleted() && (ForbiddenBook == null)) //
|| ((ForbiddenBook != null) && ForbiddenBook.isStarted()) //
|| ((ForbiddenBook != null) && ForbiddenBook.isCompleted() && (Monastery == null)) //
|| ((Power != null) && Power.isStarted()))
|| ((ForbiddenBook != null) && ForbiddenBook.isCompleted() && (Monastery == null)))
{
enterInstance(talker, "ElcadiasTent.xml", START_LOC);
enterInstance(talker, new ETWorld(), "ElcadiasTent.xml", TEMPLATE_ID);
}
else
{
@ -91,37 +88,13 @@ public final class ElcadiasTent extends AbstractNpcAI
return super.onTalk(npc, talker);
}
private void enterInstance(L2PcInstance player, String template, Location loc)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (!(world instanceof ETWorld))
{
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
}
else
{
teleportPlayer(player, loc, world.getInstanceId(), false);
}
}
else
{
// New instance.
world = new ETWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
_log.info("Elcadia's Tent started " + template + " Instance: " + world.getInstanceId() + " created by player: " + player.getName());
// Teleport players.
teleportPlayer(player, loc, world.getInstanceId(), false);
world.addAllowed(player.getObjectId());
}
teleportPlayer(player, START_LOC, world.getInstanceId(), false);
}
public static void main(String[] args)
{
new ElcadiasTent();
}
}
}

View File

@ -18,8 +18,8 @@
*/
package instances.FaeronTrainingGrounds1;
import instances.AbstractInstance;
import quests.Q10735_ASpecialPower.Q10735_ASpecialPower;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.Location;
@ -28,21 +28,21 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
/**
* Fearon Training Grounds Instance Zone.
* @author Sdw
*/
public class FaeronTrainingGrounds1 extends AbstractNpcAI
public final class FaeronTrainingGrounds1 extends AbstractInstance
{
// Locations
private static final Location START_LOC = new Location(-74903, 240618, -3584);
private static final Location EXIT_LOC = new Location(-82088, 249880, -3392);
// NPC's
private static final int AYANTHE = 33942;
private static final int AYANTHE_2 = 33944;
// Instance
// Locations
private static final Location START_LOC = new Location(-74903, 240618, -3584);
private static final Location EXIT_LOC = new Location(-82088, 249880, -3392);
// Misc
private static final int TEMPLATE_ID = 251;
protected class FTGWorld extends InstanceWorld
@ -60,7 +60,8 @@ public class FaeronTrainingGrounds1 extends AbstractNpcAI
if (event.equals("enter_instance"))
{
enterInstance(player, "FaeronTrainingGrounds1.xml");
enterInstance(player, new FTGWorld(), "FaeronTrainingGrounds1.xml", TEMPLATE_ID);
}
else if (event.equals("exit_instance"))
{
@ -72,39 +73,21 @@ public class FaeronTrainingGrounds1 extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
private FaeronTrainingGrounds1()
public FaeronTrainingGrounds1()
{
super(FaeronTrainingGrounds1.class.getSimpleName(), "instances");
super(FaeronTrainingGrounds1.class.getSimpleName());
addStartNpc(AYANTHE, AYANTHE_2);
addTalkId(AYANTHE, AYANTHE_2);
}
private void enterInstance(L2PcInstance player, String template)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (world instanceof FTGWorld)
{
teleportPlayer(player, START_LOC, world.getInstanceId());
return;
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
world.addAllowed(player.getObjectId());
showOnScreenMsg(player, NpcStringId.TALK_TO_MAGISTER_AYANTHE, ExShowScreenMessage.TOP_CENTER, 4500);
}
world = new FTGWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.addAllowed(player.getObjectId());
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
teleportPlayer(player, START_LOC, world.getInstanceId());
showOnScreenMsg(player, NpcStringId.TALK_TO_MAGISTER_AYANTHE, ExShowScreenMessage.TOP_CENTER, 4500);
}
public static void main(String[] args)
{
new FaeronTrainingGrounds1();
}
}
}

View File

@ -18,8 +18,8 @@
*/
package instances.FaeronTrainingGrounds2;
import instances.AbstractInstance;
import quests.Q10736_ASpecialPower.Q10736_ASpecialPower;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.model.Location;
@ -28,21 +28,21 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.quest.QuestState;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
/**
* Fearon Training Grounds Instance Zone.
* @author Sdw
*/
public class FaeronTrainingGrounds2 extends AbstractNpcAI
public final class FaeronTrainingGrounds2 extends AbstractInstance
{
// Locations
private static final Location START_LOC = new Location(-74903, 240618, -3584);
private static final Location EXIT_LOC = new Location(-82088, 249880, -3392);
// NPC's
private static final int KATALIN = 33943;
private static final int KATALIN_2 = 33945;
// Instance
// Locations
private static final Location START_LOC = new Location(-74903, 240618, -3584);
private static final Location EXIT_LOC = new Location(-82088, 249880, -3392);
// Misc
private static final int TEMPLATE_ID = 252;
protected class FTGWorld extends InstanceWorld
@ -60,7 +60,7 @@ public class FaeronTrainingGrounds2 extends AbstractNpcAI
if (event.equals("enter_instance"))
{
enterInstance(player, "FaeronTrainingGrounds2.xml");
enterInstance(player, new FTGWorld(), "FaeronTrainingGrounds2.xml", TEMPLATE_ID);
}
else if (event.equals("exit_instance"))
{
@ -72,39 +72,21 @@ public class FaeronTrainingGrounds2 extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
private FaeronTrainingGrounds2()
public FaeronTrainingGrounds2()
{
super(FaeronTrainingGrounds2.class.getSimpleName(), "instances");
super(FaeronTrainingGrounds2.class.getSimpleName());
addStartNpc(KATALIN, KATALIN_2);
addTalkId(KATALIN, KATALIN_2);
}
private void enterInstance(L2PcInstance player, String template)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (world instanceof FTGWorld)
{
teleportPlayer(player, START_LOC, world.getInstanceId());
return;
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
world.addAllowed(player.getObjectId());
showOnScreenMsg(player, NpcStringId.TALK_TO_MASTER_KATALIN, ExShowScreenMessage.TOP_CENTER, 4500);
}
world = new FTGWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.addAllowed(player.getObjectId());
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
teleportPlayer(player, START_LOC, world.getInstanceId());
showOnScreenMsg(player, NpcStringId.TALK_TO_MASTER_KATALIN, ExShowScreenMessage.TOP_CENTER, 4500);
}
public static void main(String[] args)
{
new FaeronTrainingGrounds2();
}
}
}

View File

@ -18,8 +18,9 @@
*/
package instances.FinalEmperialTomb;
import instances.AbstractInstance;
import java.io.File;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -59,7 +60,6 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.effects.L2EffectType;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.quest.Quest;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
@ -81,31 +81,31 @@ import com.l2jserver.gameserver.util.Util;
* Use proper zone spawn system.
* @author Gigiikun
*/
public final class FinalEmperialTomb extends Quest
public final class FinalEmperialTomb extends AbstractInstance
{
private class FETWorld extends InstanceWorld
{
public Lock lock = new ReentrantLock();
public FastList<L2Npc> npcList = new FastList<>();
public int darkChoirPlayerCount = 0;
public FrintezzaSong OnSong = null;
public ScheduledFuture<?> songTask = null;
public ScheduledFuture<?> songEffectTask = null;
public boolean isVideo = false;
public L2Npc frintezzaDummy = null;
public L2Npc overheadDummy = null;
public L2Npc portraitDummy1 = null;
public L2Npc portraitDummy3 = null;
public L2Npc scarletDummy = null;
public L2GrandBossInstance frintezza = null;
public L2GrandBossInstance activeScarlet = null;
public List<L2MonsterInstance> demons = new FastList<>();
public Map<L2MonsterInstance, Integer> portraits = new FastMap<>();
public int scarlet_x = 0;
public int scarlet_y = 0;
public int scarlet_z = 0;
public int scarlet_h = 0;
public int scarlet_a = 0;
protected Lock lock = new ReentrantLock();
protected FastList<L2Npc> npcList = new FastList<>();
protected int darkChoirPlayerCount = 0;
protected FrintezzaSong OnSong = null;
protected ScheduledFuture<?> songTask = null;
protected ScheduledFuture<?> songEffectTask = null;
protected boolean isVideo = false;
protected L2Npc frintezzaDummy = null;
protected L2Npc overheadDummy = null;
protected L2Npc portraitDummy1 = null;
protected L2Npc portraitDummy3 = null;
protected L2Npc scarletDummy = null;
protected L2GrandBossInstance frintezza = null;
protected L2GrandBossInstance activeScarlet = null;
protected List<L2MonsterInstance> demons = new FastList<>();
protected Map<L2MonsterInstance, Integer> portraits = new FastMap<>();
protected int scarlet_x = 0;
protected int scarlet_y = 0;
protected int scarlet_z = 0;
protected int scarlet_h = 0;
protected int scarlet_a = 0;
protected FETWorld()
{
@ -142,24 +142,9 @@ public final class FinalEmperialTomb extends Quest
}
}
private static final int TEMPLATE_ID = 136; // this is the client number
private static final int MIN_PLAYERS = 36;
private static final int MAX_PLAYERS = 45;
private static final boolean debug = false;
private final Map<Integer, L2Territory> _spawnZoneList = new HashMap<>();
private final Map<Integer, List<FETSpawn>> _spawnList = new HashMap<>();
private final List<Integer> _mustKillMobsId = new FastList<>();
// Teleports
private static final Location ENTER_TELEPORT = new Location(-88015, -141153, -9168);
// NPCs
private static final int GUIDE = 32011;
private static final int CUBE = 29061;
// Item
private static final int DEWDROP_OF_DESTRUCTION_ITEM_ID = 8556;
// mobs
private static final int SCARLET1 = 29046;
private static final int SCARLET2 = 29047;
private static final int FRINTEZZA = 29045;
@ -175,15 +160,19 @@ public final class FinalEmperialTomb extends Quest
};
private static final int HALL_ALARM = 18328;
private static final int HALL_KEEPER_CAPTAIN = 18329;
// Items
private static final int HALL_KEEPER_SUICIDAL_SOLDIER = 18333;
private static final int DARK_CHOIR_PLAYER = 18339;
private static final int[] AI_DISABLED_MOBS =
{
18328
};
private static final int DEWDROP_OF_DESTRUCTION_ITEM_ID = 8556;
private static final int FIRST_SCARLET_WEAPON = 8204;
private static final int SECOND_SCARLET_WEAPON = 7903;
// Skills
private static final int DEWDROP_OF_DESTRUCTION_SKILL_ID = 2276;
private static final int SOUL_BREAKING_ARROW_SKILL_ID = 2234;
protected static final SkillHolder INTRO_SKILL = new SkillHolder(5004, 1);
private static final SkillHolder FIRST_MORPH_SKILL = new SkillHolder(5017, 1);
@ -195,10 +184,19 @@ public final class FinalEmperialTomb extends Quest
new FrintezzaSong(new SkillHolder(5007, 4), new SkillHolder(5008, 4), NpcStringId.FUGUE_OF_JUBILATION, 90),
new FrintezzaSong(new SkillHolder(5007, 5), new SkillHolder(5008, 5), NpcStringId.HYPNOTIC_MAZURKA, 100),
};
// Skills
private static final int DEWDROP_OF_DESTRUCTION_SKILL_ID = 2276;
private static final int SOUL_BREAKING_ARROW_SKILL_ID = 2234;
// Doors/Walls/Zones
// Locations
private static final Location ENTER_TELEPORT = new Location(-88015, -141153, -9168);
protected static final Location MOVE_TO_CENTER = new Location(-87904, -141296, -9168, 0);
// Misc
private static final int TEMPLATE_ID = 136; // this is the client number
private static final int MIN_PLAYERS = 36;
private static final int MAX_PLAYERS = 45;
private static final int TIME_BETWEEN_DEMON_SPAWNS = 20000;
private static final int MAX_DEMONS = 24;
private static final boolean debug = false;
private final Map<Integer, L2Territory> _spawnZoneList = new HashMap<>();
private final Map<Integer, List<FETSpawn>> _spawnList = new HashMap<>();
private final List<Integer> _mustKillMobsId = new FastList<>();
protected static final int[] FIRST_ROOM_DOORS =
{
17130051,
@ -223,7 +221,6 @@ public final class FinalEmperialTomb extends Quest
17130069,
17130070
};
protected static final int[] FIRST_ROUTE_DOORS =
{
17130042,
@ -234,68 +231,19 @@ public final class FinalEmperialTomb extends Quest
17130045,
17130046
};
protected static final Location MOVE_TO_CENTER = new Location(-87904, -141296, -9168, 0);
// spawns
private static final int TIME_BETWEEN_DEMON_SPAWNS = 20000;
private static final int MAX_DEMONS = 24;
// @formatter:off
protected static final int[][] PORTRAIT_SPAWNS =
{
{
29048,
-89381,
-153981,
-9168,
3368,
-89378,
-153968,
-9168,
3368
},
{
29048,
-86234,
-152467,
-9168,
37656,
-86261,
-152492,
-9168,
37656
},
{
29049,
-89342,
-152479,
-9168,
-5152,
-89311,
-152491,
-9168,
-5152
},
{
29049,
-86189,
-153968,
-9168,
29456,
-86217,
-153956,
-9168,
29456
}
{29048, -89381, -153981, -9168, 3368, -89378, -153968, -9168, 3368},
{29048, -86234, -152467, -9168, 37656, -86261, -152492, -9168, 37656},
{29049, -89342, -152479, -9168, -5152, -89311, -152491, -9168, -5152},
{29049, -86189, -153968, -9168, 29456, -86217, -153956, -9168, 29456},
};
// @formatter:on
// Initialization at 6:30 am on Wednesday and Saturday
private static final int RESET_HOUR = 6;
private static final int RESET_MIN = 30;
private static final int RESET_DAY_1 = 4;
private static final int RESET_DAY_2 = 7;
private FinalEmperialTomb()
public FinalEmperialTomb()
{
super(-1, FinalEmperialTomb.class.getSimpleName(), "instances");
super(FinalEmperialTomb.class.getSimpleName());
load();
addAttackId(SCARLET1, FRINTEZZA);
addAttackId(PORTRAITS);
@ -532,19 +480,22 @@ public final class FinalEmperialTomb extends Quest
}
}
private boolean checkConditions(L2PcInstance player)
@Override
protected boolean checkConditions(L2PcInstance player)
{
if (debug || player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS))
{
return true;
}
L2Party party = player.getParty();
final L2Party party = player.getParty();
if (party == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_CURRENTLY_IN_A_PARTY_SO_YOU_CANNOT_ENTER);
return false;
}
L2CommandChannel channel = player.getParty().getCommandChannel();
final L2CommandChannel channel = player.getParty().getCommandChannel();
if (channel == null)
{
player.sendPacket(SystemMessageId.YOU_CANNOT_ENTER_BECAUSE_YOU_ARE_NOT_ASSOCIATED_WITH_THE_CURRENT_COMMAND_CHANNEL);
@ -571,82 +522,51 @@ public final class FinalEmperialTomb extends Quest
{
if (channelMember.getLevel() < 80)
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY);
sm.addPcName(channelMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_S_LEVEL_DOES_NOT_CORRESPOND_TO_THE_REQUIREMENTS_FOR_ENTRY).addPcName(channelMember));
return false;
}
if (!Util.checkIfInRange(1000, player, channelMember, true))
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED);
sm.addPcName(channelMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_A_LOCATION_WHICH_CANNOT_BE_ENTERED_THEREFORE_IT_CANNOT_BE_PROCESSED).addPcName(channelMember));
return false;
}
Long reentertime = InstanceManager.getInstance().getInstanceTime(channelMember.getObjectId(), TEMPLATE_ID);
final Long reentertime = InstanceManager.getInstance().getInstanceTime(channelMember.getObjectId(), TEMPLATE_ID);
if (System.currentTimeMillis() < reentertime)
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_RE_ENTER_YET);
sm.addPcName(channelMember);
party.broadcastPacket(sm);
party.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_RE_ENTER_YET).addPcName(channelMember));
return false;
}
}
return true;
}
protected int enterInstance(L2PcInstance player, String template, Location loc)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
// check for existing instances for this player
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
// existing instance
if (world != null)
if (firstEntrance)
{
if (!(world instanceof FETWorld))
controlStatus((FETWorld) world);
if ((player.getParty() == null) || (player.getParty().getCommandChannel() == null))
{
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return 0;
player.destroyItemByItemId(getName(), DEWDROP_OF_DESTRUCTION_ITEM_ID, player.getInventory().getInventoryItemCount(DEWDROP_OF_DESTRUCTION_ITEM_ID, -1), null, true);
world.addAllowed(player.getObjectId());
teleportPlayer(player, ENTER_TELEPORT, world.getInstanceId(), false);
}
else
{
for (L2PcInstance channelMember : player.getParty().getCommandChannel().getMembers())
{
channelMember.destroyItemByItemId(getName(), DEWDROP_OF_DESTRUCTION_ITEM_ID, channelMember.getInventory().getInventoryItemCount(DEWDROP_OF_DESTRUCTION_ITEM_ID, -1), null, true);
world.addAllowed(channelMember.getObjectId());
teleportPlayer(channelMember, ENTER_TELEPORT, world.getInstanceId(), false);
}
}
teleportPlayer(player, loc, world.getInstanceId(), false);
return world.getInstanceId();
}
// New instance
if (!checkConditions(player))
{
return 0;
}
if (!player.canOverrideCond(PcCondOverride.INSTANCE_CONDITIONS) && !player.destroyItemByItemId("QUEST", 8073, 1, player, true))
{
return 0;
}
final int instanceId = InstanceManager.getInstance().createDynamicInstance(template);
// Instance ins = InstanceManager.getInstance().getInstance(instanceId);
// ins.setSpawnLoc(new int[]{player.getX(),player.getY(),player.getZ()});
world = new FETWorld();
world.setTemplateId(TEMPLATE_ID);
world.setInstanceId(instanceId);
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
controlStatus((FETWorld) world);
_log.info("Final Emperial Tomb started " + template + " Instance: " + instanceId + " created by player: " + player.getName());
// teleport players
if ((player.getParty() == null) || (player.getParty().getCommandChannel() == null))
{
player.destroyItemByItemId(getName(), DEWDROP_OF_DESTRUCTION_ITEM_ID, player.getInventory().getInventoryItemCount(DEWDROP_OF_DESTRUCTION_ITEM_ID, -1), null, true);
world.addAllowed(player.getObjectId());
teleportPlayer(player, loc, instanceId, false);
}
else
{
for (L2PcInstance channelMember : player.getParty().getCommandChannel().getMembers())
{
channelMember.destroyItemByItemId(getName(), DEWDROP_OF_DESTRUCTION_ITEM_ID, channelMember.getInventory().getInventoryItemCount(DEWDROP_OF_DESTRUCTION_ITEM_ID, -1), null, true);
world.addAllowed(channelMember.getObjectId());
teleportPlayer(channelMember, loc, instanceId, false);
}
teleportPlayer(player, ENTER_TELEPORT, world.getInstanceId(), false);
}
return instanceId;
}
protected boolean checkKillProgress(L2Npc mob, FETWorld world)
@ -738,7 +658,7 @@ public final class FinalEmperialTomb extends Quest
{
world.activeScarlet.abortCast();
}
setInstanceTimeRestrictions(world);
handleReenterTime(world);
world.activeScarlet.doCast(FIRST_MORPH_SKILL.getSkill());
ThreadPoolManager.getInstance().scheduleGeneral(new SongTask(world, 2), 1500);
break;
@ -801,7 +721,7 @@ public final class FinalEmperialTomb extends Quest
protected void spawn(FETWorld world, int npcId, int x, int y, int z, int h, boolean addToKillTable)
{
L2Npc npc = addSpawn(npcId, x, y, z, h, false, 0, false, world.getInstanceId());
final L2Npc npc = addSpawn(npcId, x, y, z, h, false, 0, false, world.getInstanceId());
if (addToKillTable)
{
world.npcList.add(npc);
@ -1414,46 +1334,6 @@ public final class FinalEmperialTomb extends Quest
}
}
protected void setInstanceTimeRestrictions(FETWorld world)
{
Calendar reenter = Calendar.getInstance();
reenter.set(Calendar.MINUTE, RESET_MIN);
reenter.set(Calendar.HOUR_OF_DAY, RESET_HOUR);
// if time is >= RESET_HOUR - roll to the next day
if (reenter.getTimeInMillis() <= System.currentTimeMillis())
{
reenter.add(Calendar.DAY_OF_MONTH, 1);
}
if (reenter.get(Calendar.DAY_OF_WEEK) <= RESET_DAY_1)
{
while (reenter.get(Calendar.DAY_OF_WEEK) != RESET_DAY_1)
{
reenter.add(Calendar.DAY_OF_MONTH, 1);
}
}
else
{
while (reenter.get(Calendar.DAY_OF_WEEK) != RESET_DAY_2)
{
reenter.add(Calendar.DAY_OF_MONTH, 1);
}
}
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_S_ENTRY_HAS_BEEN_RESTRICTED_YOU_CAN_CHECK_THE_NEXT_POSSIBLE_ENTRY_TIME_BY_USING_THE_COMMAND_INSTANCEZONE);
sm.addInstanceName(TEMPLATE_ID);
// set instance reenter time for all allowed players
for (int objectId : world.getAllowed())
{
L2PcInstance player = L2World.getInstance().getPlayer(objectId);
InstanceManager.getInstance().setInstanceTime(objectId, TEMPLATE_ID, reenter.getTimeInMillis());
if ((player != null) && player.isOnline())
{
player.sendPacket(sm);
}
}
}
protected void broadCastPacket(FETWorld world, L2GameServerPacket packet)
{
for (int objId : world.getAllowed())
@ -1587,7 +1467,7 @@ public final class FinalEmperialTomb extends Quest
getQuestState(player, true);
if (npcId == GUIDE)
{
enterInstance(player, "FinalEmperialTomb.xml", ENTER_TELEPORT);
enterInstance(player, new FETWorld(), "FinalEmperialTomb.xml", TEMPLATE_ID);
}
else if (npc.getId() == CUBE)
{
@ -1598,9 +1478,4 @@ public final class FinalEmperialTomb extends Quest
}
return "";
}
public static void main(String[] args)
{
new FinalEmperialTomb();
}
}
}

View File

@ -18,13 +18,13 @@
*/
package instances.HarnakUndergroundRuins;
import instances.AbstractInstance;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import ai.npc.AbstractNpcAI;
import com.l2jserver.gameserver.ai.CtrlIntention;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.instancemanager.InstanceManager;
@ -32,30 +32,36 @@ import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.model.holders.SkillHolder;
import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
import com.l2jserver.gameserver.model.zone.L2ZoneType;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.clientpackets.Say2;
import com.l2jserver.gameserver.network.serverpackets.ExSendUIEvent;
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
import com.l2jserver.gameserver.util.Util;
/**
* Harnak Underground Ruins Instance Zone.
* @author Sdw
*/
public class HarnakUndergroundRuins extends AbstractNpcAI
public final class HarnakUndergroundRuins extends AbstractInstance
{
private static final int TEMPLATE_ID = 195;
// Locations
private static final Location START_LOC = new Location(-107910, 205828, -10872);
private static final Location NPC_ROOM1_LOC = new Location(-107930, 206328, -10872);
private static final Location EXIT_LOC = new Location(-114962, 226564, -2864);
// Doors
private static final int DOOR_ONE = 16240100;
private static final int DOOR_TWO = 16240102;
protected class HuRWorld extends InstanceWorld
{
protected int wave = 0;
protected int currentNpc = 0;
protected int waveNpcId = 0;
protected int maximalDefenseCounter = 0;
protected int timerCount = 0;
protected int enabledSeal = 0;
protected Set<L2Npc> spawnedNpc = Collections.newSetFromMap(new ConcurrentHashMap<L2Npc, Boolean>());
protected boolean openingPlayed = false;
protected boolean harnakMessage1 = false;
protected boolean harnakMessage2 = false;
protected boolean harnakMessage3 = false;
}
// NPCs
private static final int HADEL = 33344;
private static final int KRAKIA_BATHUS = 27437;
@ -75,37 +81,28 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
33556,
33557
};
// Locations
private static final Location START_LOC = new Location(-107910, 205828, -10872);
private static final Location NPC_ROOM1_LOC = new Location(-107930, 206328, -10872);
private static final Location EXIT_LOC = new Location(-114962, 226564, -2864);
// Skills
private static final SkillHolder RELEASE_OF_POWER = new SkillHolder(14625, 1);
private static final SkillHolder MAXIMUM_DEFENSE = new SkillHolder(14700, 1);
private static final SkillHolder LIGHT_HEAL = new SkillHolder(14736, 1);
private static final SkillHolder ULTIMATE_BUFF = new SkillHolder(4318, 1);
// Zones
// Misc
private static final int TEMPLATE_ID = 195;
private static final int ZONE_ROOM_2 = 200032;
private static final int ZONE_ROOM_3 = 200033;
// Movies
private static final int LAST_ROOM_OPENING = 46;
private static final int SUCCES_ENDING = 47;
private static final int FAILED_ENDING = 48;
private static final int DOOR_ONE = 16240100;
private static final int DOOR_TWO = 16240102;
protected class HuRWorld extends InstanceWorld
public HarnakUndergroundRuins()
{
protected int wave = 0;
protected int currentNpc = 0;
protected int waveNpcId = 0;
protected int maximalDefenseCounter = 0;
protected int timerCount = 0;
protected int enabledSeal = 0;
protected Set<L2Npc> spawnedNpc = Collections.newSetFromMap(new ConcurrentHashMap<L2Npc, Boolean>());
protected boolean openingPlayed = false;
protected boolean harnakMessage1 = false;
protected boolean harnakMessage2 = false;
protected boolean harnakMessage3 = false;
}
private HarnakUndergroundRuins()
{
super(HarnakUndergroundRuins.class.getSimpleName(), "instances");
super(HarnakUndergroundRuins.class.getSimpleName());
registerMobs(KRAKIA_BATHUS, KRAKIA_CARCASS, KRAKIA_LOTUS, RAKZAN, WEISS_KHAN, BAMONTI, SEKNUS, WEISS_ELE, HARNAKS_WRAITH);
addSeeCreatureId(POWER_SOURCES);
addEnterZoneId(ZONE_ROOM_2, ZONE_ROOM_3);
@ -122,7 +119,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
{
case "enter_instance":
{
enterInstance(player, "HarnakUndergroundRuins.xml");
enterInstance(player, new HuRWorld(), "HarnakUndergroundRuins.xml", TEMPLATE_ID);
break;
}
case "message1":
@ -200,9 +197,8 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
if (tmpworld instanceof HuRWorld)
{
HuRWorld world = (HuRWorld) tmpworld;
Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
List<L2Npc> spawnedNpcs = inst.spawnGroup("first_room");
final HuRWorld world = (HuRWorld) tmpworld;
final List<L2Npc> spawnedNpcs = spawnGroup("first_room", world.getInstanceId());
world.spawnedNpc.addAll(spawnedNpcs);
final L2Npc razkan = spawnedNpcs.stream().filter(n -> n.getId() == RAKZAN).findFirst().orElse(null);
if (razkan != null)
@ -219,8 +215,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
case "spawn_npc2":
{
openDoor(DOOR_ONE, player.getInstanceId());
final Instance inst = InstanceManager.getInstance().getInstance(player.getInstanceId());
inst.spawnGroup("power_sources");
spawnGroup("power_sources", player.getInstanceId());
break;
}
case "spawn_npc3":
@ -228,10 +223,9 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
if (tmpworld instanceof HuRWorld)
{
HuRWorld world = (HuRWorld) tmpworld;
final HuRWorld world = (HuRWorld) tmpworld;
world.incStatus();
Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
List<L2Npc> spawnedNpcs = inst.spawnGroup("third_room");
final List<L2Npc> spawnedNpcs = spawnGroup("third_room", world.getInstanceId());
final L2Npc powerSource = spawnedNpcs.stream().filter(n -> n.getId() == POWER_SOURCE).findFirst().orElse(null);
if (powerSource != null)
{
@ -289,8 +283,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
if (tmpworld instanceof HuRWorld)
{
final HuRWorld world = (HuRWorld) tmpworld;
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
final List<L2Npc> spawnedNpcs = inst.spawnGroup("second_room_wave_1_" + npcId);
final List<L2Npc> spawnedNpcs = spawnGroup("second_room_wave_1_" + npcId, world.getInstanceId());
world.spawnedNpc.addAll(spawnedNpcs);
world.waveNpcId = npcId;
for (L2Npc spawnedNpc : spawnedNpcs)
@ -308,8 +301,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
if (tmpworld instanceof HuRWorld)
{
final HuRWorld world = (HuRWorld) tmpworld;
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
final List<L2Npc> spawnedNpcs = inst.spawnGroup("second_room_wave_2_" + world.waveNpcId);
final List<L2Npc> spawnedNpcs = spawnGroup("second_room_wave_2_" + world.waveNpcId, world.getInstanceId());
world.spawnedNpc.addAll(spawnedNpcs);
for (L2Npc spawnedNpc : spawnedNpcs)
{
@ -325,15 +317,14 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
if (tmpworld instanceof HuRWorld)
{
HuRWorld world = (HuRWorld) tmpworld;
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
List<L2Npc> spawnedNpcs = inst.spawnGroup("second_room_wave_3_" + world.waveNpcId);
final HuRWorld world = (HuRWorld) tmpworld;
final List<L2Npc> spawnedNpcs = spawnGroup("second_room_wave_3_" + world.waveNpcId, world.getInstanceId());
world.spawnedNpc.addAll(spawnedNpcs);
for (L2Npc spawnedNpc : spawnedNpcs)
{
addAttackPlayerDesire(spawnedNpc, player);
}
final List<L2Npc> powersources = inst.spawnGroup("power_source");
final List<L2Npc> powersources = spawnGroup("power_source", world.getInstanceId());
for (L2Npc powersource : powersources)
{
powersource.setTarget(player);
@ -348,7 +339,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
if (tmpworld instanceof HuRWorld)
{
HuRWorld world = (HuRWorld) tmpworld;
final HuRWorld world = (HuRWorld) tmpworld;
if (npc.calculateDistance(player, true, false) < MAXIMUM_DEFENSE.getSkill().getCastRange())
{
npc.doCast(MAXIMUM_DEFENSE.getSkill());
@ -403,13 +394,12 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
if (tmpworld instanceof HuRWorld)
{
final HuRWorld world = (HuRWorld) tmpworld;
final Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
List<L2Npc> spawnedNpcs = inst.spawnGroup("third_room_" + world.waveNpcId);
List<L2Npc> spawnedNpcs = spawnGroup("third_room_" + world.waveNpcId, world.getInstanceId());
for (L2Npc spawnedNpc : spawnedNpcs)
{
addAttackPlayerDesire(spawnedNpc, player);
}
spawnedNpcs = inst.spawnGroup("seal");
spawnedNpcs = spawnGroup("seal", world.getInstanceId());
for (L2Npc spawnedNpc : spawnedNpcs)
{
broadcastNpcSay(spawnedNpc, Say2.NPC_ALL, NpcStringId.DISABLE_DEVICE_WILL_GO_OUT_OF_CONTROL_IN_1_MINUTE);
@ -423,7 +413,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(player);
if (tmpworld instanceof HuRWorld)
{
HuRWorld world = (HuRWorld) tmpworld;
final HuRWorld world = (HuRWorld) tmpworld;
if (npc.getScriptValue() == 0)
{
npc.setScriptValue(1);
@ -512,8 +502,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
}
case "spawn_hermuncus":
{
final Instance inst = InstanceManager.getInstance().getInstance(player.getInstanceId());
inst.spawnGroup("hermuncus");
spawnGroup("hermuncus", player.getInstanceId());
break;
}
case "cast_release_power":
@ -536,34 +525,19 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
return htmltext;
}
private void enterInstance(L2PcInstance player, String template)
@Override
public void onEnterInstance(L2PcInstance player, InstanceWorld world, boolean firstEntrance)
{
InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
if (world != null)
if (firstEntrance)
{
if (world instanceof HuRWorld)
{
teleportPlayer(player, START_LOC, world.getInstanceId());
return;
}
player.sendPacket(SystemMessageId.YOU_HAVE_ENTERED_ANOTHER_INSTANT_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
return;
startQuestTimer("fail_instance", 1260000, null, player);
startQuestTimer("message1", 2500, null, player);
startQuestTimer("message2", 5000, null, player);
startQuestTimer("message3", 8500, null, player);
startQuestTimer("spawn_npc1", 10000, null, player);
}
world = new HuRWorld();
world.setInstanceId(InstanceManager.getInstance().createDynamicInstance(template));
world.setTemplateId(TEMPLATE_ID);
world.addAllowed(player.getObjectId());
world.setStatus(0);
InstanceManager.getInstance().addWorld(world);
teleportPlayer(player, START_LOC, world.getInstanceId());
startQuestTimer("fail_instance", 1260000, null, player);
startQuestTimer("message1", 2500, null, player);
startQuestTimer("message2", 5000, null, player);
startQuestTimer("message3", 8500, null, player);
startQuestTimer("spawn_npc1", 10000, null, player);
}
@Override
@ -572,7 +546,7 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
final InstanceWorld tmpworld = InstanceManager.getInstance().getPlayerWorld(killer);
if ((tmpworld instanceof HuRWorld))
{
HuRWorld world = (HuRWorld) tmpworld;
final HuRWorld world = (HuRWorld) tmpworld;
if (world.isStatus(0))
{
world.spawnedNpc.remove(npc);
@ -800,7 +774,6 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
}
}
}
return super.onAttack(npc, player, damage, isSummon);
}
@ -855,9 +828,4 @@ public class HarnakUndergroundRuins extends AbstractNpcAI
}
return super.onEnterZone(character, zone);
}
public static void main(String[] args)
{
new HarnakUndergroundRuins();
}
}

Some files were not shown because too many files have changed in this diff Show More