AbstractEffect.java 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * Copyright (C) 2004-2013 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.effects;
  20. import java.lang.reflect.Constructor;
  21. import java.lang.reflect.InvocationTargetException;
  22. import java.util.ArrayList;
  23. import java.util.Collections;
  24. import java.util.List;
  25. import java.util.logging.Logger;
  26. import com.l2jserver.gameserver.handler.EffectHandler;
  27. import com.l2jserver.gameserver.model.ChanceCondition;
  28. import com.l2jserver.gameserver.model.StatsSet;
  29. import com.l2jserver.gameserver.model.conditions.Condition;
  30. import com.l2jserver.gameserver.model.interfaces.IChanceSkillTrigger;
  31. import com.l2jserver.gameserver.model.skills.AbnormalVisualEffect;
  32. import com.l2jserver.gameserver.model.skills.BuffInfo;
  33. import com.l2jserver.gameserver.model.skills.funcs.Func;
  34. import com.l2jserver.gameserver.model.skills.funcs.FuncTemplate;
  35. import com.l2jserver.gameserver.model.stats.Env;
  36. /**
  37. * Abstract effect implementation.<br>
  38. * Instant effects should not override {@link #onExit(BuffInfo)}.<br>
  39. * Instant effects should not override {@link #canStart(BuffInfo)}, all checks should be done {@link #onStart(BuffInfo)}. Do not call super class methods {@link #onStart(BuffInfo)} nor {@link #onExit(BuffInfo)}.<br>
  40. * @since <a href="http://trac.l2jserver.com/changeset/6249">Changeset 6249</a> the "effect steal constructor" is deprecated.
  41. * @author Zoey76
  42. */
  43. public abstract class AbstractEffect implements IChanceSkillTrigger
  44. {
  45. protected static final Logger _log = Logger.getLogger(AbstractEffect.class.getName());
  46. // Conditions
  47. private final Condition _attachCond;
  48. // private final Condition _applyCond; // TODO: Use or cleanup.
  49. // Abnormal visual effect
  50. private final AbnormalVisualEffect _abnormalEffect;
  51. private final AbnormalVisualEffect[] _specialEffect;
  52. private final AbnormalVisualEffect _eventEffect;
  53. private List<FuncTemplate> _funcTemplates;
  54. private final String _name;
  55. private final double _val;
  56. private final boolean _isSelfEffect;
  57. /** Ticks. */
  58. private final int _ticks;
  59. private final int _triggeredId;
  60. private final int _triggeredLevel;
  61. private final ChanceCondition _chanceCondition;
  62. private final StatsSet _parameters;
  63. /**
  64. * Abstract effect constructor.
  65. * @param attachCond
  66. * @param applyCond
  67. * @param set
  68. * @param params
  69. */
  70. protected AbstractEffect(Condition attachCond, Condition applyCond, StatsSet set, StatsSet params)
  71. {
  72. _attachCond = attachCond;
  73. // _applyCond = applyCond;
  74. _name = set.getString("name");
  75. _val = set.getDouble("val", 0);
  76. _isSelfEffect = set.getInt("self", 0) == 1;
  77. _ticks = set.getInt("ticks", 0);
  78. _abnormalEffect = AbnormalVisualEffect.getByName(set.getString("abnormalVisualEffect", ""));
  79. final String[] specialEffects = set.getString("special", "").split(",");
  80. _specialEffect = new AbnormalVisualEffect[specialEffects.length];
  81. for (int i = 0; i < specialEffects.length; i++)
  82. {
  83. _specialEffect[i] = AbnormalVisualEffect.getByName(specialEffects[i]);
  84. }
  85. _eventEffect = AbnormalVisualEffect.getByName(set.getString("event", ""));
  86. _triggeredId = set.getInt("triggeredId", 0);
  87. _triggeredLevel = set.getInt("triggeredLevel", 1);
  88. _chanceCondition = ChanceCondition.parse(set.getString("chanceType", null), set.getInt("activationChance", -1), set.getInt("activationMinDamage", -1), set.getString("activationElements", null), set.getString("activationSkills", null), set.getBoolean("pvpChanceOnly", false));
  89. _parameters = params;
  90. }
  91. public static final AbstractEffect createEffect(Condition attachCond, Condition applyCond, StatsSet set, StatsSet params)
  92. {
  93. final String name = set.getString("name");
  94. final Class<? extends AbstractEffect> handler = EffectHandler.getInstance().getHandler(name);
  95. if (handler == null)
  96. {
  97. _log.warning(AbstractEffect.class.getSimpleName() + ": Requested unexistent effect handler: " + name);
  98. return null;
  99. }
  100. final Constructor<?> constructor;
  101. try
  102. {
  103. constructor = handler.getConstructor(Condition.class, Condition.class, StatsSet.class, StatsSet.class);
  104. }
  105. catch (NoSuchMethodException | SecurityException e1)
  106. {
  107. _log.warning(AbstractEffect.class.getSimpleName() + ": Requested unexistent constructor for effect handler: " + name);
  108. e1.printStackTrace();
  109. return null;
  110. }
  111. try
  112. {
  113. return (AbstractEffect) constructor.newInstance(attachCond, applyCond, set, params);
  114. }
  115. catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
  116. {
  117. e.printStackTrace();
  118. }
  119. return null;
  120. }
  121. /**
  122. * Tests the attach condition.
  123. * @param env the data
  124. * @return {@code true} if there isn't a condition to test or it's passed, {@code false} otherwise
  125. */
  126. public boolean testConditions(Env env)
  127. {
  128. return (_attachCond == null) || _attachCond.test(env);
  129. }
  130. /**
  131. * Attachs a function template.
  132. * @param f the function
  133. */
  134. public void attach(FuncTemplate f)
  135. {
  136. if (_funcTemplates == null)
  137. {
  138. _funcTemplates = new ArrayList<>(1);
  139. }
  140. _funcTemplates.add(f);
  141. }
  142. /**
  143. * Gets the effect name.
  144. * @return the name
  145. */
  146. public String getName()
  147. {
  148. return _name;
  149. }
  150. /**
  151. * Verify if this is a self-effect.
  152. * @return {@code true} if it is a self-effect, {@code false} otherwise
  153. */
  154. public boolean isSelfEffect()
  155. {
  156. return _isSelfEffect;
  157. }
  158. /**
  159. * Gets the generic value.
  160. * @return the value
  161. */
  162. public double getValue()
  163. {
  164. return _val;
  165. }
  166. /**
  167. * Gets the effect ticks
  168. * @return the ticks
  169. */
  170. public int getTicks()
  171. {
  172. return _ticks;
  173. }
  174. public AbnormalVisualEffect getAbnormalEffect()
  175. {
  176. return _abnormalEffect;
  177. }
  178. public AbnormalVisualEffect[] getSpecialEffect()
  179. {
  180. return _specialEffect;
  181. }
  182. public AbnormalVisualEffect getEventEffect()
  183. {
  184. return _eventEffect;
  185. }
  186. public List<FuncTemplate> getFuncTemplates()
  187. {
  188. return _funcTemplates;
  189. }
  190. @Override
  191. public int getTriggeredChanceId()
  192. {
  193. return _triggeredId;
  194. }
  195. @Override
  196. public int getTriggeredChanceLevel()
  197. {
  198. return _triggeredLevel;
  199. }
  200. @Override
  201. public ChanceCondition getTriggeredChanceCondition()
  202. {
  203. return _chanceCondition;
  204. }
  205. /**
  206. * Verify if this effect template has parameters.
  207. * @return {@code true} if this effect template has parameters, {@code false} otherwise
  208. */
  209. public boolean hasParameters()
  210. {
  211. return _parameters != null;
  212. }
  213. /**
  214. * Get the parameters.
  215. * @return the parameters of this effect template
  216. */
  217. public StatsSet getParameters()
  218. {
  219. return _parameters;
  220. }
  221. /**
  222. * Calculates whether this effects land or not.<br>
  223. * If it lands will be scheduled and added to the character effect list.<br>
  224. * Override in effect implementation to change behavior. <br>
  225. * <b>Warning:</b> Must be used only for instant effects continuous effects will not call this they have their success handled by activate_rate.
  226. * @param info the buff info
  227. * @return {@code true} if this effect land, {@code false} otherwise
  228. */
  229. public boolean calcSuccess(BuffInfo info)
  230. {
  231. return true;
  232. }
  233. /**
  234. * Get this effect's type.<br>
  235. * TODO: Remove.
  236. * @return the effect type
  237. */
  238. public L2EffectType getEffectType()
  239. {
  240. return L2EffectType.NONE;
  241. }
  242. /**
  243. * Verify if the buff can start.<br>
  244. * Used for continuous effects.
  245. * @param info the buff info
  246. * @return {@code true} if all the start conditions are meet, {@code false} otherwise
  247. */
  248. public boolean canStart(BuffInfo info)
  249. {
  250. return true;
  251. }
  252. /**
  253. * Called on effect start.
  254. * @param info the buff info
  255. */
  256. public void onStart(BuffInfo info)
  257. {
  258. }
  259. /**
  260. * Called on each tick.<br>
  261. * If the abnormal time is lesser than zero it will last forever.
  262. * @param info the buff info
  263. * @return if {@code true} this effect will continue forever, if {@code false} it will stop after abnormal time has passed
  264. */
  265. public boolean onActionTime(BuffInfo info)
  266. {
  267. return false;
  268. }
  269. /**
  270. * Called when the effect is exited.
  271. * @param info the buff info
  272. */
  273. public void onExit(BuffInfo info)
  274. {
  275. }
  276. /**
  277. * Get this effect's stats functions.
  278. * @param env the data
  279. * @return a list of stat functions.
  280. */
  281. public List<Func> getStatFuncs(Env env)
  282. {
  283. if (getFuncTemplates() == null)
  284. {
  285. return Collections.<Func> emptyList();
  286. }
  287. final List<Func> funcs = new ArrayList<>(getFuncTemplates().size());
  288. for (FuncTemplate t : getFuncTemplates())
  289. {
  290. final Func f = t.getFunc(env, this);
  291. if (f != null)
  292. {
  293. funcs.add(f);
  294. }
  295. }
  296. return funcs;
  297. }
  298. /**
  299. * Get the effect flags.
  300. * @return bit flag for current effect
  301. */
  302. public int getEffectFlags()
  303. {
  304. return EffectFlag.NONE.getMask();
  305. }
  306. @Override
  307. public String toString()
  308. {
  309. return "Effect " + _name;
  310. }
  311. public void decreaseForce()
  312. {
  313. }
  314. public void increaseEffect()
  315. {
  316. }
  317. public boolean checkCondition(Object obj)
  318. {
  319. return true;
  320. }
  321. @Override
  322. public boolean triggersChanceSkill()
  323. {
  324. return _triggeredId > 0;
  325. }
  326. /**
  327. * Verify if this effect is an instant effect.
  328. * @return {@code true} if this effect is instant, {@code false} otherwise
  329. */
  330. public boolean isInstant()
  331. {
  332. return false;
  333. }
  334. }