Resolved seven sign question Interlude

Simple code to convert SS to AA.

Use the commands:
.aared
.aagreen
.aablue


Code:
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() {
    }
}
Code:
# 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.
 
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">
 
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">
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.
 
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.
This is an EXT mod code for you to compile a mod.

Follow the tutorial


 
Last edited:
이것은 모드를 컴파일하기 위한 EXT 모드 코드입니다.

튜토리얼을 따르세요


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?
 
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?
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.
 
Back
Top