AbstractScript.java 122 KB

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