DocumentBase.java 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402
  1. /*
  2. * Copyright (C) 2004-2014 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.engines;
  20. import java.io.File;
  21. import java.util.ArrayList;
  22. import java.util.HashSet;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import java.util.StringTokenizer;
  27. import java.util.logging.Level;
  28. import java.util.logging.Logger;
  29. import javax.xml.parsers.DocumentBuilderFactory;
  30. import javolution.util.FastMap;
  31. import org.w3c.dom.Document;
  32. import org.w3c.dom.NamedNodeMap;
  33. import org.w3c.dom.Node;
  34. import com.l2jserver.gameserver.datatables.ItemTable;
  35. import com.l2jserver.gameserver.enums.CategoryType;
  36. import com.l2jserver.gameserver.enums.InstanceType;
  37. import com.l2jserver.gameserver.enums.NpcRace;
  38. import com.l2jserver.gameserver.enums.PcRace;
  39. import com.l2jserver.gameserver.model.StatsSet;
  40. import com.l2jserver.gameserver.model.base.PlayerState;
  41. import com.l2jserver.gameserver.model.conditions.Condition;
  42. import com.l2jserver.gameserver.model.conditions.ConditionCategoryType;
  43. import com.l2jserver.gameserver.model.conditions.ConditionChangeWeapon;
  44. import com.l2jserver.gameserver.model.conditions.ConditionGameChance;
  45. import com.l2jserver.gameserver.model.conditions.ConditionGameTime;
  46. import com.l2jserver.gameserver.model.conditions.ConditionGameTime.CheckGameTime;
  47. import com.l2jserver.gameserver.model.conditions.ConditionLogicAnd;
  48. import com.l2jserver.gameserver.model.conditions.ConditionLogicNot;
  49. import com.l2jserver.gameserver.model.conditions.ConditionLogicOr;
  50. import com.l2jserver.gameserver.model.conditions.ConditionMinDistance;
  51. import com.l2jserver.gameserver.model.conditions.ConditionPlayerActiveEffectId;
  52. import com.l2jserver.gameserver.model.conditions.ConditionPlayerActiveSkillId;
  53. import com.l2jserver.gameserver.model.conditions.ConditionPlayerAgathionId;
  54. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCallPc;
  55. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanCreateBase;
  56. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanCreateOutpost;
  57. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanEscape;
  58. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanRefuelAirship;
  59. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanSummon;
  60. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanSummonSiegeGolem;
  61. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanSweep;
  62. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanTakeCastle;
  63. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanTakeFort;
  64. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanTransform;
  65. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanUntransform;
  66. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCharges;
  67. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCheckAbnormal;
  68. import com.l2jserver.gameserver.model.conditions.ConditionPlayerClassIdRestriction;
  69. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCloakStatus;
  70. import com.l2jserver.gameserver.model.conditions.ConditionPlayerCp;
  71. import com.l2jserver.gameserver.model.conditions.ConditionPlayerFlyMounted;
  72. import com.l2jserver.gameserver.model.conditions.ConditionPlayerGrade;
  73. import com.l2jserver.gameserver.model.conditions.ConditionPlayerHasCastle;
  74. import com.l2jserver.gameserver.model.conditions.ConditionPlayerHasClanHall;
  75. import com.l2jserver.gameserver.model.conditions.ConditionPlayerHasFort;
  76. import com.l2jserver.gameserver.model.conditions.ConditionPlayerHasPet;
  77. import com.l2jserver.gameserver.model.conditions.ConditionPlayerHp;
  78. import com.l2jserver.gameserver.model.conditions.ConditionPlayerInsideZoneId;
  79. import com.l2jserver.gameserver.model.conditions.ConditionPlayerInstanceId;
  80. import com.l2jserver.gameserver.model.conditions.ConditionPlayerInvSize;
  81. import com.l2jserver.gameserver.model.conditions.ConditionPlayerIsClanLeader;
  82. import com.l2jserver.gameserver.model.conditions.ConditionPlayerIsHero;
  83. import com.l2jserver.gameserver.model.conditions.ConditionPlayerLandingZone;
  84. import com.l2jserver.gameserver.model.conditions.ConditionPlayerLevel;
  85. import com.l2jserver.gameserver.model.conditions.ConditionPlayerLevelRange;
  86. import com.l2jserver.gameserver.model.conditions.ConditionPlayerMp;
  87. import com.l2jserver.gameserver.model.conditions.ConditionPlayerPkCount;
  88. import com.l2jserver.gameserver.model.conditions.ConditionPlayerPledgeClass;
  89. import com.l2jserver.gameserver.model.conditions.ConditionPlayerRace;
  90. import com.l2jserver.gameserver.model.conditions.ConditionPlayerRangeFromNpc;
  91. import com.l2jserver.gameserver.model.conditions.ConditionPlayerServitorNpcId;
  92. import com.l2jserver.gameserver.model.conditions.ConditionPlayerSex;
  93. import com.l2jserver.gameserver.model.conditions.ConditionPlayerSiegeSide;
  94. import com.l2jserver.gameserver.model.conditions.ConditionPlayerSouls;
  95. import com.l2jserver.gameserver.model.conditions.ConditionPlayerState;
  96. import com.l2jserver.gameserver.model.conditions.ConditionPlayerSubclass;
  97. import com.l2jserver.gameserver.model.conditions.ConditionPlayerTransformationId;
  98. import com.l2jserver.gameserver.model.conditions.ConditionPlayerTvTEvent;
  99. import com.l2jserver.gameserver.model.conditions.ConditionPlayerVehicleMounted;
  100. import com.l2jserver.gameserver.model.conditions.ConditionPlayerWeight;
  101. import com.l2jserver.gameserver.model.conditions.ConditionSiegeZone;
  102. import com.l2jserver.gameserver.model.conditions.ConditionSlotItemId;
  103. import com.l2jserver.gameserver.model.conditions.ConditionTargetAbnormal;
  104. import com.l2jserver.gameserver.model.conditions.ConditionTargetActiveEffectId;
  105. import com.l2jserver.gameserver.model.conditions.ConditionTargetActiveSkillId;
  106. import com.l2jserver.gameserver.model.conditions.ConditionTargetAggro;
  107. import com.l2jserver.gameserver.model.conditions.ConditionTargetClassIdRestriction;
  108. import com.l2jserver.gameserver.model.conditions.ConditionTargetInvSize;
  109. import com.l2jserver.gameserver.model.conditions.ConditionTargetLevel;
  110. import com.l2jserver.gameserver.model.conditions.ConditionTargetLevelRange;
  111. import com.l2jserver.gameserver.model.conditions.ConditionTargetMyPartyExceptMe;
  112. import com.l2jserver.gameserver.model.conditions.ConditionTargetNpcId;
  113. import com.l2jserver.gameserver.model.conditions.ConditionTargetNpcRace;
  114. import com.l2jserver.gameserver.model.conditions.ConditionTargetNpcType;
  115. import com.l2jserver.gameserver.model.conditions.ConditionTargetPlayable;
  116. import com.l2jserver.gameserver.model.conditions.ConditionTargetRace;
  117. import com.l2jserver.gameserver.model.conditions.ConditionTargetUsesWeaponKind;
  118. import com.l2jserver.gameserver.model.conditions.ConditionTargetWeight;
  119. import com.l2jserver.gameserver.model.conditions.ConditionUsingItemType;
  120. import com.l2jserver.gameserver.model.conditions.ConditionUsingSkill;
  121. import com.l2jserver.gameserver.model.conditions.ConditionWithSkill;
  122. import com.l2jserver.gameserver.model.effects.AbstractEffect;
  123. import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
  124. import com.l2jserver.gameserver.model.items.L2Item;
  125. import com.l2jserver.gameserver.model.items.type.ArmorType;
  126. import com.l2jserver.gameserver.model.items.type.WeaponType;
  127. import com.l2jserver.gameserver.model.skills.AbnormalType;
  128. import com.l2jserver.gameserver.model.skills.EffectScope;
  129. import com.l2jserver.gameserver.model.skills.Skill;
  130. import com.l2jserver.gameserver.model.skills.funcs.FuncTemplate;
  131. import com.l2jserver.gameserver.model.skills.funcs.Lambda;
  132. import com.l2jserver.gameserver.model.skills.funcs.LambdaCalc;
  133. import com.l2jserver.gameserver.model.skills.funcs.LambdaConst;
  134. import com.l2jserver.gameserver.model.skills.funcs.LambdaStats;
  135. import com.l2jserver.gameserver.model.stats.Env;
  136. import com.l2jserver.gameserver.model.stats.Stats;
  137. /**
  138. * @author mkizub
  139. */
  140. public abstract class DocumentBase
  141. {
  142. protected final Logger _log = Logger.getLogger(getClass().getName());
  143. private final File _file;
  144. protected Map<String, String[]> _tables;
  145. protected DocumentBase(File pFile)
  146. {
  147. _file = pFile;
  148. _tables = new FastMap<>();
  149. }
  150. public Document parse()
  151. {
  152. Document doc = null;
  153. try
  154. {
  155. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  156. factory.setValidating(false);
  157. factory.setIgnoringComments(true);
  158. doc = factory.newDocumentBuilder().parse(_file);
  159. parseDocument(doc);
  160. }
  161. catch (Exception e)
  162. {
  163. _log.log(Level.SEVERE, "Error loading file " + _file, e);
  164. }
  165. return doc;
  166. }
  167. protected abstract void parseDocument(Document doc);
  168. protected abstract StatsSet getStatsSet();
  169. protected abstract String getTableValue(String name);
  170. protected abstract String getTableValue(String name, int idx);
  171. protected void resetTable()
  172. {
  173. _tables = new FastMap<>();
  174. }
  175. protected void setTable(String name, String[] table)
  176. {
  177. _tables.put(name, table);
  178. }
  179. protected void parseTemplate(Node n, Object template)
  180. {
  181. parseTemplate(n, template, null);
  182. }
  183. protected void parseTemplate(Node n, Object template, EffectScope effectScope)
  184. {
  185. Condition condition = null;
  186. n = n.getFirstChild();
  187. if (n == null)
  188. {
  189. return;
  190. }
  191. if ("cond".equalsIgnoreCase(n.getNodeName()))
  192. {
  193. condition = parseCondition(n.getFirstChild(), template);
  194. Node msg = n.getAttributes().getNamedItem("msg");
  195. Node msgId = n.getAttributes().getNamedItem("msgId");
  196. if ((condition != null) && (msg != null))
  197. {
  198. condition.setMessage(msg.getNodeValue());
  199. }
  200. else if ((condition != null) && (msgId != null))
  201. {
  202. condition.setMessageId(Integer.decode(getValue(msgId.getNodeValue(), null)));
  203. Node addName = n.getAttributes().getNamedItem("addName");
  204. if ((addName != null) && (Integer.decode(getValue(msgId.getNodeValue(), null)) > 0))
  205. {
  206. condition.addName();
  207. }
  208. }
  209. n = n.getNextSibling();
  210. }
  211. for (; n != null; n = n.getNextSibling())
  212. {
  213. switch (n.getNodeName().toLowerCase())
  214. {
  215. case "add":
  216. {
  217. attachFunc(n, template, "Add", condition);
  218. break;
  219. }
  220. case "sub":
  221. {
  222. attachFunc(n, template, "Sub", condition);
  223. break;
  224. }
  225. case "mul":
  226. {
  227. attachFunc(n, template, "Mul", condition);
  228. break;
  229. }
  230. case "basemul":
  231. {
  232. attachFunc(n, template, "BaseMul", condition);
  233. break;
  234. }
  235. case "div":
  236. {
  237. attachFunc(n, template, "Div", condition);
  238. break;
  239. }
  240. case "set":
  241. {
  242. attachFunc(n, template, "Set", condition);
  243. break;
  244. }
  245. case "share":
  246. {
  247. attachFunc(n, template, "Share", condition);
  248. break;
  249. }
  250. case "enchant":
  251. {
  252. attachFunc(n, template, "Enchant", condition);
  253. break;
  254. }
  255. case "enchanthp":
  256. {
  257. attachFunc(n, template, "EnchantHp", condition);
  258. break;
  259. }
  260. case "effect":
  261. {
  262. if (template instanceof AbstractEffect)
  263. {
  264. throw new RuntimeException("Nested effects");
  265. }
  266. attachEffect(n, template, condition, effectScope);
  267. break;
  268. }
  269. }
  270. }
  271. }
  272. protected void attachFunc(Node n, Object template, String name, Condition attachCond)
  273. {
  274. Stats stat = Stats.valueOfXml(n.getAttributes().getNamedItem("stat").getNodeValue());
  275. String order = n.getAttributes().getNamedItem("order").getNodeValue();
  276. Lambda lambda = getLambda(n, template);
  277. int ord = Integer.decode(getValue(order, template));
  278. Condition applayCond = parseCondition(n.getFirstChild(), template);
  279. FuncTemplate ft = new FuncTemplate(attachCond, applayCond, name, stat, ord, lambda);
  280. if (template instanceof L2Item)
  281. {
  282. ((L2Item) template).attach(ft);
  283. }
  284. else if (template instanceof Skill)
  285. {
  286. ((Skill) template).attach(ft);
  287. }
  288. else if (template instanceof AbstractEffect)
  289. {
  290. ((AbstractEffect) template).attach(ft);
  291. }
  292. }
  293. protected void attachLambdaFunc(Node n, Object template, LambdaCalc calc)
  294. {
  295. String name = n.getNodeName();
  296. final StringBuilder sb = new StringBuilder(name);
  297. sb.setCharAt(0, Character.toUpperCase(name.charAt(0)));
  298. name = sb.toString();
  299. Lambda lambda = getLambda(n, template);
  300. FuncTemplate ft = new FuncTemplate(null, null, name, null, calc.funcs.length, lambda);
  301. calc.addFunc(ft.getFunc(new Env(), calc));
  302. }
  303. protected void attachEffect(Node n, Object template, Condition attachCond)
  304. {
  305. attachEffect(n, template, attachCond, null);
  306. }
  307. protected void attachEffect(Node n, Object template, Condition attachCond, EffectScope effectScope)
  308. {
  309. final NamedNodeMap attrs = n.getAttributes();
  310. final StatsSet set = new StatsSet();
  311. for (int i = 0; i < attrs.getLength(); i++)
  312. {
  313. Node att = attrs.item(i);
  314. set.set(att.getNodeName(), getValue(att.getNodeValue(), template));
  315. }
  316. final StatsSet parameters = parseParameters(n.getFirstChild(), template);
  317. final Condition applayCond = parseCondition(n.getFirstChild(), template);
  318. if (template instanceof IIdentifiable)
  319. {
  320. set.set("id", ((IIdentifiable) template).getId());
  321. }
  322. final AbstractEffect effect = AbstractEffect.createEffect(attachCond, applayCond, set, parameters);
  323. parseTemplate(n, effect);
  324. if (template instanceof L2Item)
  325. {
  326. ((L2Item) template).attach(effect);
  327. }
  328. else if (template instanceof Skill)
  329. {
  330. final Skill skill = (Skill) template;
  331. if (effectScope != null)
  332. {
  333. skill.addEffect(effectScope, effect);
  334. }
  335. else if (skill.isPassive())
  336. {
  337. skill.addEffect(EffectScope.PASSIVE, effect);
  338. }
  339. else
  340. {
  341. skill.addEffect(EffectScope.GENERAL, effect);
  342. }
  343. }
  344. }
  345. /**
  346. * Parse effect's parameters.
  347. * @param n the node to start the parsing
  348. * @param template the effect template
  349. * @return the list of parameters if any, {@code null} otherwise
  350. */
  351. private StatsSet parseParameters(Node n, Object template)
  352. {
  353. StatsSet parameters = null;
  354. while ((n != null))
  355. {
  356. // Parse all parameters.
  357. if ((n.getNodeType() == Node.ELEMENT_NODE) && "param".equals(n.getNodeName()))
  358. {
  359. if (parameters == null)
  360. {
  361. parameters = new StatsSet();
  362. }
  363. NamedNodeMap params = n.getAttributes();
  364. for (int i = 0; i < params.getLength(); i++)
  365. {
  366. Node att = params.item(i);
  367. parameters.set(att.getNodeName(), getValue(att.getNodeValue(), template));
  368. }
  369. }
  370. n = n.getNextSibling();
  371. }
  372. return parameters == null ? StatsSet.EMPTY_STATSET : parameters;
  373. }
  374. protected Condition parseCondition(Node n, Object template)
  375. {
  376. while ((n != null) && (n.getNodeType() != Node.ELEMENT_NODE))
  377. {
  378. n = n.getNextSibling();
  379. }
  380. Condition condition = null;
  381. if (n != null)
  382. {
  383. switch (n.getNodeName().toLowerCase())
  384. {
  385. case "and":
  386. {
  387. condition = parseLogicAnd(n, template);
  388. break;
  389. }
  390. case "or":
  391. {
  392. condition = parseLogicOr(n, template);
  393. break;
  394. }
  395. case "not":
  396. {
  397. condition = parseLogicNot(n, template);
  398. break;
  399. }
  400. case "player":
  401. {
  402. condition = parsePlayerCondition(n, template);
  403. break;
  404. }
  405. case "target":
  406. {
  407. condition = parseTargetCondition(n, template);
  408. break;
  409. }
  410. case "using":
  411. {
  412. condition = parseUsingCondition(n);
  413. break;
  414. }
  415. case "game":
  416. {
  417. condition = parseGameCondition(n);
  418. break;
  419. }
  420. }
  421. }
  422. return condition;
  423. }
  424. protected Condition parseLogicAnd(Node n, Object template)
  425. {
  426. ConditionLogicAnd cond = new ConditionLogicAnd();
  427. for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
  428. {
  429. if (n.getNodeType() == Node.ELEMENT_NODE)
  430. {
  431. cond.add(parseCondition(n, template));
  432. }
  433. }
  434. if ((cond.conditions == null) || (cond.conditions.length == 0))
  435. {
  436. _log.severe("Empty <and> condition in " + _file);
  437. }
  438. return cond;
  439. }
  440. protected Condition parseLogicOr(Node n, Object template)
  441. {
  442. ConditionLogicOr cond = new ConditionLogicOr();
  443. for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
  444. {
  445. if (n.getNodeType() == Node.ELEMENT_NODE)
  446. {
  447. cond.add(parseCondition(n, template));
  448. }
  449. }
  450. if ((cond.conditions == null) || (cond.conditions.length == 0))
  451. {
  452. _log.severe("Empty <or> condition in " + _file);
  453. }
  454. return cond;
  455. }
  456. protected Condition parseLogicNot(Node n, Object template)
  457. {
  458. for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
  459. {
  460. if (n.getNodeType() == Node.ELEMENT_NODE)
  461. {
  462. return new ConditionLogicNot(parseCondition(n, template));
  463. }
  464. }
  465. _log.severe("Empty <not> condition in " + _file);
  466. return null;
  467. }
  468. protected Condition parsePlayerCondition(Node n, Object template)
  469. {
  470. Condition cond = null;
  471. NamedNodeMap attrs = n.getAttributes();
  472. for (int i = 0; i < attrs.getLength(); i++)
  473. {
  474. Node a = attrs.item(i);
  475. switch (a.getNodeName().toLowerCase())
  476. {
  477. case "races":
  478. {
  479. final String[] racesVal = a.getNodeValue().split(",");
  480. final PcRace[] races = new PcRace[racesVal.length];
  481. for (int r = 0; r < racesVal.length; r++)
  482. {
  483. if (racesVal[r] != null)
  484. {
  485. races[r] = PcRace.valueOf(racesVal[r]);
  486. }
  487. }
  488. cond = joinAnd(cond, new ConditionPlayerRace(races));
  489. break;
  490. }
  491. case "level":
  492. {
  493. int lvl = Integer.decode(getValue(a.getNodeValue(), template));
  494. cond = joinAnd(cond, new ConditionPlayerLevel(lvl));
  495. break;
  496. }
  497. case "levelrange":
  498. {
  499. String[] range = getValue(a.getNodeValue(), template).split(";");
  500. if (range.length == 2)
  501. {
  502. int[] lvlRange = new int[2];
  503. lvlRange[0] = Integer.decode(getValue(a.getNodeValue(), template).split(";")[0]);
  504. lvlRange[1] = Integer.decode(getValue(a.getNodeValue(), template).split(";")[1]);
  505. cond = joinAnd(cond, new ConditionPlayerLevelRange(lvlRange));
  506. }
  507. break;
  508. }
  509. case "resting":
  510. {
  511. boolean val = Boolean.parseBoolean(a.getNodeValue());
  512. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.RESTING, val));
  513. break;
  514. }
  515. case "flying":
  516. {
  517. boolean val = Boolean.parseBoolean(a.getNodeValue());
  518. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.FLYING, val));
  519. break;
  520. }
  521. case "moving":
  522. {
  523. boolean val = Boolean.parseBoolean(a.getNodeValue());
  524. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.MOVING, val));
  525. break;
  526. }
  527. case "running":
  528. {
  529. boolean val = Boolean.parseBoolean(a.getNodeValue());
  530. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.RUNNING, val));
  531. break;
  532. }
  533. case "standing":
  534. {
  535. boolean val = Boolean.parseBoolean(a.getNodeValue());
  536. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.STANDING, val));
  537. break;
  538. }
  539. case "behind":
  540. {
  541. boolean val = Boolean.parseBoolean(a.getNodeValue());
  542. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.BEHIND, val));
  543. break;
  544. }
  545. case "front":
  546. {
  547. boolean val = Boolean.parseBoolean(a.getNodeValue());
  548. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.FRONT, val));
  549. break;
  550. }
  551. case "chaotic":
  552. {
  553. boolean val = Boolean.parseBoolean(a.getNodeValue());
  554. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.CHAOTIC, val));
  555. break;
  556. }
  557. case "olympiad":
  558. {
  559. boolean val = Boolean.parseBoolean(a.getNodeValue());
  560. cond = joinAnd(cond, new ConditionPlayerState(PlayerState.OLYMPIAD, val));
  561. break;
  562. }
  563. case "ishero":
  564. {
  565. boolean val = Boolean.parseBoolean(a.getNodeValue());
  566. cond = joinAnd(cond, new ConditionPlayerIsHero(val));
  567. break;
  568. }
  569. case "transformationid":
  570. {
  571. int id = Integer.parseInt(a.getNodeValue());
  572. cond = joinAnd(cond, new ConditionPlayerTransformationId(id));
  573. break;
  574. }
  575. case "hp":
  576. {
  577. int hp = Integer.decode(getValue(a.getNodeValue(), null));
  578. cond = joinAnd(cond, new ConditionPlayerHp(hp));
  579. break;
  580. }
  581. case "mp":
  582. {
  583. int hp = Integer.decode(getValue(a.getNodeValue(), null));
  584. cond = joinAnd(cond, new ConditionPlayerMp(hp));
  585. break;
  586. }
  587. case "cp":
  588. {
  589. int cp = Integer.decode(getValue(a.getNodeValue(), null));
  590. cond = joinAnd(cond, new ConditionPlayerCp(cp));
  591. break;
  592. }
  593. case "grade":
  594. {
  595. int expIndex = Integer.decode(getValue(a.getNodeValue(), template));
  596. cond = joinAnd(cond, new ConditionPlayerGrade(expIndex));
  597. break;
  598. }
  599. case "pkcount":
  600. {
  601. int expIndex = Integer.decode(getValue(a.getNodeValue(), template));
  602. cond = joinAnd(cond, new ConditionPlayerPkCount(expIndex));
  603. break;
  604. }
  605. case "siegezone":
  606. {
  607. int value = Integer.decode(getValue(a.getNodeValue(), null));
  608. cond = joinAnd(cond, new ConditionSiegeZone(value, true));
  609. break;
  610. }
  611. case "siegeside":
  612. {
  613. int value = Integer.decode(getValue(a.getNodeValue(), null));
  614. cond = joinAnd(cond, new ConditionPlayerSiegeSide(value));
  615. break;
  616. }
  617. case "charges":
  618. {
  619. int value = Integer.decode(getValue(a.getNodeValue(), template));
  620. cond = joinAnd(cond, new ConditionPlayerCharges(value));
  621. break;
  622. }
  623. case "souls":
  624. {
  625. int value = Integer.decode(getValue(a.getNodeValue(), template));
  626. cond = joinAnd(cond, new ConditionPlayerSouls(value));
  627. break;
  628. }
  629. case "weight":
  630. {
  631. int weight = Integer.decode(getValue(a.getNodeValue(), null));
  632. cond = joinAnd(cond, new ConditionPlayerWeight(weight));
  633. break;
  634. }
  635. case "invsize":
  636. {
  637. int size = Integer.decode(getValue(a.getNodeValue(), null));
  638. cond = joinAnd(cond, new ConditionPlayerInvSize(size));
  639. break;
  640. }
  641. case "isclanleader":
  642. {
  643. boolean val = Boolean.parseBoolean(a.getNodeValue());
  644. cond = joinAnd(cond, new ConditionPlayerIsClanLeader(val));
  645. break;
  646. }
  647. case "ontvtevent":
  648. {
  649. boolean val = Boolean.parseBoolean(a.getNodeValue());
  650. cond = joinAnd(cond, new ConditionPlayerTvTEvent(val));
  651. break;
  652. }
  653. case "pledgeclass":
  654. {
  655. int pledgeClass = Integer.decode(getValue(a.getNodeValue(), null));
  656. cond = joinAnd(cond, new ConditionPlayerPledgeClass(pledgeClass));
  657. break;
  658. }
  659. case "clanhall":
  660. {
  661. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  662. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  663. while (st.hasMoreTokens())
  664. {
  665. String item = st.nextToken().trim();
  666. array.add(Integer.decode(getValue(item, null)));
  667. }
  668. cond = joinAnd(cond, new ConditionPlayerHasClanHall(array));
  669. break;
  670. }
  671. case "fort":
  672. {
  673. int fort = Integer.decode(getValue(a.getNodeValue(), null));
  674. cond = joinAnd(cond, new ConditionPlayerHasFort(fort));
  675. break;
  676. }
  677. case "castle":
  678. {
  679. int castle = Integer.decode(getValue(a.getNodeValue(), null));
  680. cond = joinAnd(cond, new ConditionPlayerHasCastle(castle));
  681. break;
  682. }
  683. case "sex":
  684. {
  685. int sex = Integer.decode(getValue(a.getNodeValue(), null));
  686. cond = joinAnd(cond, new ConditionPlayerSex(sex));
  687. break;
  688. }
  689. case "flymounted":
  690. {
  691. boolean val = Boolean.parseBoolean(a.getNodeValue());
  692. cond = joinAnd(cond, new ConditionPlayerFlyMounted(val));
  693. break;
  694. }
  695. case "vehiclemounted":
  696. {
  697. boolean val = Boolean.parseBoolean(a.getNodeValue());
  698. cond = joinAnd(cond, new ConditionPlayerVehicleMounted(val));
  699. break;
  700. }
  701. case "landingzone":
  702. {
  703. boolean val = Boolean.parseBoolean(a.getNodeValue());
  704. cond = joinAnd(cond, new ConditionPlayerLandingZone(val));
  705. break;
  706. }
  707. case "active_effect_id":
  708. {
  709. int effect_id = Integer.decode(getValue(a.getNodeValue(), template));
  710. cond = joinAnd(cond, new ConditionPlayerActiveEffectId(effect_id));
  711. break;
  712. }
  713. case "active_effect_id_lvl":
  714. {
  715. String val = getValue(a.getNodeValue(), template);
  716. int effect_id = Integer.decode(getValue(val.split(",")[0], template));
  717. int effect_lvl = Integer.decode(getValue(val.split(",")[1], template));
  718. cond = joinAnd(cond, new ConditionPlayerActiveEffectId(effect_id, effect_lvl));
  719. break;
  720. }
  721. case "active_skill_id":
  722. {
  723. int skill_id = Integer.decode(getValue(a.getNodeValue(), template));
  724. cond = joinAnd(cond, new ConditionPlayerActiveSkillId(skill_id));
  725. break;
  726. }
  727. case "active_skill_id_lvl":
  728. {
  729. String val = getValue(a.getNodeValue(), template);
  730. int skill_id = Integer.decode(getValue(val.split(",")[0], template));
  731. int skill_lvl = Integer.decode(getValue(val.split(",")[1], template));
  732. cond = joinAnd(cond, new ConditionPlayerActiveSkillId(skill_id, skill_lvl));
  733. break;
  734. }
  735. case "class_id_restriction":
  736. {
  737. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  738. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  739. while (st.hasMoreTokens())
  740. {
  741. String item = st.nextToken().trim();
  742. array.add(Integer.decode(getValue(item, null)));
  743. }
  744. cond = joinAnd(cond, new ConditionPlayerClassIdRestriction(array));
  745. break;
  746. }
  747. case "subclass":
  748. {
  749. boolean val = Boolean.parseBoolean(a.getNodeValue());
  750. cond = joinAnd(cond, new ConditionPlayerSubclass(val));
  751. break;
  752. }
  753. case "instanceid":
  754. {
  755. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  756. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  757. while (st.hasMoreTokens())
  758. {
  759. String item = st.nextToken().trim();
  760. array.add(Integer.decode(getValue(item, null)));
  761. }
  762. cond = joinAnd(cond, new ConditionPlayerInstanceId(array));
  763. break;
  764. }
  765. case "agathionid":
  766. {
  767. int agathionId = Integer.decode(a.getNodeValue());
  768. cond = joinAnd(cond, new ConditionPlayerAgathionId(agathionId));
  769. break;
  770. }
  771. case "cloakstatus":
  772. {
  773. int val = Integer.parseInt(a.getNodeValue());
  774. cond = joinAnd(cond, new ConditionPlayerCloakStatus(val));
  775. break;
  776. }
  777. case "haspet":
  778. {
  779. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  780. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  781. while (st.hasMoreTokens())
  782. {
  783. String item = st.nextToken().trim();
  784. array.add(Integer.decode(getValue(item, null)));
  785. }
  786. cond = joinAnd(cond, new ConditionPlayerHasPet(array));
  787. break;
  788. }
  789. case "servitornpcid":
  790. {
  791. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  792. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  793. while (st.hasMoreTokens())
  794. {
  795. String item = st.nextToken().trim();
  796. array.add(Integer.decode(getValue(item, null)));
  797. }
  798. cond = joinAnd(cond, new ConditionPlayerServitorNpcId(array));
  799. break;
  800. }
  801. case "npcidradius":
  802. {
  803. final StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  804. if (st.countTokens() == 3)
  805. {
  806. final String[] ids = st.nextToken().split(";");
  807. final int[] npcIds = new int[ids.length];
  808. for (int index = 0; index < ids.length; index++)
  809. {
  810. npcIds[index] = Integer.parseInt(getValue(ids[index], template));
  811. }
  812. final int radius = Integer.parseInt(st.nextToken());
  813. final boolean val = Boolean.parseBoolean(st.nextToken());
  814. cond = joinAnd(cond, new ConditionPlayerRangeFromNpc(npcIds, radius, val));
  815. }
  816. break;
  817. }
  818. case "callpc":
  819. {
  820. cond = joinAnd(cond, new ConditionPlayerCallPc(Boolean.parseBoolean(a.getNodeValue())));
  821. break;
  822. }
  823. case "cancreatebase":
  824. {
  825. cond = joinAnd(cond, new ConditionPlayerCanCreateBase(Boolean.parseBoolean(a.getNodeValue())));
  826. break;
  827. }
  828. case "cancreateoutpost":
  829. {
  830. cond = joinAnd(cond, new ConditionPlayerCanCreateOutpost(Boolean.parseBoolean(a.getNodeValue())));
  831. break;
  832. }
  833. case "canescape":
  834. {
  835. cond = joinAnd(cond, new ConditionPlayerCanEscape(Boolean.parseBoolean(a.getNodeValue())));
  836. break;
  837. }
  838. case "canrefuelairship":
  839. {
  840. cond = joinAnd(cond, new ConditionPlayerCanRefuelAirship(Integer.parseInt(a.getNodeValue())));
  841. break;
  842. }
  843. case "cansummon":
  844. {
  845. cond = joinAnd(cond, new ConditionPlayerCanSummon(Boolean.parseBoolean(a.getNodeValue())));
  846. break;
  847. }
  848. case "cansummonsiegegolem":
  849. {
  850. cond = joinAnd(cond, new ConditionPlayerCanSummonSiegeGolem(Boolean.parseBoolean(a.getNodeValue())));
  851. break;
  852. }
  853. case "cansweep":
  854. {
  855. cond = joinAnd(cond, new ConditionPlayerCanSweep(Boolean.parseBoolean(a.getNodeValue())));
  856. break;
  857. }
  858. case "cantakecastle":
  859. {
  860. cond = joinAnd(cond, new ConditionPlayerCanTakeCastle(Boolean.parseBoolean(a.getNodeValue())));
  861. break;
  862. }
  863. case "cantakefort":
  864. {
  865. cond = joinAnd(cond, new ConditionPlayerCanTakeFort(Boolean.parseBoolean(a.getNodeValue())));
  866. break;
  867. }
  868. case "cantransform":
  869. {
  870. cond = joinAnd(cond, new ConditionPlayerCanTransform(Boolean.parseBoolean(a.getNodeValue())));
  871. break;
  872. }
  873. case "canuntransform":
  874. {
  875. cond = joinAnd(cond, new ConditionPlayerCanUntransform(Boolean.parseBoolean(a.getNodeValue())));
  876. break;
  877. }
  878. case "insidezoneid":
  879. {
  880. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  881. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  882. while (st.hasMoreTokens())
  883. {
  884. String item = st.nextToken().trim();
  885. array.add(Integer.decode(getValue(item, null)));
  886. }
  887. cond = joinAnd(cond, new ConditionPlayerInsideZoneId(array));
  888. break;
  889. }
  890. case "checkabnormal":
  891. {
  892. final String value = a.getNodeValue();
  893. if (value.contains(","))
  894. {
  895. final String[] values = value.split(",");
  896. cond = joinAnd(cond, new ConditionPlayerCheckAbnormal(AbnormalType.valueOf(values[0]), Integer.decode(getValue(values[1], template))));
  897. }
  898. else
  899. {
  900. cond = joinAnd(cond, new ConditionPlayerCheckAbnormal(AbnormalType.valueOf(value)));
  901. }
  902. break;
  903. }
  904. case "categorytype":
  905. {
  906. final String[] values = a.getNodeValue().split(",");
  907. final Set<CategoryType> array = new HashSet<>(values.length);
  908. for (String value : values)
  909. {
  910. array.add(CategoryType.valueOf(getValue(value, null)));
  911. }
  912. cond = joinAnd(cond, new ConditionCategoryType(array));
  913. break;
  914. }
  915. }
  916. }
  917. if (cond == null)
  918. {
  919. _log.severe("Unrecognized <player> condition in " + _file);
  920. }
  921. return cond;
  922. }
  923. protected Condition parseTargetCondition(Node n, Object template)
  924. {
  925. Condition cond = null;
  926. NamedNodeMap attrs = n.getAttributes();
  927. for (int i = 0; i < attrs.getLength(); i++)
  928. {
  929. Node a = attrs.item(i);
  930. switch (a.getNodeName().toLowerCase())
  931. {
  932. case "aggro":
  933. {
  934. boolean val = Boolean.parseBoolean(a.getNodeValue());
  935. cond = joinAnd(cond, new ConditionTargetAggro(val));
  936. break;
  937. }
  938. case "siegezone":
  939. {
  940. int value = Integer.decode(getValue(a.getNodeValue(), null));
  941. cond = joinAnd(cond, new ConditionSiegeZone(value, false));
  942. break;
  943. }
  944. case "level":
  945. {
  946. int lvl = Integer.decode(getValue(a.getNodeValue(), template));
  947. cond = joinAnd(cond, new ConditionTargetLevel(lvl));
  948. break;
  949. }
  950. case "levelrange":
  951. {
  952. String[] range = getValue(a.getNodeValue(), template).split(";");
  953. if (range.length == 2)
  954. {
  955. int[] lvlRange = new int[2];
  956. lvlRange[0] = Integer.decode(getValue(a.getNodeValue(), template).split(";")[0]);
  957. lvlRange[1] = Integer.decode(getValue(a.getNodeValue(), template).split(";")[1]);
  958. cond = joinAnd(cond, new ConditionTargetLevelRange(lvlRange));
  959. }
  960. break;
  961. }
  962. case "mypartyexceptme":
  963. {
  964. cond = joinAnd(cond, new ConditionTargetMyPartyExceptMe(Boolean.parseBoolean(a.getNodeValue())));
  965. break;
  966. }
  967. case "playable":
  968. {
  969. cond = joinAnd(cond, new ConditionTargetPlayable());
  970. break;
  971. }
  972. case "class_id_restriction":
  973. {
  974. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  975. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  976. while (st.hasMoreTokens())
  977. {
  978. String item = st.nextToken().trim();
  979. array.add(Integer.decode(getValue(item, null)));
  980. }
  981. cond = joinAnd(cond, new ConditionTargetClassIdRestriction(array));
  982. break;
  983. }
  984. case "active_effect_id":
  985. {
  986. int effect_id = Integer.decode(getValue(a.getNodeValue(), template));
  987. cond = joinAnd(cond, new ConditionTargetActiveEffectId(effect_id));
  988. break;
  989. }
  990. case "active_effect_id_lvl":
  991. {
  992. String val = getValue(a.getNodeValue(), template);
  993. int effect_id = Integer.decode(getValue(val.split(",")[0], template));
  994. int effect_lvl = Integer.decode(getValue(val.split(",")[1], template));
  995. cond = joinAnd(cond, new ConditionTargetActiveEffectId(effect_id, effect_lvl));
  996. break;
  997. }
  998. case "active_skill_id":
  999. {
  1000. int skill_id = Integer.decode(getValue(a.getNodeValue(), template));
  1001. cond = joinAnd(cond, new ConditionTargetActiveSkillId(skill_id));
  1002. break;
  1003. }
  1004. case "active_skill_id_lvl":
  1005. {
  1006. String val = getValue(a.getNodeValue(), template);
  1007. int skill_id = Integer.decode(getValue(val.split(",")[0], template));
  1008. int skill_lvl = Integer.decode(getValue(val.split(",")[1], template));
  1009. cond = joinAnd(cond, new ConditionTargetActiveSkillId(skill_id, skill_lvl));
  1010. break;
  1011. }
  1012. case "abnormal":
  1013. {
  1014. int abnormalId = Integer.decode(getValue(a.getNodeValue(), template));
  1015. cond = joinAnd(cond, new ConditionTargetAbnormal(abnormalId));
  1016. break;
  1017. }
  1018. case "mindistance":
  1019. {
  1020. int distance = Integer.decode(getValue(a.getNodeValue(), null));
  1021. cond = joinAnd(cond, new ConditionMinDistance(distance * distance));
  1022. break;
  1023. }
  1024. case "npcrace":
  1025. {
  1026. // used for npc race
  1027. final String[] values = a.getNodeValue().split(",");
  1028. final Set<NpcRace> array = new HashSet<>(values.length);
  1029. for (String value : values)
  1030. {
  1031. array.add(NpcRace.valueOf(getValue(value, null)));
  1032. }
  1033. cond = joinAnd(cond, new ConditionTargetNpcRace(array));
  1034. break;
  1035. }
  1036. case "races":
  1037. {
  1038. // used for pc race
  1039. final String[] racesVal = a.getNodeValue().split(",");
  1040. final PcRace[] races = new PcRace[racesVal.length];
  1041. for (int r = 0; r < racesVal.length; r++)
  1042. {
  1043. if (racesVal[r] != null)
  1044. {
  1045. races[r] = PcRace.valueOf(racesVal[r]);
  1046. }
  1047. }
  1048. cond = joinAnd(cond, new ConditionTargetRace(races));
  1049. break;
  1050. }
  1051. case "using":
  1052. {
  1053. int mask = 0;
  1054. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  1055. while (st.hasMoreTokens())
  1056. {
  1057. String item = st.nextToken().trim();
  1058. for (WeaponType wt : WeaponType.values())
  1059. {
  1060. if (wt.getName().equals(item))
  1061. {
  1062. mask |= wt.mask();
  1063. break;
  1064. }
  1065. }
  1066. for (ArmorType at : ArmorType.values())
  1067. {
  1068. if (at.getName().equals(item))
  1069. {
  1070. mask |= at.mask();
  1071. break;
  1072. }
  1073. }
  1074. }
  1075. cond = joinAnd(cond, new ConditionTargetUsesWeaponKind(mask));
  1076. break;
  1077. }
  1078. case "npcid":
  1079. {
  1080. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  1081. ArrayList<Integer> array = new ArrayList<>(st.countTokens());
  1082. while (st.hasMoreTokens())
  1083. {
  1084. String item = st.nextToken().trim();
  1085. array.add(Integer.decode(getValue(item, null)));
  1086. }
  1087. cond = joinAnd(cond, new ConditionTargetNpcId(array));
  1088. break;
  1089. }
  1090. case "npctype":
  1091. {
  1092. String values = getValue(a.getNodeValue(), template).trim();
  1093. String[] valuesSplit = values.split(",");
  1094. InstanceType[] types = new InstanceType[valuesSplit.length];
  1095. InstanceType type;
  1096. for (int j = 0; j < valuesSplit.length; j++)
  1097. {
  1098. type = Enum.valueOf(InstanceType.class, valuesSplit[j]);
  1099. if (type == null)
  1100. {
  1101. throw new IllegalArgumentException("Instance type not recognized: " + valuesSplit[j]);
  1102. }
  1103. types[j] = type;
  1104. }
  1105. cond = joinAnd(cond, new ConditionTargetNpcType(types));
  1106. break;
  1107. }
  1108. case "weight":
  1109. {
  1110. int weight = Integer.decode(getValue(a.getNodeValue(), null));
  1111. cond = joinAnd(cond, new ConditionTargetWeight(weight));
  1112. break;
  1113. }
  1114. case "invsize":
  1115. {
  1116. int size = Integer.decode(getValue(a.getNodeValue(), null));
  1117. cond = joinAnd(cond, new ConditionTargetInvSize(size));
  1118. break;
  1119. }
  1120. }
  1121. }
  1122. if (cond == null)
  1123. {
  1124. _log.severe("Unrecognized <target> condition in " + _file);
  1125. }
  1126. return cond;
  1127. }
  1128. protected Condition parseUsingCondition(Node n)
  1129. {
  1130. Condition cond = null;
  1131. NamedNodeMap attrs = n.getAttributes();
  1132. for (int i = 0; i < attrs.getLength(); i++)
  1133. {
  1134. Node a = attrs.item(i);
  1135. switch (a.getNodeName().toLowerCase())
  1136. {
  1137. case "kind":
  1138. {
  1139. int mask = 0;
  1140. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ",");
  1141. while (st.hasMoreTokens())
  1142. {
  1143. int old = mask;
  1144. String item = st.nextToken().trim();
  1145. if (ItemTable._weaponTypes.containsKey(item))
  1146. {
  1147. mask |= ItemTable._weaponTypes.get(item).mask();
  1148. }
  1149. if (ItemTable._armorTypes.containsKey(item))
  1150. {
  1151. mask |= ItemTable._armorTypes.get(item).mask();
  1152. }
  1153. if (old == mask)
  1154. {
  1155. _log.info("[parseUsingCondition=\"kind\"] Unknown item type name: " + item);
  1156. }
  1157. }
  1158. cond = joinAnd(cond, new ConditionUsingItemType(mask));
  1159. break;
  1160. }
  1161. case "skill":
  1162. {
  1163. int id = Integer.parseInt(a.getNodeValue());
  1164. cond = joinAnd(cond, new ConditionUsingSkill(id));
  1165. break;
  1166. }
  1167. case "slotitem":
  1168. {
  1169. StringTokenizer st = new StringTokenizer(a.getNodeValue(), ";");
  1170. int id = Integer.parseInt(st.nextToken().trim());
  1171. int slot = Integer.parseInt(st.nextToken().trim());
  1172. int enchant = 0;
  1173. if (st.hasMoreTokens())
  1174. {
  1175. enchant = Integer.parseInt(st.nextToken().trim());
  1176. }
  1177. cond = joinAnd(cond, new ConditionSlotItemId(slot, id, enchant));
  1178. break;
  1179. }
  1180. case "weaponchange":
  1181. {
  1182. boolean val = Boolean.parseBoolean(a.getNodeValue());
  1183. cond = joinAnd(cond, new ConditionChangeWeapon(val));
  1184. break;
  1185. }
  1186. }
  1187. }
  1188. if (cond == null)
  1189. {
  1190. _log.severe("Unrecognized <using> condition in " + _file);
  1191. }
  1192. return cond;
  1193. }
  1194. protected Condition parseGameCondition(Node n)
  1195. {
  1196. Condition cond = null;
  1197. NamedNodeMap attrs = n.getAttributes();
  1198. for (int i = 0; i < attrs.getLength(); i++)
  1199. {
  1200. Node a = attrs.item(i);
  1201. if ("skill".equalsIgnoreCase(a.getNodeName()))
  1202. {
  1203. boolean val = Boolean.parseBoolean(a.getNodeValue());
  1204. cond = joinAnd(cond, new ConditionWithSkill(val));
  1205. }
  1206. if ("night".equalsIgnoreCase(a.getNodeName()))
  1207. {
  1208. boolean val = Boolean.parseBoolean(a.getNodeValue());
  1209. cond = joinAnd(cond, new ConditionGameTime(CheckGameTime.NIGHT, val));
  1210. }
  1211. if ("chance".equalsIgnoreCase(a.getNodeName()))
  1212. {
  1213. int val = Integer.decode(getValue(a.getNodeValue(), null));
  1214. cond = joinAnd(cond, new ConditionGameChance(val));
  1215. }
  1216. }
  1217. if (cond == null)
  1218. {
  1219. _log.severe("Unrecognized <game> condition in " + _file);
  1220. }
  1221. return cond;
  1222. }
  1223. protected void parseTable(Node n)
  1224. {
  1225. NamedNodeMap attrs = n.getAttributes();
  1226. String name = attrs.getNamedItem("name").getNodeValue();
  1227. if (name.charAt(0) != '#')
  1228. {
  1229. throw new IllegalArgumentException("Table name must start with #");
  1230. }
  1231. StringTokenizer data = new StringTokenizer(n.getFirstChild().getNodeValue());
  1232. List<String> array = new ArrayList<>(data.countTokens());
  1233. while (data.hasMoreTokens())
  1234. {
  1235. array.add(data.nextToken());
  1236. }
  1237. setTable(name, array.toArray(new String[array.size()]));
  1238. }
  1239. protected void parseBeanSet(Node n, StatsSet set, Integer level)
  1240. {
  1241. String name = n.getAttributes().getNamedItem("name").getNodeValue().trim();
  1242. String value = n.getAttributes().getNamedItem("val").getNodeValue().trim();
  1243. char ch = value.isEmpty() ? ' ' : value.charAt(0);
  1244. if ((ch == '#') || (ch == '-') || Character.isDigit(ch))
  1245. {
  1246. set.set(name, String.valueOf(getValue(value, level)));
  1247. }
  1248. else
  1249. {
  1250. set.set(name, value);
  1251. }
  1252. }
  1253. protected void setExtractableSkillData(StatsSet set, String value)
  1254. {
  1255. set.set("capsuled_items_skill", value);
  1256. }
  1257. protected Lambda getLambda(Node n, Object template)
  1258. {
  1259. Node nval = n.getAttributes().getNamedItem("val");
  1260. if (nval != null)
  1261. {
  1262. String val = nval.getNodeValue();
  1263. if (val.charAt(0) == '#')
  1264. { // table by level
  1265. return new LambdaConst(Double.parseDouble(getTableValue(val)));
  1266. }
  1267. else if (val.charAt(0) == '$')
  1268. {
  1269. if (val.equalsIgnoreCase("$player_level"))
  1270. {
  1271. return new LambdaStats(LambdaStats.StatsType.PLAYER_LEVEL);
  1272. }
  1273. if (val.equalsIgnoreCase("$target_level"))
  1274. {
  1275. return new LambdaStats(LambdaStats.StatsType.TARGET_LEVEL);
  1276. }
  1277. if (val.equalsIgnoreCase("$player_max_hp"))
  1278. {
  1279. return new LambdaStats(LambdaStats.StatsType.PLAYER_MAX_HP);
  1280. }
  1281. if (val.equalsIgnoreCase("$player_max_mp"))
  1282. {
  1283. return new LambdaStats(LambdaStats.StatsType.PLAYER_MAX_MP);
  1284. }
  1285. // try to find value out of item fields
  1286. StatsSet set = getStatsSet();
  1287. String field = set.getString(val.substring(1));
  1288. if (field != null)
  1289. {
  1290. return new LambdaConst(Double.parseDouble(getValue(field, template)));
  1291. }
  1292. // failed
  1293. throw new IllegalArgumentException("Unknown value " + val);
  1294. }
  1295. else
  1296. {
  1297. return new LambdaConst(Double.parseDouble(val));
  1298. }
  1299. }
  1300. LambdaCalc calc = new LambdaCalc();
  1301. n = n.getFirstChild();
  1302. while ((n != null) && (n.getNodeType() != Node.ELEMENT_NODE))
  1303. {
  1304. n = n.getNextSibling();
  1305. }
  1306. if ((n == null) || !"val".equals(n.getNodeName()))
  1307. {
  1308. throw new IllegalArgumentException("Value not specified");
  1309. }
  1310. for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
  1311. {
  1312. if (n.getNodeType() != Node.ELEMENT_NODE)
  1313. {
  1314. continue;
  1315. }
  1316. attachLambdaFunc(n, template, calc);
  1317. }
  1318. return calc;
  1319. }
  1320. protected String getValue(String value, Object template)
  1321. {
  1322. // is it a table?
  1323. if (value.charAt(0) == '#')
  1324. {
  1325. if (template instanceof Skill)
  1326. {
  1327. return getTableValue(value);
  1328. }
  1329. else if (template instanceof Integer)
  1330. {
  1331. return getTableValue(value, ((Integer) template).intValue());
  1332. }
  1333. else
  1334. {
  1335. throw new IllegalStateException();
  1336. }
  1337. }
  1338. return value;
  1339. }
  1340. protected Condition joinAnd(Condition cond, Condition c)
  1341. {
  1342. if (cond == null)
  1343. {
  1344. return c;
  1345. }
  1346. if (cond instanceof ConditionLogicAnd)
  1347. {
  1348. ((ConditionLogicAnd) cond).add(c);
  1349. return cond;
  1350. }
  1351. ConditionLogicAnd and = new ConditionLogicAnd();
  1352. and.add(cond);
  1353. and.add(c);
  1354. return and;
  1355. }
  1356. }