DocumentBase.java 43 KB

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