How can I end the Seven Signs cycle and enable the permanent exchange of Seal Stones for Ancient Adena?
add multisell to npcHow can I end the Seven Signs cycle and enable the permanent exchange of Seal Stones for Ancient Adena?
package AncientAdenaMake;
import l2.commons.configuration.ExProperties;
import l2.gameserver.handler.voicecommands.IVoicedCommandHandler;
import l2.gameserver.handler.voicecommands.VoicedCommandHandler;
import l2.gameserver.model.Player;
import l2.gameserver.model.items.ItemInstance;
import l2.gameserver.network.l2.s2c.InventoryUpdate;
import l2.gameserver.scripts.ScriptFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
public class AncientAdenaMake implements IVoicedCommandHandler, ScriptFile {
private static final long MAX_ANCIENT_ADENA = 2_000_000_000L; // 2 billion limit
private static int ANCIENT_ADENA = 5575;
private static int BLUE_SEAL_STONE = 6360;
private static int GREEN_SEAL_STONE = 6361;
private static int RED_SEAL_STONE = 6362;
private String[] _voicedCommands;
private boolean _enabled;
private int _minLevel;
private int _blueMultiplier;
private int _greenMultiplier;
private int _redMultiplier;
private String _successMessage;
private String _noSealStonesMessage;
private String _inventoryFullMessage;
private String _adenaLimitMessage;
public AncientAdenaMake() {
loadConfig();
}
private void loadConfig() {
ExProperties properties = new ExProperties();
File configFile = new File("config/custom/AncientAdenaMake.properties");
try {
properties.load(configFile);
_enabled = properties.getProperty("Enabled", true);
String commands = properties.getProperty("Commands", "aared,aagreen,aablue");
_voicedCommands = Arrays.stream(commands.split(","))
.map(String::trim)
.filter(cmd -> !cmd.isEmpty() && cmd.matches("[a-zA-Z0-9]+"))
.distinct()
.toArray(String[]::new);
if (_voicedCommands.length < 1) {
_voicedCommands = new String[]{"aared", "aagreen", "aablue"};
}
_minLevel = properties.getProperty("MinLevel", 1);
ANCIENT_ADENA = properties.getProperty("AncientAdenaId", 5575);
BLUE_SEAL_STONE = properties.getProperty("BlueSealStoneId", 6360);
GREEN_SEAL_STONE = properties.getProperty("GreenSealStoneId", 6361);
RED_SEAL_STONE = properties.getProperty("RedSealStoneId", 6362);
_blueMultiplier = properties.getProperty("BlueSealStoneMultiplier", 3);
_greenMultiplier = properties.getProperty("GreenSealStoneMultiplier", 5);
_redMultiplier = properties.getProperty("RedSealStoneMultiplier", 10);
_successMessage = properties.getProperty("SuccessMessage", "Exchanged %d Seal Stones for %d Ancient Adena.");
_noSealStonesMessage = properties.getProperty("NoSealStonesMessage", "You don't have Seal Stones to exchange.");
_inventoryFullMessage = properties.getProperty("InventoryFullMessage", "Your inventory is full! Please free up some space.");
_adenaLimitMessage = properties.getProperty("AdenaLimitMessage", "Ancient Adena limit of %d reached. Exchanged %d Seal Stones for %d Ancient Adena.");
} catch (FileNotFoundException e) {
System.err.println("Configuration file AncientAdenaMake.properties not found. Using defaults.");
setDefaultConfig();
} catch (IOException e) {
System.err.println("Error reading AncientAdenaMake.properties: " + e.getMessage());
setDefaultConfig();
}
if (_enabled) {
System.out.println("AncientAdenaMake loaded. Commands: " + Arrays.toString(_voicedCommands));
System.out.println("Multipliers: Blue=" + _blueMultiplier +
", Green=" + _greenMultiplier +
", Red=" + _redMultiplier);
} else {
System.out.println("AncientAdenaMake disabled in configuration.");
}
}
private void setDefaultConfig() {
_enabled = true;
_voicedCommands = new String[]{"aared", "aagreen", "aablue"};
_minLevel = 1;
_blueMultiplier = 3;
_greenMultiplier = 5;
_redMultiplier = 10;
_successMessage = "Exchanged %d Seal Stones for %d Ancient Adena.";
_noSealStonesMessage = "You don't have Seal Stones to exchange.";
_inventoryFullMessage = "Your inventory is full! Please free up some space.";
_adenaLimitMessage = "Ancient Adena limit of %d reached. Exchanged %d Seal Stones for %d Ancient Adena.";
}
@Override
public boolean useVoicedCommand(String command, Player player, String args) {
if (!_enabled || !Arrays.asList(_voicedCommands).contains(command)) {
return false;
}
if (player.getLevel() < _minLevel) {
player.sendMessage("You must be at least level " + _minLevel + " to use this command.");
return false;
}
int sealStoneId;
int multiplier;
String stoneType;
if (command.equals("aared")) {
sealStoneId = RED_SEAL_STONE;
multiplier = _redMultiplier;
stoneType = "Red";
} else if (command.equals("aagreen")) {
sealStoneId = GREEN_SEAL_STONE;
multiplier = _greenMultiplier;
stoneType = "Green";
} else if (command.equals("aablue")) {
sealStoneId = BLUE_SEAL_STONE;
multiplier = _blueMultiplier;
stoneType = "Blue";
} else {
return false;
}
InventoryUpdate iu = new InventoryUpdate();
player.getInventory().writeLock();
try {
ItemInstance currentAdena = player.getInventory().getItemByItemId(ANCIENT_ADENA);
long currentAdenaCount = currentAdena != null ? currentAdena.getCount() : 0;
long availableAdena = MAX_ANCIENT_ADENA - currentAdenaCount;
if (availableAdena <= 0) {
player.sendMessage(String.format(_adenaLimitMessage, MAX_ANCIENT_ADENA, 0, 0));
return false;
}
ItemInstance sealStone = player.getInventory().getItemByItemId(sealStoneId);
long sealStoneCount = sealStone != null ? sealStone.getCount() : 0;
if (sealStoneCount <= 0) {
player.sendMessage(_noSealStonesMessage);
return false;
}
long potentialAA = sealStoneCount * multiplier;
long qtyAA = Math.min(potentialAA, availableAdena);
long stonesToUse = qtyAA / multiplier;
if (qtyAA % multiplier > 0) {
stonesToUse++;
qtyAA = stonesToUse * multiplier;
if (qtyAA > availableAdena) {
stonesToUse--;
qtyAA = stonesToUse * multiplier;
}
}
if (qtyAA <= 0 || qtyAA > Integer.MAX_VALUE || !player.getInventory().validateCapacity(currentAdena == null ? 1 : 0)) {
player.sendMessage(_inventoryFullMessage);
return false;
}
ItemInstance aaItem = currentAdena;
if (aaItem == null) {
aaItem = player.getInventory().addItem(ANCIENT_ADENA, 1);
if (aaItem == null || aaItem.getCount() != 1) {
player.sendMessage("Failed to create Ancient Adena slot. Please try again.");
return false;
}
iu.addNewItem(aaItem);
if (qtyAA > 1) {
long newCount = aaItem.getCount() + (qtyAA - 1);
aaItem.setCount(newCount);
iu.addModifiedItem(aaItem);
}
} else {
long newCount = aaItem.getCount() + qtyAA;
aaItem.setCount(newCount);
iu.addModifiedItem(aaItem);
}
ItemInstance[] adenaItems = Arrays.stream(player.getInventory().getItems())
.filter(item -> item.getItemId() == ANCIENT_ADENA)
.toArray(ItemInstance[]::new);
if (adenaItems.length > 1) {
long totalAdena = Arrays.stream(adenaItems).mapToLong(ItemInstance::getCount).sum();
for (int i = 1; i < adenaItems.length; i++) {
player.getInventory().destroyItem(adenaItems[i]);
iu.addRemovedItem(adenaItems[i]);
}
aaItem.setCount(totalAdena);
iu.addModifiedItem(aaItem);
}
if (stonesToUse > 0) {
long newCount = sealStone.getCount() - stonesToUse;
if (newCount > 0) {
sealStone.setCount(newCount);
iu.addModifiedItem(sealStone);
} else {
player.getInventory().destroyItemByItemId(sealStoneId, stonesToUse);
iu.addRemovedItem(sealStone);
}
}
player.sendPacket(iu);
if (qtyAA < potentialAA) {
player.sendMessage(String.format(_adenaLimitMessage, MAX_ANCIENT_ADENA, stonesToUse, qtyAA));
} else {
player.sendMessage(String.format(_successMessage, stonesToUse, qtyAA));
}
} finally {
player.getInventory().writeUnlock();
}
return true;
}
@Override
public String[] getVoicedCommandList() {
return _enabled ? _voicedCommands : new String[0];
}
@Override
public void onLoad() {
if (_enabled) {
VoicedCommandHandler.getInstance().registerVoicedCommandHandler(this);
}
}
@Override
public void onReload() {
loadConfig();
if (_enabled) {
VoicedCommandHandler.getInstance().registerVoicedCommandHandler(this);
}
}
@Override
public void onShutdown() {
}
}
# Enable or disable the mod
Enabled=true
# Minimum player level to use the commands
MinLevel=1
# IDs of items (default Interlude IDs)
AncientAdenaId=5575
BlueSealStoneId=6360
GreenSealStoneId=6361
RedSealStoneId=6362
# Multipliers for conversion (Seal Stone x Multiplier = Ancient Adena)
BlueSealStoneMultiplier=3
GreenSealStoneMultiplier=5
RedSealStoneMultiplier=10
# Voiced commands separated by comma
Commands=aablue,aagreen,aared
# Messages
SuccessMessage=Exchanged %d Seal Stones for %d Ancient Adena.
NoSealStonesMessage=You don't have Seal Stones to exchange.
InventoryFullMessage=Your inventory is full! Please free up some space.
AdenaLimitMessage=Ancient Adena limit of %d reached. Exchanged %d Seal Stones for %d Ancient Adena.
First of all, thank you very much. Could you please let me know which folder I should copy and paste the code you provided into, and how to save it? I can’t understand just from the code you’ve shown.If you prefer, you can make the button via HTML.
<button width=94 height=28 back="L2UI_CH3.inventory_tab2" fore="L2UI_CH3.inventory_tab2" value=" Red Seal Stone to AA" action="bypass -h user_aared">
<button width=94 height=28 back="L2UI_CH3.inventory_tab2" fore="L2UI_CH3.inventory_tab2" value="Green Seal Stone to AA" action="bypass -h user_aagreen">
<button width=94 height=28 back="L2UI_CH3.inventory_tab2" fore="L2UI_CH3.inventory_tab2" value="Blue Seal Stone to AA" action="bypass -h user_aablue">
This is an EXT mod code for you to compile a mod.Primeiramente, muito obrigado. Você poderia me informar em qual pasta devo copiar e colar o código que você forneceu e como salvá-lo? Não consigo entender apenas pelo código que você mostrou.
I’ve watched this simple code hundreds of times in slow motion, but I still encounter many errors. Could you please share the Java file written with your code?이것은 모드를 컴파일하기 위한 EXT 모드 코드입니다.
튜토리얼을 따르세요
An example of a simple code is in the video. I'll also add custom quests to this section and how to do them with the description.
Be sure to remember that to properly load your jar the name should be *.ext.jar
- Deazer
- Replies: 18
- Forum: Server Dev Section/Разработка дополнений сервера
If you struggle to find proper configs and/or don’t understand those (yet), then trying to code your own extension might be too much for you. You will benefit more in general if you’ll take it slow and first understand the data pack, then once you do aim for understanding code base needed to write these extensions.I’ve watched this simple code hundreds of times in slow motion, but I still encounter many errors. Could you please share the Java file written with your code?