SHOW:
|
|
- or go back to the newest paste.
1 | ### Eclipse Workspace Patch 1.0 | |
2 | #P aCis_gameserver405 | |
3 | diff --git config/players.properties config/players.properties | |
4 | index 99e7087..863c6c5 100644 | |
5 | --- config/players.properties | |
6 | +++ config/players.properties | |
7 | @@ -259,6 +259,22 @@ | |
8 | # Store buffs/debuffs on user logout. Default: True | |
9 | StoreSkillCooltime = True | |
10 | ||
11 | + | |
12 | + | |
13 | +#========================================================================== | |
14 | +# RANDOM CRAFT SYSTEM NPC - ID - CONSUME - REFRESH - CREATE - ITEMS | |
15 | +#========================================================================== | |
16 | + | |
17 | +RandomCraftItemId = 57 | |
18 | + | |
19 | +RandomCraftConsumeRefresh = 50000 | |
20 | + | |
21 | +RandromCraftConsumeCreate = 300000 | |
22 | + | |
23 | + | |
24 | + | |
25 | + | |
26 | + | |
27 | # DressMe system. | |
28 | AllowDressMeSystem = True | |
29 | ||
30 | diff --git java/Base/Data/IconTable.java java/Base/Data/IconTable.java | |
31 | new file mode 100644 | |
32 | index 0000000..fdce5d7 | |
33 | --- /dev/null | |
34 | +++ java/Base/Data/IconTable.java | |
35 | @@ -0,0 +1,62 @@ | |
36 | +package Base.Data; | |
37 | + | |
38 | +import java.io.File; | |
39 | +import java.util.HashMap; | |
40 | +import java.util.Map; | |
41 | + | |
42 | +import org.w3c.dom.Document; | |
43 | +import org.w3c.dom.NamedNodeMap; | |
44 | +import org.w3c.dom.Node; | |
45 | + | |
46 | +public class IconTable extends XMLDocument | |
47 | +{ | |
48 | + private static final Map<Integer, String> itemIcons = new HashMap<>(); | |
49 | + | |
50 | + public IconTable() | |
51 | + { | |
52 | + load(); | |
53 | + } | |
54 | + | |
55 | + @Override | |
56 | + protected void load() | |
57 | + { | |
58 | + loadDocument("./data/xml/icons.xml"); | |
59 | + LOG.info("Loaded " + itemIcons.size() + " icons."); | |
60 | + } | |
61 | + | |
62 | + @Override | |
63 | + protected void parseDocument(Document doc, File f) | |
64 | + { | |
65 | + // First element is never read. | |
66 | + final Node n = doc.getFirstChild(); | |
67 | + | |
68 | + for (Node o = n.getFirstChild(); o != null; o = o.getNextSibling()) | |
69 | + { | |
70 | + if (!"icon".equalsIgnoreCase(o.getNodeName())) | |
71 | + { | |
72 | + continue; | |
73 | + } | |
74 | + | |
75 | + final NamedNodeMap attrs = o.getAttributes(); | |
76 | + final int itemId = Integer.valueOf(attrs.getNamedItem("Id").getNodeValue()); | |
77 | + final String value = String.valueOf(attrs.getNamedItem("value").getNodeValue()); | |
78 | + | |
79 | + itemIcons.put(itemId, value); | |
80 | + } | |
81 | + } | |
82 | + | |
83 | + public String getIcon(int id) | |
84 | + { | |
85 | + return itemIcons.get(id) == null ? "icon.noimage" : itemIcons.get(id); | |
86 | + } | |
87 | + | |
88 | + public static IconTable getInstance() | |
89 | + { | |
90 | + return SingletonHolder._instance; | |
91 | + } | |
92 | + | |
93 | + private static class SingletonHolder | |
94 | + { | |
95 | + protected static final IconTable _instance = new IconTable(); | |
96 | + } | |
97 | +} | |
98 | diff --git java/Base/Data/XMLDocument.java java/Base/Data/XMLDocument.java | |
99 | new file mode 100644 | |
100 | index 0000000..7ba3079 | |
101 | --- /dev/null | |
102 | +++ java/Base/Data/XMLDocument.java | |
103 | @@ -0,0 +1,119 @@ | |
104 | +package Base.Data; | |
105 | + | |
106 | +import java.io.File; | |
107 | +import java.util.logging.Level; | |
108 | +import java.util.logging.Logger; | |
109 | + | |
110 | +import javax.xml.parsers.DocumentBuilderFactory; | |
111 | +import javax.xml.transform.OutputKeys; | |
112 | +import javax.xml.transform.Transformer; | |
113 | +import javax.xml.transform.TransformerException; | |
114 | +import javax.xml.transform.TransformerFactory; | |
115 | +import javax.xml.transform.dom.DOMSource; | |
116 | +import javax.xml.transform.stream.StreamResult; | |
117 | + | |
118 | +import net.sf.l2j.commons.data.StatSet; | |
119 | + | |
120 | +import org.w3c.dom.Document; | |
121 | +import org.w3c.dom.NamedNodeMap; | |
122 | +import org.w3c.dom.Node; | |
123 | + | |
124 | +/** | |
125 | + * An XML document, relying on a static and single DocumentBuilderFactory. | |
126 | + */ | |
127 | +public abstract class XMLDocument | |
128 | +{ | |
129 | + protected static final Logger LOG = Logger.getLogger(XMLDocument.class.getName()); | |
130 | + | |
131 | + protected Document document; | |
132 | + | |
133 | + private static final DocumentBuilderFactory BUILDER; | |
134 | + static | |
135 | + { | |
136 | + BUILDER = DocumentBuilderFactory.newInstance(); | |
137 | + BUILDER.setValidating(false); | |
138 | + BUILDER.setIgnoringComments(true); | |
139 | + } | |
140 | + | |
141 | + abstract protected void load(); | |
142 | + | |
143 | + abstract protected void parseDocument(Document doc, File f); | |
144 | + | |
145 | + public void loadDocument(String filePath) | |
146 | + { | |
147 | + loadDocument(new File(filePath)); | |
148 | + } | |
149 | + | |
150 | + public void writeDocument(Document doc, String fileName) | |
151 | + { | |
152 | + try | |
153 | + { | |
154 | + TransformerFactory transformerFactory = TransformerFactory.newInstance(); | |
155 | + Transformer transformer = transformerFactory.newTransformer(); | |
156 | + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); | |
157 | + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
158 | + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); | |
159 | + | |
160 | + DOMSource source = new DOMSource(doc); | |
161 | + StreamResult result = new StreamResult(new File(fileName)); | |
162 | + | |
163 | + transformer.transform(source, result); | |
164 | + LOG.info("XML file saved to " + fileName); | |
165 | + } | |
166 | + catch (TransformerException e) | |
167 | + { | |
168 | + LOG.warning("Error saving XML file: " + e.getMessage()); | |
169 | + } | |
170 | + } | |
171 | + | |
172 | + /** | |
173 | + * Parse an entire directory or file if found. | |
174 | + * @param file | |
175 | + */ | |
176 | + public void loadDocument(File file) | |
177 | + { | |
178 | + if (!file.exists()) | |
179 | + { | |
180 | + LOG.severe("The following file or directory doesn't exist: " + file.getName()); | |
181 | + return; | |
182 | + } | |
183 | + | |
184 | + if (file.isDirectory()) | |
185 | + { | |
186 | + for (File f : file.listFiles()) | |
187 | + { | |
188 | + loadDocument(f); | |
189 | + } | |
190 | + } | |
191 | + else if (file.isFile()) | |
192 | + { | |
193 | + try | |
194 | + { | |
195 | + parseDocument(BUILDER.newDocumentBuilder().parse(file), file); | |
196 | + } | |
197 | + catch (Exception e) | |
198 | + { | |
199 | + LOG.log(Level.SEVERE, "Error loading XML file " + file.getName(), e); | |
200 | + } | |
201 | + } | |
202 | + } | |
203 | + | |
204 | + public Document getDocument() | |
205 | + { | |
206 | + return document; | |
207 | + } | |
208 | + | |
209 | + /** | |
210 | + * This method parses the content of a NamedNodeMap and feed the given StatsSet. | |
211 | + * @param attrs : The NamedNodeMap to parse. | |
212 | + * @param set : The StatsSet to feed. | |
213 | + */ | |
214 | + public static void parseAndFeed(NamedNodeMap attrs, StatSet set) | |
215 | + { | |
216 | + for (int i = 0; i < attrs.getLength(); i++) | |
217 | + { | |
218 | + final Node attr = attrs.item(i); | |
219 | + set.set(attr.getNodeName(), attr.getNodeValue()); | |
220 | + } | |
221 | + } | |
222 | +} | |
223 | diff --git java/Base/RandomCraft/RandomCraftItem.java java/Base/RandomCraft/RandomCraftItem.java | |
224 | new file mode 100644 | |
225 | index 0000000..088d66f | |
226 | --- /dev/null | |
227 | +++ java/Base/RandomCraft/RandomCraftItem.java | |
228 | @@ -0,0 +1,50 @@ | |
229 | +package Base.RandomCraft; | |
230 | + | |
231 | +import net.sf.l2j.gameserver.data.xml.ItemData; | |
232 | +import net.sf.l2j.gameserver.model.item.kind.Item; | |
233 | + | |
234 | +public class RandomCraftItem | |
235 | +{ | |
236 | + private int id; | |
237 | + private int cantidad; | |
238 | + private double probabilidad; | |
239 | + private boolean announce; | |
240 | + | |
241 | + public RandomCraftItem(int id, int cantidad, double probabilidad, boolean announce) | |
242 | + { | |
243 | + this.id = id; | |
244 | + this.cantidad = cantidad; | |
245 | + this.probabilidad = probabilidad; | |
246 | + this.announce = announce; | |
247 | + } | |
248 | + | |
249 | + public int getId() | |
250 | + { | |
251 | + return id; | |
252 | + } | |
253 | + | |
254 | + public int getCantidad() | |
255 | + { | |
256 | + return cantidad; | |
257 | + } | |
258 | + | |
259 | + public double getProbabilidad() | |
260 | + { | |
261 | + return probabilidad; | |
262 | + } | |
263 | + | |
264 | + public boolean getAnnounce() | |
265 | + { | |
266 | + return announce; | |
267 | + } | |
268 | + | |
269 | + public String getIcon() | |
270 | + { | |
271 | + return getItem().getIcon(); | |
272 | + } | |
273 | + | |
274 | + public Item getItem() | |
275 | + { | |
276 | + return ItemData.getInstance().getTemplate(id); | |
277 | + } | |
278 | +} | |
279 | diff --git java/Base/RandomCraft/RandomCraftXML.java java/Base/RandomCraft/RandomCraftXML.java | |
280 | new file mode 100644 | |
281 | index 0000000..0f2672d | |
282 | --- /dev/null | |
283 | +++ java/Base/RandomCraft/RandomCraftXML.java | |
284 | @@ -0,0 +1,80 @@ | |
285 | +package Base.RandomCraft; | |
286 | + | |
287 | +import java.io.File; | |
288 | +import java.util.HashMap; | |
289 | +import java.util.Map; | |
290 | + | |
291 | +import org.w3c.dom.Document; | |
292 | +import org.w3c.dom.NamedNodeMap; | |
293 | +import org.w3c.dom.Node; | |
294 | + | |
295 | +import Base.Data.XMLDocument; | |
296 | + | |
297 | +public class RandomCraftXML extends XMLDocument | |
298 | +{ | |
299 | + private Map<Integer, RandomCraftItem> items; | |
300 | + | |
301 | + public RandomCraftXML() | |
302 | + { | |
303 | + items = new HashMap<>(); | |
304 | + load(); | |
305 | + } | |
306 | + | |
307 | + public static RandomCraftXML getInstance() | |
308 | + { | |
309 | + return SingletonHolder.INSTANCE; | |
310 | + } | |
311 | + | |
312 | + private static class SingletonHolder | |
313 | + { | |
314 | + protected static final RandomCraftXML INSTANCE = new RandomCraftXML(); | |
315 | + } | |
316 | + | |
317 | + @Override | |
318 | + protected void load() | |
319 | + { | |
320 | + loadDocument("./data/xml/RandomCraft.xml"); | |
321 | + LOG.info("RandomCraftItemData: Loaded " + items.size() + " items."); | |
322 | + } | |
323 | + | |
324 | + @Override | |
325 | + protected void parseDocument(Document doc, File file) | |
326 | + { | |
327 | + try | |
328 | + { | |
329 | + final Node root = doc.getFirstChild(); | |
330 | + | |
331 | + for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) | |
332 | + { | |
333 | + if (!"item".equalsIgnoreCase(node.getNodeName())) | |
334 | + { | |
335 | + continue; | |
336 | + } | |
337 | + | |
338 | + NamedNodeMap attrs = node.getAttributes(); | |
339 | + int id = Integer.parseInt(attrs.getNamedItem("id").getNodeValue()); | |
340 | + int cantidad = Integer.parseInt(attrs.getNamedItem("count").getNodeValue()); | |
341 | + double probabilidad = Double.parseDouble(attrs.getNamedItem("chance").getNodeValue()); | |
342 | + boolean announce = Boolean.parseBoolean(attrs.getNamedItem("announce").getNodeValue()); | |
343 | + | |
344 | + RandomCraftItem item = new RandomCraftItem(id, cantidad, probabilidad, announce); | |
345 | + items.put(id, item); | |
346 | + } | |
347 | + } | |
348 | + catch (Exception e) | |
349 | + { | |
350 | + // LOG.warning("RandomCraftItemData: Error while loading items: " + e); | |
351 | + e.printStackTrace(); | |
352 | + } | |
353 | + } | |
354 | + | |
355 | + public Map<Integer, RandomCraftItem> getItems() | |
356 | + { | |
357 | + return items; | |
358 | + } | |
359 | + | |
360 | + public RandomCraftItem getItemById(int id) | |
361 | + { | |
362 | + return items.get(id); | |
363 | + } | |
364 | +} | |
365 | diff --git java/net/sf/l2j/Config.java java/net/sf/l2j/Config.java | |
366 | index a0fde2e..30397a1 100644 | |
367 | --- java/net/sf/l2j/Config.java | |
368 | +++ java/net/sf/l2j/Config.java | |
369 | @@ -49,6 +49,16 @@ | |
370 | // Clans settings | |
371 | // -------------------------------------------------- | |
372 | ||
373 | + | |
374 | + | |
375 | + public static int RANDOM_CRAFT_ITEM_ID_CONSUME; | |
376 | + public static int RANDOM_CRAFT_ITEM_CONSUME_REFRESH; | |
377 | + public static int RANDOM_CRAFT_ITEM_CONSUME_CREATE; | |
378 | + | |
379 | + | |
380 | + | |
381 | + | |
382 | + | |
383 | /** Clans */ | |
384 | public static int CLAN_JOIN_DAYS; | |
385 | public static int CLAN_CREATE_DAYS; | |
386 | @@ -963,6 +973,13 @@ | |
387 | HP_REGEN_MULTIPLIER = players.getProperty("HpRegenMultiplier", 1.); | |
388 | MP_REGEN_MULTIPLIER = players.getProperty("MpRegenMultiplier", 1.); | |
389 | CP_REGEN_MULTIPLIER = players.getProperty("CpRegenMultiplier", 1.); | |
390 | + | |
391 | + RANDOM_CRAFT_ITEM_ID_CONSUME = players.getProperty("RandomCraftItemId", 57); | |
392 | + | |
393 | + RANDOM_CRAFT_ITEM_CONSUME_REFRESH = players.getProperty("RandomCraftConsumeRefresh", 50000); | |
394 | + | |
395 | + RANDOM_CRAFT_ITEM_CONSUME_CREATE = players.getProperty("RandromCraftConsumeCreate", 300000); | |
396 | + | |
397 | PLAYER_SPAWN_PROTECTION = players.getProperty("PlayerSpawnProtection", 0); | |
398 | PLAYER_FAKEDEATH_UP_PROTECTION = players.getProperty("PlayerFakeDeathUpProtection", 5); | |
399 | RESPAWN_RESTORE_HP = players.getProperty("RespawnRestoreHP", 0.7); | |
400 | diff --git java/net/sf/l2j/gameserver/GameServer.java java/net/sf/l2j/gameserver/GameServer.java | |
401 | index 29763e0..e7cc44c 100644 | |
402 | --- java/net/sf/l2j/gameserver/GameServer.java | |
403 | +++ java/net/sf/l2j/gameserver/GameServer.java | |
404 | @@ -102,6 +102,8 @@ | |
405 | import net.sf.l2j.util.DeadLockDetector; | |
406 | import net.sf.l2j.util.IPv4Filter; | |
407 | ||
408 | +import Base.Data.IconTable; | |
409 | +import Base.RandomCraft.RandomCraftXML; | |
410 | import Base.Skin.DressMeData; | |
411 | ||
412 | public class GameServer | |
413 | @@ -266,6 +268,11 @@ | |
414 | StringUtil.printSection("Spawns"); | |
415 | SpawnManager.getInstance().spawn(); | |
416 | ||
417 | + IconTable.getInstance(); | |
418 | + | |
419 | + StringUtil.printSection("RandomCraft - Terius"); | |
420 | + RandomCraftXML.getInstance(); | |
421 | + | |
422 | StringUtil.printSection("Handlers"); | |
423 | LOGGER.info("Loaded {} admin command handlers.", AdminCommandHandler.getInstance().size()); | |
424 | LOGGER.info("Loaded {} chat handlers.", ChatHandler.getInstance().size()); | |
425 | diff --git java/net/sf/l2j/gameserver/model/actor/Player.java java/net/sf/l2j/gameserver/model/actor/Player.java | |
426 | index 8610748..35bca86 100644 | |
427 | --- java/net/sf/l2j/gameserver/model/actor/Player.java | |
428 | +++ java/net/sf/l2j/gameserver/model/actor/Player.java | |
429 | @@ -228,6 +228,7 @@ | |
430 | import net.sf.l2j.gameserver.taskmanager.ShadowItemTaskManager; | |
431 | import net.sf.l2j.gameserver.taskmanager.WaterTaskManager; | |
432 | ||
433 | +import Base.RandomCraft.RandomCraftItem; | |
434 | import Base.Skin.DressMeData; | |
435 | ||
436 | /** | |
437 | @@ -319,6 +320,8 @@ | |
438 | protected int _activeClass; | |
439 | protected int _classIndex; | |
440 | ||
441 | + private List<RandomCraftItem> generatedCraftItems; | |
442 | + | |
443 | private final Map<Integer, SubClass> _subClasses = new ConcurrentSkipListMap<>(); | |
444 | private final ReentrantLock _subclassLock = new ReentrantLock(); | |
445 | ||
446 | @@ -7368,6 +7371,8 @@ | |
447 | return false; | |
448 | } | |
449 | ||
450 | + | |
451 | + | |
452 | @Override | |
453 | public void unpolymorph() | |
454 | { | |
455 | @@ -7375,6 +7380,25 @@ | |
456 | sendPacket(new UserInfo(this)); | |
457 | } | |
458 | ||
459 | + | |
460 | + public List<RandomCraftItem> getGeneratedCraftItems() | |
461 | + { | |
462 | + return generatedCraftItems; | |
463 | + } | |
464 | + | |
465 | + public void setGeneratedCraftItems(List<RandomCraftItem> items) | |
466 | + { | |
467 | + generatedCraftItems = items; | |
468 | + } | |
469 | + | |
470 | + public void clearGeneratedCraftItems() | |
471 | + { | |
472 | + generatedCraftItems.clear(); | |
473 | + } | |
474 | + | |
475 | + | |
476 | + | |
477 | + | |
478 | @Override | |
479 | public void addKnownObject(WorldObject object) | |
480 | { | |
481 | diff --git java/net/sf/l2j/gameserver/model/actor/instance/RandomCraft.java java/net/sf/l2j/gameserver/model/actor/instance/RandomCraft.java | |
482 | new file mode 100644 | |
483 | index 0000000..2be171d | |
484 | --- /dev/null | |
485 | +++ java/net/sf/l2j/gameserver/model/actor/instance/RandomCraft.java | |
486 | @@ -0,0 +1,524 @@ | |
487 | +package net.sf.l2j.gameserver.model.actor.instance; | |
488 | + | |
489 | +import java.sql.Connection; | |
490 | +import java.sql.PreparedStatement; | |
491 | +import java.sql.ResultSet; | |
492 | +import java.sql.SQLException; | |
493 | +import java.util.ArrayList; | |
494 | +import java.util.LinkedList; | |
495 | +import java.util.List; | |
496 | +import java.util.Map; | |
497 | +import java.util.Random; | |
498 | + | |
499 | +import net.sf.l2j.commons.pool.ConnectionPool; | |
500 | + | |
501 | +import net.sf.l2j.Config; | |
502 | +import net.sf.l2j.gameserver.model.World; | |
503 | +import net.sf.l2j.gameserver.model.actor.Npc; | |
504 | +import net.sf.l2j.gameserver.model.actor.Player; | |
505 | +import net.sf.l2j.gameserver.model.actor.template.NpcTemplate; | |
506 | +import net.sf.l2j.gameserver.model.item.instance.ItemInstance; | |
507 | +import net.sf.l2j.gameserver.network.serverpackets.ActionFailed; | |
508 | +import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage; | |
509 | +import net.sf.l2j.gameserver.network.serverpackets.ItemList; | |
510 | +import net.sf.l2j.gameserver.network.serverpackets.MoveToPawn; | |
511 | +import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage; | |
512 | +import Base.RandomCraft.RandomCraftItem; | |
513 | +import Base.RandomCraft.RandomCraftXML; | |
514 | + | |
515 | +/** | |
516 | + * @author Terius | |
517 | + */ | |
518 | + | |
519 | +public class RandomCraft extends Npc | |
520 | +{ | |
521 | + private boolean hasGeneratedItems; | |
522 | + List<RandomCraftItem> items = new LinkedList<>(); | |
523 | + | |
524 | + public RandomCraft(int objectId, NpcTemplate template) | |
525 | + { | |
526 | + super(objectId, template); | |
527 | + setHasGeneratedItems(false); | |
528 | + } | |
529 | + | |
530 | + | |
531 | + @Override | |
532 | + public void onInteract(Player player) | |
533 | + { | |
534 | + // Rotate the player to face the instance | |
535 | + player.sendPacket(new MoveToPawn(player, this, Npc.INTERACTION_DISTANCE)); | |
536 | + | |
537 | + if (hasRandomAnimation()) | |
538 | + { | |
539 | + onRandomAnimation(1); | |
540 | + } | |
541 | + | |
542 | + loadGeneratedItems(player); | |
543 | + | |
544 | + showHtmlWindow(player); | |
545 | + | |
546 | + // Enviar ActionFailed al jugador para evitar quedarse atascado | |
547 | + player.sendPacket(ActionFailed.STATIC_PACKET); | |
548 | + } | |
549 | + | |
550 | + | |
551 | + | |
552 | + | |
553 | + @Override | |
554 | + public void onBypassFeedback(Player player, String command) | |
555 | + { | |
556 | + if (command.startsWith("refresh")) | |
557 | + { | |
558 | + // Verifique si el jugador tiene el artículo requerido (ID 57) y la cantidad (50000) | |
559 | + ItemInstance item57 = player.getInventory().getItemByItemId(Config.RANDOM_CRAFT_ITEM_ID_CONSUME); | |
560 | + if (item57 != null && item57.getCount() >= Config.RANDOM_CRAFT_ITEM_CONSUME_REFRESH) | |
561 | + { | |
562 | + // Cargue al jugador el artículo requerido (ID 57) y la cantidad (50000) | |
563 | + player.getInventory().destroyItemByItemId("Random Craft", Config.RANDOM_CRAFT_ITEM_ID_CONSUME, Config.RANDOM_CRAFT_ITEM_CONSUME_REFRESH, player, this); | |
564 | + | |
565 | + generateItems(player); | |
566 | + | |
567 | + player.sendPacket(new ItemList(player, true)); | |
568 | + | |
569 | + showHtmlWindow(player); | |
570 | + | |
571 | + // Almacene los elementos generados en la base de datos para el jugador | |
572 | + saveGeneratedItems(player); | |
573 | + } | |
574 | + else | |
575 | + { | |
576 | + player.sendMessage("Necesitas al menos 50000 Adena para actualizar Random Craft."); | |
577 | + } | |
578 | + } | |
579 | + else if (command.startsWith("create")) | |
580 | + { | |
581 | + // Eliminar los elementos generados para el jugador de la tabla RandomCraftItem | |
582 | + deleteGeneratedItems(player); | |
583 | + | |
584 | + createItem(player); | |
585 | + | |
586 | + // showHtmlWindow(player); | |
587 | + } | |
588 | + | |
589 | + else if (command.startsWith("back")) | |
590 | + { | |
591 | + | |
592 | + showHtmlWindow(player); | |
593 | + } | |
594 | + | |
595 | + } | |
596 | + | |
597 | + private void generateItems(Player player) | |
598 | + { | |
599 | + List<RandomCraftItem> items = new LinkedList<>(); | |
600 | + RandomCraftXML randomCraftXML = RandomCraftXML.getInstance(); | |
601 | + Map<Integer, RandomCraftItem> craftItems = randomCraftXML.getItems(); | |
602 | + | |
603 | + // Genera 4 elementos únicos para cada jugador en función de la probabilidad | |
604 | + List<Integer> selectedItems = new ArrayList<>(); | |
605 | + while (selectedItems.size() < 4) | |
606 | + { | |
607 | + int itemId = getRandomItem(craftItems); | |
608 | + if (!selectedItems.contains(itemId)) | |
609 | + { | |
610 | + selectedItems.add(itemId); | |
611 | + items.add(craftItems.get(itemId)); | |
612 | + } | |
613 | + } | |
614 | + | |
615 | + // Asignar los elementos generados al jugador | |
616 | + player.setGeneratedCraftItems(items); | |
617 | + setHasGeneratedItems(true); | |
618 | + | |
619 | + } | |
620 | + | |
621 | + private static void deleteGeneratedItems(Player player) | |
622 | + { | |
623 | + try (Connection con = ConnectionPool.getConnection(); | |
624 | + PreparedStatement stmt = con.prepareStatement("DELETE FROM RandomCraftItem WHERE object_id = ?")) | |
625 | + { | |
626 | + stmt.setInt(1, player.getObjectId()); | |
627 | + stmt.execute(); | |
628 | + } | |
629 | + catch (SQLException e) | |
630 | + { | |
631 | + e.printStackTrace(); | |
632 | + } | |
633 | + } | |
634 | + | |
635 | + private static void saveGeneratedItems(Player player) | |
636 | + { | |
637 | + try (Connection con = ConnectionPool.getConnection(); | |
638 | + PreparedStatement stmt = con.prepareStatement("DELETE FROM RandomCraftItem WHERE object_id = ?")) | |
639 | + { | |
640 | + stmt.setInt(1, player.getObjectId()); | |
641 | + stmt.execute(); | |
642 | + | |
643 | + try (PreparedStatement insertStmt = con.prepareStatement("INSERT INTO RandomCraftItem (object_id, item_id, amount, chance, announce) VALUES (?, ?, ?, ?, ?)")) | |
644 | + { | |
645 | + insertStmt.setInt(1, player.getObjectId()); | |
646 | + List<RandomCraftItem> items = player.getGeneratedCraftItems(); | |
647 | + if (items != null) | |
648 | + { | |
649 | + for (RandomCraftItem item : items) | |
650 | + { | |
651 | + insertStmt.setInt(2, item.getId()); | |
652 | + insertStmt.setInt(3, item.getCantidad()); | |
653 | + insertStmt.setDouble(4, item.getProbabilidad()); | |
654 | + insertStmt.setBoolean(5, item.getAnnounce()); | |
655 | + insertStmt.addBatch(); // Agregar la consulta al lote (batch) | |
656 | + } | |
657 | + insertStmt.executeBatch(); // Ejecutar el lote de consultas | |
658 | + } | |
659 | + } | |
660 | + } | |
661 | + catch (SQLException e) | |
662 | + { | |
663 | + e.printStackTrace(); | |
664 | + } | |
665 | + } | |
666 | + | |
667 | + private void loadGeneratedItems(Player player) | |
668 | + { | |
669 | + try (Connection con = ConnectionPool.getConnection(); | |
670 | + PreparedStatement stmt = con.prepareStatement("SELECT item_id, amount, chance, announce FROM RandomCraftItem WHERE object_id = ?")) | |
671 | + { | |
672 | + stmt.setInt(1, player.getObjectId()); | |
673 | + | |
674 | + try (ResultSet rset = stmt.executeQuery()) | |
675 | + { | |
676 | + List<RandomCraftItem> items = new LinkedList<>(); | |
677 | + while (rset.next()) | |
678 | + { | |
679 | + int itemId = rset.getInt("item_id"); | |
680 | + int amount = rset.getInt("amount"); | |
681 | + int chance = rset.getInt("chance"); | |
682 | + boolean announce = rset.getBoolean("announce"); | |
683 | + RandomCraftItem item = new RandomCraftItem(itemId, amount, chance, announce); | |
684 | + items.add(item); | |
685 | + } | |
686 | + | |
687 | + player.setGeneratedCraftItems(items); | |
688 | + setHasGeneratedItems(!items.isEmpty()); | |
689 | + } | |
690 | + } | |
691 | + catch (SQLException e) | |
692 | + { | |
693 | + e.printStackTrace(); | |
694 | + } | |
695 | + } | |
696 | + | |
697 | + private static int getRandomItem(Map<Integer, RandomCraftItem> craftItems) | |
698 | + { | |
699 | + // Calcular la suma de probabilidad total | |
700 | + double totalProbability = 0; | |
701 | + for (RandomCraftItem item : craftItems.values()) | |
702 | + { | |
703 | + totalProbability += item.getProbabilidad(); | |
704 | + } | |
705 | + | |
706 | + // Generar un valor aleatorio entre 0 y la probabilidad total | |
707 | + Random random = new Random(); | |
708 | + double randomValue = random.nextDouble() * totalProbability; | |
709 | + | |
710 | + // Seleccione el elemento en función de la probabilidad | |
711 | + double cumulativeProbability = 0; | |
712 | + for (RandomCraftItem item : craftItems.values()) | |
713 | + { | |
714 | + cumulativeProbability += item.getProbabilidad(); | |
715 | + if (randomValue <= cumulativeProbability) | |
716 | + { | |
717 | + return item.getId(); | |
718 | + } | |
719 | + } | |
720 | + | |
721 | + // Si no se selecciona ningún artÃculo, devolver un artÃculo al azar | |
722 | + List<Integer> itemIds = new ArrayList<>(craftItems.keySet()); | |
723 | + int index = random.nextInt(itemIds.size()); | |
724 | + return itemIds.get(index); | |
725 | + } | |
726 | + | |
727 | + private void createItem(Player player) | |
728 | + { | |
729 | + // Comprueba si la lista de elementos está vacía | |
730 | + List<RandomCraftItem> items = player.getGeneratedCraftItems(); | |
731 | + if (items == null || items.isEmpty()) | |
732 | + { | |
733 | + player.sendMessage("Necesita actualizar para poder crear un elemento aleatorio."); | |
734 | + return; | |
735 | + } | |
736 | + | |
737 | + // Obtén un elemento aleatorio de la lista de elementos generados | |
738 | + Random random = new Random(); | |
739 | + int index = random.nextInt(items.size()); | |
740 | + RandomCraftItem craftItem = items.get(index); | |
741 | + | |
742 | + // Carga al jugador el artículo con ID 57 y cantidad 300000 | |
743 | + ItemInstance item57 = player.getInventory().getItemByItemId(Config.RANDOM_CRAFT_ITEM_ID_CONSUME); | |
744 | + if (item57 != null && item57.getCount() >= Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE) | |
745 | + { | |
746 | + player.getInventory().destroyItemByItemId("Random Craft", Config.RANDOM_CRAFT_ITEM_ID_CONSUME, Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE, player, this); | |
747 | + | |
748 | + // Da el artículo al jugador | |
749 | + ItemInstance itemInstance = player.getInventory().addItem("Random Craft", craftItem.getId(), craftItem.getCantidad(), player, this); | |
750 | + if (itemInstance != null) | |
751 | + { | |
752 | + player.sendPacket(new ItemList(player, true)); | |
753 | + | |
754 | + // Envía un mensaje al jugador con el nombre del artículo y la cantidad. | |
755 | + String message = "¡Felicidades! Has recibido " + craftItem.getItem().getName() + " (Cantidad: " + craftItem.getCantidad() + ")"; | |
756 | + player.sendMessage(message); | |
757 | + | |
758 | + // Obtén el nombre del jugador que creó el elemento | |
759 | + String creatorName = player.getName(); | |
760 | + | |
761 | + // Comprueba si el artículo tiene announce en true en el archivo XML | |
762 | + if (craftItem.getAnnounce()) | |
763 | + { | |
764 | + | |
765 | + for (Player players : World.getInstance().getPlayers()) | |
766 | + { | |
767 | + | |
768 | + String text = creatorName + " Ha Crafteado: " + craftItem.getItem().getName() + " En el RandomCraft System"; | |
769 | + | |
770 | + players.sendPacket(new ExShowScreenMessage(text, 12000)); | |
771 | + | |
772 | + } | |
773 | + | |
774 | + } | |
775 | + | |
776 | + // Borra la lista de elementos para el jugador | |
777 | + player.clearGeneratedCraftItems(); | |
778 | + setHasGeneratedItems(false); | |
779 | + | |
780 | + // Muestra la ventana de felicitaciones con el item ganador | |
781 | + showCongratulationsWindow(player, craftItem); | |
782 | + | |
783 | + return; | |
784 | + } | |
785 | + } | |
786 | + | |
787 | + player.sendMessage("Necesitas al menos 300000 Adena para crear un elemento aleatorio."); | |
788 | + } | |
789 | + | |
790 | + private void showHtmlWindow(Player player) | |
791 | + { | |
792 | + StringBuilder html = new StringBuilder(); | |
793 | + html.append("<html><body>"); | |
794 | + html.append("<center>Bienvenido a Random Craft System!</center>"); | |
795 | + html.append("<br>"); | |
796 | + html.append("<center>Podras Crear 1 item entre los 4 que salgan random!</center>"); | |
797 | + html.append("<br>"); | |
798 | + html.append("<center>Les Deseo Mucha Suerte</center>"); | |
799 | + html.append("<br>"); | |
800 | + html.append("<br>"); | |
801 | + | |
802 | + List<RandomCraftItem> items = player.getGeneratedCraftItems(); | |
803 | + if (items == null || items.isEmpty()) | |
804 | + { | |
805 | + html.append("<center>La Lista Esta Vacia Dale a Refresh</center>"); | |
806 | + } | |
807 | + else | |
808 | + { | |
809 | + // Generar los iconos de los artículos en forma horizontal | |
810 | + for (RandomCraftItem item : items) | |
811 | + { | |
812 | + html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>"); | |
813 | + html.append("<div align=center>"); | |
814 | + html.append("<table>"); | |
815 | + html.append("<tr>"); | |
816 | + html.append("<td>"); | |
817 | + html.append("<img src=").append(item.getIcon()).append(" width=32 height=32>"); | |
818 | + html.append("</td>"); | |
819 | + html.append("<td width=260>"); | |
820 | + html.append("<font color=LEVEL>").append(item.getItem().getName()).append("</font>"); | |
821 | + | |
822 | + html.append("</td>"); | |
823 | + html.append("</tr>"); | |
824 | + html.append("</table>"); | |
825 | + html.append("</div>"); | |
826 | + html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>"); | |
827 | + html.append("<br>"); | |
828 | + } | |
829 | + } | |
830 | + | |
831 | + html.append("<br>"); | |
832 | + html.append("<br>"); | |
833 | + html.append("<center>"); | |
834 | + html.append("<table>"); | |
835 | + html.append("<tr>"); | |
836 | + html.append("<td width=75 height=21>"); | |
837 | + html.append("<button value=\"Refresh\" action=\"bypass -h npc_").append(getObjectId()).append("_refresh\" width=75 height=21 back=\"L2UI.DefaultButton_click\" fore=\"L2UI.DefaultButton\">"); | |
838 | + html.append("</td>"); | |
839 | + html.append("<td width=75 height=21>"); | |
840 | + html.append("<button value=\"Create\" action=\"bypass -h npc_").append(getObjectId()).append("_create\" width=75 height=21 back=\"L2UI.DefaultButton_click\" fore=\"L2UI.DefaultButton\">"); | |
841 | + html.append("</td>"); | |
842 | + html.append("</tr>"); | |
843 | + html.append("</table>"); | |
844 | + html.append("</center>"); | |
845 | + | |
846 | + html.append("</body></html>"); | |
847 | + | |
848 | + showHtmlWindow(player, html.toString()); | |
849 | + } | |
850 | + | |
851 | + private void showHtmlWindow(Player player, String htmlContent) | |
852 | + { | |
853 | + NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); | |
854 | + html.setHtml(htmlContent); | |
855 | + | |
856 | + player.sendPacket(html); | |
857 | + } | |
858 | + | |
859 | + private void showCongratulationsWindow(Player player, RandomCraftItem craftItem) | |
860 | + { | |
861 | + StringBuilder html = new StringBuilder(); | |
862 | + | |
863 | + html.append("<html><body>"); | |
864 | + html.append("<center>Felicidades, has ganado un item</center>"); | |
865 | + html.append("<br>"); | |
866 | + html.append("<center>¡Has recibido</center>"); | |
867 | + html.append("<br>"); | |
868 | + html.append("<br>"); | |
869 | + html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>"); | |
870 | + html.append("<center>"); | |
871 | + html.append("<table>"); | |
872 | + html.append("<tr>"); | |
873 | + html.append("<td>"); | |
874 | + html.append("<img src=").append(craftItem.getIcon()).append(" width=32 height=32>"); | |
875 | + html.append("</td>"); | |
876 | + html.append("<td width=260>"); | |
877 | + html.append("<font color=LEVEL>").append(craftItem.getItem().getName()).append("</font>"); | |
878 | + html.append("</td>"); | |
879 | + html.append("</tr>"); | |
880 | + html.append("</table>"); | |
881 | + html.append("</center>"); | |
882 | + html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>"); | |
883 | + html.append("<br>"); | |
884 | + html.append("<br>"); | |
885 | + html.append("<br>"); | |
886 | + html.append("<br>"); | |
887 | + html.append("<center>"); | |
888 | + html.append("<button value=\"Back\" action=\"bypass -h npc_").append(getObjectId()).append("_back\" width=75 height=21 back=\"L2UI.DefaultButton_click\" fore=\"L2UI.DefaultButton\">"); | |
889 | + html.append("</center>"); | |
890 | + html.append("</body></html>"); | |
891 | + | |
892 | + showHtmlWindow(player, html.toString()); | |
893 | + } | |
894 | + | |
895 | + /** | |
896 | + * @return the hasGeneratedItems | |
897 | + */ | |
898 | + public boolean isHasGeneratedItems() | |
899 | + { | |
900 | + return hasGeneratedItems; | |
901 | + } | |
902 | + | |
903 | + /** | |
904 | + * @param hasGeneratedItems the hasGeneratedItems to set | |
905 | + */ | |
906 | + public void setHasGeneratedItems(boolean hasGeneratedItems) | |
907 | + { | |
908 | + this.hasGeneratedItems = hasGeneratedItems; | |
909 | + } | |
910 | +} | |
911 | diff --git java/net/sf/l2j/gameserver/model/item/kind/Item.java java/net/sf/l2j/gameserver/model/item/kind/Item.java | |
912 | index 9c641b1..054e694 100644 | |
913 | --- java/net/sf/l2j/gameserver/model/item/kind/Item.java | |
914 | +++ java/net/sf/l2j/gameserver/model/item/kind/Item.java | |
915 | @@ -34,6 +34,8 @@ | |
916 | import net.sf.l2j.gameserver.skills.basefuncs.FuncTemplate; | |
917 | import net.sf.l2j.gameserver.skills.conditions.Condition; | |
918 | ||
919 | +import Base.Data.IconTable; | |
920 | + | |
921 | /** | |
922 | * This container contains all informations concerning an item (weapon, armor, etc). | |
923 | */ | |
924 | @@ -531,6 +533,16 @@ | |
925 | return _defaultAction; | |
926 | } | |
927 | ||
928 | + | |
929 | + public String getIcon() | |
930 | + { | |
931 | + return IconTable.getInstance().getIcon(getItemId()); | |
932 | + } | |
933 | + | |
934 | + | |
935 | + | |
936 | + | |
937 | + | |
938 | /** | |
939 | * Returns the name of the item | |
940 | * @return String | |
941 | diff --git server/gameserver/data/xml/RandomCraft.xml server/gameserver/data/xml/RandomCraft.xml | |
942 | new file mode 100644 | |
943 | index 0000000..ff31b12 | |
944 | --- /dev/null | |
945 | +++ server/gameserver/data/xml/RandomCraft.xml | |
946 | @@ -0,0 +1,38 @@ | |
947 | +<?xml version="1.0" encoding="UTF-8"?> | |
948 | +<rewards> | |
949 | + <item id="5644" count="1" chance="25" announce="false"/> | |
950 | + <item id="5704" count="1" chance="25" announce="false"/> | |
951 | + <item id="5706" count="1" chance="25" announce="false"/> | |
952 | + <item id="5709" count="1" chance="10" announce="false"/> | |
953 | + <item id="5714" count="1" chance="10" announce="false"/> | |
954 | + <item id="5715" count="1" chance="10" announce="false"/> | |
955 | + <item id="5720" count="1" chance="10" announce="false"/> | |
956 | + <item id="5727" count="1" chance="10" announce="false"/> | |
957 | + <item id="5765" count="1" chance="15" announce="false"/> | |
958 | + <item id="5766" count="1" chance="15" announce="false"/> | |
959 | + <item id="5767" count="1" chance="15" announce="false"/> | |
960 | + <item id="5768" count="1" chance="15" announce="false"/> | |
961 | + <item id="5769" count="1" chance="15" announce="false"/> | |
962 | + <item id="5770" count="1" chance="20" announce="false"/> | |
963 | + <item id="5771" count="1" chance="15" announce="false"/> | |
964 | + <item id="5772" count="1" chance="15" announce="false"/> | |
965 | + <item id="5773" count="1" chance="15" announce="false"/> | |
966 | + <item id="5774" count="1" chance="15" announce="false"/> | |
967 | + <item id="5775" count="1" chance="15" announce="false"/> | |
968 | + <item id="5776" count="1" chance="15" announce="false"/> | |
969 | + <item id="5777" count="1" chance="15" announce="false"/> | |
970 | + <item id="5778" count="1" chance="15" announce="false"/> | |
971 | + <item id="5779" count="1" chance="15" announce="false"/> | |
972 | + <item id="5780" count="1" chance="20" announce="false"/> | |
973 | + <item id="5781" count="1" chance="20" announce="false"/> | |
974 | + <item id="5782" count="1" chance="20" announce="false"/> | |
975 | + <item id="5783" count="1" chance="20" announce="false"/> | |
976 | + <item id="5784" count="1" chance="20" announce="false"/> | |
977 | + <item id="5785" count="1" chance="20" announce="false"/> | |
978 | + <item id="5787" count="1" chance="20" announce="false"/> | |
979 | + <item id="6367" count="1" chance="25" announce="false"/> | |
980 | + <item id="6372" count="1" chance="25" announce="false"/> | |
981 | + <item id="6373" count="1" chance="2" announce="true"/> | |
982 | + <item id="6374" count="1" chance="2" announce="true"/> | |
983 | + <item id="6375" count="1" chance="2" announce="true"/> | |
984 | + <item id="6376" count="1" chance="2" announce="true"/> | |
985 | + <item id="6377" count="1" chance="2" announce="true"/> | |
986 | + <item id="6378" count="1" chance="2" announce="true"/> | |
987 | + <item id="6379" count="1" chance="2" announce="true"/> | |
988 | + <item id="6380" count="1" chance="2" announce="true"/> | |
989 | + <item id="6381" count="1" chance="2" announce="true"/> | |
990 | + <item id="6382" count="1" chance="2" announce="true"/> | |
991 | + <item id="6383" count="1" chance="2" announce="true"/> | |
992 | + <item id="6384" count="1" chance="2" announce="true"/> | |
993 | + <item id="6385" count="1" chance="2" announce="true"/> | |
994 | + <item id="6386" count="1" chance="2" announce="true"/> | |
995 | + <item id="6392" count="1" chance="10" announce="false"/> | |
996 | + <item id="6582" count="1" chance="2" announce="true"/> | |
997 | + <item id="6587" count="1" chance="2" announce="true"/> | |
998 | + <item id="6590" count="1" chance="2" announce="true"/> | |
999 | + <item id="6594" count="1" chance="2" announce="true"/> | |
1000 | + <item id="6597" count="1" chance="2" announce="true"/> | |
1001 | + <item id="6599" count="1" chance="2" announce="true"/> | |
1002 | + <item id="6604" count="1" chance="2" announce="true"/> | |
1003 | + <item id="6606" count="1" chance="2" announce="true"/> | |
1004 | + <item id="6609" count="1" chance="2" announce="true"/> | |
1005 | +</rewards> | |
1006 | + | |
1007 |