· last year · Jan 03, 2024, 01:15 AM
1### Eclipse Workspace Patch 1.0
2#P aCis_gameserver
3diff --git java/Base/Data/XMLDocument.java java/Base/Data/XMLDocument.java
4new file mode 100644
5index 0000000..3f06c0f
6--- /dev/null
7+++ java/Base/Data/XMLDocument.java
8@@ -0,0 +1,121 @@
9+package Base.Data;
10+
11+
12+
13+import java.io.File;
14+import java.util.logging.Level;
15+import java.util.logging.Logger;
16+
17+import javax.xml.parsers.DocumentBuilderFactory;
18+import javax.xml.transform.OutputKeys;
19+import javax.xml.transform.Transformer;
20+import javax.xml.transform.TransformerException;
21+import javax.xml.transform.TransformerFactory;
22+import javax.xml.transform.dom.DOMSource;
23+import javax.xml.transform.stream.StreamResult;
24+
25+import net.sf.l2j.commons.data.StatSet;
26+
27+import org.w3c.dom.Document;
28+import org.w3c.dom.NamedNodeMap;
29+import org.w3c.dom.Node;
30+
31+/**
32+ * An XML document, relying on a static and single DocumentBuilderFactory.
33+ */
34+public abstract class XMLDocument
35+{
36+ protected static final Logger LOG = Logger.getLogger(XMLDocument.class.getName());
37+
38+ protected Document document;
39+
40+ private static final DocumentBuilderFactory BUILDER;
41+ static
42+ {
43+ BUILDER = DocumentBuilderFactory.newInstance();
44+ BUILDER.setValidating(false);
45+ BUILDER.setIgnoringComments(true);
46+ }
47+
48+ abstract protected void load();
49+
50+ abstract protected void parseDocument(Document doc, File f);
51+
52+ public void loadDocument(String filePath)
53+ {
54+ loadDocument(new File(filePath));
55+ }
56+
57+ public void writeDocument(Document doc, String fileName)
58+ {
59+ try
60+ {
61+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
62+ Transformer transformer = transformerFactory.newTransformer();
63+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
64+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
65+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
66+
67+ DOMSource source = new DOMSource(doc);
68+ StreamResult result = new StreamResult(new File(fileName));
69+
70+ transformer.transform(source, result);
71+ LOG.info("XML file saved to " + fileName);
72+ }
73+ catch (TransformerException e)
74+ {
75+ LOG.warning("Error saving XML file: " + e.getMessage());
76+ }
77+ }
78+
79+ /**
80+ * Parse an entire directory or file if found.
81+ * @param file
82+ */
83+ public void loadDocument(File file)
84+ {
85+ if (!file.exists())
86+ {
87+ LOG.severe("The following file or directory doesn't exist: " + file.getName());
88+ return;
89+ }
90+
91+ if (file.isDirectory())
92+ {
93+ for (File f : file.listFiles())
94+ {
95+ loadDocument(f);
96+ }
97+ }
98+ else if (file.isFile())
99+ {
100+ try
101+ {
102+ parseDocument(BUILDER.newDocumentBuilder().parse(file), file);
103+ }
104+ catch (Exception e)
105+ {
106+ LOG.log(Level.SEVERE, "Error loading XML file " + file.getName(), e);
107+ }
108+ }
109+ }
110+
111+ public Document getDocument()
112+ {
113+ return document;
114+ }
115+
116+ /**
117+ * This method parses the content of a NamedNodeMap and feed the given StatsSet.
118+ * @param attrs : The NamedNodeMap to parse.
119+ * @param set : The StatsSet to feed.
120+ */
121+ public static void parseAndFeed(NamedNodeMap attrs, StatSet set)
122+ {
123+ for (int i = 0; i < attrs.getLength(); i++)
124+ {
125+ final Node attr = attrs.item(i);
126+ set.set(attr.getNodeName(), attr.getNodeValue());
127+ }
128+ }
129+}
130diff --git data/xml/RandomCraft.xml data/xml/RandomCraft.xml
131new file mode 100644
132index 0000000..7e7a013
133--- /dev/null
134+++ data/xml/RandomCraft.xml
135@@ -0,0 +1,9 @@
136+<?xml version="1.0" encoding="UTF-8"?>
137+<rewards>
138+ <item id="8762" count="1" chance="20" announce="false"/>
139+ <item id="8790" count="1" chance="40" announce="true"/>
140+ <item id="8793" count="1" chance="40" announce="true"/>
141+ <item id="8794" count="1" chance="40" announce="true"/>
142+
143+
144+</rewards>
145\ No newline at end of file
146diff --git config/players.properties config/players.properties
147index 745d341..944d438 100644
148--- config/players.properties
149+++ config/players.properties
150@@ -235,4 +235,12 @@
151 # ExpertisePenalty, чтобы отключить штраф за уровень
152 # False : Игроки могут использовать экипировку S ранга с 1 уровня.
153 # True : Игроки не могут использовать экипировку S ранга с 1 уровня.
154-ExpertisePenalty = True
155\ No newline at end of file
156+ExpertisePenalty = True
157+
158+
159+
160+RandomCraftItemIdRefresh = 3470
161+RandomCraftItemIdCreate = 6392
162+RandomCraftConsumeRefresh = 10
163+RandromCraftConsumeCreate = 50
164+MaxItemGeneratorForRandomCraft = 5
165diff --git sql/randomcraftitem.sql sql/randomcraftitem.sql
166new file mode 100644
167index 0000000..e5be5fd
168--- /dev/null
169+++ sql/randomcraftitem.sql
170@@ -0,0 +1,29 @@
171+/*
172+Navicat MySQL Data Transfer
173+
174+Source Server : localhost
175+Source Server Version : 50740
176+Source Host : localhost:3306
177+Source Database : 1faris
178+
179+Target Server Type : MYSQL
180+Target Server Version : 50740
181+File Encoding : 65001
182+
183+Date: 2024-01-02 21:52:28
184+*/
185+
186+SET FOREIGN_KEY_CHECKS=0;
187+
188+-- ----------------------------
189+-- Table structure for randomcraftitem
190+-- ----------------------------
191+DROP TABLE IF EXISTS `randomcraftitem`;
192+CREATE TABLE `randomcraftitem` (
193+ `object_id` int(11) NOT NULL,
194+ `item_id` int(11) NOT NULL,
195+ `amount` int(11) NOT NULL,
196+ `chance` double NOT NULL,
197+ `announce` tinyint(1) NOT NULL DEFAULT '0',
198+ PRIMARY KEY (`object_id`,`item_id`)
199+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
200diff --git java/Base/RandomCraft/RandomCraftItem.java java/Base/RandomCraft/RandomCraftItem.java
201new file mode 100644
202index 0000000..c69f3c0
203--- /dev/null
204+++ java/Base/RandomCraft/RandomCraftItem.java
205@@ -0,0 +1,52 @@
206+package Base.RandomCraft;
207+
208+
209+import net.sf.l2j.gameserver.data.xml.ItemData;
210+import net.sf.l2j.gameserver.model.item.kind.Item;
211+
212+public class RandomCraftItem {
213+ private int id;
214+ private int cantidad;
215+ private double probabilidad;
216+ private boolean announce;
217+ private String itemName; // New field for item name
218+
219+ public RandomCraftItem(int id, int cantidad, double probabilidad, boolean announce) {
220+ this.id = id;
221+ this.cantidad = cantidad;
222+ this.probabilidad = probabilidad;
223+ this.announce = announce;
224+ }
225+
226+ public int getId() {
227+ return id;
228+ }
229+
230+ public int getCantidad() {
231+ return cantidad;
232+ }
233+
234+ public double getProbabilidad() {
235+ return probabilidad;
236+ }
237+
238+ public boolean getAnnounce() {
239+ return announce;
240+ }
241+
242+ public String getIcon() {
243+ return getItem().getIcon();
244+ }
245+
246+ public Item getItem() {
247+ return ItemData.getInstance().getTemplate(id);
248+ }
249+
250+ public void setItemName(String itemName) { // Setter for item name
251+ this.itemName = itemName;
252+ }
253+
254+ public String getItemName() { // Getter for item name
255+ return itemName;
256+ }
257+}
258diff --git java/Base/RandomCraft/RandomCraftXML.java java/Base/RandomCraft/RandomCraftXML.java
259new file mode 100644
260index 0000000..4448cb3
261--- /dev/null
262+++ java/Base/RandomCraft/RandomCraftXML.java
263@@ -0,0 +1,77 @@
264+package Base.RandomCraft;
265+
266+import java.io.File;
267+import java.util.HashMap;
268+import java.util.Map;
269+
270+import org.w3c.dom.Document;
271+import org.w3c.dom.NamedNodeMap;
272+import org.w3c.dom.Node;
273+import Base.Data.XMLDocument;
274+
275+public class RandomCraftXML extends XMLDocument {
276+ private Map<Integer, RandomCraftItem> items;
277+
278+ public RandomCraftXML() {
279+ items = new HashMap<>();
280+ load();
281+
282+ }
283+
284+ public void reload() {
285+ items.clear();
286+ load();
287+ }
288+
289+ public static RandomCraftXML getInstance() {
290+ return SingletonHolder.INSTANCE;
291+ }
292+
293+ private static class SingletonHolder {
294+ protected static final RandomCraftXML INSTANCE = new RandomCraftXML();
295+ }
296+
297+ @Override
298+ protected void load() {
299+ loadDocument("./data/xml/RandomCraft.xml");
300+ LOG.info("RandomCraftItemData: Loaded " + items.size() + " items.");
301+
302+ }
303+
304+
305+
306+
307+ @Override
308+ protected void parseDocument(Document doc, File file) {
309+ try {
310+ final Node root = doc.getFirstChild();
311+
312+ for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
313+ if (!"item".equalsIgnoreCase(node.getNodeName())) {
314+ continue;
315+ }
316+
317+ NamedNodeMap attrs = node.getAttributes();
318+ int id = Integer.parseInt(attrs.getNamedItem("id").getNodeValue());
319+ int cantidad = Integer.parseInt(attrs.getNamedItem("count").getNodeValue());
320+ double probabilidad = Double.parseDouble(attrs.getNamedItem("chance").getNodeValue());
321+ boolean announce = Boolean.parseBoolean(attrs.getNamedItem("announce").getNodeValue());
322+
323+ RandomCraftItem item = new RandomCraftItem(id, cantidad, probabilidad, announce);
324+ items.put(id, item);
325+
326+
327+ }
328+ } catch (Exception e) {
329+ e.printStackTrace();
330+ }
331+ }
332+
333+ public Map<Integer, RandomCraftItem> getItems() {
334+ return items;
335+ }
336+
337+ public RandomCraftItem getItemById(int id) {
338+ return items.get(id);
339+ }
340+}
341diff --git java/net/sf/l2j/Config.java java/net/sf/l2j/Config.java
342index 2e168ac..e9fef43 100644
343--- java/net/sf/l2j/Config.java
344+++ java/net/sf/l2j/Config.java
345@@ -57,6 +57,18 @@
346 public static final String SERVER_FILE = "./config/server.properties";
347 public static final String SIEGE_FILE = "./config/siege.properties";
348
349+
350+
351+ public static int RANDOM_CRAFT_ITEM_ID_CONSUME;
352+ public static int RANDOM_CRAFT_ITEM_CONSUME_REFRESH;
353+ public static int RANDOM_CRAFT_ITEM_ID_CREATE;
354+ public static int RANDOM_CRAFT_ITEM_CONSUME_CREATE;
355+ public static int RANDOM_CRAFT_ITEM_GENERATOR;
356+
357+
358+
359+
360+
361 // --------------------------------------------------
362 // Clans settings
363 // --------------------------------------------------
364@@ -1957,6 +1969,14 @@
365 {
366 final ExProperties players = initProperties(PLAYERS_FILE);
367
368+
369+ RANDOM_CRAFT_ITEM_ID_CONSUME = players.getProperty("RandomCraftItemIdRefresh", 57);
370+
371+ RANDOM_CRAFT_ITEM_CONSUME_REFRESH = players.getProperty("RandomCraftConsumeRefresh", 50000);
372+ RANDOM_CRAFT_ITEM_ID_CREATE = players.getProperty("RandomCraftItemIdCreate", 3470);
373+ RANDOM_CRAFT_ITEM_CONSUME_CREATE = players.getProperty("RandromCraftConsumeCreate", 300000);
374+ RANDOM_CRAFT_ITEM_GENERATOR = players.getProperty("MaxItemGeneratorForRandomCraft", 5);
375+
376 EFFECT_CANCELING = players.getProperty("CancelLesserEffect", true);
377 HP_REGEN_MULTIPLIER = players.getProperty("HpRegenMultiplier", 1.);
378 MP_REGEN_MULTIPLIER = players.getProperty("MpRegenMultiplier", 1.);
379diff --git java/net/sf/l2j/gameserver/GameServer.java java/net/sf/l2j/gameserver/GameServer.java
380index 2c0ee64..760aa4b 100644
381--- java/net/sf/l2j/gameserver/GameServer.java
382+++ java/net/sf/l2j/gameserver/GameServer.java
383@@ -116,6 +116,7 @@
384 import net.sf.l2j.util.IPv4Filter;
385
386 import Base.DropMaster.DropMaster;
387+import Base.RandomCraft.RandomCraftXML;
388 import Base.TeleportInterface.TeleportLocationData;
389
390 public class GameServer
391@@ -323,7 +324,8 @@
392 StringUtil.printSection("Gk Interface");
393 TeleportLocationData.getInstance();
394
395-
396+ StringUtil.printSection("RandomCraft");
397+ RandomCraftXML.getInstance();
398
399
400 StringUtil.printSection("System");
401diff --git java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminReload.java java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminReload.java
402index 5b7cc45..60e0619 100644
403--- java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminReload.java
404+++ java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminReload.java
405@@ -28,6 +28,7 @@
406 import net.sf.l2j.gameserver.model.World;
407 import net.sf.l2j.gameserver.model.actor.Player;
408
409+import Base.RandomCraft.RandomCraftXML;
410 import Base.TeleportInterface.TeleportLocationData;
411
412 public class AdminReload implements IAdminCommandHandler
413@@ -108,7 +109,11 @@
414 TeleportLocationData.getInstance().reload();
415 player.sendMessage("Teleport Reloads.");
416 }
417-
418+ else if (type.equals("randomcraft"))
419+ {
420+ RandomCraftXML.getInstance().reload();
421+ player.sendMessage("RandomCraft Reload.");
422+ }
423 else if (type.equals("npc"))
424 {
425 NpcData.getInstance().reload();
426@@ -182,7 +187,7 @@
427 player.sendMessage("Usage : //reload <admin|announcement|buylist|config>");
428 player.sendMessage("Usage : //reload <crest|cw|door|htm|item|multisell|npc>");
429 player.sendMessage("Usage : //reload <npcwalker|script|skill|teleport|zone>");
430- player.sendMessage("Usage : //reload <spawnlist|sysstring|teleto|capsule>");
431+ player.sendMessage("Usage : //reload <spawnlist|sysstring|randomcraft|teleto|capsule>");
432 }
433
434 @Override
435diff --git java/net/sf/l2j/gameserver/model/actor/Player.java java/net/sf/l2j/gameserver/model/actor/Player.java
436index ddfcb84..1c756b4 100644
437--- java/net/sf/l2j/gameserver/model/actor/Player.java
438+++ java/net/sf/l2j/gameserver/model/actor/Player.java
439@@ -243,6 +243,7 @@
440 import net.sf.l2j.gameserver.taskmanager.WaterTaskManager;
441
442 import Base.AutoFarm.AutofarmPlayerRoutine;
443+import Base.RandomCraft.RandomCraftItem;
444
445 /**
446 * This class represents a player in the world.<br>
447@@ -7970,4 +7971,21 @@
448 }
449 }
450
451+ private List<RandomCraftItem> generatedCraftItems;
452+
453+ public List<RandomCraftItem> getGeneratedCraftItems()
454+ {
455+ return generatedCraftItems;
456+ }
457+
458+ public void setGeneratedCraftItems(List<RandomCraftItem> items)
459+ {
460+ generatedCraftItems = items;
461+ }
462+
463+ public void clearGeneratedCraftItems()
464+ {
465+ generatedCraftItems.clear();
466+ }
467+
468 }
469\ No newline at end of file
470diff --git java/net/sf/l2j/gameserver/model/actor/instance/RandomCraft.java java/net/sf/l2j/gameserver/model/actor/instance/RandomCraft.java
471new file mode 100644
472index 0000000..edd3dc4
473--- /dev/null
474+++ java/net/sf/l2j/gameserver/model/actor/instance/RandomCraft.java
475@@ -0,0 +1,511 @@
476+package net.sf.l2j.gameserver.model.actor.instance;
477+
478+
479+
480+import java.sql.Connection;
481+import java.sql.PreparedStatement;
482+import java.sql.ResultSet;
483+import java.sql.SQLException;
484+import java.util.ArrayList;
485+import java.util.LinkedList;
486+import java.util.List;
487+import java.util.Map;
488+import java.util.Random;
489+
490+import net.sf.l2j.commons.pool.ConnectionPool;
491+
492+import net.sf.l2j.Config;
493+import net.sf.l2j.gameserver.data.xml.ItemData;
494+import net.sf.l2j.gameserver.model.World;
495+import net.sf.l2j.gameserver.model.actor.Npc;
496+import net.sf.l2j.gameserver.model.actor.Player;
497+import net.sf.l2j.gameserver.model.actor.template.NpcTemplate;
498+import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
499+import net.sf.l2j.gameserver.model.item.kind.Item;
500+import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
501+import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
502+import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse;
503+import net.sf.l2j.gameserver.network.serverpackets.MoveToPawn;
504+import net.sf.l2j.gameserver.network.serverpackets.MyTargetSelected;
505+import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
506+import net.sf.l2j.gameserver.network.serverpackets.ValidateLocation;
507+
508+import Base.RandomCraft.RandomCraftItem;
509+import Base.RandomCraft.RandomCraftXML;
510+
511+/**
512+ * @author Terius
513+ */
514+
515+public class RandomCraft extends Npc
516+{
517+ private boolean hasGeneratedItems;
518+ List<RandomCraftItem> items = new LinkedList<>();
519+
520+
521+ public RandomCraft(int objectId, NpcTemplate template)
522+ {
523+ super(objectId, template);
524+ setHasGeneratedItems(false);
525+ }
526+
527+ @Override
528+ public void onInteract(Player player)
529+ {
530+ if (this != player.getTarget())
531+ {
532+ player.setTarget(this);
533+ player.sendPacket(new MyTargetSelected(getObjectId(), 0));
534+ player.sendPacket(new ValidateLocation(this));
535+ }
536+ else
537+ {
538+ // Gira el jugador para enfrentar la instancia
539+ player.sendPacket(new MoveToPawn(player, this, Npc.INTERACTION_DISTANCE));
540+
541+
542+
543+ loadGeneratedItems(player);
544+
545+ showHtmlWindow(player);
546+
547+ // Enviar ActionFailed al jugador para evitar quedarse atascado
548+ player.sendPacket(ActionFailed.STATIC_PACKET);
549+ }
550+ }
551+
552+
553+
554+ private static String getItemNameById(int id) {
555+ Item item = ItemData.getInstance().getTemplate(id);
556+ if (item != null) {
557+ return item.getName();
558+ }
559+ return "Unknown"; // Si no se encuentra el elemento, se devuelve "Unknown" como nombre predeterminado
560+ }
561+
562+
563+ @Override
564+ public void onBypassFeedback(Player player, String command)
565+ {
566+ if (command.startsWith("refresh"))
567+ {
568+ // Verifique si el jugador tiene el artículo requerido (ID 57) y la cantidad (50000)
569+ ItemInstance item57 = player.getInventory().getItemByItemId(Config.RANDOM_CRAFT_ITEM_ID_CONSUME);
570+ if (item57 != null && item57.getCount() >= Config.RANDOM_CRAFT_ITEM_CONSUME_REFRESH)
571+ {
572+ // Cargue al jugador el artículo requerido (ID 57) y la cantidad (50000)
573+ player.destroyItemByItemId("Random Craft", Config.RANDOM_CRAFT_ITEM_ID_CONSUME, Config.RANDOM_CRAFT_ITEM_CONSUME_REFRESH, null, true);
574+
575+ generateItems(player);
576+
577+
578+
579+
580+
581+
582+ showHtmlWindow(player);
583+
584+ // Almacene los elementos generados en la base de datos para el jugador
585+ saveGeneratedItems(player);
586+ }
587+ else
588+ {
589+ player.sendMessage("Necesitas al menos " + Config.RANDOM_CRAFT_ITEM_CONSUME_REFRESH + " De: " + getItemNameById(Config.RANDOM_CRAFT_ITEM_ID_CONSUME) + " para actualizar Random Craft.");
590+ showHtmlWindow(player);
591+ }
592+ }
593+ else if (command.startsWith("create"))
594+ {
595+
596+ // Carga al jugador el artículo con ID 57 y cantidad 300000
597+ ItemInstance item57 = player.getInventory().getItemByItemId(Config.RANDOM_CRAFT_ITEM_ID_CREATE);
598+ if (item57 != null && item57.getCount() >= Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE) {
599+ // Eliminar los elementos generados para el jugador de la tabla RandomCraftItem
600+ deleteGeneratedItems(player);
601+
602+ createItem(player);
603+ }
604+ else {
605+ player.sendMessage("Necesitas al menos " + Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE + " De: " + getItemNameById(Config.RANDOM_CRAFT_ITEM_ID_CREATE) + " para crear un elemento aleatorio.");
606+ showHtmlWindow(player);
607+ }
608+
609+
610+ }
611+
612+ else if (command.startsWith("back"))
613+ {
614+
615+ showHtmlWindow(player);
616+ }
617+
618+ }
619+
620+ private void generateItems(Player player)
621+ {
622+ List<RandomCraftItem> items = new LinkedList<>();
623+ RandomCraftXML randomCraftXML = RandomCraftXML.getInstance();
624+ Map<Integer, RandomCraftItem> craftItems = randomCraftXML.getItems();
625+
626+ // Genera 4 elementos únicos para cada jugador en función de la probabilidad
627+ List<Integer> selectedItems = new ArrayList<>();
628+ while (selectedItems.size() < Config.RANDOM_CRAFT_ITEM_GENERATOR)
629+ {
630+ int itemId = getRandomItem(craftItems);
631+ if (!selectedItems.contains(itemId))
632+ {
633+ selectedItems.add(itemId);
634+ items.add(craftItems.get(itemId));
635+ }
636+ }
637+
638+ // Asignar los elementos generados al jugador
639+ player.setGeneratedCraftItems(items);
640+ setHasGeneratedItems(true);
641+
642+ }
643+
644+ private static void deleteGeneratedItems(Player player)
645+ {
646+ try (Connection con = ConnectionPool.getConnection(); PreparedStatement stmt = con.prepareStatement("DELETE FROM RandomCraftItem WHERE object_id = ?"))
647+ {
648+ stmt.setInt(1, player.getObjectId());
649+ stmt.execute();
650+ }
651+ catch (SQLException e)
652+ {
653+ e.printStackTrace();
654+ }
655+ }
656+
657+ private static void saveGeneratedItems(Player player)
658+ {
659+ try (Connection con = ConnectionPool.getConnection(); PreparedStatement stmt = con.prepareStatement("DELETE FROM RandomCraftItem WHERE object_id = ?"))
660+ {
661+ stmt.setInt(1, player.getObjectId());
662+ stmt.execute();
663+
664+ try (PreparedStatement insertStmt = con.prepareStatement("INSERT INTO RandomCraftItem (object_id, item_id, amount, chance, announce) VALUES (?, ?, ?, ?, ?)"))
665+ {
666+ insertStmt.setInt(1, player.getObjectId());
667+ List<RandomCraftItem> items = player.getGeneratedCraftItems();
668+ if (items != null)
669+ {
670+ for (RandomCraftItem item : items)
671+ {
672+ insertStmt.setInt(2, item.getId());
673+ insertStmt.setInt(3, item.getCantidad());
674+ insertStmt.setDouble(4, item.getProbabilidad());
675+ insertStmt.setBoolean(5, item.getAnnounce());
676+ insertStmt.addBatch(); // Agregar la consulta al lote (batch)
677+ }
678+ insertStmt.executeBatch(); // Ejecutar el lote de consultas
679+ }
680+ }
681+ }
682+ catch (SQLException e)
683+ {
684+ e.printStackTrace();
685+ }
686+ }
687+
688+ private void loadGeneratedItems(Player player)
689+ {
690+ try (Connection con = ConnectionPool.getConnection(); PreparedStatement stmt = con.prepareStatement("SELECT item_id, amount, chance, announce FROM RandomCraftItem WHERE object_id = ?"))
691+ {
692+ stmt.setInt(1, player.getObjectId());
693+
694+ try (ResultSet rset = stmt.executeQuery())
695+ {
696+ List<RandomCraftItem> items = new LinkedList<>();
697+ while (rset.next())
698+ {
699+ int itemId = rset.getInt("item_id");
700+ int amount = rset.getInt("amount");
701+ int chance = rset.getInt("chance");
702+ boolean announce = rset.getBoolean("announce");
703+ RandomCraftItem item = new RandomCraftItem(itemId, amount, chance, announce);
704+ items.add(item);
705+ }
706+
707+ player.setGeneratedCraftItems(items);
708+ setHasGeneratedItems(!items.isEmpty());
709+ }
710+ }
711+ catch (SQLException e)
712+ {
713+ e.printStackTrace();
714+ }
715+ }
716+
717+ private static int getRandomItem(Map<Integer, RandomCraftItem> craftItems)
718+ {
719+ // Calcular la suma de probabilidad total
720+ double totalProbability = 0;
721+ for (RandomCraftItem item : craftItems.values())
722+ {
723+ totalProbability += item.getProbabilidad();
724+ }
725+
726+ // Generar un valor aleatorio entre 0 y la probabilidad total
727+ Random random = new Random();
728+ double randomValue = random.nextDouble() * totalProbability;
729+
730+ // Seleccione el elemento en función de la probabilidad
731+ double cumulativeProbability = 0;
732+ for (RandomCraftItem item : craftItems.values())
733+ {
734+ cumulativeProbability += item.getProbabilidad();
735+ if (randomValue <= cumulativeProbability)
736+ {
737+ return item.getId();
738+ }
739+ }
740+
741+ // Si no se selecciona ningún artículo, devolver un artículo al azar
742+ List<Integer> itemIds = new ArrayList<>(craftItems.keySet());
743+ int index = random.nextInt(itemIds.size());
744+ return itemIds.get(index);
745+ }
746+
747+ private void createItem(Player player)
748+ {
749+ // Comprueba si la lista de elementos está vacía
750+ List<RandomCraftItem> items = player.getGeneratedCraftItems();
751+ if (items == null || items.isEmpty())
752+ {
753+ player.sendMessage("Necesita actualizar para poder crear un elemento aleatorio.");
754+ return;
755+ }
756+
757+ // Obtén un elemento aleatorio de la lista de elementos generados
758+ Random random = new Random();
759+ int index = random.nextInt(items.size());
760+ RandomCraftItem craftItem = items.get(index);
761+
762+ // Carga al jugador el artículo con ID 57 y cantidad 300000
763+ ItemInstance item57 = player.getInventory().getItemByItemId(Config.RANDOM_CRAFT_ITEM_ID_CREATE);
764+ if (item57 != null && item57.getCount() >= Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE)
765+ {
766+
767+ // Da el artículo al jugador
768+ ItemInstance itemInstance = player.getInventory().addItem("Random Craft", craftItem.getId(), craftItem.getCantidad(), player, this);
769+ if (itemInstance != null)
770+ {
771+
772+
773+
774+ player.destroyItemByItemId("Random Craft", Config.RANDOM_CRAFT_ITEM_ID_CREATE, Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE, null, true);
775+
776+
777+
778+ // Envía un mensaje al jugador con el nombre del artículo y la cantidad.
779+ String message = "¡Felicidades! Has recibido " + craftItem.getItem().getName() + " (Cantidad: " + craftItem.getCantidad() + ")";
780+ player.sendMessage(message);
781+
782+ // Obtén el nombre del jugador que creó el elemento
783+ String creatorName = player.getName();
784+
785+ // Comprueba si el artículo tiene announce en true en el archivo XML
786+ if (craftItem.getAnnounce())
787+ {
788+
789+ for (Player players : World.getInstance().getPlayers())
790+ {
791+
792+ String text = creatorName + " Ha Crafteado: " + craftItem.getItem().getName() + " En el RandomCraft System";
793+
794+ players.sendPacket(new ExShowScreenMessage(text, 5000));
795+
796+ }
797+
798+ }
799+
800+ // Agrega un efecto al jugador si el artículo lo permite
801+ if (craftItem.getAnnounce())
802+ {
803+ MagicSkillUse MSU = new MagicSkillUse(player, player, 2024, 1, 1, 0);
804+ player.broadcastPacket(MSU);
805+ }
806+
807+
808+ // Borra la lista de elementos para el jugador
809+ player.clearGeneratedCraftItems();
810+ setHasGeneratedItems(false);
811+
812+ // Muestra la ventana de felicitaciones con el item ganador
813+ showCongratulationsWindow(player, craftItem);
814+
815+ return;
816+ }
817+ }
818+ player.sendMessage("Necesitas al menos " + Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE + " De: " + getItemNameById(Config.RANDOM_CRAFT_ITEM_ID_CREATE) + " para crear un elemento aleatorio.");
819+
820+ }
821+
822+ private void showHtmlWindow(Player player) {
823+ StringBuilder html = new StringBuilder();
824+
825+ int requiredItemsCount = player.getInventory().getItemCount(Config.RANDOM_CRAFT_ITEM_ID_CREATE);
826+
827+ html.append("<html><body>");
828+ // Agregar información sobre los CraftPoints y la cantidad necesaria
829+
830+ if(requiredItemsCount > 0) {
831+ html.append("<center><font color=\"00FF00\">CraftPoints: ").append(requiredItemsCount).append("</font></center>");
832+ }else {
833+ html.append("<center><font color=\"00FF00\">CraftPoints: ").append(0).append("</font></center>");
834+ }
835+
836+ html.append("<center><font color=\"FF0000\">Necesarios: ").append(Config.RANDOM_CRAFT_ITEM_CONSUME_CREATE).append("</font></center>");
837+ html.append("<br>");
838+ html.append("<center>Bienvenido a Random Craft System!</center>");
839+ html.append("<br>");
840+ html.append("<center>Podrás Crear 1 item entre los 5 que salgan random!</center>");
841+ html.append("<br>");
842+ html.append("<center>Les Deseo Mucha Suerte</center>");
843+ html.append("<br>");
844+ html.append("<br>");
845+
846+ List<RandomCraftItem> items = player.getGeneratedCraftItems();
847+ if (items == null || items.isEmpty()) {
848+ html.append("<center>La Lista Esta Vacia. Dale a Refresh</center>");
849+ } else {
850+ // Generar los iconos de los artículos en forma horizontal
851+ for (RandomCraftItem item : items) {
852+ html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>");
853+ html.append("<div align=center>");
854+ html.append("<table>");
855+ html.append("<tr>");
856+ html.append("<td>");
857+ html.append("<img src=").append(item.getIcon()).append(" width=32 height=32>");
858+ html.append("</td>");
859+ html.append("<td width=260>");
860+
861+ double chance = item.getProbabilidad();
862+ String color;
863+ String additionalInfo;
864+
865+ if (chance <= 25) {
866+ color = "FF0000"; // Rojo
867+ additionalInfo = " - Legendary";
868+ } else if (chance <= 50) {
869+ color = "9932CC"; // Violeta
870+ additionalInfo = " - Epic";
871+ } else {
872+ color = "FFFF00"; // Amarillo
873+ additionalInfo = " - Normal";
874+ }
875+
876+ html.append("<font color=").append(color).append(">").append(item.getItem().getName()).append(" x").append(item.getCantidad()).append(additionalInfo).append("</font>");
877+
878+ html.append("</td>");
879+ html.append("</tr>");
880+ html.append("</table>");
881+ html.append("</div>");
882+ html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>");
883+ html.append("<br>");
884+ }
885+ }
886+
887+ html.append("<br>");
888+ html.append("<br>");
889+ html.append("<center>");
890+ html.append("<table>");
891+ html.append("<tr>");
892+ html.append("<td width=75 height=21>");
893+ html.append("<button value=\"Refresh\" action=\"bypass -h npc_").append(getObjectId()).append("_refresh\" width=75 height=21 back=\"L2UI.DefaultButton_click\" fore=\"L2UI.DefaultButton\">");
894+ html.append("</td>");
895+ html.append("<td width=75 height=21>");
896+ html.append("<button value=\"Create\" action=\"bypass -h npc_").append(getObjectId()).append("_create\" width=75 height=21 back=\"L2UI.DefaultButton_click\" fore=\"L2UI.DefaultButton\">");
897+ html.append("</td>");
898+ html.append("</tr>");
899+ html.append("</table>");
900+ html.append("</center>");
901+
902+ html.append("</body></html>");
903+
904+ showHtmlWindow(player, html.toString());
905+ }
906+
907+
908+
909+ private void showHtmlWindow(Player player, String htmlContent)
910+ {
911+ NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
912+ html.setHtml(htmlContent);
913+
914+ player.sendPacket(html);
915+ }
916+
917+ private void showCongratulationsWindow(Player player, RandomCraftItem craftItem) {
918+ StringBuilder html = new StringBuilder();
919+
920+ html.append("<html><body>");
921+ html.append("<center>Felicidades, has ganado un item</center>");
922+ html.append("<br>");
923+ html.append("<center>¡Has recibido</center>");
924+ html.append("<br>");
925+ html.append("<br>");
926+ html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>");
927+ html.append("<center>");
928+ html.append("<table>");
929+ html.append("<tr>");
930+ html.append("<td>");
931+ html.append("<img src=").append(craftItem.getIcon()).append(" width=32 height=32>");
932+ html.append("</td>");
933+ html.append("<td width=260>");
934+
935+ double chance = craftItem.getProbabilidad();
936+ String color;
937+ String additionalInfo;
938+
939+ if (chance <= 25) {
940+ color = "FF0000"; // Rojo
941+ additionalInfo = " - Legendary";
942+ } else if (chance <= 50) {
943+ color = "9932CC"; // Violeta
944+ additionalInfo = " - Epic";
945+ } else {
946+ color = "FFFF00"; // Amarillo
947+ additionalInfo = " - Normal";
948+ }
949+
950+ html.append("<font color=").append(color).append(">").append(craftItem.getItem().getName()).append(" x").append(craftItem.getCantidad()).append(additionalInfo).append("</font>");
951+
952+
953+ html.append("</td>");
954+ html.append("</tr>");
955+ html.append("</table>");
956+ html.append("</center>");
957+ html.append("<img src=\"L2UI.SquareGray\" width=295 height=1>");
958+ html.append("<br>");
959+ html.append("<br>");
960+ html.append("<br>");
961+ html.append("<br>");
962+ html.append("<center>");
963+ html.append("<button value=\"Back\" action=\"bypass -h npc_").append(getObjectId()).append("_back\" width=75 height=21 back=\"L2UI.DefaultButton_click\" fore=\"L2UI.DefaultButton\">");
964+ html.append("</center>");
965+ html.append("</body></html>");
966+
967+ showHtmlWindow(player, html.toString());
968+ }
969+
970+
971+ /**
972+ * @return the hasGeneratedItems
973+ */
974+ public boolean isHasGeneratedItems()
975+ {
976+ return hasGeneratedItems;
977+ }
978+
979+ /**
980+ * @param hasGeneratedItems the hasGeneratedItems to set
981+ */
982+ public void setHasGeneratedItems(boolean hasGeneratedItems)
983+ {
984+ this.hasGeneratedItems = hasGeneratedItems;
985+ }
986+}
987