L2CharacterAI.java 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package net.sf.l2j.gameserver.ai;
  16. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
  17. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
  18. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_CAST;
  19. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
  20. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
  21. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_INTERACT;
  22. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_MOVE_TO;
  23. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_PICK_UP;
  24. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_REST;
  25. import net.sf.l2j.Config;
  26. import net.sf.l2j.gameserver.Universe;
  27. import net.sf.l2j.gameserver.model.L2Attackable;
  28. import net.sf.l2j.gameserver.model.L2CharPosition;
  29. import net.sf.l2j.gameserver.model.L2Character;
  30. import net.sf.l2j.gameserver.model.L2Object;
  31. import net.sf.l2j.gameserver.model.L2Skill;
  32. import net.sf.l2j.gameserver.model.actor.instance.L2BoatInstance;
  33. import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
  34. import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
  35. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  36. import net.sf.l2j.gameserver.serverpackets.AutoAttackStop;
  37. import net.sf.l2j.gameserver.taskmanager.AttackStanceTaskManager;
  38. /**
  39. * This class manages AI of L2Character.<BR><BR>
  40. *
  41. * L2CharacterAI :<BR><BR>
  42. * <li>L2AttackableAI</li>
  43. * <li>L2DoorAI</li>
  44. * <li>L2PlayerAI</li>
  45. * <li>L2SummonAI</li><BR><BR>
  46. *
  47. */
  48. public class L2CharacterAI extends AbstractAI
  49. {
  50. @Override
  51. protected void onEvtAttacked(L2Character attacker)
  52. {
  53. clientStartAutoAttack();
  54. }
  55. /**
  56. * Constructor of L2CharacterAI.<BR><BR>
  57. *
  58. * @param accessor The AI accessor of the L2Character
  59. *
  60. */
  61. public L2CharacterAI(L2Character.AIAccessor accessor)
  62. {
  63. super(accessor);
  64. }
  65. /**
  66. * Manage the Idle Intention : Stop Attack, Movement and Stand Up the actor.<BR><BR>
  67. *
  68. * <B><U> Actions</U> :</B><BR><BR>
  69. * <li>Set the AI Intention to AI_INTENTION_IDLE </li>
  70. * <li>Init cast and attack target </li>
  71. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast) </li>
  72. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast) </li>
  73. * <li>Stand up the actor server side AND client side by sending Server->Client packet ChangeWaitType (broadcast) </li><BR><BR>
  74. *
  75. */
  76. @Override
  77. protected void onIntentionIdle()
  78. {
  79. // Set the AI Intention to AI_INTENTION_IDLE
  80. changeIntention(AI_INTENTION_IDLE, null, null);
  81. // Init cast and attack target
  82. setCastTarget(null);
  83. setAttackTarget(null);
  84. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  85. clientStopMoving(null);
  86. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  87. clientStopAutoAttack();
  88. }
  89. /**
  90. * Manage the Active Intention : Stop Attack, Movement and Launch Think Event.<BR><BR>
  91. *
  92. * <B><U> Actions</U> : <I>if the Intention is not already Active</I></B><BR><BR>
  93. * <li>Set the AI Intention to AI_INTENTION_ACTIVE </li>
  94. * <li>Init cast and attack target </li>
  95. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast) </li>
  96. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast) </li>
  97. * <li>Launch the Think Event </li><BR><BR>
  98. *
  99. */
  100. @Override
  101. protected void onIntentionActive()
  102. {
  103. // Check if the Intention is not already Active
  104. if (getIntention() != AI_INTENTION_ACTIVE)
  105. {
  106. // Set the AI Intention to AI_INTENTION_ACTIVE
  107. changeIntention(AI_INTENTION_ACTIVE, null, null);
  108. // Init cast and attack target
  109. setCastTarget(null);
  110. setAttackTarget(null);
  111. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  112. clientStopMoving(null);
  113. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  114. clientStopAutoAttack();
  115. // Also enable random animations for this L2Character if allowed
  116. // This is only for mobs - town npcs are handled in their constructor
  117. if (_actor instanceof L2Attackable)
  118. ((L2NpcInstance)_actor).startRandomAnimationTimer();
  119. // Launch the Think Event
  120. onEvtThink();
  121. }
  122. }
  123. /**
  124. * Manage the Rest Intention.<BR><BR>
  125. *
  126. * <B><U> Actions</U> : </B><BR><BR>
  127. * <li>Set the AI Intention to AI_INTENTION_IDLE </li><BR><BR>
  128. *
  129. */
  130. @Override
  131. protected void onIntentionRest()
  132. {
  133. // Set the AI Intention to AI_INTENTION_IDLE
  134. setIntention(AI_INTENTION_IDLE);
  135. }
  136. /**
  137. * Manage the Attack Intention : Stop current Attack (if necessary), Start a new Attack and Launch Think Event.<BR><BR>
  138. *
  139. * <B><U> Actions</U> : </B><BR><BR>
  140. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast) </li>
  141. * <li>Set the Intention of this AI to AI_INTENTION_ATTACK </li>
  142. * <li>Set or change the AI attack target </li>
  143. * <li>Start the actor Auto Attack client side by sending Server->Client packet AutoAttackStart (broadcast) </li>
  144. * <li>Launch the Think Event </li><BR><BR>
  145. *
  146. *
  147. * <B><U> Overridden in</U> :</B><BR><BR>
  148. * <li>L2AttackableAI : Calculate attack timeout</li><BR><BR>
  149. *
  150. */
  151. @Override
  152. protected void onIntentionAttack(L2Character target)
  153. {
  154. if (target == null)
  155. {
  156. clientActionFailed();
  157. return;
  158. }
  159. if (getIntention() == AI_INTENTION_REST)
  160. {
  161. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  162. clientActionFailed();
  163. return;
  164. }
  165. if (_actor.isAllSkillsDisabled() || _actor.isAfraid())
  166. {
  167. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  168. clientActionFailed();
  169. return;
  170. }
  171. // Check if the Intention is already AI_INTENTION_ATTACK
  172. if (getIntention() == AI_INTENTION_ATTACK)
  173. {
  174. // Check if the AI already targets the L2Character
  175. if (getAttackTarget() != target)
  176. {
  177. // Set the AI attack target (change target)
  178. setAttackTarget(target);
  179. stopFollow();
  180. // Launch the Think Event
  181. notifyEvent(CtrlEvent.EVT_THINK, null);
  182. }
  183. else
  184. clientActionFailed(); // else client freezes until cancel target
  185. }
  186. else
  187. {
  188. // Set the Intention of this AbstractAI to AI_INTENTION_ATTACK
  189. changeIntention(AI_INTENTION_ATTACK, target, null);
  190. // Set the AI attack target
  191. setAttackTarget(target);
  192. stopFollow();
  193. // Launch the Think Event
  194. notifyEvent(CtrlEvent.EVT_THINK, null);
  195. }
  196. }
  197. /**
  198. * Manage the Cast Intention : Stop current Attack, Init the AI in order to cast and Launch Think Event.<BR><BR>
  199. *
  200. * <B><U> Actions</U> : </B><BR><BR>
  201. * <li>Set the AI cast target </li>
  202. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast) </li>
  203. * <li>Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor </li>
  204. * <li>Set the AI skill used by INTENTION_CAST </li>
  205. * <li>Set the Intention of this AI to AI_INTENTION_CAST </li>
  206. * <li>Launch the Think Event </li><BR><BR>
  207. *
  208. */
  209. @Override
  210. protected void onIntentionCast(L2Skill skill, L2Object target)
  211. {
  212. if (getIntention() == AI_INTENTION_REST && skill.isMagic())
  213. {
  214. clientActionFailed();
  215. return;
  216. }
  217. if (_actor.isAllSkillsDisabled())
  218. {
  219. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  220. clientActionFailed();
  221. return;
  222. }
  223. // can't cast if muted
  224. if (_actor.isMuted() && skill.isMagic())
  225. {
  226. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  227. clientActionFailed();
  228. return;
  229. }
  230. // Set the AI cast target
  231. setCastTarget((L2Character) target);
  232. // Stop actions client-side to cast the skill
  233. if (skill.getHitTime() > 50)
  234. {
  235. // Abort the attack of the L2Character and send Server->Client ActionFailed packet
  236. _actor.abortAttack();
  237. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  238. // no need for second ActionFailed packet, abortAttack() already sent it
  239. //clientActionFailed();
  240. }
  241. // Set the AI skill used by INTENTION_CAST
  242. _skill = skill;
  243. // Change the Intention of this AbstractAI to AI_INTENTION_CAST
  244. changeIntention(AI_INTENTION_CAST, skill, target);
  245. // Launch the Think Event
  246. notifyEvent(CtrlEvent.EVT_THINK, null);
  247. }
  248. /**
  249. * Manage the Move To Intention : Stop current Attack and Launch a Move to Location Task.<BR><BR>
  250. *
  251. * <B><U> Actions</U> : </B><BR><BR>
  252. * <li>Stop the actor auto-attack server side AND client side by sending Server->Client packet AutoAttackStop (broadcast) </li>
  253. * <li>Set the Intention of this AI to AI_INTENTION_MOVE_TO </li>
  254. * <li>Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast) </li><BR><BR>
  255. *
  256. */
  257. @Override
  258. protected void onIntentionMoveTo(L2CharPosition pos)
  259. {
  260. if (getIntention() == AI_INTENTION_REST)
  261. {
  262. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  263. clientActionFailed();
  264. return;
  265. }
  266. if (_actor.isAllSkillsDisabled())
  267. {
  268. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  269. clientActionFailed();
  270. return;
  271. }
  272. // Set the Intention of this AbstractAI to AI_INTENTION_MOVE_TO
  273. changeIntention(AI_INTENTION_MOVE_TO, pos, null);
  274. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  275. clientStopAutoAttack();
  276. // Abort the attack of the L2Character and send Server->Client ActionFailed packet
  277. _actor.abortAttack();
  278. // Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
  279. moveTo(pos.x, pos.y, pos.z);
  280. }
  281. /* (non-Javadoc)
  282. * @see net.sf.l2j.gameserver.ai.AbstractAI#onIntentionMoveToInABoat(net.sf.l2j.gameserver.model.L2CharPosition, net.sf.l2j.gameserver.model.L2CharPosition)
  283. */
  284. @Override
  285. protected void onIntentionMoveToInABoat(L2CharPosition destination, L2CharPosition origin)
  286. {
  287. if (getIntention() == AI_INTENTION_REST)
  288. {
  289. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  290. clientActionFailed();
  291. return;
  292. }
  293. if (_actor.isAllSkillsDisabled())
  294. {
  295. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  296. clientActionFailed();
  297. return;
  298. }
  299. // Set the Intention of this AbstractAI to AI_INTENTION_MOVE_TO
  300. //
  301. //changeIntention(AI_INTENTION_MOVE_TO, new L2CharPosition(((L2PcInstance)_actor).getBoat().getX() - destination.x, ((L2PcInstance)_actor).getBoat().getY() - destination.y, ((L2PcInstance)_actor).getBoat().getZ() - destination.z, 0) , null);
  302. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  303. clientStopAutoAttack();
  304. // Abort the attack of the L2Character and send Server->Client ActionFailed packet
  305. _actor.abortAttack();
  306. // Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
  307. moveToInABoat(destination, origin);
  308. }
  309. /**
  310. * Manage the Follow Intention : Stop current Attack and Launch a Follow Task.<BR><BR>
  311. *
  312. * <B><U> Actions</U> : </B><BR><BR>
  313. * <li>Stop the actor auto-attack server side AND client side by sending Server->Client packet AutoAttackStop (broadcast) </li>
  314. * <li>Set the Intention of this AI to AI_INTENTION_FOLLOW </li>
  315. * <li>Create and Launch an AI Follow Task to execute every 1s </li><BR><BR>
  316. *
  317. */
  318. @Override
  319. protected void onIntentionFollow(L2Character target)
  320. {
  321. if (getIntention() == AI_INTENTION_REST)
  322. {
  323. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  324. clientActionFailed();
  325. return;
  326. }
  327. if (_actor.isAllSkillsDisabled())
  328. {
  329. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  330. clientActionFailed();
  331. return;
  332. }
  333. if (_actor.isImobilised() || _actor.isRooted())
  334. {
  335. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  336. clientActionFailed();
  337. return;
  338. }
  339. // Dead actors can`t follow
  340. if (_actor.isDead())
  341. {
  342. clientActionFailed();
  343. return;
  344. }
  345. // do not follow yourself
  346. if (_actor == target)
  347. {
  348. clientActionFailed();
  349. return;
  350. }
  351. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  352. clientStopAutoAttack();
  353. // Set the Intention of this AbstractAI to AI_INTENTION_FOLLOW
  354. changeIntention(AI_INTENTION_FOLLOW, target, null);
  355. // Create and Launch an AI Follow Task to execute every 1s
  356. startFollow(target);
  357. }
  358. /**
  359. * Manage the PickUp Intention : Set the pick up target and Launch a Move To Pawn Task (offset=20).<BR><BR>
  360. *
  361. * <B><U> Actions</U> : </B><BR><BR>
  362. * <li>Set the AI pick up target </li>
  363. * <li>Set the Intention of this AI to AI_INTENTION_PICK_UP </li>
  364. * <li>Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast) </li><BR><BR>
  365. *
  366. */
  367. @Override
  368. protected void onIntentionPickUp(L2Object object)
  369. {
  370. if (getIntention() == AI_INTENTION_REST)
  371. {
  372. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  373. clientActionFailed();
  374. return;
  375. }
  376. if (_actor.isAllSkillsDisabled())
  377. {
  378. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  379. clientActionFailed();
  380. return;
  381. }
  382. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  383. clientStopAutoAttack();
  384. // Set the Intention of this AbstractAI to AI_INTENTION_PICK_UP
  385. changeIntention(AI_INTENTION_PICK_UP, object, null);
  386. // Set the AI pick up target
  387. setTarget(object);
  388. if(object.getX() == 0 && object.getY() == 0) // TODO: Find the drop&spawn bug
  389. {
  390. _log.warning("Object in coords 0,0 - using a temporary fix");
  391. object.setXYZ(getActor().getX(), getActor().getY(), getActor().getZ()+5);
  392. }
  393. // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
  394. moveToPawn(object, 20);
  395. }
  396. /**
  397. * Manage the Interact Intention : Set the interact target and Launch a Move To Pawn Task (offset=60).<BR><BR>
  398. *
  399. * <B><U> Actions</U> : </B><BR><BR>
  400. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast) </li>
  401. * <li>Set the AI interact target </li>
  402. * <li>Set the Intention of this AI to AI_INTENTION_INTERACT </li>
  403. * <li>Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast) </li><BR><BR>
  404. *
  405. */
  406. @Override
  407. protected void onIntentionInteract(L2Object object)
  408. {
  409. if (getIntention() == AI_INTENTION_REST)
  410. {
  411. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  412. clientActionFailed();
  413. return;
  414. }
  415. if (_actor.isAllSkillsDisabled())
  416. {
  417. // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
  418. clientActionFailed();
  419. return;
  420. }
  421. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  422. clientStopAutoAttack();
  423. if (getIntention() != AI_INTENTION_INTERACT)
  424. {
  425. // Set the Intention of this AbstractAI to AI_INTENTION_INTERACT
  426. changeIntention(AI_INTENTION_INTERACT, object, null);
  427. // Set the AI interact target
  428. setTarget(object);
  429. // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
  430. moveToPawn(object, 60);
  431. }
  432. }
  433. /**
  434. * Do nothing.<BR><BR>
  435. */
  436. @Override
  437. protected void onEvtThink()
  438. {
  439. // do nothing
  440. }
  441. /**
  442. * Do nothing.<BR><BR>
  443. */
  444. @Override
  445. protected void onEvtAggression(@SuppressWarnings("unused")
  446. L2Character target, @SuppressWarnings("unused")
  447. int aggro)
  448. {
  449. // do nothing
  450. }
  451. /**
  452. * Launch actions corresponding to the Event Stunned then onAttacked Event.<BR><BR>
  453. *
  454. * <B><U> Actions</U> :</B><BR><BR>
  455. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li>
  456. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li>
  457. * <li>Break an attack and send Server->Client ActionFailed packet and a System Message to the L2Character </li>
  458. * <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character </li>
  459. * <li>Launch actions corresponding to the Event onAttacked (only for L2AttackableAI after the stunning periode) </li><BR><BR>
  460. *
  461. */
  462. @Override
  463. protected void onEvtStunned(L2Character attacker)
  464. {
  465. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  466. _actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));
  467. if (AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
  468. AttackStanceTaskManager.getInstance().removeAttackStanceTask(_actor);
  469. // Stop Server AutoAttack also
  470. setAutoAttacking(false);
  471. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  472. clientStopMoving(null);
  473. // Launch actions corresponding to the Event onAttacked (only for L2AttackableAI after the stunning periode)
  474. onEvtAttacked(attacker);
  475. }
  476. /**
  477. * Launch actions corresponding to the Event Sleeping.<BR><BR>
  478. *
  479. * <B><U> Actions</U> :</B><BR><BR>
  480. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li>
  481. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li>
  482. * <li>Break an attack and send Server->Client ActionFailed packet and a System Message to the L2Character </li>
  483. * <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character </li><BR><BR>
  484. *
  485. */
  486. @Override
  487. protected void onEvtSleeping(@SuppressWarnings("unused")
  488. L2Character attacker)
  489. {
  490. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  491. _actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));
  492. if (AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
  493. AttackStanceTaskManager.getInstance().removeAttackStanceTask(_actor);
  494. // stop Server AutoAttack also
  495. setAutoAttacking(false);
  496. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  497. clientStopMoving(null);
  498. }
  499. /**
  500. * Launch actions corresponding to the Event Rooted.<BR><BR>
  501. *
  502. * <B><U> Actions</U> :</B><BR><BR>
  503. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li>
  504. * <li>Launch actions corresponding to the Event onAttacked</li><BR><BR>
  505. *
  506. */
  507. @Override
  508. protected void onEvtRooted(L2Character attacker)
  509. {
  510. // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
  511. //_actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));
  512. //if (AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
  513. // AttackStanceTaskManager.getInstance().removeAttackStanceTask(_actor);
  514. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  515. clientStopMoving(null);
  516. // Launch actions corresponding to the Event onAttacked
  517. onEvtAttacked(attacker);
  518. }
  519. /**
  520. * Launch actions corresponding to the Event Confused.<BR><BR>
  521. *
  522. * <B><U> Actions</U> :</B><BR><BR>
  523. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li>
  524. * <li>Launch actions corresponding to the Event onAttacked</li><BR><BR>
  525. *
  526. */
  527. @Override
  528. protected void onEvtConfused(L2Character attacker)
  529. {
  530. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  531. clientStopMoving(null);
  532. // Launch actions corresponding to the Event onAttacked
  533. onEvtAttacked(attacker);
  534. }
  535. /**
  536. * Launch actions corresponding to the Event Muted.<BR><BR>
  537. *
  538. * <B><U> Actions</U> :</B><BR><BR>
  539. * <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character </li><BR><BR>
  540. *
  541. */
  542. @Override
  543. protected void onEvtMuted(L2Character attacker)
  544. {
  545. // Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character
  546. onEvtAttacked(attacker);
  547. }
  548. /**
  549. * Launch actions corresponding to the Event ReadyToAct.<BR><BR>
  550. *
  551. * <B><U> Actions</U> :</B><BR><BR>
  552. * <li>Launch actions corresponding to the Event Think</li><BR><BR>
  553. *
  554. */
  555. @Override
  556. protected void onEvtReadyToAct()
  557. {
  558. // Launch actions corresponding to the Event Think
  559. onEvtThink();
  560. }
  561. /**
  562. * Do nothing.<BR><BR>
  563. */
  564. @Override
  565. protected void onEvtUserCmd(@SuppressWarnings("unused")
  566. Object arg0, @SuppressWarnings("unused")
  567. Object arg1)
  568. {
  569. // do nothing
  570. }
  571. /**
  572. * Launch actions corresponding to the Event Arrived.<BR><BR>
  573. *
  574. * <B><U> Actions</U> :</B><BR><BR>
  575. * <li>If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE</li>
  576. * <li>Launch actions corresponding to the Event Think</li><BR><BR>
  577. *
  578. */
  579. @Override
  580. protected void onEvtArrived()
  581. {
  582. // Launch an explore task if necessary
  583. if (_accessor.getActor() instanceof L2PcInstance)
  584. {
  585. if (Config.ACTIVATE_POSITION_RECORDER)
  586. ((L2PcInstance) _accessor.getActor()).explore();
  587. ((L2PcInstance) _accessor.getActor()).revalidateZone(true);
  588. }
  589. else _accessor.getActor().revalidateZone();
  590. if (_accessor.getActor().moveToNextRoutePoint())
  591. return;
  592. clientStoppedMoving();
  593. // If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE
  594. if (getIntention() == AI_INTENTION_MOVE_TO) setIntention(AI_INTENTION_ACTIVE);
  595. // Launch actions corresponding to the Event Think
  596. onEvtThink();
  597. if (_actor instanceof L2BoatInstance)
  598. {
  599. ((L2BoatInstance) _actor).evtArrived();
  600. }
  601. }
  602. /**
  603. * Launch actions corresponding to the Event ArrivedRevalidate.<BR><BR>
  604. *
  605. * <B><U> Actions</U> :</B><BR><BR>
  606. * <li>Launch actions corresponding to the Event Think</li><BR><BR>
  607. *
  608. */
  609. @Override
  610. protected void onEvtArrivedRevalidate()
  611. {
  612. // Launch actions corresponding to the Event Think
  613. onEvtThink();
  614. }
  615. /**
  616. * Launch actions corresponding to the Event ArrivedBlocked.<BR><BR>
  617. *
  618. * <B><U> Actions</U> :</B><BR><BR>
  619. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li>
  620. * <li>If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE</li>
  621. * <li>Launch actions corresponding to the Event Think</li><BR><BR>
  622. *
  623. */
  624. @Override
  625. protected void onEvtArrivedBlocked(L2CharPosition blocked_at_pos)
  626. {
  627. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  628. clientStopMoving(blocked_at_pos);
  629. if (Config.ACTIVATE_POSITION_RECORDER
  630. && Universe.getInstance().shouldLog(_accessor.getActor().getObjectId()))
  631. {
  632. if (!_accessor.getActor().isFlying())
  633. Universe.getInstance().registerObstacle(blocked_at_pos.x, blocked_at_pos.y,
  634. blocked_at_pos.z);
  635. if (_accessor.getActor() instanceof L2PcInstance)
  636. ((L2PcInstance) _accessor.getActor()).explore();
  637. }
  638. // If the Intention was AI_INTENTION_MOVE_TO, tet the Intention to AI_INTENTION_ACTIVE
  639. if (getIntention() == AI_INTENTION_MOVE_TO) setIntention(AI_INTENTION_ACTIVE);
  640. // Launch actions corresponding to the Event Think
  641. onEvtThink();
  642. }
  643. /**
  644. * Launch actions corresponding to the Event ForgetObject.<BR><BR>
  645. *
  646. * <B><U> Actions</U> :</B><BR><BR>
  647. * <li>If the object was targeted and the Intention was AI_INTENTION_INTERACT or AI_INTENTION_PICK_UP, set the Intention to AI_INTENTION_ACTIVE</li>
  648. * <li>If the object was targeted to attack, stop the auto-attack, cancel target and set the Intention to AI_INTENTION_ACTIVE</li>
  649. * <li>If the object was targeted to cast, cancel target and set the Intention to AI_INTENTION_ACTIVE</li>
  650. * <li>If the object was targeted to follow, stop the movement, cancel AI Follow Task and set the Intention to AI_INTENTION_ACTIVE</li>
  651. * <li>If the targeted object was the actor , cancel AI target, stop AI Follow Task, stop the movement and set the Intention to AI_INTENTION_IDLE </li><BR><BR>
  652. *
  653. */
  654. @Override
  655. protected void onEvtForgetObject(L2Object object)
  656. {
  657. // If the object was targeted and the Intention was AI_INTENTION_INTERACT or AI_INTENTION_PICK_UP, set the Intention to AI_INTENTION_ACTIVE
  658. if (getTarget() == object)
  659. {
  660. setTarget(null);
  661. if (getIntention() == AI_INTENTION_INTERACT) setIntention(AI_INTENTION_ACTIVE);
  662. else if (getIntention() == AI_INTENTION_PICK_UP) setIntention(AI_INTENTION_ACTIVE);
  663. }
  664. // Check if the object was targeted to attack
  665. if (getAttackTarget() == object)
  666. {
  667. // Cancel attack target
  668. setAttackTarget(null);
  669. // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
  670. setIntention(AI_INTENTION_ACTIVE);
  671. }
  672. // Check if the object was targeted to cast
  673. if (getCastTarget() == object)
  674. {
  675. // Cancel cast target
  676. setCastTarget(null);
  677. // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
  678. setIntention(AI_INTENTION_ACTIVE);
  679. }
  680. // Check if the object was targeted to follow
  681. if (getFollowTarget() == object)
  682. {
  683. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  684. clientStopMoving(null);
  685. // Stop an AI Follow Task
  686. stopFollow();
  687. // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
  688. setIntention(AI_INTENTION_ACTIVE);
  689. }
  690. // Check if the targeted object was the actor
  691. if (_actor == object)
  692. {
  693. // Cancel AI target
  694. setTarget(null);
  695. setAttackTarget(null);
  696. setCastTarget(null);
  697. // Stop an AI Follow Task
  698. stopFollow();
  699. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  700. clientStopMoving(null);
  701. // Set the Intention of this AbstractAI to AI_INTENTION_IDLE
  702. changeIntention(AI_INTENTION_IDLE, null, null);
  703. }
  704. }
  705. /**
  706. * Launch actions corresponding to the Event Cancel.<BR><BR>
  707. *
  708. * <B><U> Actions</U> :</B><BR><BR>
  709. * <li>Stop an AI Follow Task</li>
  710. * <li>Launch actions corresponding to the Event Think</li><BR><BR>
  711. *
  712. */
  713. @Override
  714. protected void onEvtCancel()
  715. {
  716. // Stop an AI Follow Task
  717. stopFollow();
  718. if (!AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
  719. _actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));
  720. // Launch actions corresponding to the Event Think
  721. onEvtThink();
  722. }
  723. /**
  724. * Launch actions corresponding to the Event Dead.<BR><BR>
  725. *
  726. * <B><U> Actions</U> :</B><BR><BR>
  727. * <li>Stop an AI Follow Task</li>
  728. * <li>Kill the actor client side by sending Server->Client packet AutoAttackStop, StopMove/StopRotation, Die (broadcast)</li><BR><BR>
  729. *
  730. */
  731. @Override
  732. protected void onEvtDead()
  733. {
  734. // Stop an AI Follow Task
  735. stopFollow();
  736. // Kill the actor client side by sending Server->Client packet AutoAttackStop, StopMove/StopRotation, Die (broadcast)
  737. clientNotifyDead();
  738. if (!(_actor instanceof L2PcInstance))
  739. _actor.setWalking();
  740. }
  741. /**
  742. * Launch actions corresponding to the Event Fake Death.<BR><BR>
  743. *
  744. * <B><U> Actions</U> :</B><BR><BR>
  745. * <li>Stop an AI Follow Task</li>
  746. *
  747. */
  748. @Override
  749. protected void onEvtFakeDeath()
  750. {
  751. // Stop an AI Follow Task
  752. stopFollow();
  753. // Stop the actor movement and send Server->Client packet StopMove/StopRotation (broadcast)
  754. clientStopMoving(null);
  755. // Init AI
  756. _intention = AI_INTENTION_IDLE;
  757. setTarget(null);
  758. setCastTarget(null);
  759. setAttackTarget(null);
  760. }
  761. /**
  762. * Do nothing.<BR><BR>
  763. */
  764. @Override
  765. protected void onEvtFinishCasting()
  766. {
  767. // do nothing
  768. }
  769. /**
  770. * Manage the Move to Pawn action in function of the distance and of the Interact area.<BR><BR>
  771. *
  772. * <B><U> Actions</U> :</B><BR><BR>
  773. * <li>Get the distance between the current position of the L2Character and the target (x,y)</li>
  774. * <li>If the distance > offset+20, move the actor (by running) to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)</li>
  775. * <li>If the distance <= offset+20, Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li><BR><BR>
  776. *
  777. * <B><U> Example of use </U> :</B><BR><BR>
  778. * <li> L2PLayerAI, L2SummonAI</li><BR><BR>
  779. *
  780. * @param target The targeted L2Object
  781. * @param offset The Interact area radius
  782. *
  783. * @return True if a movement must be done
  784. *
  785. */
  786. protected boolean maybeMoveToPawn(L2Object target, int offset)
  787. {
  788. // Get the distance between the current position of the L2Character and the target (x,y)
  789. if (target == null)
  790. {
  791. _log.warning("maybeMoveToPawn: target == NULL!");
  792. return false;
  793. }
  794. if(offset < 0) return false; // skill radius -1
  795. offset += _actor.getTemplate().collisionRadius;
  796. if (target instanceof L2Character)
  797. offset += ((L2Character)target).getTemplate().collisionRadius;
  798. if (!_actor.isInsideRadius(target, offset, false, false))
  799. {
  800. // Caller should be L2Playable and thinkAttack/thinkCast/thinkInteract/thinkPickUp
  801. if (getFollowTarget() != null) {
  802. // allow larger hit range when the target is moving (check is run only once per second)
  803. if (!_actor.isInsideRadius(target, offset + 100, false, false)) return true;
  804. stopFollow();
  805. return false;
  806. }
  807. if (_actor.isMovementDisabled()) return true;
  808. // If not running, set the L2Character movement type to run and send Server->Client packet ChangeMoveType to all others L2PcInstance
  809. if (!_actor.isRunning() && !(this instanceof L2PlayerAI)) _actor.setRunning();
  810. stopFollow();
  811. if ((target instanceof L2Character) && !(target instanceof L2DoorInstance))
  812. {
  813. if (((L2Character)target).isMoving()) offset -= 100;
  814. if (offset < 5) offset = 5;
  815. startFollow((L2Character) target, offset);
  816. }
  817. else
  818. {
  819. // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
  820. moveToPawn(target, offset);
  821. }
  822. return true;
  823. }
  824. if (getFollowTarget() != null) stopFollow();
  825. // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
  826. // clientStopMoving(null);
  827. return false;
  828. }
  829. /**
  830. * Modify current Intention and actions if the target is lost or dead.<BR><BR>
  831. *
  832. * <B><U> Actions</U> : <I>If the target is lost or dead</I></B><BR><BR>
  833. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li>
  834. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li>
  835. * <li>Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE</li><BR><BR>
  836. *
  837. * <B><U> Example of use </U> :</B><BR><BR>
  838. * <li> L2PLayerAI, L2SummonAI</li><BR><BR>
  839. *
  840. * @param target The targeted L2Object
  841. *
  842. * @return True if the target is lost or dead (false if fakedeath)
  843. *
  844. */
  845. protected boolean checkTargetLostOrDead(L2Character target)
  846. {
  847. if (target == null || target.isAlikeDead())
  848. {
  849. //check if player is fakedeath
  850. if (target != null && target.isFakeDeath())
  851. {
  852. target.stopFakeDeath(null);
  853. return false;
  854. }
  855. // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
  856. setIntention(AI_INTENTION_ACTIVE);
  857. return true;
  858. }
  859. return false;
  860. }
  861. /**
  862. * Modify current Intention and actions if the target is lost.<BR><BR>
  863. *
  864. * <B><U> Actions</U> : <I>If the target is lost</I></B><BR><BR>
  865. * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li>
  866. * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li>
  867. * <li>Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE</li><BR><BR>
  868. *
  869. * <B><U> Example of use </U> :</B><BR><BR>
  870. * <li> L2PLayerAI, L2SummonAI</li><BR><BR>
  871. *
  872. * @param target The targeted L2Object
  873. *
  874. * @return True if the target is lost
  875. *
  876. */
  877. protected boolean checkTargetLost(L2Object target)
  878. {
  879. // check if player is fakedeath
  880. if (target instanceof L2PcInstance)
  881. {
  882. L2PcInstance target2 = (L2PcInstance) target; //convert object to chara
  883. if (target2.isFakeDeath())
  884. {
  885. target2.stopFakeDeath(null);
  886. return false;
  887. }
  888. }
  889. if (target == null)
  890. {
  891. // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
  892. setIntention(AI_INTENTION_ACTIVE);
  893. return true;
  894. }
  895. return false;
  896. }
  897. }