AbstractScript.java 124 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368
  1. /*
  2. * Copyright (C) 2004-2018 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model.events;
  20. import java.io.File;
  21. import java.lang.annotation.Annotation;
  22. import java.lang.reflect.Method;
  23. import java.util.ArrayList;
  24. import java.util.Arrays;
  25. import java.util.Collection;
  26. import java.util.Collections;
  27. import java.util.HashMap;
  28. import java.util.Iterator;
  29. import java.util.LinkedList;
  30. import java.util.List;
  31. import java.util.Map;
  32. import java.util.Map.Entry;
  33. import java.util.Set;
  34. import java.util.concurrent.ConcurrentHashMap;
  35. import java.util.concurrent.CopyOnWriteArrayList;
  36. import java.util.function.Consumer;
  37. import java.util.function.Function;
  38. import java.util.logging.Level;
  39. import java.util.logging.Logger;
  40. import com.l2jserver.Config;
  41. import com.l2jserver.gameserver.GameTimeController;
  42. import com.l2jserver.gameserver.ai.CtrlIntention;
  43. import com.l2jserver.gameserver.data.xml.impl.DoorData;
  44. import com.l2jserver.gameserver.data.xml.impl.NpcData;
  45. import com.l2jserver.gameserver.datatables.ItemTable;
  46. import com.l2jserver.gameserver.enums.audio.IAudio;
  47. import com.l2jserver.gameserver.enums.audio.Sound;
  48. import com.l2jserver.gameserver.instancemanager.CastleManager;
  49. import com.l2jserver.gameserver.instancemanager.FortManager;
  50. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  51. import com.l2jserver.gameserver.instancemanager.ZoneManager;
  52. import com.l2jserver.gameserver.model.L2Spawn;
  53. import com.l2jserver.gameserver.model.Location;
  54. import com.l2jserver.gameserver.model.actor.L2Attackable;
  55. import com.l2jserver.gameserver.model.actor.L2Character;
  56. import com.l2jserver.gameserver.model.actor.L2Npc;
  57. import com.l2jserver.gameserver.model.actor.L2Playable;
  58. import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
  59. import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
  60. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  61. import com.l2jserver.gameserver.model.actor.instance.L2TrapInstance;
  62. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  63. import com.l2jserver.gameserver.model.drops.GeneralDropItem;
  64. import com.l2jserver.gameserver.model.drops.GroupedGeneralDropItem;
  65. import com.l2jserver.gameserver.model.drops.IDropItem;
  66. import com.l2jserver.gameserver.model.entity.Castle;
  67. import com.l2jserver.gameserver.model.entity.Fort;
  68. import com.l2jserver.gameserver.model.entity.Instance;
  69. import com.l2jserver.gameserver.model.events.annotations.Id;
  70. import com.l2jserver.gameserver.model.events.annotations.Ids;
  71. import com.l2jserver.gameserver.model.events.annotations.NpcLevelRange;
  72. import com.l2jserver.gameserver.model.events.annotations.NpcLevelRanges;
  73. import com.l2jserver.gameserver.model.events.annotations.Priority;
  74. import com.l2jserver.gameserver.model.events.annotations.Range;
  75. import com.l2jserver.gameserver.model.events.annotations.Ranges;
  76. import com.l2jserver.gameserver.model.events.annotations.RegisterEvent;
  77. import com.l2jserver.gameserver.model.events.annotations.RegisterType;
  78. import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
  79. import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
  80. import com.l2jserver.gameserver.model.events.impl.character.OnCreatureZoneEnter;
  81. import com.l2jserver.gameserver.model.events.impl.character.OnCreatureZoneExit;
  82. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCanBeSeen;
  83. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
  84. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcEventReceived;
  85. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
  86. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveFinished;
  87. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveNodeArrived;
  88. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcMoveRouteFinished;
  89. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillFinished;
  90. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSkillSee;
  91. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcSpawn;
  92. import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcTeleport;
  93. import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAggroRangeEnter;
  94. import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
  95. import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableFactionCall;
  96. import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableHate;
  97. import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
  98. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogin;
  99. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLogout;
  100. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerProfessionCancel;
  101. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerProfessionChange;
  102. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSkillLearn;
  103. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSummonSpawn;
  104. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerSummonTalk;
  105. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerTutorialClientEvent;
  106. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerTutorialCmd;
  107. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerTutorialEvent;
  108. import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerTutorialQuestionMark;
  109. import com.l2jserver.gameserver.model.events.impl.character.trap.OnTrapAction;
  110. import com.l2jserver.gameserver.model.events.impl.item.OnItemBypassEvent;
  111. import com.l2jserver.gameserver.model.events.impl.item.OnItemTalk;
  112. import com.l2jserver.gameserver.model.events.impl.olympiad.OnOlympiadMatchResult;
  113. import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeFinish;
  114. import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeOwnerChange;
  115. import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
  116. import com.l2jserver.gameserver.model.events.listeners.AbstractEventListener;
  117. import com.l2jserver.gameserver.model.events.listeners.AnnotationEventListener;
  118. import com.l2jserver.gameserver.model.events.listeners.ConsumerEventListener;
  119. import com.l2jserver.gameserver.model.events.listeners.DummyEventListener;
  120. import com.l2jserver.gameserver.model.events.listeners.FunctionEventListener;
  121. import com.l2jserver.gameserver.model.events.listeners.RunnableEventListener;
  122. import com.l2jserver.gameserver.model.events.returns.AbstractEventReturn;
  123. import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
  124. import com.l2jserver.gameserver.model.holders.ItemHolder;
  125. import com.l2jserver.gameserver.model.holders.SkillHolder;
  126. import com.l2jserver.gameserver.model.interfaces.INamable;
  127. import com.l2jserver.gameserver.model.interfaces.IPositionable;
  128. import com.l2jserver.gameserver.model.itemcontainer.Inventory;
  129. import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
  130. import com.l2jserver.gameserver.model.items.L2EtcItem;
  131. import com.l2jserver.gameserver.model.items.L2Item;
  132. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  133. import com.l2jserver.gameserver.model.olympiad.Olympiad;
  134. import com.l2jserver.gameserver.model.skills.Skill;
  135. import com.l2jserver.gameserver.model.zone.L2ZoneType;
  136. import com.l2jserver.gameserver.network.NpcStringId;
  137. import com.l2jserver.gameserver.network.SystemMessageId;
  138. import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
  139. import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
  140. import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
  141. import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
  142. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  143. import com.l2jserver.gameserver.scripting.ScriptEngineManager;
  144. import com.l2jserver.gameserver.scripting.ScriptManager;
  145. import com.l2jserver.gameserver.util.MinionList;
  146. import com.l2jserver.util.Rnd;
  147. import com.l2jserver.util.Util;
  148. /**
  149. * Abstract script.
  150. * @author KenM, UnAfraid, Zoey76
  151. */
  152. public abstract class AbstractScript implements INamable
  153. {
  154. public static final Logger _log = Logger.getLogger(AbstractScript.class.getName());
  155. private final Map<ListenerRegisterType, Set<Integer>> _registeredIds = new ConcurrentHashMap<>();
  156. private final List<AbstractEventListener> _listeners = new CopyOnWriteArrayList<>();
  157. private final File _scriptFile;
  158. private boolean _isActive;
  159. public AbstractScript()
  160. {
  161. _scriptFile = ScriptEngineManager.getInstance().getCurrentLoadingScript();
  162. initializeAnnotationListeners();
  163. }
  164. private void initializeAnnotationListeners()
  165. {
  166. final List<Integer> ids = new ArrayList<>();
  167. for (Method method : getClass().getMethods())
  168. {
  169. if (method.isAnnotationPresent(RegisterEvent.class) && method.isAnnotationPresent(RegisterType.class))
  170. {
  171. final RegisterEvent listener = method.getAnnotation(RegisterEvent.class);
  172. final RegisterType regType = method.getAnnotation(RegisterType.class);
  173. final ListenerRegisterType type = regType.value();
  174. final EventType eventType = listener.value();
  175. if (method.getParameterCount() != 1)
  176. {
  177. _log.log(Level.WARNING, getClass().getSimpleName() + ": Non properly defined annotation listener on method: " + method.getName() + " expected parameter count is 1 but found: " + method.getParameterCount());
  178. continue;
  179. }
  180. else if (!eventType.isEventClass(method.getParameterTypes()[0]))
  181. {
  182. _log.log(Level.WARNING, getClass().getSimpleName() + ": Non properly defined annotation listener on method: " + method.getName() + " expected parameter to be type of: " + eventType.getEventClass().getSimpleName() + " but found: " + method.getParameterTypes()[0].getSimpleName());
  183. continue;
  184. }
  185. else if (!eventType.isReturnClass(method.getReturnType()))
  186. {
  187. _log.log(Level.WARNING, getClass().getSimpleName() + ": Non properly defined annotation listener on method: " + method.getName() + " expected return type to be one of: " + Arrays.toString(eventType.getReturnClasses()) + " but found: " + method.getReturnType().getSimpleName());
  188. continue;
  189. }
  190. int priority = 0;
  191. // Clear the list
  192. ids.clear();
  193. // Scan for possible Id filters
  194. for (Annotation annotation : method.getAnnotations())
  195. {
  196. if (annotation instanceof Id)
  197. {
  198. final Id npc = (Id) annotation;
  199. for (int id : npc.value())
  200. {
  201. ids.add(id);
  202. }
  203. }
  204. else if (annotation instanceof Ids)
  205. {
  206. final Ids npcs = (Ids) annotation;
  207. for (Id npc : npcs.value())
  208. {
  209. for (int id : npc.value())
  210. {
  211. ids.add(id);
  212. }
  213. }
  214. }
  215. else if (annotation instanceof Range)
  216. {
  217. final Range range = (Range) annotation;
  218. if (range.from() > range.to())
  219. {
  220. _log.log(Level.WARNING, getClass().getSimpleName() + ": Wrong " + annotation.getClass().getSimpleName() + " from is higher then to!");
  221. continue;
  222. }
  223. for (int id = range.from(); id <= range.to(); id++)
  224. {
  225. ids.add(id);
  226. }
  227. }
  228. else if (annotation instanceof Ranges)
  229. {
  230. final Ranges ranges = (Ranges) annotation;
  231. for (Range range : ranges.value())
  232. {
  233. if (range.from() > range.to())
  234. {
  235. _log.log(Level.WARNING, getClass().getSimpleName() + ": Wrong " + annotation.getClass().getSimpleName() + " from is higher then to!");
  236. continue;
  237. }
  238. for (int id = range.from(); id <= range.to(); id++)
  239. {
  240. ids.add(id);
  241. }
  242. }
  243. }
  244. else if (annotation instanceof NpcLevelRange)
  245. {
  246. final NpcLevelRange range = (NpcLevelRange) annotation;
  247. if (range.from() > range.to())
  248. {
  249. _log.log(Level.WARNING, getClass().getSimpleName() + ": Wrong " + annotation.getClass().getSimpleName() + " from is higher then to!");
  250. continue;
  251. }
  252. else if (type != ListenerRegisterType.NPC)
  253. {
  254. _log.log(Level.WARNING, getClass().getSimpleName() + ": ListenerRegisterType " + type + " for " + annotation.getClass().getSimpleName() + " NPC is expected!");
  255. continue;
  256. }
  257. for (int level = range.from(); level <= range.to(); level++)
  258. {
  259. final List<L2NpcTemplate> templates = NpcData.getInstance().getAllOfLevel(level);
  260. templates.forEach(template -> ids.add(template.getId()));
  261. }
  262. }
  263. else if (annotation instanceof NpcLevelRanges)
  264. {
  265. final NpcLevelRanges ranges = (NpcLevelRanges) annotation;
  266. for (NpcLevelRange range : ranges.value())
  267. {
  268. if (range.from() > range.to())
  269. {
  270. _log.log(Level.WARNING, getClass().getSimpleName() + ": Wrong " + annotation.getClass().getSimpleName() + " from is higher then to!");
  271. continue;
  272. }
  273. else if (type != ListenerRegisterType.NPC)
  274. {
  275. _log.log(Level.WARNING, getClass().getSimpleName() + ": ListenerRegisterType " + type + " for " + annotation.getClass().getSimpleName() + " NPC is expected!");
  276. continue;
  277. }
  278. for (int level = range.from(); level <= range.to(); level++)
  279. {
  280. final List<L2NpcTemplate> templates = NpcData.getInstance().getAllOfLevel(level);
  281. templates.forEach(template -> ids.add(template.getId()));
  282. }
  283. }
  284. }
  285. else if (annotation instanceof Priority)
  286. {
  287. final Priority p = (Priority) annotation;
  288. priority = p.value();
  289. }
  290. }
  291. if (!ids.isEmpty())
  292. {
  293. _registeredIds.putIfAbsent(type, ConcurrentHashMap.newKeySet(ids.size()));
  294. _registeredIds.get(type).addAll(ids);
  295. }
  296. registerAnnotation(method, eventType, type, priority, ids);
  297. }
  298. }
  299. }
  300. public void setActive(boolean status)
  301. {
  302. _isActive = status;
  303. }
  304. public boolean isActive()
  305. {
  306. return _isActive;
  307. }
  308. public File getScriptFile()
  309. {
  310. return _scriptFile;
  311. }
  312. public boolean reload()
  313. {
  314. try
  315. {
  316. ScriptEngineManager.getInstance().executeScript(getScriptFile());
  317. return true;
  318. }
  319. catch (Exception e)
  320. {
  321. return false;
  322. }
  323. }
  324. /**
  325. * Unloads all listeners registered by this class.
  326. * @return {@code true}
  327. */
  328. public boolean unload()
  329. {
  330. _listeners.forEach(AbstractEventListener::unregisterMe);
  331. _listeners.clear();
  332. return true;
  333. }
  334. public abstract ScriptManager<?> getManager();
  335. // ---------------------------------------------------------------------------------------------------------------------------
  336. /**
  337. * Provides delayed (Depending on {@link com.l2jserver.gameserver.model.actor.L2Attackable#getOnKillDelay()}) callback operation when L2Attackable dies from a player.
  338. * @param callback
  339. * @param npcIds
  340. * @return
  341. */
  342. protected final List<AbstractEventListener> setAttackableKillId(Consumer<OnAttackableKill> callback, int... npcIds)
  343. {
  344. return registerConsumer(callback, EventType.ON_ATTACKABLE_KILL, ListenerRegisterType.NPC, npcIds);
  345. }
  346. /**
  347. * Provides delayed (Depending on {@link com.l2jserver.gameserver.model.actor.L2Attackable#getOnKillDelay()}) callback operation when L2Attackable dies from a player.
  348. * @param callback
  349. * @param npcIds
  350. * @return
  351. */
  352. protected final List<AbstractEventListener> setAttackableKillId(Consumer<OnAttackableKill> callback, Collection<Integer> npcIds)
  353. {
  354. return registerConsumer(callback, EventType.ON_ATTACKABLE_KILL, ListenerRegisterType.NPC, npcIds);
  355. }
  356. // ---------------------------------------------------------------------------------------------------------------------------
  357. /**
  358. * Provides instant callback operation when L2Attackable dies from a player with return type.
  359. * @param callback
  360. * @param npcIds
  361. * @return
  362. */
  363. protected final List<AbstractEventListener> addCreatureKillId(Function<OnCreatureKill, ? extends AbstractEventReturn> callback, int... npcIds)
  364. {
  365. return registerFunction(callback, EventType.ON_CREATURE_KILL, ListenerRegisterType.NPC, npcIds);
  366. }
  367. /**
  368. * Provides instant callback operation when L2Attackable dies from a player.
  369. * @param callback
  370. * @param npcIds
  371. * @return
  372. */
  373. protected final List<AbstractEventListener> setCreatureKillId(Consumer<OnCreatureKill> callback, int... npcIds)
  374. {
  375. return registerConsumer(callback, EventType.ON_CREATURE_KILL, ListenerRegisterType.NPC, npcIds);
  376. }
  377. /**
  378. * Provides instant callback operation when {@link L2Attackable} dies from a {@link L2PcInstance}.
  379. * @param callback
  380. * @param npcIds
  381. * @return
  382. */
  383. protected final List<AbstractEventListener> setCreatureKillId(Consumer<OnCreatureKill> callback, Collection<Integer> npcIds)
  384. {
  385. return registerConsumer(callback, EventType.ON_CREATURE_KILL, ListenerRegisterType.NPC, npcIds);
  386. }
  387. // ---------------------------------------------------------------------------------------------------------------------------
  388. /**
  389. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} for first time.
  390. * @param callback
  391. * @param npcIds
  392. * @return
  393. */
  394. protected final List<AbstractEventListener> setNpcFirstTalkId(Consumer<OnNpcFirstTalk> callback, int... npcIds)
  395. {
  396. return registerConsumer(callback, EventType.ON_NPC_FIRST_TALK, ListenerRegisterType.NPC, npcIds);
  397. }
  398. /**
  399. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} for first time.
  400. * @param callback
  401. * @param npcIds
  402. * @return
  403. */
  404. protected final List<AbstractEventListener> setNpcFirstTalkId(Consumer<OnNpcFirstTalk> callback, Collection<Integer> npcIds)
  405. {
  406. return registerConsumer(callback, EventType.ON_NPC_FIRST_TALK, ListenerRegisterType.NPC, npcIds);
  407. }
  408. // ---------------------------------------------------------------------------------------------------------------------------
  409. protected final List<AbstractEventListener> setPlayerTutorialEvent(Consumer<OnPlayerTutorialEvent> callback)
  410. {
  411. return registerConsumer(callback, EventType.ON_PLAYER_TUTORIAL_EVENT, ListenerRegisterType.GLOBAL);
  412. }
  413. protected final List<AbstractEventListener> setPlayerTutorialClientEvent(Consumer<OnPlayerTutorialClientEvent> callback)
  414. {
  415. return registerConsumer(callback, EventType.ON_PLAYER_TUTORIAL_CLIENT_EVENT, ListenerRegisterType.GLOBAL);
  416. }
  417. protected final List<AbstractEventListener> setPlayerTutorialQuestionMark(Consumer<OnPlayerTutorialQuestionMark> callback)
  418. {
  419. return registerConsumer(callback, EventType.ON_PLAYER_TUTORIAL_QUESTION_MARK, ListenerRegisterType.GLOBAL);
  420. }
  421. protected final List<AbstractEventListener> setPlayerTutorialCmd(Consumer<OnPlayerTutorialCmd> callback)
  422. {
  423. return registerConsumer(callback, EventType.ON_PLAYER_TUTORIAL_CMD, ListenerRegisterType.GLOBAL);
  424. }
  425. // ---------------------------------------------------------------------------------------------------------------------------
  426. /**
  427. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc}.
  428. * @param npcIds
  429. * @return
  430. */
  431. protected final List<AbstractEventListener> setNpcTalkId(Collection<Integer> npcIds)
  432. {
  433. return registerDummy(EventType.ON_NPC_TALK, ListenerRegisterType.NPC, npcIds);
  434. }
  435. /**
  436. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc}.
  437. * @param npcIds
  438. * @return
  439. */
  440. protected final List<AbstractEventListener> setNpcTalkId(int... npcIds)
  441. {
  442. return registerDummy(EventType.ON_NPC_TALK, ListenerRegisterType.NPC, npcIds);
  443. }
  444. // ---------------------------------------------------------------------------------------------------------------------------
  445. /**
  446. * Provides instant callback operation when teleport {@link L2Npc}.
  447. * @param callback
  448. * @param npcIds
  449. * @return
  450. */
  451. protected final List<AbstractEventListener> setNpcTeleportId(Consumer<OnNpcTeleport> callback, Collection<Integer> npcIds)
  452. {
  453. return registerConsumer(callback, EventType.ON_NPC_TELEPORT, ListenerRegisterType.NPC, npcIds);
  454. }
  455. /**
  456. * Provides instant callback operation when teleport {@link L2Npc}.
  457. * @param callback
  458. * @param npcIds
  459. * @return
  460. */
  461. protected final List<AbstractEventListener> setNpcTeleportId(Consumer<OnNpcTeleport> callback, int... npcIds)
  462. {
  463. return registerConsumer(callback, EventType.ON_NPC_TELEPORT, ListenerRegisterType.NPC, npcIds);
  464. }
  465. // ---------------------------------------------------------------------------------------------------------------------------
  466. /**
  467. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} and must receive quest state.
  468. * @param npcIds
  469. * @return
  470. */
  471. protected final List<AbstractEventListener> setNpcQuestStartId(int... npcIds)
  472. {
  473. return registerDummy(EventType.ON_NPC_QUEST_START, ListenerRegisterType.NPC, npcIds);
  474. }
  475. /**
  476. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Npc} and must receive quest state.
  477. * @param npcIds
  478. * @return
  479. */
  480. protected final List<AbstractEventListener> setNpcQuestStartId(Collection<Integer> npcIds)
  481. {
  482. return registerDummy(EventType.ON_NPC_QUEST_START, ListenerRegisterType.NPC, npcIds);
  483. }
  484. // ---------------------------------------------------------------------------------------------------------------------------
  485. /**
  486. * Provides instant callback operation when L2Npc sees skill from a player.
  487. * @param callback
  488. * @param npcIds
  489. * @return
  490. */
  491. protected final List<AbstractEventListener> setNpcSkillSeeId(Consumer<OnNpcSkillSee> callback, int... npcIds)
  492. {
  493. return registerConsumer(callback, EventType.ON_NPC_SKILL_SEE, ListenerRegisterType.NPC, npcIds);
  494. }
  495. /**
  496. * Provides instant callback operation when L2Npc sees skill from a player.
  497. * @param callback
  498. * @param npcIds
  499. * @return
  500. */
  501. protected final List<AbstractEventListener> setNpcSkillSeeId(Consumer<OnNpcSkillSee> callback, Collection<Integer> npcIds)
  502. {
  503. return registerConsumer(callback, EventType.ON_NPC_SKILL_SEE, ListenerRegisterType.NPC, npcIds);
  504. }
  505. // ---------------------------------------------------------------------------------------------------------------------------
  506. /**
  507. * Provides instant callback operation when L2Npc casts skill on a player.
  508. * @param callback
  509. * @param npcIds
  510. * @return
  511. */
  512. protected final List<AbstractEventListener> setNpcSkillFinishedId(Consumer<OnNpcSkillFinished> callback, int... npcIds)
  513. {
  514. return registerConsumer(callback, EventType.ON_NPC_SKILL_FINISHED, ListenerRegisterType.NPC, npcIds);
  515. }
  516. /**
  517. * Provides instant callback operation when L2Npc casts skill on a player.
  518. * @param callback
  519. * @param npcIds
  520. * @return
  521. */
  522. protected final List<AbstractEventListener> setNpcSkillFinishedId(Consumer<OnNpcSkillFinished> callback, Collection<Integer> npcIds)
  523. {
  524. return registerConsumer(callback, EventType.ON_NPC_SKILL_FINISHED, ListenerRegisterType.NPC, npcIds);
  525. }
  526. // ---------------------------------------------------------------------------------------------------------------------------
  527. /**
  528. * Provides instant callback operation when L2Npc is spawned.
  529. * @param callback
  530. * @param npcIds
  531. * @return
  532. */
  533. protected final List<AbstractEventListener> setNpcSpawnId(Consumer<OnNpcSpawn> callback, int... npcIds)
  534. {
  535. return registerConsumer(callback, EventType.ON_NPC_SPAWN, ListenerRegisterType.NPC, npcIds);
  536. }
  537. /**
  538. * Provides instant callback operation when L2Npc is spawned.
  539. * @param callback
  540. * @param npcIds
  541. * @return
  542. */
  543. protected final List<AbstractEventListener> setNpcSpawnId(Consumer<OnNpcSpawn> callback, Collection<Integer> npcIds)
  544. {
  545. return registerConsumer(callback, EventType.ON_NPC_SPAWN, ListenerRegisterType.NPC, npcIds);
  546. }
  547. // ---------------------------------------------------------------------------------------------------------------------------
  548. /**
  549. * Provides instant callback operation when {@link L2Npc} receives event from another {@link L2Npc}
  550. * @param callback
  551. * @param npcIds
  552. * @return
  553. */
  554. protected final List<AbstractEventListener> setNpcEventReceivedId(Consumer<OnNpcEventReceived> callback, int... npcIds)
  555. {
  556. return registerConsumer(callback, EventType.ON_NPC_EVENT_RECEIVED, ListenerRegisterType.NPC, npcIds);
  557. }
  558. /**
  559. * Provides instant callback operation when {@link L2Npc} receives event from another {@link L2Npc}
  560. * @param callback
  561. * @param npcIds
  562. * @return
  563. */
  564. protected final List<AbstractEventListener> setNpcEventReceivedId(Consumer<OnNpcEventReceived> callback, Collection<Integer> npcIds)
  565. {
  566. return registerConsumer(callback, EventType.ON_NPC_EVENT_RECEIVED, ListenerRegisterType.NPC, npcIds);
  567. }
  568. // ---------------------------------------------------------------------------------------------------------------------------
  569. /**
  570. * Provides instant callback operation when {@link L2Npc} finishes to move.
  571. * @param callback
  572. * @param npcIds
  573. * @return
  574. */
  575. protected final List<AbstractEventListener> setNpcMoveFinishedId(Consumer<OnNpcMoveFinished> callback, int... npcIds)
  576. {
  577. return registerConsumer(callback, EventType.ON_NPC_MOVE_FINISHED, ListenerRegisterType.NPC, npcIds);
  578. }
  579. /**
  580. * Provides instant callback operation when {@link L2Npc} finishes to move.
  581. * @param callback
  582. * @param npcIds
  583. * @return
  584. */
  585. protected final List<AbstractEventListener> setNpcMoveFinishedId(Consumer<OnNpcMoveFinished> callback, Collection<Integer> npcIds)
  586. {
  587. return registerConsumer(callback, EventType.ON_NPC_MOVE_FINISHED, ListenerRegisterType.NPC, npcIds);
  588. }
  589. // ---------------------------------------------------------------------------------------------------------------------------
  590. /**
  591. * Provides instant callback operation when {@link L2Npc} arrive to node of its route
  592. * @param callback
  593. * @param npcIds
  594. * @return
  595. */
  596. protected final List<AbstractEventListener> setNpcMoveNodeArrivedId(Consumer<OnNpcMoveNodeArrived> callback, int... npcIds)
  597. {
  598. return registerConsumer(callback, EventType.ON_NPC_MOVE_NODE_ARRIVED, ListenerRegisterType.NPC, npcIds);
  599. }
  600. /**
  601. * Provides instant callback operation when {@link L2Npc} arrive to node of its route
  602. * @param callback
  603. * @param npcIds
  604. * @return
  605. */
  606. protected final List<AbstractEventListener> setNpcMoveNodeArrivedId(Consumer<OnNpcMoveNodeArrived> callback, Collection<Integer> npcIds)
  607. {
  608. return registerConsumer(callback, EventType.ON_NPC_MOVE_NODE_ARRIVED, ListenerRegisterType.NPC, npcIds);
  609. }
  610. // ---------------------------------------------------------------------------------------------------------------------------
  611. /**
  612. * Provides instant callback operation when {@link L2Npc} finishes to move on its route.
  613. * @param callback
  614. * @param npcIds
  615. * @return
  616. */
  617. protected final List<AbstractEventListener> setNpcMoveRouteFinishedId(Consumer<OnNpcMoveRouteFinished> callback, int... npcIds)
  618. {
  619. return registerConsumer(callback, EventType.ON_NPC_MOVE_ROUTE_FINISHED, ListenerRegisterType.NPC, npcIds);
  620. }
  621. /**
  622. * Provides instant callback operation when {@link L2Npc} finishes to move on its route.
  623. * @param callback
  624. * @param npcIds
  625. * @return
  626. */
  627. protected final List<AbstractEventListener> setNpcMoveRouteFinishedId(Consumer<OnNpcMoveRouteFinished> callback, Collection<Integer> npcIds)
  628. {
  629. return registerConsumer(callback, EventType.ON_NPC_MOVE_ROUTE_FINISHED, ListenerRegisterType.NPC, npcIds);
  630. }
  631. // ---------------------------------------------------------------------------------------------------------------------------
  632. /**
  633. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  634. * @param callback
  635. * @param npcIds
  636. * @return
  637. */
  638. protected final List<AbstractEventListener> setNpcHateId(Consumer<OnAttackableHate> callback, int... npcIds)
  639. {
  640. return registerConsumer(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
  641. }
  642. /**
  643. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  644. * @param callback
  645. * @param npcIds
  646. * @return
  647. */
  648. protected final List<AbstractEventListener> setNpcHateId(Consumer<OnAttackableHate> callback, Collection<Integer> npcIds)
  649. {
  650. return registerConsumer(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
  651. }
  652. /**
  653. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  654. * @param callback
  655. * @param npcIds
  656. * @return
  657. */
  658. protected final List<AbstractEventListener> addNpcHateId(Function<OnAttackableHate, TerminateReturn> callback, int... npcIds)
  659. {
  660. return registerFunction(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
  661. }
  662. /**
  663. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  664. * @param callback
  665. * @param npcIds
  666. * @return
  667. */
  668. protected final List<AbstractEventListener> addNpcHateId(Function<OnAttackableHate, TerminateReturn> callback, Collection<Integer> npcIds)
  669. {
  670. return registerFunction(callback, EventType.ON_NPC_HATE, ListenerRegisterType.NPC, npcIds);
  671. }
  672. // ---------------------------------------------------------------------------------------------------------------------------
  673. /**
  674. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  675. * @param callback
  676. * @param npcIds
  677. * @return
  678. */
  679. protected final List<AbstractEventListener> setNpcCanBeSeenId(Consumer<OnNpcCanBeSeen> callback, int... npcIds)
  680. {
  681. return registerConsumer(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
  682. }
  683. /**
  684. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  685. * @param callback
  686. * @param npcIds
  687. * @return
  688. */
  689. protected final List<AbstractEventListener> setNpcCanBeSeenId(Consumer<OnNpcCanBeSeen> callback, Collection<Integer> npcIds)
  690. {
  691. return registerConsumer(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
  692. }
  693. /**
  694. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  695. * @param callback
  696. * @param npcIds
  697. * @return
  698. */
  699. protected final List<AbstractEventListener> setNpcCanBeSeenId(Function<OnNpcCanBeSeen, TerminateReturn> callback, int... npcIds)
  700. {
  701. return registerFunction(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
  702. }
  703. /**
  704. * Provides instant callback operation when {@link L2Npc} is about to hate and start attacking a creature.
  705. * @param callback
  706. * @param npcIds
  707. * @return
  708. */
  709. protected final List<AbstractEventListener> setNpcCanBeSeenId(Function<OnNpcCanBeSeen, TerminateReturn> callback, Collection<Integer> npcIds)
  710. {
  711. return registerFunction(callback, EventType.ON_NPC_CAN_BE_SEEN, ListenerRegisterType.NPC, npcIds);
  712. }
  713. // ---------------------------------------------------------------------------------------------------------------------------
  714. /**
  715. * Provides instant callback operation when {@link L2Npc} sees another creature.
  716. * @param callback
  717. * @param npcIds
  718. * @return
  719. */
  720. protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, int... npcIds)
  721. {
  722. return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
  723. }
  724. /**
  725. * Provides instant callback operation when {@link L2Npc} sees another creature.
  726. * @param callback
  727. * @param npcIds
  728. * @return
  729. */
  730. protected final List<AbstractEventListener> setNpcCreatureSeeId(Consumer<OnNpcCreatureSee> callback, Collection<Integer> npcIds)
  731. {
  732. return registerConsumer(callback, EventType.ON_NPC_CREATURE_SEE, ListenerRegisterType.NPC, npcIds);
  733. }
  734. // ---------------------------------------------------------------------------------------------------------------------------
  735. /**
  736. * Provides instant callback operation when L2Attackable is under attack to other clan mates.
  737. * @param callback
  738. * @param npcIds
  739. * @return
  740. */
  741. protected final List<AbstractEventListener> setAttackableFactionIdId(Consumer<OnAttackableFactionCall> callback, int... npcIds)
  742. {
  743. return registerConsumer(callback, EventType.ON_ATTACKABLE_FACTION_CALL, ListenerRegisterType.NPC, npcIds);
  744. }
  745. /**
  746. * Provides instant callback operation when L2Attackable is under attack to other clan mates.
  747. * @param callback
  748. * @param npcIds
  749. * @return
  750. */
  751. protected final List<AbstractEventListener> setAttackableFactionIdId(Consumer<OnAttackableFactionCall> callback, Collection<Integer> npcIds)
  752. {
  753. return registerConsumer(callback, EventType.ON_ATTACKABLE_FACTION_CALL, ListenerRegisterType.NPC, npcIds);
  754. }
  755. // ---------------------------------------------------------------------------------------------------------------------------
  756. /**
  757. * Provides instant callback operation when L2Attackable is attacked from a player.
  758. * @param callback
  759. * @param npcIds
  760. * @return
  761. */
  762. protected final List<AbstractEventListener> setAttackableAttackId(Consumer<OnAttackableAttack> callback, int... npcIds)
  763. {
  764. return registerConsumer(callback, EventType.ON_ATTACKABLE_ATTACK, ListenerRegisterType.NPC, npcIds);
  765. }
  766. /**
  767. * Provides instant callback operation when L2Attackable is attacked from a player.
  768. * @param callback
  769. * @param npcIds
  770. * @return
  771. */
  772. protected final List<AbstractEventListener> setAttackableAttackId(Consumer<OnAttackableAttack> callback, Collection<Integer> npcIds)
  773. {
  774. return registerConsumer(callback, EventType.ON_ATTACKABLE_ATTACK, ListenerRegisterType.NPC, npcIds);
  775. }
  776. // ---------------------------------------------------------------------------------------------------------------------------
  777. /**
  778. * Provides instant callback operation when {@link L2PcInstance} enters in {@link L2Attackable}'s aggressive range.
  779. * @param callback
  780. * @param npcIds
  781. * @return
  782. */
  783. protected final List<AbstractEventListener> setAttackableAggroRangeEnterId(Consumer<OnAttackableAggroRangeEnter> callback, int... npcIds)
  784. {
  785. return registerConsumer(callback, EventType.ON_ATTACKABLE_AGGRO_RANGE_ENTER, ListenerRegisterType.NPC, npcIds);
  786. }
  787. /**
  788. * Provides instant callback operation when {@link L2PcInstance} enters in {@link L2Attackable}'s aggressive range.
  789. * @param callback
  790. * @param npcIds
  791. * @return
  792. */
  793. protected final List<AbstractEventListener> setAttackableAggroRangeEnterId(Consumer<OnAttackableAggroRangeEnter> callback, Collection<Integer> npcIds)
  794. {
  795. return registerConsumer(callback, EventType.ON_ATTACKABLE_AGGRO_RANGE_ENTER, ListenerRegisterType.NPC, npcIds);
  796. }
  797. // ---------------------------------------------------------------------------------------------------------------------------
  798. /**
  799. * Provides instant callback operation when {@link L2PcInstance} learn's a {@link Skill}.
  800. * @param callback
  801. * @param npcIds
  802. * @return
  803. */
  804. protected final List<AbstractEventListener> setPlayerSkillLearnId(Consumer<OnPlayerSkillLearn> callback, int... npcIds)
  805. {
  806. return registerConsumer(callback, EventType.ON_PLAYER_SKILL_LEARN, ListenerRegisterType.NPC, npcIds);
  807. }
  808. /**
  809. * Provides instant callback operation when {@link L2PcInstance} learn's a {@link Skill}.
  810. * @param callback
  811. * @param npcIds
  812. * @return
  813. */
  814. protected final List<AbstractEventListener> setPlayerSkillLearnId(Consumer<OnPlayerSkillLearn> callback, Collection<Integer> npcIds)
  815. {
  816. return registerConsumer(callback, EventType.ON_PLAYER_SKILL_LEARN, ListenerRegisterType.NPC, npcIds);
  817. }
  818. // ---------------------------------------------------------------------------------------------------------------------------
  819. /**
  820. * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
  821. * @param callback
  822. * @param npcIds
  823. * @return
  824. */
  825. protected final List<AbstractEventListener> setPlayerSummonSpawnId(Consumer<OnPlayerSummonSpawn> callback, int... npcIds)
  826. {
  827. return registerConsumer(callback, EventType.ON_PLAYER_SUMMON_SPAWN, ListenerRegisterType.NPC, npcIds);
  828. }
  829. /**
  830. * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
  831. * @param callback
  832. * @param npcIds
  833. * @return
  834. */
  835. protected final List<AbstractEventListener> setPlayerSummonSpawnId(Consumer<OnPlayerSummonSpawn> callback, Collection<Integer> npcIds)
  836. {
  837. return registerConsumer(callback, EventType.ON_PLAYER_SUMMON_SPAWN, ListenerRegisterType.NPC, npcIds);
  838. }
  839. // ---------------------------------------------------------------------------------------------------------------------------
  840. /**
  841. * Provides instant callback operation when {@link L2PcInstance} talk with a servitor or a pet
  842. * @param callback
  843. * @param npcIds
  844. * @return
  845. */
  846. protected final List<AbstractEventListener> setPlayerSummonTalkId(Consumer<OnPlayerSummonTalk> callback, int... npcIds)
  847. {
  848. return registerConsumer(callback, EventType.ON_PLAYER_SUMMON_TALK, ListenerRegisterType.NPC, npcIds);
  849. }
  850. /**
  851. * Provides instant callback operation when {@link L2PcInstance} talk with a servitor or a pet
  852. * @param callback
  853. * @param npcIds
  854. * @return
  855. */
  856. protected final List<AbstractEventListener> setPlayerSummonTalkId(Consumer<OnPlayerSummonSpawn> callback, Collection<Integer> npcIds)
  857. {
  858. return registerConsumer(callback, EventType.ON_PLAYER_SUMMON_TALK, ListenerRegisterType.NPC, npcIds);
  859. }
  860. // ---------------------------------------------------------------------------------------------------------------------------
  861. /**
  862. * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
  863. * @param callback
  864. * @return
  865. */
  866. protected final List<AbstractEventListener> setPlayerLoginId(Consumer<OnPlayerLogin> callback)
  867. {
  868. return registerConsumer(callback, EventType.ON_PLAYER_LOGIN, ListenerRegisterType.GLOBAL);
  869. }
  870. // ---------------------------------------------------------------------------------------------------------------------------
  871. /**
  872. * Provides instant callback operation when {@link L2PcInstance} summons a servitor or a pet
  873. * @param callback
  874. * @return
  875. */
  876. protected final List<AbstractEventListener> setPlayerLogoutId(Consumer<OnPlayerLogout> callback)
  877. {
  878. return registerConsumer(callback, EventType.ON_PLAYER_LOGOUT, ListenerRegisterType.GLOBAL);
  879. }
  880. // ---------------------------------------------------------------------------------------------------------------------------
  881. /**
  882. * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Enters on a {@link L2ZoneType}.
  883. * @param callback
  884. * @param npcIds
  885. * @return
  886. */
  887. protected final List<AbstractEventListener> setCreatureZoneEnterId(Consumer<OnCreatureZoneEnter> callback, int... npcIds)
  888. {
  889. return registerConsumer(callback, EventType.ON_CREATURE_ZONE_ENTER, ListenerRegisterType.ZONE, npcIds);
  890. }
  891. /**
  892. * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Enters on a {@link L2ZoneType}.
  893. * @param callback
  894. * @param npcIds
  895. * @return
  896. */
  897. protected final List<AbstractEventListener> setCreatureZoneEnterId(Consumer<OnCreatureZoneEnter> callback, Collection<Integer> npcIds)
  898. {
  899. return registerConsumer(callback, EventType.ON_CREATURE_ZONE_ENTER, ListenerRegisterType.ZONE, npcIds);
  900. }
  901. // ---------------------------------------------------------------------------------------------------------------------------
  902. /**
  903. * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Exits on a {@link L2ZoneType}.
  904. * @param callback
  905. * @param npcIds
  906. * @return
  907. */
  908. protected final List<AbstractEventListener> setCreatureZoneExitId(Consumer<OnCreatureZoneExit> callback, int... npcIds)
  909. {
  910. return registerConsumer(callback, EventType.ON_CREATURE_ZONE_EXIT, ListenerRegisterType.ZONE, npcIds);
  911. }
  912. /**
  913. * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.L2Character} Exits on a {@link L2ZoneType}.
  914. * @param callback
  915. * @param npcIds
  916. * @return
  917. */
  918. protected final List<AbstractEventListener> setCreatureZoneExitId(Consumer<OnCreatureZoneExit> callback, Collection<Integer> npcIds)
  919. {
  920. return registerConsumer(callback, EventType.ON_CREATURE_ZONE_EXIT, ListenerRegisterType.ZONE, npcIds);
  921. }
  922. // ---------------------------------------------------------------------------------------------------------------------------
  923. /**
  924. * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.instance.L2TrapInstance} acts.
  925. * @param callback
  926. * @param npcIds
  927. * @return
  928. */
  929. protected final List<AbstractEventListener> setTrapActionId(Consumer<OnTrapAction> callback, int... npcIds)
  930. {
  931. return registerConsumer(callback, EventType.ON_TRAP_ACTION, ListenerRegisterType.NPC, npcIds);
  932. }
  933. /**
  934. * Provides instant callback operation when {@link com.l2jserver.gameserver.model.actor.instance.L2TrapInstance} acts.
  935. * @param callback
  936. * @param npcIds
  937. * @return
  938. */
  939. protected final List<AbstractEventListener> setTrapActionId(Consumer<OnTrapAction> callback, Collection<Integer> npcIds)
  940. {
  941. return registerConsumer(callback, EventType.ON_TRAP_ACTION, ListenerRegisterType.NPC, npcIds);
  942. }
  943. // ---------------------------------------------------------------------------------------------------------------------------
  944. /**
  945. * Provides instant callback operation when {@link L2Item} receives an event from {@link L2PcInstance}.
  946. * @param callback
  947. * @param npcIds
  948. * @return
  949. */
  950. protected final List<AbstractEventListener> setItemBypassEvenId(Consumer<OnItemBypassEvent> callback, int... npcIds)
  951. {
  952. return registerConsumer(callback, EventType.ON_ITEM_BYPASS_EVENT, ListenerRegisterType.ITEM, npcIds);
  953. }
  954. /**
  955. * Provides instant callback operation when {@link L2Item} receives an event from {@link L2PcInstance}.
  956. * @param callback
  957. * @param npcIds
  958. * @return
  959. */
  960. protected final List<AbstractEventListener> setItemBypassEvenId(Consumer<OnItemBypassEvent> callback, Collection<Integer> npcIds)
  961. {
  962. return registerConsumer(callback, EventType.ON_ITEM_BYPASS_EVENT, ListenerRegisterType.ITEM, npcIds);
  963. }
  964. // ---------------------------------------------------------------------------------------------------------------------------
  965. /**
  966. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Item}.
  967. * @param callback
  968. * @param npcIds
  969. * @return
  970. */
  971. protected final List<AbstractEventListener> setItemTalkId(Consumer<OnItemTalk> callback, int... npcIds)
  972. {
  973. return registerConsumer(callback, EventType.ON_ITEM_TALK, ListenerRegisterType.ITEM, npcIds);
  974. }
  975. /**
  976. * Provides instant callback operation when {@link L2PcInstance} talk to {@link L2Item}.
  977. * @param callback
  978. * @param npcIds
  979. * @return
  980. */
  981. protected final List<AbstractEventListener> setItemTalkId(Consumer<OnItemTalk> callback, Collection<Integer> npcIds)
  982. {
  983. return registerConsumer(callback, EventType.ON_ITEM_TALK, ListenerRegisterType.ITEM, npcIds);
  984. }
  985. // ---------------------------------------------------------------------------------------------------------------------------
  986. /**
  987. * Provides instant callback operation when Olympiad match finishes.
  988. * @param callback
  989. * @return
  990. */
  991. protected final List<AbstractEventListener> setOlympiadMatchResult(Consumer<OnOlympiadMatchResult> callback)
  992. {
  993. return registerConsumer(callback, EventType.ON_OLYMPIAD_MATCH_RESULT, ListenerRegisterType.OLYMPIAD);
  994. }
  995. // ---------------------------------------------------------------------------------------------------------------------------
  996. /**
  997. * Provides instant callback operation when castle siege begins
  998. * @param callback
  999. * @param castleIds
  1000. * @return
  1001. */
  1002. protected final List<AbstractEventListener> setCastleSiegeStartId(Consumer<OnCastleSiegeStart> callback, int... castleIds)
  1003. {
  1004. return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_START, ListenerRegisterType.CASTLE, castleIds);
  1005. }
  1006. /**
  1007. * Provides instant callback operation when castle siege begins
  1008. * @param callback
  1009. * @param castleIds
  1010. * @return
  1011. */
  1012. protected final List<AbstractEventListener> setCastleSiegeStartId(Consumer<OnCastleSiegeStart> callback, Collection<Integer> castleIds)
  1013. {
  1014. return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_START, ListenerRegisterType.CASTLE, castleIds);
  1015. }
  1016. // ---------------------------------------------------------------------------------------------------------------------------
  1017. /**
  1018. * Provides instant callback operation when Castle owner has changed during a siege
  1019. * @param callback
  1020. * @param castleIds
  1021. * @return
  1022. */
  1023. protected final List<AbstractEventListener> setCastleSiegeOwnerChangeId(Consumer<OnCastleSiegeOwnerChange> callback, int... castleIds)
  1024. {
  1025. return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_OWNER_CHANGE, ListenerRegisterType.CASTLE, castleIds);
  1026. }
  1027. /**
  1028. * Provides instant callback operation when Castle owner has changed during a siege
  1029. * @param callback
  1030. * @param castleIds
  1031. * @return
  1032. */
  1033. protected final List<AbstractEventListener> setCastleSiegeOwnerChangeId(Consumer<OnCastleSiegeOwnerChange> callback, Collection<Integer> castleIds)
  1034. {
  1035. return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_OWNER_CHANGE, ListenerRegisterType.CASTLE, castleIds);
  1036. }
  1037. // ---------------------------------------------------------------------------------------------------------------------------
  1038. /**
  1039. * Provides instant callback operation when castle siege ends
  1040. * @param callback
  1041. * @param castleIds
  1042. * @return
  1043. */
  1044. protected final List<AbstractEventListener> setCastleSiegeFinishId(Consumer<OnCastleSiegeFinish> callback, int... castleIds)
  1045. {
  1046. return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_FINISH, ListenerRegisterType.CASTLE, castleIds);
  1047. }
  1048. /**
  1049. * Provides instant callback operation when castle siege ends
  1050. * @param callback
  1051. * @param castleIds
  1052. * @return
  1053. */
  1054. protected final List<AbstractEventListener> setCastleSiegeFinishId(Consumer<OnCastleSiegeFinish> callback, Collection<Integer> castleIds)
  1055. {
  1056. return registerConsumer(callback, EventType.ON_CASTLE_SIEGE_FINISH, ListenerRegisterType.CASTLE, castleIds);
  1057. }
  1058. // ---------------------------------------------------------------------------------------------------------------------------
  1059. /**
  1060. * Provides instant callback operation when player's profession has change
  1061. * @param callback
  1062. * @return
  1063. */
  1064. protected final List<AbstractEventListener> setPlayerProfessionChangeId(Consumer<OnPlayerProfessionChange> callback)
  1065. {
  1066. return registerConsumer(callback, EventType.ON_PLAYER_PROFESSION_CHANGE, ListenerRegisterType.GLOBAL);
  1067. }
  1068. /**
  1069. * Provides instant callback operation when player's cancel profession
  1070. * @param callback
  1071. * @return
  1072. */
  1073. protected final List<AbstractEventListener> setPlayerProfessionCancelId(Consumer<OnPlayerProfessionCancel> callback)
  1074. {
  1075. return registerConsumer(callback, EventType.ON_PLAYER_PROFESSION_CANCEL, ListenerRegisterType.GLOBAL);
  1076. }
  1077. // --------------------------------------------------------------------------------------------------
  1078. // --------------------------------Default listener register methods---------------------------------
  1079. // --------------------------------------------------------------------------------------------------
  1080. /**
  1081. * Method that registers Function type of listeners (Listeners that need parameters but doesn't return objects)
  1082. * @param callback
  1083. * @param type
  1084. * @param registerType
  1085. * @param npcIds
  1086. * @return
  1087. */
  1088. protected final List<AbstractEventListener> registerConsumer(Consumer<? extends IBaseEvent> callback, EventType type, ListenerRegisterType registerType, int... npcIds)
  1089. {
  1090. return registerListener((container) -> new ConsumerEventListener(container, type, callback, this), registerType, npcIds);
  1091. }
  1092. /**
  1093. * Method that registers Function type of listeners (Listeners that need parameters but doesn't return objects)
  1094. * @param callback
  1095. * @param type
  1096. * @param registerType
  1097. * @param npcIds
  1098. * @return
  1099. */
  1100. protected final List<AbstractEventListener> registerConsumer(Consumer<? extends IBaseEvent> callback, EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
  1101. {
  1102. return registerListener((container) -> new ConsumerEventListener(container, type, callback, this), registerType, npcIds);
  1103. }
  1104. /**
  1105. * Method that registers Function type of listeners (Listeners that need parameters and return objects)
  1106. * @param callback
  1107. * @param type
  1108. * @param registerType
  1109. * @param npcIds
  1110. * @return
  1111. */
  1112. protected final List<AbstractEventListener> registerFunction(Function<? extends IBaseEvent, ? extends AbstractEventReturn> callback, EventType type, ListenerRegisterType registerType, int... npcIds)
  1113. {
  1114. return registerListener((container) -> new FunctionEventListener(container, type, callback, this), registerType, npcIds);
  1115. }
  1116. /**
  1117. * Method that registers Function type of listeners (Listeners that need parameters and return objects)
  1118. * @param callback
  1119. * @param type
  1120. * @param registerType
  1121. * @param npcIds
  1122. * @return
  1123. */
  1124. protected final List<AbstractEventListener> registerFunction(Function<? extends IBaseEvent, ? extends AbstractEventReturn> callback, EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
  1125. {
  1126. return registerListener((container) -> new FunctionEventListener(container, type, callback, this), registerType, npcIds);
  1127. }
  1128. /**
  1129. * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
  1130. * @param callback
  1131. * @param type
  1132. * @param registerType
  1133. * @param npcIds
  1134. * @return
  1135. */
  1136. protected final List<AbstractEventListener> registerRunnable(Runnable callback, EventType type, ListenerRegisterType registerType, int... npcIds)
  1137. {
  1138. return registerListener((container) -> new RunnableEventListener(container, type, callback, this), registerType, npcIds);
  1139. }
  1140. /**
  1141. * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
  1142. * @param callback
  1143. * @param type
  1144. * @param registerType
  1145. * @param npcIds
  1146. * @return
  1147. */
  1148. protected final List<AbstractEventListener> registerRunnable(Runnable callback, EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
  1149. {
  1150. return registerListener((container) -> new RunnableEventListener(container, type, callback, this), registerType, npcIds);
  1151. }
  1152. /**
  1153. * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
  1154. * @param callback
  1155. * @param type
  1156. * @param registerType
  1157. * @param priority
  1158. * @param npcIds
  1159. * @return
  1160. */
  1161. protected final List<AbstractEventListener> registerAnnotation(Method callback, EventType type, ListenerRegisterType registerType, int priority, int... npcIds)
  1162. {
  1163. return registerListener((container) -> new AnnotationEventListener(container, type, callback, this, priority), registerType, npcIds);
  1164. }
  1165. /**
  1166. * Method that registers runnable type of listeners (Listeners that doesn't needs parameters or return objects)
  1167. * @param callback
  1168. * @param type
  1169. * @param registerType
  1170. * @param priority
  1171. * @param npcIds
  1172. * @return
  1173. */
  1174. protected final List<AbstractEventListener> registerAnnotation(Method callback, EventType type, ListenerRegisterType registerType, int priority, Collection<Integer> npcIds)
  1175. {
  1176. return registerListener((container) -> new AnnotationEventListener(container, type, callback, this, priority), registerType, npcIds);
  1177. }
  1178. /**
  1179. * Method that registers dummy type of listeners (Listeners doesn't gets notification but just used to check if their type present or not)
  1180. * @param type
  1181. * @param registerType
  1182. * @param npcIds
  1183. * @return
  1184. */
  1185. protected final List<AbstractEventListener> registerDummy(EventType type, ListenerRegisterType registerType, int... npcIds)
  1186. {
  1187. return registerListener((container) -> new DummyEventListener(container, type, this), registerType, npcIds);
  1188. }
  1189. /**
  1190. * Method that registers dummy type of listeners (Listeners doesn't gets notification but just used to check if their type present or not)
  1191. * @param type
  1192. * @param registerType
  1193. * @param npcIds
  1194. * @return
  1195. */
  1196. protected final List<AbstractEventListener> registerDummy(EventType type, ListenerRegisterType registerType, Collection<Integer> npcIds)
  1197. {
  1198. return registerListener((container) -> new DummyEventListener(container, type, this), registerType, npcIds);
  1199. }
  1200. // --------------------------------------------------------------------------------------------------
  1201. // --------------------------------------Register methods--------------------------------------------
  1202. // --------------------------------------------------------------------------------------------------
  1203. /**
  1204. * Generic listener register method
  1205. * @param action
  1206. * @param registerType
  1207. * @param ids
  1208. * @return
  1209. */
  1210. protected final List<AbstractEventListener> registerListener(Function<ListenersContainer, AbstractEventListener> action, ListenerRegisterType registerType, int... ids)
  1211. {
  1212. final List<AbstractEventListener> listeners = new ArrayList<>(ids.length > 0 ? ids.length : 1);
  1213. if (ids.length > 0)
  1214. {
  1215. for (int id : ids)
  1216. {
  1217. switch (registerType)
  1218. {
  1219. case NPC:
  1220. {
  1221. final L2NpcTemplate template = NpcData.getInstance().getTemplate(id);
  1222. if (template != null)
  1223. {
  1224. listeners.add(template.addListener(action.apply(template)));
  1225. }
  1226. break;
  1227. }
  1228. case ZONE:
  1229. {
  1230. final L2ZoneType template = ZoneManager.getInstance().getZoneById(id);
  1231. if (template != null)
  1232. {
  1233. listeners.add(template.addListener(action.apply(template)));
  1234. }
  1235. break;
  1236. }
  1237. case ITEM:
  1238. {
  1239. final L2Item template = ItemTable.getInstance().getTemplate(id);
  1240. if (template != null)
  1241. {
  1242. listeners.add(template.addListener(action.apply(template)));
  1243. }
  1244. break;
  1245. }
  1246. case CASTLE:
  1247. {
  1248. final Castle template = CastleManager.getInstance().getCastleById(id);
  1249. if (template != null)
  1250. {
  1251. listeners.add(template.addListener(action.apply(template)));
  1252. }
  1253. break;
  1254. }
  1255. case FORTRESS:
  1256. {
  1257. final Fort template = FortManager.getInstance().getFortById(id);
  1258. if (template != null)
  1259. {
  1260. listeners.add(template.addListener(action.apply(template)));
  1261. }
  1262. break;
  1263. }
  1264. default:
  1265. {
  1266. _log.log(Level.WARNING, getClass().getSimpleName() + ": Unhandled register type: " + registerType);
  1267. }
  1268. }
  1269. _registeredIds.putIfAbsent(registerType, ConcurrentHashMap.newKeySet(1));
  1270. _registeredIds.get(registerType).add(id);
  1271. }
  1272. }
  1273. else
  1274. {
  1275. switch (registerType)
  1276. {
  1277. case OLYMPIAD:
  1278. {
  1279. final Olympiad template = Olympiad.getInstance();
  1280. listeners.add(template.addListener(action.apply(template)));
  1281. break;
  1282. }
  1283. case GLOBAL: // Global Listener
  1284. {
  1285. final ListenersContainer template = Containers.Global();
  1286. listeners.add(template.addListener(action.apply(template)));
  1287. break;
  1288. }
  1289. case GLOBAL_NPCS: // Global Npcs Listener
  1290. {
  1291. final ListenersContainer template = Containers.Npcs();
  1292. listeners.add(template.addListener(action.apply(template)));
  1293. break;
  1294. }
  1295. case GLOBAL_MONSTERS: // Global Monsters Listener
  1296. {
  1297. final ListenersContainer template = Containers.Monsters();
  1298. listeners.add(template.addListener(action.apply(template)));
  1299. break;
  1300. }
  1301. case GLOBAL_PLAYERS: // Global Players Listener
  1302. {
  1303. final ListenersContainer template = Containers.Players();
  1304. listeners.add(template.addListener(action.apply(template)));
  1305. break;
  1306. }
  1307. }
  1308. }
  1309. _listeners.addAll(listeners);
  1310. return listeners;
  1311. }
  1312. /**
  1313. * Generic listener register method
  1314. * @param action
  1315. * @param registerType
  1316. * @param ids
  1317. * @return
  1318. */
  1319. protected final List<AbstractEventListener> registerListener(Function<ListenersContainer, AbstractEventListener> action, ListenerRegisterType registerType, Collection<Integer> ids)
  1320. {
  1321. final List<AbstractEventListener> listeners = new ArrayList<>(!ids.isEmpty() ? ids.size() : 1);
  1322. if (!ids.isEmpty())
  1323. {
  1324. for (int id : ids)
  1325. {
  1326. switch (registerType)
  1327. {
  1328. case NPC:
  1329. {
  1330. final L2NpcTemplate template = NpcData.getInstance().getTemplate(id);
  1331. if (template != null)
  1332. {
  1333. listeners.add(template.addListener(action.apply(template)));
  1334. }
  1335. break;
  1336. }
  1337. case ZONE:
  1338. {
  1339. final L2ZoneType template = ZoneManager.getInstance().getZoneById(id);
  1340. if (template != null)
  1341. {
  1342. listeners.add(template.addListener(action.apply(template)));
  1343. }
  1344. break;
  1345. }
  1346. case ITEM:
  1347. {
  1348. final L2Item template = ItemTable.getInstance().getTemplate(id);
  1349. if (template != null)
  1350. {
  1351. listeners.add(template.addListener(action.apply(template)));
  1352. }
  1353. break;
  1354. }
  1355. case CASTLE:
  1356. {
  1357. final Castle template = CastleManager.getInstance().getCastleById(id);
  1358. if (template != null)
  1359. {
  1360. listeners.add(template.addListener(action.apply(template)));
  1361. }
  1362. break;
  1363. }
  1364. case FORTRESS:
  1365. {
  1366. final Fort template = FortManager.getInstance().getFortById(id);
  1367. if (template != null)
  1368. {
  1369. listeners.add(template.addListener(action.apply(template)));
  1370. }
  1371. break;
  1372. }
  1373. default:
  1374. {
  1375. _log.log(Level.WARNING, getClass().getSimpleName() + ": Unhandled register type: " + registerType);
  1376. }
  1377. }
  1378. }
  1379. _registeredIds.putIfAbsent(registerType, ConcurrentHashMap.newKeySet(ids.size()));
  1380. _registeredIds.get(registerType).addAll(ids);
  1381. }
  1382. else
  1383. {
  1384. switch (registerType)
  1385. {
  1386. case OLYMPIAD:
  1387. {
  1388. final Olympiad template = Olympiad.getInstance();
  1389. listeners.add(template.addListener(action.apply(template)));
  1390. break;
  1391. }
  1392. case GLOBAL: // Global Listener
  1393. {
  1394. final ListenersContainer template = Containers.Global();
  1395. listeners.add(template.addListener(action.apply(template)));
  1396. break;
  1397. }
  1398. case GLOBAL_NPCS: // Global Npcs Listener
  1399. {
  1400. final ListenersContainer template = Containers.Npcs();
  1401. listeners.add(template.addListener(action.apply(template)));
  1402. break;
  1403. }
  1404. case GLOBAL_MONSTERS: // Global Monsters Listener
  1405. {
  1406. final ListenersContainer template = Containers.Monsters();
  1407. listeners.add(template.addListener(action.apply(template)));
  1408. break;
  1409. }
  1410. case GLOBAL_PLAYERS: // Global Players Listener
  1411. {
  1412. final ListenersContainer template = Containers.Players();
  1413. listeners.add(template.addListener(action.apply(template)));
  1414. break;
  1415. }
  1416. }
  1417. }
  1418. _listeners.addAll(listeners);
  1419. return listeners;
  1420. }
  1421. public Set<Integer> getRegisteredIds(ListenerRegisterType type)
  1422. {
  1423. return _registeredIds.containsKey(type) ? _registeredIds.get(type) : Collections.emptySet();
  1424. }
  1425. public List<AbstractEventListener> getListeners()
  1426. {
  1427. return _listeners;
  1428. }
  1429. /**
  1430. * -------------------------------------------------------------------------------------------------------
  1431. */
  1432. /**
  1433. * Show an on screen message to the player.
  1434. * @param player the player to display the message to
  1435. * @param text the message to display
  1436. * @param time the duration of the message in milliseconds
  1437. */
  1438. public static void showOnScreenMsg(L2PcInstance player, String text, int time)
  1439. {
  1440. player.sendPacket(new ExShowScreenMessage(text, time));
  1441. }
  1442. /**
  1443. * Show an on screen message to the player.
  1444. * @param player the player to display the message to
  1445. * @param npcString the NPC string to display
  1446. * @param position the position of the message on the screen
  1447. * @param time the duration of the message in milliseconds
  1448. * @param params values of parameters to replace in the NPC String (like S1, C1 etc.)
  1449. */
  1450. public static void showOnScreenMsg(L2PcInstance player, NpcStringId npcString, int position, int time, String... params)
  1451. {
  1452. player.sendPacket(new ExShowScreenMessage(npcString, position, time, params));
  1453. }
  1454. /**
  1455. * Show an on screen message to the player.
  1456. * @param player the player to display the message to
  1457. * @param systemMsg the system message to display
  1458. * @param position the position of the message on the screen
  1459. * @param time the duration of the message in milliseconds
  1460. * @param params values of parameters to replace in the system message (like S1, C1 etc.)
  1461. */
  1462. public static void showOnScreenMsg(L2PcInstance player, SystemMessageId systemMsg, int position, int time, String... params)
  1463. {
  1464. player.sendPacket(new ExShowScreenMessage(systemMsg, position, time, params));
  1465. }
  1466. /**
  1467. * Add a temporary spawn of the specified NPC.
  1468. * @param npcId the ID of the NPC to spawn
  1469. * @param pos the object containing the spawn location coordinates
  1470. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1471. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1472. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
  1473. */
  1474. public static L2Npc addSpawn(int npcId, IPositionable pos)
  1475. {
  1476. return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), false, 0, false, 0);
  1477. }
  1478. /**
  1479. * Add a temporary spawn of the specified NPC.
  1480. * @param summoner the NPC that requires this spawn
  1481. * @param npcId the ID of the NPC to spawn
  1482. * @param pos the object containing the spawn location coordinates
  1483. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1484. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1485. * @return the {@link L2Npc} object of the newly spawned NPC, {@code null} if the NPC doesn't exist
  1486. */
  1487. public static L2Npc addSpawn(L2Npc summoner, int npcId, IPositionable pos, boolean randomOffset, long despawnDelay)
  1488. {
  1489. return addSpawn(summoner, npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), randomOffset, despawnDelay, false, 0);
  1490. }
  1491. /**
  1492. * Add a temporary spawn of the specified NPC.
  1493. * @param npcId the ID of the NPC to spawn
  1494. * @param pos the object containing the spawn location coordinates
  1495. * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
  1496. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1497. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1498. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
  1499. */
  1500. public static L2Npc addSpawn(int npcId, IPositionable pos, boolean isSummonSpawn)
  1501. {
  1502. return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), false, 0, isSummonSpawn, 0);
  1503. }
  1504. /**
  1505. * Add a temporary spawn of the specified NPC.
  1506. * @param npcId the ID of the NPC to spawn
  1507. * @param pos the object containing the spawn location coordinates
  1508. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1509. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1510. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1511. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1512. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
  1513. */
  1514. public static L2Npc addSpawn(int npcId, IPositionable pos, boolean randomOffset, long despawnDelay)
  1515. {
  1516. return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), randomOffset, despawnDelay, false, 0);
  1517. }
  1518. /**
  1519. * Add a temporary spawn of the specified NPC.
  1520. * @param npcId the ID of the NPC to spawn
  1521. * @param pos the object containing the spawn location coordinates
  1522. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1523. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1524. * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
  1525. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1526. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1527. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
  1528. */
  1529. public static L2Npc addSpawn(int npcId, IPositionable pos, boolean randomOffset, long despawnDelay, boolean isSummonSpawn)
  1530. {
  1531. return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), randomOffset, despawnDelay, isSummonSpawn, 0);
  1532. }
  1533. /**
  1534. * Add a temporary spawn of the specified NPC.
  1535. * @param npcId the ID of the NPC to spawn
  1536. * @param pos the object containing the spawn location coordinates
  1537. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1538. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1539. * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
  1540. * @param instanceId the ID of the instance to spawn the NPC in (0 - the open world)
  1541. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1542. * @see #addSpawn(int, IPositionable)
  1543. * @see #addSpawn(int, IPositionable, boolean)
  1544. * @see #addSpawn(int, IPositionable, boolean, long)
  1545. * @see #addSpawn(int, IPositionable, boolean, long, boolean)
  1546. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
  1547. */
  1548. public static L2Npc addSpawn(int npcId, IPositionable pos, boolean randomOffset, long despawnDelay, boolean isSummonSpawn, int instanceId)
  1549. {
  1550. return addSpawn(npcId, pos.getX(), pos.getY(), pos.getZ(), pos.getHeading(), randomOffset, despawnDelay, isSummonSpawn, instanceId);
  1551. }
  1552. /**
  1553. * Add a temporary spawn of the specified NPC.
  1554. * @param npcId the ID of the NPC to spawn
  1555. * @param x the X coordinate of the spawn location
  1556. * @param y the Y coordinate of the spawn location
  1557. * @param z the Z coordinate (height) of the spawn location
  1558. * @param heading the heading of the NPC
  1559. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1560. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1561. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1562. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1563. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
  1564. */
  1565. public static L2Npc addSpawn(int npcId, int x, int y, int z, int heading, boolean randomOffset, long despawnDelay)
  1566. {
  1567. return addSpawn(npcId, x, y, z, heading, randomOffset, despawnDelay, false, 0);
  1568. }
  1569. /**
  1570. * Add a temporary spawn of the specified NPC.
  1571. * @param npcId the ID of the NPC to spawn
  1572. * @param x the X coordinate of the spawn location
  1573. * @param y the Y coordinate of the spawn location
  1574. * @param z the Z coordinate (height) of the spawn location
  1575. * @param heading the heading of the NPC
  1576. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1577. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1578. * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
  1579. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1580. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1581. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean, int)
  1582. */
  1583. public static L2Npc addSpawn(int npcId, int x, int y, int z, int heading, boolean randomOffset, long despawnDelay, boolean isSummonSpawn)
  1584. {
  1585. return addSpawn(npcId, x, y, z, heading, randomOffset, despawnDelay, isSummonSpawn, 0);
  1586. }
  1587. /**
  1588. * Add a temporary spawn of the specified NPC.
  1589. * @param npcId the ID of the NPC to spawn
  1590. * @param x the X coordinate of the spawn location
  1591. * @param y the Y coordinate of the spawn location
  1592. * @param z the Z coordinate (height) of the spawn location
  1593. * @param heading the heading of the NPC
  1594. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1595. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1596. * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
  1597. * @param instanceId the ID of the instance to spawn the NPC in (0 - the open world)
  1598. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1599. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1600. * @see #addSpawn(int, int, int, int, int, boolean, long)
  1601. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean)
  1602. */
  1603. public static L2Npc addSpawn(int npcId, int x, int y, int z, int heading, boolean randomOffset, long despawnDelay, boolean isSummonSpawn, int instanceId)
  1604. {
  1605. return addSpawn(null, npcId, x, y, z, heading, randomOffset, despawnDelay, isSummonSpawn, instanceId);
  1606. }
  1607. /**
  1608. * Add a temporary spawn of the specified NPC.
  1609. * @param summoner the NPC that requires this spawn
  1610. * @param npcId the ID of the NPC to spawn
  1611. * @param x the X coordinate of the spawn location
  1612. * @param y the Y coordinate of the spawn location
  1613. * @param z the Z coordinate (height) of the spawn location
  1614. * @param heading the heading of the NPC
  1615. * @param randomOffset if {@code true}, adds +/- 50~100 to X/Y coordinates of the spawn location
  1616. * @param despawnDelay time in milliseconds till the NPC is despawned (0 - only despawned on server shutdown)
  1617. * @param isSummonSpawn if {@code true}, displays a summon animation on NPC spawn
  1618. * @param instanceId the ID of the instance to spawn the NPC in (0 - the open world)
  1619. * @return the {@link L2Npc} object of the newly spawned NPC or {@code null} if the NPC doesn't exist
  1620. * @see #addSpawn(int, IPositionable, boolean, long, boolean, int)
  1621. * @see #addSpawn(int, int, int, int, int, boolean, long)
  1622. * @see #addSpawn(int, int, int, int, int, boolean, long, boolean)
  1623. */
  1624. public static L2Npc addSpawn(L2Npc summoner, int npcId, int x, int y, int z, int heading, boolean randomOffset, long despawnDelay, boolean isSummonSpawn, int instanceId)
  1625. {
  1626. try
  1627. {
  1628. if ((x == 0) && (y == 0))
  1629. {
  1630. _log.log(Level.SEVERE, "addSpawn(): invalid spawn coordinates for NPC #" + npcId + "!");
  1631. return null;
  1632. }
  1633. if (randomOffset)
  1634. {
  1635. int offset = Rnd.get(50, 100);
  1636. if (Rnd.nextBoolean())
  1637. {
  1638. offset *= -1;
  1639. }
  1640. x += offset;
  1641. offset = Rnd.get(50, 100);
  1642. if (Rnd.nextBoolean())
  1643. {
  1644. offset *= -1;
  1645. }
  1646. y += offset;
  1647. }
  1648. final L2Spawn spawn = new L2Spawn(npcId);
  1649. spawn.setInstanceId(instanceId);
  1650. spawn.setHeading(heading);
  1651. spawn.setX(x);
  1652. spawn.setY(y);
  1653. spawn.setZ(z);
  1654. spawn.stopRespawn();
  1655. final L2Npc npc = spawn.spawnOne(isSummonSpawn);
  1656. if (despawnDelay > 0)
  1657. {
  1658. npc.scheduleDespawn(despawnDelay);
  1659. }
  1660. if (summoner != null)
  1661. {
  1662. summoner.addSummonedNpc(npc);
  1663. }
  1664. return npc;
  1665. }
  1666. catch (Exception e)
  1667. {
  1668. _log.warning("Could not spawn NPC #" + npcId + "; error: " + e.getMessage());
  1669. }
  1670. return null;
  1671. }
  1672. /**
  1673. * @param trapId
  1674. * @param x
  1675. * @param y
  1676. * @param z
  1677. * @param heading
  1678. * @param skill
  1679. * @param instanceId
  1680. * @return
  1681. */
  1682. public L2TrapInstance addTrap(int trapId, int x, int y, int z, int heading, Skill skill, int instanceId)
  1683. {
  1684. final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(trapId);
  1685. L2TrapInstance trap = new L2TrapInstance(npcTemplate, instanceId, -1);
  1686. trap.setCurrentHp(trap.getMaxHp());
  1687. trap.setCurrentMp(trap.getMaxMp());
  1688. trap.setIsInvul(true);
  1689. trap.setHeading(heading);
  1690. trap.spawnMe(x, y, z);
  1691. return trap;
  1692. }
  1693. /**
  1694. * @param master
  1695. * @param minionId
  1696. * @return
  1697. */
  1698. public L2Npc addMinion(L2MonsterInstance master, int minionId)
  1699. {
  1700. return MinionList.spawnMinion(master, minionId);
  1701. }
  1702. /**
  1703. * Get the amount of an item in player's inventory.
  1704. * @param player the player whose inventory to check
  1705. * @param itemId the ID of the item whose amount to get
  1706. * @return the amount of the specified item in player's inventory
  1707. */
  1708. public static long getQuestItemsCount(L2PcInstance player, int itemId)
  1709. {
  1710. return player.getInventory().getInventoryItemCount(itemId, -1);
  1711. }
  1712. /**
  1713. * Get the total amount of all specified items in player's inventory.
  1714. * @param player the player whose inventory to check
  1715. * @param itemIds a list of IDs of items whose amount to get
  1716. * @return the summary amount of all listed items in player's inventory
  1717. */
  1718. public long getQuestItemsCount(L2PcInstance player, int... itemIds)
  1719. {
  1720. long count = 0;
  1721. for (L2ItemInstance item : player.getInventory().getItems())
  1722. {
  1723. if (item == null)
  1724. {
  1725. continue;
  1726. }
  1727. for (int itemId : itemIds)
  1728. {
  1729. if (item.getId() == itemId)
  1730. {
  1731. if ((count + item.getCount()) > Long.MAX_VALUE)
  1732. {
  1733. return Long.MAX_VALUE;
  1734. }
  1735. count += item.getCount();
  1736. }
  1737. }
  1738. }
  1739. return count;
  1740. }
  1741. /**
  1742. * Check if the player has the specified item in his inventory.
  1743. * @param player the player whose inventory to check for the specified item
  1744. * @param item the {@link ItemHolder} object containing the ID and count of the item to check
  1745. * @return {@code true} if the player has the required count of the item
  1746. */
  1747. protected static boolean hasItem(L2PcInstance player, ItemHolder item)
  1748. {
  1749. return hasItem(player, item, true);
  1750. }
  1751. /**
  1752. * Check if the player has the required count of the specified item in his inventory.
  1753. * @param player the player whose inventory to check for the specified item
  1754. * @param item the {@link ItemHolder} object containing the ID and count of the item to check
  1755. * @param checkCount if {@code true}, check if each item is at least of the count specified in the ItemHolder,<br>
  1756. * otherwise check only if the player has the item at all
  1757. * @return {@code true} if the player has the item
  1758. */
  1759. protected static boolean hasItem(L2PcInstance player, ItemHolder item, boolean checkCount)
  1760. {
  1761. if (item == null)
  1762. {
  1763. return false;
  1764. }
  1765. if (checkCount)
  1766. {
  1767. return (getQuestItemsCount(player, item.getId()) >= item.getCount());
  1768. }
  1769. return hasQuestItems(player, item.getId());
  1770. }
  1771. /**
  1772. * Check if the player has all the specified items in his inventory and, if necessary, if their count is also as required.
  1773. * @param player the player whose inventory to check for the specified item
  1774. * @param checkCount if {@code true}, check if each item is at least of the count specified in the ItemHolder,<br>
  1775. * otherwise check only if the player has the item at all
  1776. * @param itemList a list of {@link ItemHolder} objects containing the IDs of the items to check
  1777. * @return {@code true} if the player has all the items from the list
  1778. */
  1779. protected static boolean hasAllItems(L2PcInstance player, boolean checkCount, ItemHolder... itemList)
  1780. {
  1781. if ((itemList == null) || (itemList.length == 0))
  1782. {
  1783. return false;
  1784. }
  1785. for (ItemHolder item : itemList)
  1786. {
  1787. if (!hasItem(player, item, checkCount))
  1788. {
  1789. return false;
  1790. }
  1791. }
  1792. return true;
  1793. }
  1794. /**
  1795. * Check for an item in player's inventory.
  1796. * @param player the player whose inventory to check for quest items
  1797. * @param itemId the ID of the item to check for
  1798. * @return {@code true} if the item exists in player's inventory, {@code false} otherwise
  1799. */
  1800. public static boolean hasQuestItems(L2PcInstance player, int itemId)
  1801. {
  1802. return (player.getInventory().getItemByItemId(itemId) != null);
  1803. }
  1804. /**
  1805. * Check for multiple items in player's inventory.
  1806. * @param player the player whose inventory to check for quest items
  1807. * @param itemIds a list of item IDs to check for
  1808. * @return {@code true} if all items exist in player's inventory, {@code false} otherwise
  1809. */
  1810. public static boolean hasQuestItems(L2PcInstance player, int... itemIds)
  1811. {
  1812. if ((itemIds == null) || (itemIds.length == 0))
  1813. {
  1814. return false;
  1815. }
  1816. final PcInventory inv = player.getInventory();
  1817. for (int itemId : itemIds)
  1818. {
  1819. if (inv.getItemByItemId(itemId) == null)
  1820. {
  1821. return false;
  1822. }
  1823. }
  1824. return true;
  1825. }
  1826. /**
  1827. * Check for multiple items in player's inventory.
  1828. * @param player the player whose inventory to check for quest items
  1829. * @param itemIds a list of item IDs to check for
  1830. * @return {@code true} if at least one items exist in player's inventory, {@code false} otherwise
  1831. */
  1832. public boolean hasAtLeastOneQuestItem(L2PcInstance player, int... itemIds)
  1833. {
  1834. final PcInventory inv = player.getInventory();
  1835. for (int itemId : itemIds)
  1836. {
  1837. if (inv.getItemByItemId(itemId) != null)
  1838. {
  1839. return true;
  1840. }
  1841. }
  1842. return false;
  1843. }
  1844. /**
  1845. * Get the enchantment level of an item in player's inventory.
  1846. * @param player the player whose item to check
  1847. * @param itemId the ID of the item whose enchantment level to get
  1848. * @return the enchantment level of the item or 0 if the item was not found
  1849. */
  1850. public static int getEnchantLevel(L2PcInstance player, int itemId)
  1851. {
  1852. final L2ItemInstance enchantedItem = player.getInventory().getItemByItemId(itemId);
  1853. if (enchantedItem == null)
  1854. {
  1855. return 0;
  1856. }
  1857. return enchantedItem.getEnchantLevel();
  1858. }
  1859. /**
  1860. * Give Adena to the player.
  1861. * @param player the player to whom to give the Adena
  1862. * @param count the amount of Adena to give
  1863. * @param applyRates if {@code true} quest rates will be applied to the amount
  1864. */
  1865. public void giveAdena(L2PcInstance player, long count, boolean applyRates)
  1866. {
  1867. if (applyRates)
  1868. {
  1869. rewardItems(player, Inventory.ADENA_ID, count);
  1870. }
  1871. else
  1872. {
  1873. giveItems(player, Inventory.ADENA_ID, count);
  1874. }
  1875. }
  1876. /**
  1877. * Give a reward to player using multipliers.
  1878. * @param player the player to whom to give the item
  1879. * @param holder
  1880. */
  1881. public static void rewardItems(L2PcInstance player, ItemHolder holder)
  1882. {
  1883. rewardItems(player, holder.getId(), holder.getCount());
  1884. }
  1885. /**
  1886. * Give a reward to player using multipliers.
  1887. * @param player the player to whom to give the item
  1888. * @param itemId the ID of the item to give
  1889. * @param count the amount of items to give
  1890. */
  1891. public static void rewardItems(L2PcInstance player, int itemId, long count)
  1892. {
  1893. if (count <= 0)
  1894. {
  1895. return;
  1896. }
  1897. final L2Item item = ItemTable.getInstance().getTemplate(itemId);
  1898. if (item == null)
  1899. {
  1900. return;
  1901. }
  1902. try
  1903. {
  1904. if (itemId == Inventory.ADENA_ID)
  1905. {
  1906. count *= Config.RATE_QUEST_REWARD_ADENA;
  1907. }
  1908. else if (Config.RATE_QUEST_REWARD_USE_MULTIPLIERS)
  1909. {
  1910. if (item instanceof L2EtcItem)
  1911. {
  1912. switch (((L2EtcItem) item).getItemType())
  1913. {
  1914. case POTION:
  1915. count *= Config.RATE_QUEST_REWARD_POTION;
  1916. break;
  1917. case SCRL_ENCHANT_WP:
  1918. case SCRL_ENCHANT_AM:
  1919. case SCROLL:
  1920. count *= Config.RATE_QUEST_REWARD_SCROLL;
  1921. break;
  1922. case RECIPE:
  1923. count *= Config.RATE_QUEST_REWARD_RECIPE;
  1924. break;
  1925. case MATERIAL:
  1926. count *= Config.RATE_QUEST_REWARD_MATERIAL;
  1927. break;
  1928. default:
  1929. count *= Config.RATE_QUEST_REWARD;
  1930. }
  1931. }
  1932. }
  1933. else
  1934. {
  1935. count *= Config.RATE_QUEST_REWARD;
  1936. }
  1937. }
  1938. catch (Exception e)
  1939. {
  1940. count = Long.MAX_VALUE;
  1941. }
  1942. // Add items to player's inventory
  1943. final L2ItemInstance itemInstance = player.getInventory().addItem("Quest", itemId, count, player, player.getTarget());
  1944. if (itemInstance == null)
  1945. {
  1946. return;
  1947. }
  1948. sendItemGetMessage(player, itemInstance, count);
  1949. }
  1950. /**
  1951. * Send the system message and the status update packets to the player.
  1952. * @param player the player that has got the item
  1953. * @param item the item obtain by the player
  1954. * @param count the item count
  1955. */
  1956. private static void sendItemGetMessage(L2PcInstance player, L2ItemInstance item, long count)
  1957. {
  1958. // If item for reward is gold, send message of gold reward to client
  1959. if (item.getId() == Inventory.ADENA_ID)
  1960. {
  1961. SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S1_ADENA);
  1962. smsg.addLong(count);
  1963. player.sendPacket(smsg);
  1964. }
  1965. // Otherwise, send message of object reward to client
  1966. else
  1967. {
  1968. if (count > 1)
  1969. {
  1970. SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
  1971. smsg.addItemName(item);
  1972. smsg.addLong(count);
  1973. player.sendPacket(smsg);
  1974. }
  1975. else
  1976. {
  1977. SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
  1978. smsg.addItemName(item);
  1979. player.sendPacket(smsg);
  1980. }
  1981. }
  1982. // send packets
  1983. StatusUpdate su = new StatusUpdate(player);
  1984. su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
  1985. player.sendPacket(su);
  1986. }
  1987. /**
  1988. * Give item/reward to the player
  1989. * @param player
  1990. * @param itemId
  1991. * @param count
  1992. */
  1993. public static void giveItems(L2PcInstance player, int itemId, long count)
  1994. {
  1995. giveItems(player, itemId, count, 0);
  1996. }
  1997. /**
  1998. * Give item/reward to the player
  1999. * @param player
  2000. * @param holder
  2001. */
  2002. protected static void giveItems(L2PcInstance player, ItemHolder holder)
  2003. {
  2004. giveItems(player, holder.getId(), holder.getCount());
  2005. }
  2006. /**
  2007. * @param player
  2008. * @param itemId
  2009. * @param count
  2010. * @param enchantlevel
  2011. */
  2012. public static void giveItems(L2PcInstance player, int itemId, long count, int enchantlevel)
  2013. {
  2014. if (count <= 0)
  2015. {
  2016. return;
  2017. }
  2018. // Add items to player's inventory
  2019. final L2ItemInstance item = player.getInventory().addItem("Quest", itemId, count, player, player.getTarget());
  2020. if (item == null)
  2021. {
  2022. return;
  2023. }
  2024. // set enchant level for item if that item is not adena
  2025. if ((enchantlevel > 0) && (itemId != Inventory.ADENA_ID))
  2026. {
  2027. item.setEnchantLevel(enchantlevel);
  2028. }
  2029. sendItemGetMessage(player, item, count);
  2030. }
  2031. /**
  2032. * @param player
  2033. * @param itemId
  2034. * @param count
  2035. * @param attributeId
  2036. * @param attributeLevel
  2037. */
  2038. public static void giveItems(L2PcInstance player, int itemId, long count, byte attributeId, int attributeLevel)
  2039. {
  2040. if (count <= 0)
  2041. {
  2042. return;
  2043. }
  2044. // Add items to player's inventory
  2045. final L2ItemInstance item = player.getInventory().addItem("Quest", itemId, count, player, player.getTarget());
  2046. if (item == null)
  2047. {
  2048. return;
  2049. }
  2050. // set enchant level for item if that item is not adena
  2051. if ((attributeId >= 0) && (attributeLevel > 0))
  2052. {
  2053. item.setElementAttr(attributeId, attributeLevel);
  2054. if (item.isEquipped())
  2055. {
  2056. item.updateElementAttrBonus(player);
  2057. }
  2058. InventoryUpdate iu = new InventoryUpdate();
  2059. iu.addModifiedItem(item);
  2060. player.sendPacket(iu);
  2061. }
  2062. sendItemGetMessage(player, item, count);
  2063. }
  2064. /**
  2065. * Give the specified player a set amount of items if he is lucky enough.<br>
  2066. * Not recommended to use this for non-stacking items.
  2067. * @param player the player to give the item(s) to
  2068. * @param itemId the ID of the item to give
  2069. * @param amountToGive the amount of items to give
  2070. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. 0 - no limit.
  2071. * @param dropChance the drop chance as a decimal digit from 0 to 1
  2072. * @param playSound if true, plays ItemSound.quest_itemget when items are given and ItemSound.quest_middle when the limit is reached
  2073. * @return {@code true} if limit > 0 and the limit was reached or if limit <= 0 and items were given; {@code false} in all other cases
  2074. */
  2075. public static boolean giveItemRandomly(L2PcInstance player, int itemId, long amountToGive, long limit, double dropChance, boolean playSound)
  2076. {
  2077. return giveItemRandomly(player, null, itemId, amountToGive, amountToGive, limit, dropChance, playSound);
  2078. }
  2079. /**
  2080. * Give the specified player a set amount of items if he is lucky enough.<br>
  2081. * Not recommended to use this for non-stacking items.
  2082. * @param player the player to give the item(s) to
  2083. * @param npc the NPC that "dropped" the item (can be null)
  2084. * @param itemId the ID of the item to give
  2085. * @param amountToGive the amount of items to give
  2086. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. 0 - no limit.
  2087. * @param dropChance the drop chance as a decimal digit from 0 to 1
  2088. * @param playSound if true, plays ItemSound.quest_itemget when items are given and ItemSound.quest_middle when the limit is reached
  2089. * @return {@code true} if limit > 0 and the limit was reached or if limit <= 0 and items were given; {@code false} in all other cases
  2090. */
  2091. public static boolean giveItemRandomly(L2PcInstance player, L2Npc npc, int itemId, long amountToGive, long limit, double dropChance, boolean playSound)
  2092. {
  2093. return giveItemRandomly(player, npc, itemId, amountToGive, amountToGive, limit, dropChance, playSound);
  2094. }
  2095. /**
  2096. * Give the specified player a random amount of items if he is lucky enough.<br>
  2097. * Not recommended to use this for non-stacking items.
  2098. * @param player the player to give the item(s) to
  2099. * @param npc the NPC that "dropped" the item (can be null)
  2100. * @param itemId the ID of the item to give
  2101. * @param minAmount the minimum amount of items to give
  2102. * @param maxAmount the maximum amount of items to give (will give a random amount between min/maxAmount multiplied by quest rates)
  2103. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. 0 - no limit.
  2104. * @param dropChance the drop chance as a decimal digit from 0 to 1
  2105. * @param playSound if true, plays ItemSound.quest_itemget when items are given and ItemSound.quest_middle when the limit is reached
  2106. * @return {@code true} if limit > 0 and the limit was reached or if limit <= 0 and items were given; {@code false} in all other cases
  2107. */
  2108. public static boolean giveItemRandomly(L2PcInstance player, L2Npc npc, int itemId, long minAmount, long maxAmount, long limit, double dropChance, boolean playSound)
  2109. {
  2110. final long currentCount = getQuestItemsCount(player, itemId);
  2111. if ((limit > 0) && (currentCount >= limit))
  2112. {
  2113. return true;
  2114. }
  2115. minAmount *= Config.RATE_QUEST_DROP;
  2116. maxAmount *= Config.RATE_QUEST_DROP;
  2117. dropChance *= Config.RATE_QUEST_DROP; // TODO separate configs for rate and amount
  2118. if ((npc != null) && Config.L2JMOD_CHAMPION_ENABLE && npc.isChampion())
  2119. {
  2120. if ((itemId == Inventory.ADENA_ID) || (itemId == Inventory.ANCIENT_ADENA_ID))
  2121. {
  2122. dropChance *= Config.L2JMOD_CHAMPION_ADENAS_REWARDS_CHANCE;
  2123. minAmount *= Config.L2JMOD_CHAMPION_ADENAS_REWARDS_AMOUNT;
  2124. maxAmount *= Config.L2JMOD_CHAMPION_ADENAS_REWARDS_AMOUNT;
  2125. }
  2126. else
  2127. {
  2128. dropChance *= Config.L2JMOD_CHAMPION_REWARDS_CHANCE;
  2129. minAmount *= Config.L2JMOD_CHAMPION_REWARDS_AMOUNT;
  2130. maxAmount *= Config.L2JMOD_CHAMPION_REWARDS_AMOUNT;
  2131. }
  2132. }
  2133. long amountToGive = ((minAmount == maxAmount) ? minAmount : Rnd.get(minAmount, maxAmount));
  2134. final double random = Rnd.nextDouble();
  2135. // Inventory slot check (almost useless for non-stacking items)
  2136. if ((dropChance >= random) && (amountToGive > 0) && player.getInventory().validateCapacityByItemId(itemId))
  2137. {
  2138. if ((limit > 0) && ((currentCount + amountToGive) > limit))
  2139. {
  2140. amountToGive = limit - currentCount;
  2141. }
  2142. // Give the item to player
  2143. L2ItemInstance item = player.addItem("Quest", itemId, amountToGive, npc, true);
  2144. if (item != null)
  2145. {
  2146. // limit reached (if there is no limit, this block doesn't execute)
  2147. if ((currentCount + amountToGive) == limit)
  2148. {
  2149. if (playSound)
  2150. {
  2151. playSound(player, Sound.ITEMSOUND_QUEST_MIDDLE);
  2152. }
  2153. return true;
  2154. }
  2155. if (playSound)
  2156. {
  2157. playSound(player, Sound.ITEMSOUND_QUEST_ITEMGET);
  2158. }
  2159. // if there is no limit, return true every time an item is given
  2160. if (limit <= 0)
  2161. {
  2162. return true;
  2163. }
  2164. }
  2165. }
  2166. return false;
  2167. }
  2168. /**
  2169. * Gives an item to the player
  2170. * @param player
  2171. * @param item
  2172. * @param victim the character that "dropped" the item
  2173. * @return <code>true</code> if at least one item was given, <code>false</code> otherwise
  2174. */
  2175. protected static boolean giveItems(L2PcInstance player, IDropItem item, L2Character victim)
  2176. {
  2177. List<ItemHolder> items = item.calculateDrops(victim, player);
  2178. if ((items == null) || items.isEmpty())
  2179. {
  2180. return false;
  2181. }
  2182. giveItems(player, items);
  2183. return true;
  2184. }
  2185. /**
  2186. * Gives an item to the player
  2187. * @param player
  2188. * @param items
  2189. */
  2190. protected static void giveItems(L2PcInstance player, List<ItemHolder> items)
  2191. {
  2192. for (ItemHolder item : items)
  2193. {
  2194. giveItems(player, item);
  2195. }
  2196. }
  2197. /**
  2198. * Gives an item to the player
  2199. * @param player
  2200. * @param item
  2201. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached.
  2202. * @return <code>true</code> if at least one item was given to the player, <code>false</code> otherwise
  2203. */
  2204. protected static boolean giveItems(L2PcInstance player, ItemHolder item, long limit)
  2205. {
  2206. long maxToGive = limit - player.getInventory().getInventoryItemCount(item.getId(), -1);
  2207. if (maxToGive <= 0)
  2208. {
  2209. return false;
  2210. }
  2211. giveItems(player, item.getId(), Math.min(maxToGive, item.getCount()));
  2212. return true;
  2213. }
  2214. protected static boolean giveItems(L2PcInstance player, ItemHolder item, long limit, boolean playSound)
  2215. {
  2216. boolean drop = giveItems(player, item, limit);
  2217. if (drop && playSound)
  2218. {
  2219. playSound(player, Sound.ITEMSOUND_QUEST_ITEMGET);
  2220. }
  2221. return drop;
  2222. }
  2223. /**
  2224. * @param player
  2225. * @param items
  2226. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached.
  2227. * @return <code>true</code> if at least one item was given to the player, <code>false</code> otherwise
  2228. */
  2229. protected static boolean giveItems(L2PcInstance player, List<ItemHolder> items, long limit)
  2230. {
  2231. boolean b = false;
  2232. for (ItemHolder item : items)
  2233. {
  2234. b |= giveItems(player, item, limit);
  2235. }
  2236. return b;
  2237. }
  2238. protected static boolean giveItems(L2PcInstance player, List<ItemHolder> items, long limit, boolean playSound)
  2239. {
  2240. boolean drop = giveItems(player, items, limit);
  2241. if (drop && playSound)
  2242. {
  2243. playSound(player, Sound.ITEMSOUND_QUEST_ITEMGET);
  2244. }
  2245. return drop;
  2246. }
  2247. /**
  2248. * @param player
  2249. * @param items
  2250. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. If a no limit for an itemId is specified, item will always be given
  2251. * @return <code>true</code> if at least one item was given to the player, <code>false</code> otherwise
  2252. */
  2253. protected static boolean giveItems(L2PcInstance player, List<ItemHolder> items, Map<Integer, Long> limit)
  2254. {
  2255. return giveItems(player, items, Util.mapToFunction(limit));
  2256. }
  2257. /**
  2258. * @param player
  2259. * @param items
  2260. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. If a no limit for an itemId is specified, item will always be given
  2261. * @return <code>true</code> if at least one item was given to the player, <code>false</code> otherwise
  2262. */
  2263. protected static boolean giveItems(L2PcInstance player, List<ItemHolder> items, Function<Integer, Long> limit)
  2264. {
  2265. boolean b = false;
  2266. for (ItemHolder item : items)
  2267. {
  2268. if (limit != null)
  2269. {
  2270. Long longLimit = limit.apply(item.getId());
  2271. // null -> no limit specified for that item id. This trick is to avoid limit.apply() be called twice (once for the null check)
  2272. if (longLimit != null)
  2273. {
  2274. b |= giveItems(player, item, longLimit);
  2275. continue; // the item is given, continue with next
  2276. }
  2277. }
  2278. // da BIG else
  2279. // no limit specified here (either limit or limit.apply(item.getId()) is null)
  2280. b = true;
  2281. giveItems(player, item);
  2282. }
  2283. return b;
  2284. }
  2285. protected static boolean giveItems(L2PcInstance player, List<ItemHolder> items, Function<Integer, Long> limit, boolean playSound)
  2286. {
  2287. boolean drop = giveItems(player, items, limit);
  2288. if (drop && playSound)
  2289. {
  2290. playSound(player, Sound.ITEMSOUND_QUEST_ITEMGET);
  2291. }
  2292. return drop;
  2293. }
  2294. protected static boolean giveItems(L2PcInstance player, List<ItemHolder> items, Map<Integer, Long> limit, boolean playSound)
  2295. {
  2296. return giveItems(player, items, Util.mapToFunction(limit), playSound);
  2297. }
  2298. /**
  2299. * @param player
  2300. * @param item
  2301. * @param victim the character that "dropped" the item
  2302. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached.
  2303. * @return <code>true</code> if at least one item was given to the player, <code>false</code> otherwise
  2304. */
  2305. protected static boolean giveItems(L2PcInstance player, IDropItem item, L2Character victim, int limit)
  2306. {
  2307. return giveItems(player, item.calculateDrops(victim, player), limit);
  2308. }
  2309. protected static boolean giveItems(L2PcInstance player, IDropItem item, L2Character victim, int limit, boolean playSound)
  2310. {
  2311. boolean drop = giveItems(player, item, victim, limit);
  2312. if (drop && playSound)
  2313. {
  2314. playSound(player, Sound.ITEMSOUND_QUEST_ITEMGET);
  2315. }
  2316. return drop;
  2317. }
  2318. /**
  2319. * @param player
  2320. * @param item
  2321. * @param victim the character that "dropped" the item
  2322. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. If a no limit for an itemId is specified, item will always be given
  2323. * @return <code>true</code> if at least one item was given to the player, <code>false</code> otherwise
  2324. */
  2325. protected static boolean giveItems(L2PcInstance player, IDropItem item, L2Character victim, Map<Integer, Long> limit)
  2326. {
  2327. return giveItems(player, item.calculateDrops(victim, player), limit);
  2328. }
  2329. /**
  2330. * @param player
  2331. * @param item
  2332. * @param victim the character that "dropped" the item
  2333. * @param limit the maximum amount of items the player can have. Won't give more if this limit is reached. If a no limit for an itemId is specified, item will always be given
  2334. * @return <code>true</code> if at least one item was given to the player, <code>false</code> otherwise
  2335. */
  2336. protected static boolean giveItems(L2PcInstance player, IDropItem item, L2Character victim, Function<Integer, Long> limit)
  2337. {
  2338. return giveItems(player, item.calculateDrops(victim, player), limit);
  2339. }
  2340. protected static boolean giveItems(L2PcInstance player, IDropItem item, L2Character victim, Map<Integer, Long> limit, boolean playSound)
  2341. {
  2342. return giveItems(player, item, victim, Util.mapToFunction(limit), playSound);
  2343. }
  2344. protected static boolean giveItems(L2PcInstance player, IDropItem item, L2Character victim, Function<Integer, Long> limit, boolean playSound)
  2345. {
  2346. boolean drop = giveItems(player, item, victim, limit);
  2347. if (drop && playSound)
  2348. {
  2349. playSound(player, Sound.ITEMSOUND_QUEST_ITEMGET);
  2350. }
  2351. return drop;
  2352. }
  2353. /**
  2354. * Distributes items to players equally
  2355. * @param players the players to whom the items will be distributed
  2356. * @param items the items to distribute
  2357. * @param limit the limit what single player can have of each item
  2358. * @param playSound if to play sound if a player gets at least one item
  2359. * @return the counts of each items given to each player
  2360. */
  2361. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, Collection<ItemHolder> items, Function<Integer, Long> limit, boolean playSound)
  2362. {
  2363. Map<L2PcInstance, Map<Integer, Long>> rewardedCounts = calculateDistribution(players, items, limit);
  2364. // now give the calculated items to the players
  2365. giveItems(rewardedCounts, playSound);
  2366. return rewardedCounts;
  2367. }
  2368. /**
  2369. * Distributes items to players equally
  2370. * @param players the players to whom the items will be distributed
  2371. * @param items the items to distribute
  2372. * @param limit the limit what single player can have of each item
  2373. * @param playSound if to play sound if a player gets at least one item
  2374. * @return the counts of each items given to each player
  2375. */
  2376. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, Collection<ItemHolder> items, Map<Integer, Long> limit, boolean playSound)
  2377. {
  2378. return distributeItems(players, items, Util.mapToFunction(limit), playSound);
  2379. }
  2380. /**
  2381. * Distributes items to players equally
  2382. * @param players the players to whom the items will be distributed
  2383. * @param items the items to distribute
  2384. * @param limit the limit what single player can have of each item
  2385. * @param playSound if to play sound if a player gets at least one item
  2386. * @return the counts of each items given to each player
  2387. */
  2388. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, Collection<ItemHolder> items, long limit, boolean playSound)
  2389. {
  2390. return distributeItems(players, items, t -> limit, playSound);
  2391. }
  2392. /**
  2393. * Distributes items to players equally
  2394. * @param players the players to whom the items will be distributed
  2395. * @param item the items to distribute
  2396. * @param limit the limit what single player can have of each item
  2397. * @param playSound if to play sound if a player gets at least one item
  2398. * @return the counts of each items given to each player
  2399. */
  2400. protected static Map<L2PcInstance, Long> distributeItems(Collection<L2PcInstance> players, ItemHolder item, long limit, boolean playSound)
  2401. {
  2402. Map<L2PcInstance, Map<Integer, Long>> distribution = distributeItems(players, Collections.singletonList(item), limit, playSound);
  2403. Map<L2PcInstance, Long> returnMap = new HashMap<>();
  2404. for (Entry<L2PcInstance, Map<Integer, Long>> entry : distribution.entrySet())
  2405. {
  2406. for (Entry<Integer, Long> entry2 : entry.getValue().entrySet())
  2407. {
  2408. returnMap.put(entry.getKey(), entry2.getValue());
  2409. }
  2410. }
  2411. return returnMap;
  2412. }
  2413. /**
  2414. * Distributes items to players equally
  2415. * @param players the players to whom the items will be distributed
  2416. * @param items the items to distribute
  2417. * @param killer the one who "kills" the victim
  2418. * @param victim the character that "dropped" the item
  2419. * @param limit the limit what single player can have of each item
  2420. * @param playSound if to play sound if a player gets at least one item
  2421. * @return the counts of each items given to each player
  2422. */
  2423. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, IDropItem items, L2Character killer, L2Character victim, Function<Integer, Long> limit, boolean playSound)
  2424. {
  2425. return distributeItems(players, items.calculateDrops(victim, killer), limit, playSound);
  2426. }
  2427. /**
  2428. * Distributes items to players equally
  2429. * @param players the players to whom the items will be distributed
  2430. * @param items the items to distribute
  2431. * @param killer the one who "kills" the victim
  2432. * @param victim the character that "dropped" the item
  2433. * @param limit the limit what single player can have of each item
  2434. * @param playSound if to play sound if a player gets at least one item
  2435. * @return the counts of each items given to each player
  2436. */
  2437. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, IDropItem items, L2Character killer, L2Character victim, Map<Integer, Long> limit, boolean playSound)
  2438. {
  2439. return distributeItems(players, items.calculateDrops(victim, killer), limit, playSound);
  2440. }
  2441. /**
  2442. * Distributes items to players equally
  2443. * @param players the players to whom the items will be distributed
  2444. * @param items the items to distribute
  2445. * @param killer the one who "kills" the victim
  2446. * @param victim the character that "dropped" the item
  2447. * @param limit the limit what single player can have of each item
  2448. * @param playSound if to play sound if a player gets at least one item
  2449. * @return the counts of each items given to each player
  2450. */
  2451. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, IDropItem items, L2Character killer, L2Character victim, long limit, boolean playSound)
  2452. {
  2453. return distributeItems(players, items.calculateDrops(victim, killer), limit, playSound);
  2454. }
  2455. /**
  2456. * Distributes items to players equally
  2457. * @param players the players to whom the items will be distributed
  2458. * @param items the items to distribute
  2459. * @param killer the one who "kills" the victim
  2460. * @param victim the character that "dropped" the item
  2461. * @param limit the limit what single player can have of each item
  2462. * @param playSound if to play sound if a player gets at least one item
  2463. * @param smartDrop true if to not calculate a drop, which can't be given to any player 'cause of limits
  2464. * @return the counts of each items given to each player
  2465. */
  2466. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, final GroupedGeneralDropItem items, L2Character killer, L2Character victim, Function<Integer, Long> limit, boolean playSound, boolean smartDrop)
  2467. {
  2468. GroupedGeneralDropItem toDrop;
  2469. if (smartDrop)
  2470. {
  2471. toDrop = new GroupedGeneralDropItem(items.getChance(), items.getDropCalculationStrategy(), items.getKillerChanceModifierStrategy(), items.getPreciseStrategy());
  2472. List<GeneralDropItem> dropItems = new LinkedList<>(items.getItems());
  2473. ITEM_LOOP:
  2474. for (Iterator<GeneralDropItem> it = dropItems.iterator(); it.hasNext();)
  2475. {
  2476. GeneralDropItem item = it.next();
  2477. for (L2PcInstance player : players)
  2478. {
  2479. int itemId = item.getItemId();
  2480. if (player.getInventory().getInventoryItemCount(itemId, -1, true) < avoidNull(limit, itemId))
  2481. {
  2482. // we can give this item to this player
  2483. continue ITEM_LOOP;
  2484. }
  2485. }
  2486. // there's nobody to give this item to
  2487. it.remove();
  2488. }
  2489. toDrop.setItems(dropItems);
  2490. toDrop = toDrop.normalizeMe(victim, killer);
  2491. }
  2492. else
  2493. {
  2494. toDrop = items;
  2495. }
  2496. return distributeItems(players, toDrop, killer, victim, limit, playSound);
  2497. }
  2498. /**
  2499. * Distributes items to players equally
  2500. * @param players the players to whom the items will be distributed
  2501. * @param items the items to distribute
  2502. * @param killer the one who "kills" the victim
  2503. * @param victim the character that "dropped" the item
  2504. * @param limit the limit what single player can have of each item
  2505. * @param playSound if to play sound if a player gets at least one item
  2506. * @param smartDrop true if to not calculate a drop, which can't be given to any player
  2507. * @return the counts of each items given to each player
  2508. */
  2509. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, final GroupedGeneralDropItem items, L2Character killer, L2Character victim, Map<Integer, Long> limit, boolean playSound, boolean smartDrop)
  2510. {
  2511. return distributeItems(players, items, killer, victim, Util.mapToFunction(limit), playSound, smartDrop);
  2512. }
  2513. /**
  2514. * Distributes items to players equally
  2515. * @param players the players to whom the items will be distributed
  2516. * @param items the items to distribute
  2517. * @param killer the one who "kills" the victim
  2518. * @param victim the character that "dropped" the item
  2519. * @param limit the limit what single player can have of each item
  2520. * @param playSound if to play sound if a player gets at least one item
  2521. * @param smartDrop true if to not calculate a drop, which can't be given to any player
  2522. * @return the counts of each items given to each player
  2523. */
  2524. protected static Map<L2PcInstance, Map<Integer, Long>> distributeItems(Collection<L2PcInstance> players, final GroupedGeneralDropItem items, L2Character killer, L2Character victim, long limit, boolean playSound, boolean smartDrop)
  2525. {
  2526. return distributeItems(players, items, killer, victim, t -> limit, playSound, smartDrop);
  2527. }
  2528. /**
  2529. * @param players
  2530. * @param items
  2531. * @param limit
  2532. * @return
  2533. */
  2534. private static Map<L2PcInstance, Map<Integer, Long>> calculateDistribution(Collection<L2PcInstance> players, Collection<ItemHolder> items, Function<Integer, Long> limit)
  2535. {
  2536. Map<L2PcInstance, Map<Integer, Long>> rewardedCounts = new HashMap<>();
  2537. for (L2PcInstance player : players)
  2538. {
  2539. rewardedCounts.put(player, new HashMap<Integer, Long>());
  2540. }
  2541. NEXT_ITEM:
  2542. for (ItemHolder item : items)
  2543. {
  2544. long equaldist = item.getCount() / players.size();
  2545. long randomdist = item.getCount() % players.size();
  2546. List<L2PcInstance> toDist = new ArrayList<>(players);
  2547. do // this must happen at least once in order to get away already full players (and then equaldist can become nonzero)
  2548. {
  2549. for (Iterator<L2PcInstance> it = toDist.iterator(); it.hasNext();)
  2550. {
  2551. L2PcInstance player = it.next();
  2552. if (!rewardedCounts.get(player).containsKey(item.getId()))
  2553. {
  2554. rewardedCounts.get(player).put(item.getId(), 0L);
  2555. }
  2556. long maxGive = avoidNull(limit, item.getId()) - player.getInventory().getInventoryItemCount(item.getId(), -1, true) - rewardedCounts.get(player).get(item.getId());
  2557. long toGive = equaldist;
  2558. if (equaldist >= maxGive)
  2559. {
  2560. toGive = maxGive;
  2561. randomdist += (equaldist - maxGive); // overflown items are available to next players
  2562. it.remove(); // this player is already full
  2563. }
  2564. rewardedCounts.get(player).put(item.getId(), rewardedCounts.get(player).get(item.getId()) + toGive);
  2565. }
  2566. if (toDist.isEmpty())
  2567. {
  2568. // there's no one to give items anymore, all players will be full when we give the items
  2569. continue NEXT_ITEM;
  2570. }
  2571. equaldist = randomdist / toDist.size(); // the rest of items may be allowed to be equally distributed between remaining players
  2572. randomdist %= toDist.size();
  2573. }
  2574. while (equaldist > 0);
  2575. while (randomdist > 0)
  2576. {
  2577. if (toDist.isEmpty())
  2578. {
  2579. // we don't have any player left
  2580. continue NEXT_ITEM;
  2581. }
  2582. L2PcInstance player = toDist.get(getRandom(toDist.size()));
  2583. // avoid null return
  2584. long maxGive = avoidNull(limit, item.getId()) - limit.apply(item.getId()) - player.getInventory().getInventoryItemCount(item.getId(), -1, true) - rewardedCounts.get(player).get(item.getId());
  2585. if (maxGive > 0)
  2586. {
  2587. // we can add an item to player
  2588. // so we add one item to player
  2589. rewardedCounts.get(player).put(item.getId(), rewardedCounts.get(player).get(item.getId()) + 1);
  2590. randomdist--;
  2591. }
  2592. toDist.remove(player); // Either way this player isn't allowable for next random award
  2593. }
  2594. }
  2595. return rewardedCounts;
  2596. }
  2597. /**
  2598. * This function is for avoidance null returns in function limits
  2599. * @param <T> the type of function arg
  2600. * @param function the function
  2601. * @param arg the argument
  2602. * @return {@link Long#MAX_VALUE} if function.apply(arg) is null, function.apply(arg) otherwise
  2603. */
  2604. private static <T> long avoidNull(Function<T, Long> function, T arg)
  2605. {
  2606. Long longLimit = function.apply(arg);
  2607. return longLimit == null ? Long.MAX_VALUE : longLimit;
  2608. }
  2609. /**
  2610. * Distributes items to players
  2611. * @param rewardedCounts A scheme of distribution items (the structure is: Map<player Map<itemId, count>>)
  2612. * @param playSound if to play sound if a player gets at least one item
  2613. */
  2614. private static void giveItems(Map<L2PcInstance, Map<Integer, Long>> rewardedCounts, boolean playSound)
  2615. {
  2616. for (Entry<L2PcInstance, Map<Integer, Long>> entry : rewardedCounts.entrySet())
  2617. {
  2618. L2PcInstance player = entry.getKey();
  2619. boolean playPlayerSound = false;
  2620. for (Entry<Integer, Long> item : entry.getValue().entrySet())
  2621. {
  2622. if (item.getValue() >= 0)
  2623. {
  2624. playPlayerSound = true;
  2625. giveItems(player, item.getKey(), item.getValue());
  2626. }
  2627. }
  2628. if (playSound && playPlayerSound)
  2629. {
  2630. playSound(player, Sound.ITEMSOUND_QUEST_ITEMGET);
  2631. }
  2632. }
  2633. }
  2634. /**
  2635. * Take an amount of a specified item from player's inventory.
  2636. * @param player the player whose item to take
  2637. * @param itemId the ID of the item to take
  2638. * @param amount the amount to take
  2639. * @return {@code true} if any items were taken, {@code false} otherwise
  2640. */
  2641. public static boolean takeItems(L2PcInstance player, int itemId, long amount)
  2642. {
  2643. final List<L2ItemInstance> items = player.getInventory().getItemsByItemId(itemId);
  2644. if (amount < 0)
  2645. {
  2646. items.forEach(i -> takeItem(player, i, i.getCount()));
  2647. }
  2648. else
  2649. {
  2650. long currentCount = 0;
  2651. for (L2ItemInstance i : items)
  2652. {
  2653. long toDelete = i.getCount();
  2654. if ((currentCount + toDelete) > amount)
  2655. {
  2656. toDelete = amount - currentCount;
  2657. }
  2658. takeItem(player, i, toDelete);
  2659. currentCount += toDelete;
  2660. }
  2661. }
  2662. return true;
  2663. }
  2664. private static boolean takeItem(L2PcInstance player, L2ItemInstance item, long toDelete)
  2665. {
  2666. if (item.isEquipped())
  2667. {
  2668. final L2ItemInstance[] unequiped = player.getInventory().unEquipItemInBodySlotAndRecord(item.getItem().getBodyPart());
  2669. final InventoryUpdate iu = new InventoryUpdate();
  2670. for (L2ItemInstance itm : unequiped)
  2671. {
  2672. iu.addModifiedItem(itm);
  2673. }
  2674. player.sendPacket(iu);
  2675. player.broadcastUserInfo();
  2676. }
  2677. return player.destroyItemByItemId("Quest", item.getId(), toDelete, player, true);
  2678. }
  2679. /**
  2680. * Take a set amount of a specified item from player's inventory.
  2681. * @param player the player whose item to take
  2682. * @param holder the {@link ItemHolder} object containing the ID and count of the item to take
  2683. * @return {@code true} if the item was taken, {@code false} otherwise
  2684. */
  2685. protected static boolean takeItem(L2PcInstance player, ItemHolder holder)
  2686. {
  2687. if (holder == null)
  2688. {
  2689. return false;
  2690. }
  2691. return takeItems(player, holder.getId(), holder.getCount());
  2692. }
  2693. /**
  2694. * Take a set amount of all specified items from player's inventory.
  2695. * @param player the player whose items to take
  2696. * @param itemList the list of {@link ItemHolder} objects containing the IDs and counts of the items to take
  2697. * @return {@code true} if all items were taken, {@code false} otherwise
  2698. */
  2699. protected static boolean takeAllItems(L2PcInstance player, ItemHolder... itemList)
  2700. {
  2701. if ((itemList == null) || (itemList.length == 0))
  2702. {
  2703. return false;
  2704. }
  2705. // first check if the player has all items to avoid taking half the items from the list
  2706. if (!hasAllItems(player, true, itemList))
  2707. {
  2708. return false;
  2709. }
  2710. for (ItemHolder item : itemList)
  2711. {
  2712. // this should never be false, but just in case
  2713. if (!takeItem(player, item))
  2714. {
  2715. return false;
  2716. }
  2717. }
  2718. return true;
  2719. }
  2720. /**
  2721. * Take an amount of all specified items from player's inventory.
  2722. * @param player the player whose items to take
  2723. * @param amount the amount to take of each item
  2724. * @param itemIds a list or an array of IDs of the items to take
  2725. * @return {@code true} if all items were taken, {@code false} otherwise
  2726. */
  2727. public static boolean takeItems(L2PcInstance player, int amount, int... itemIds)
  2728. {
  2729. boolean check = true;
  2730. if (itemIds != null)
  2731. {
  2732. for (int item : itemIds)
  2733. {
  2734. check &= takeItems(player, item, amount);
  2735. }
  2736. }
  2737. return check;
  2738. }
  2739. /**
  2740. * Send a packet in order to play a sound to the player.
  2741. * @param player the player whom to send the packet
  2742. * @param sound the {@link IAudio} object of the sound to play
  2743. */
  2744. public static void playSound(L2PcInstance player, IAudio sound)
  2745. {
  2746. player.sendPacket(sound.getPacket());
  2747. }
  2748. /**
  2749. * Add EXP and SP as quest reward.
  2750. * @param player the player whom to reward with the EXP/SP
  2751. * @param exp the amount of EXP to give to the player
  2752. * @param sp the amount of SP to give to the player
  2753. */
  2754. public static void addExpAndSp(L2PcInstance player, long exp, int sp)
  2755. {
  2756. player.addExpAndSpQuest((long) (exp * Config.RATE_QUEST_REWARD_XP), (int) (sp * Config.RATE_QUEST_REWARD_SP));
  2757. }
  2758. /**
  2759. * Get a random integer from 0 (inclusive) to {@code max} (exclusive).<br>
  2760. * Use this method instead of importing {@link com.l2jserver.util.Rnd} utility.
  2761. * @param max the maximum value for randomization
  2762. * @return a random integer number from 0 to {@code max - 1}
  2763. */
  2764. public static int getRandom(int max)
  2765. {
  2766. return Rnd.get(max);
  2767. }
  2768. /**
  2769. * Get a random integer from {@code min} (inclusive) to {@code max} (inclusive).<br>
  2770. * Use this method instead of importing {@link com.l2jserver.util.Rnd} utility.
  2771. * @param min the minimum value for randomization
  2772. * @param max the maximum value for randomization
  2773. * @return a random integer number from {@code min} to {@code max}
  2774. */
  2775. public static int getRandom(int min, int max)
  2776. {
  2777. return Rnd.get(min, max);
  2778. }
  2779. /**
  2780. * Get a random boolean.<br>
  2781. * Use this method instead of importing {@link com.l2jserver.util.Rnd} utility.
  2782. * @return {@code true} or {@code false} randomly
  2783. */
  2784. public static boolean getRandomBoolean()
  2785. {
  2786. return Rnd.nextBoolean();
  2787. }
  2788. /**
  2789. * Get the ID of the item equipped in the specified inventory slot of the player.
  2790. * @param player the player whose inventory to check
  2791. * @param slot the location in the player's inventory to check
  2792. * @return the ID of the item equipped in the specified inventory slot or 0 if the slot is empty or item is {@code null}.
  2793. */
  2794. public static int getItemEquipped(L2PcInstance player, int slot)
  2795. {
  2796. return player.getInventory().getPaperdollItemId(slot);
  2797. }
  2798. /**
  2799. * @return the number of ticks from the {@link com.l2jserver.gameserver.GameTimeController}.
  2800. */
  2801. public static int getGameTicks()
  2802. {
  2803. return GameTimeController.getInstance().getGameTicks();
  2804. }
  2805. /**
  2806. * Execute a procedure for each player depending on the parameters.
  2807. * @param player the player on which the procedure will be executed
  2808. * @param npc the related NPC
  2809. * @param isSummon {@code true} if the event that called this method was originated by the player's summon, {@code false} otherwise
  2810. * @param includeParty if {@code true}, #actionForEachPlayer(L2PcInstance, L2Npc, boolean) will be called with the player's party members
  2811. * @param includeCommandChannel if {@code true}, {@link #actionForEachPlayer(L2PcInstance, L2Npc, boolean)} will be called with the player's command channel members
  2812. * @see #actionForEachPlayer(L2PcInstance, L2Npc, boolean)
  2813. */
  2814. public final void executeForEachPlayer(L2PcInstance player, final L2Npc npc, final boolean isSummon, boolean includeParty, boolean includeCommandChannel)
  2815. {
  2816. if ((includeParty || includeCommandChannel) && player.isInParty())
  2817. {
  2818. if (includeCommandChannel && player.getParty().isInCommandChannel())
  2819. {
  2820. player.getParty().getCommandChannel().forEachMember(member ->
  2821. {
  2822. actionForEachPlayer(member, npc, isSummon);
  2823. return true;
  2824. });
  2825. }
  2826. else if (includeParty)
  2827. {
  2828. player.getParty().forEachMember(member ->
  2829. {
  2830. actionForEachPlayer(member, npc, isSummon);
  2831. return true;
  2832. });
  2833. }
  2834. }
  2835. else
  2836. {
  2837. actionForEachPlayer(player, npc, isSummon);
  2838. }
  2839. }
  2840. /**
  2841. * Overridable method called from {@link #executeForEachPlayer(L2PcInstance, L2Npc, boolean, boolean, boolean)}
  2842. * @param player the player on which the action will be run
  2843. * @param npc the NPC related to this action
  2844. * @param isSummon {@code true} if the event that called this method was originated by the player's summon
  2845. */
  2846. public void actionForEachPlayer(L2PcInstance player, L2Npc npc, boolean isSummon)
  2847. {
  2848. // To be overridden in quest scripts.
  2849. }
  2850. /**
  2851. * Open a door if it is present on the instance and its not open.
  2852. * @param doorId the ID of the door to open
  2853. * @param instanceId the ID of the instance the door is in (0 if the door is not not inside an instance)
  2854. */
  2855. public void openDoor(int doorId, int instanceId)
  2856. {
  2857. final L2DoorInstance door = getDoor(doorId, instanceId);
  2858. if (door == null)
  2859. {
  2860. _log.log(Level.WARNING, getClass().getSimpleName() + ": called openDoor(" + doorId + ", " + instanceId + "); but door wasnt found!", new NullPointerException());
  2861. }
  2862. else if (!door.getOpen())
  2863. {
  2864. door.openMe();
  2865. }
  2866. }
  2867. /**
  2868. * Close a door if it is present in a specified the instance and its open.
  2869. * @param doorId the ID of the door to close
  2870. * @param instanceId the ID of the instance the door is in (0 if the door is not not inside an instance)
  2871. */
  2872. public void closeDoor(int doorId, int instanceId)
  2873. {
  2874. final L2DoorInstance door = getDoor(doorId, instanceId);
  2875. if (door == null)
  2876. {
  2877. _log.log(Level.WARNING, getClass().getSimpleName() + ": called closeDoor(" + doorId + ", " + instanceId + "); but door wasnt found!", new NullPointerException());
  2878. }
  2879. else if (door.getOpen())
  2880. {
  2881. door.closeMe();
  2882. }
  2883. }
  2884. /**
  2885. * Retrieve a door from an instance or the real world.
  2886. * @param doorId the ID of the door to get
  2887. * @param instanceId the ID of the instance the door is in (0 if the door is not not inside an instance)
  2888. * @return the found door or {@code null} if no door with that ID and instance ID was found
  2889. */
  2890. public L2DoorInstance getDoor(int doorId, int instanceId)
  2891. {
  2892. L2DoorInstance door = null;
  2893. if (instanceId <= 0)
  2894. {
  2895. door = DoorData.getInstance().getDoor(doorId);
  2896. }
  2897. else
  2898. {
  2899. final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
  2900. if (inst != null)
  2901. {
  2902. door = inst.getDoor(doorId);
  2903. }
  2904. }
  2905. return door;
  2906. }
  2907. /**
  2908. * Teleport a player into/out of an instance.
  2909. * @param player the player to teleport
  2910. * @param loc the {@link Location} object containing the destination coordinates
  2911. * @param instanceId the ID of the instance to teleport the player to (0 to teleport out of an instance)
  2912. */
  2913. public void teleportPlayer(L2PcInstance player, Location loc, int instanceId)
  2914. {
  2915. teleportPlayer(player, loc, instanceId, true);
  2916. }
  2917. /**
  2918. * Teleport a player into/out of an instance.
  2919. * @param player the player to teleport
  2920. * @param loc the {@link Location} object containing the destination coordinates
  2921. * @param instanceId the ID of the instance to teleport the player to (0 to teleport out of an instance)
  2922. * @param allowRandomOffset if {@code true}, will randomize the teleport coordinates by +/-Config.MAX_OFFSET_ON_TELEPORT
  2923. */
  2924. public void teleportPlayer(L2PcInstance player, Location loc, int instanceId, boolean allowRandomOffset)
  2925. {
  2926. player.teleToLocation(loc, instanceId, allowRandomOffset ? Config.MAX_OFFSET_ON_TELEPORT : 0);
  2927. }
  2928. /**
  2929. * Monster is running and attacking the playable.
  2930. * @param npc the NPC that performs the attack
  2931. * @param creature the target of the attack
  2932. */
  2933. protected void addAttackDesire(L2Npc npc, L2Character creature)
  2934. {
  2935. addAttackDesire(npc, creature, 999);
  2936. }
  2937. /**
  2938. * Monster is running and attacking the target.
  2939. * @param npc the NPC that performs the attack
  2940. * @param creature the target of the attack
  2941. * @param desire the desire to perform the attack
  2942. */
  2943. protected void addAttackDesire(L2Npc npc, L2Character creature, long desire)
  2944. {
  2945. if (npc instanceof L2Attackable)
  2946. {
  2947. ((L2Attackable) npc).addDamageHate(creature, 0, desire);
  2948. }
  2949. npc.setIsRunning(true);
  2950. npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, creature);
  2951. }
  2952. /**
  2953. * Adds desire to move to the given NPC.
  2954. * @param npc the NPC
  2955. * @param loc the location
  2956. * @param desire the desire
  2957. */
  2958. protected void addMoveToDesire(L2Npc npc, Location loc, int desire)
  2959. {
  2960. npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, loc);
  2961. }
  2962. /**
  2963. * Instantly cast a skill upon the given target.
  2964. * @param npc the caster NPC
  2965. * @param target the target of the cast
  2966. * @param skill the skill to cast
  2967. */
  2968. protected void castSkill(L2Npc npc, L2Playable target, SkillHolder skill)
  2969. {
  2970. npc.setTarget(target);
  2971. npc.doCast(skill.getSkill());
  2972. }
  2973. /**
  2974. * Instantly cast a skill upon the given target.
  2975. * @param npc the caster NPC
  2976. * @param target the target of the cast
  2977. * @param skill the skill to cast
  2978. */
  2979. protected void castSkill(L2Npc npc, L2Playable target, Skill skill)
  2980. {
  2981. npc.setTarget(target);
  2982. npc.doCast(skill);
  2983. }
  2984. /**
  2985. * Adds the desire to cast a skill to the given NPC.
  2986. * @param npc the NPC whom cast the skill
  2987. * @param target the skill target
  2988. * @param skill the skill to cast
  2989. * @param desire the desire to cast the skill
  2990. */
  2991. protected void addSkillCastDesire(L2Npc npc, L2Character target, SkillHolder skill, long desire)
  2992. {
  2993. addSkillCastDesire(npc, target, skill.getSkill(), desire);
  2994. }
  2995. /**
  2996. * Adds the desire to cast a skill to the given NPC.
  2997. * @param npc the NPC whom cast the skill
  2998. * @param target the skill target
  2999. * @param skill the skill to cast
  3000. * @param desire the desire to cast the skill
  3001. */
  3002. protected void addSkillCastDesire(L2Npc npc, L2Character target, Skill skill, long desire)
  3003. {
  3004. if (npc instanceof L2Attackable)
  3005. {
  3006. ((L2Attackable) npc).addDamageHate(target, 0, desire);
  3007. }
  3008. npc.setTarget(target);
  3009. npc.getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
  3010. }
  3011. /**
  3012. * Sends the special camera packet to the player.
  3013. * @param player the player
  3014. * @param creature the watched creature
  3015. * @param force
  3016. * @param angle1
  3017. * @param angle2
  3018. * @param time
  3019. * @param range
  3020. * @param duration
  3021. * @param relYaw
  3022. * @param relPitch
  3023. * @param isWide
  3024. * @param relAngle
  3025. */
  3026. public static final void specialCamera(L2PcInstance player, L2Character creature, int force, int angle1, int angle2, int time, int range, int duration, int relYaw, int relPitch, int isWide, int relAngle)
  3027. {
  3028. player.sendPacket(new SpecialCamera(creature, force, angle1, angle2, time, range, duration, relYaw, relPitch, isWide, relAngle));
  3029. }
  3030. /**
  3031. * Sends the special camera packet to the player.
  3032. * @param player
  3033. * @param creature
  3034. * @param force
  3035. * @param angle1
  3036. * @param angle2
  3037. * @param time
  3038. * @param duration
  3039. * @param relYaw
  3040. * @param relPitch
  3041. * @param isWide
  3042. * @param relAngle
  3043. */
  3044. public static final void specialCameraEx(L2PcInstance player, L2Character creature, int force, int angle1, int angle2, int time, int duration, int relYaw, int relPitch, int isWide, int relAngle)
  3045. {
  3046. player.sendPacket(new SpecialCamera(creature, player, force, angle1, angle2, time, duration, relYaw, relPitch, isWide, relAngle));
  3047. }
  3048. /**
  3049. * Sends the special camera packet to the player.
  3050. * @param player
  3051. * @param creature
  3052. * @param force
  3053. * @param angle1
  3054. * @param angle2
  3055. * @param time
  3056. * @param range
  3057. * @param duration
  3058. * @param relYaw
  3059. * @param relPitch
  3060. * @param isWide
  3061. * @param relAngle
  3062. * @param unk
  3063. */
  3064. public static final void specialCamera3(L2PcInstance player, L2Character creature, int force, int angle1, int angle2, int time, int range, int duration, int relYaw, int relPitch, int isWide, int relAngle, int unk)
  3065. {
  3066. player.sendPacket(new SpecialCamera(creature, force, angle1, angle2, time, range, duration, relYaw, relPitch, isWide, relAngle, unk));
  3067. }
  3068. /**
  3069. * @param player
  3070. * @param x
  3071. * @param y
  3072. * @param z
  3073. */
  3074. public static void addRadar(L2PcInstance player, int x, int y, int z)
  3075. {
  3076. player.getRadar().addMarker(x, y, z);
  3077. }
  3078. /**
  3079. * @param player
  3080. * @param x
  3081. * @param y
  3082. * @param z
  3083. */
  3084. public void removeRadar(L2PcInstance player, int x, int y, int z)
  3085. {
  3086. player.getRadar().removeMarker(x, y, z);
  3087. }
  3088. /**
  3089. * @param player
  3090. */
  3091. public void clearRadar(L2PcInstance player)
  3092. {
  3093. player.getRadar().removeAllMarkers();
  3094. }
  3095. }