[share] Рулетка под сервера на базе OverWorld

Gaikotsu

яжпрограммист
Легенда
Победитель в номинации 2023
Победитель в номинации 2022
Победитель в номинации 2021
Участник Новогоднего Фонда 2021
Эксперт
Знаток
Просветитель
Магистр реакций
Знаток письма
Куратор Данных
Медаль Благодарности
Старожил II степени
Старожил I степени
Победитель в номинации 2020
Победитель в номинации 2019
Клиент разработчик
Преподаватель
За веру и верность форуму
Победитель в номинации 2018
Медаль за активность на Форуме
За заслуги перед форумом
Web разработчик
Разработчик
За знание датапака
За знание ядра
Сообщения
1 509
Розыгрыши
0
Решения
24
Репутация
5 922
Реакции
2 521
Баллы
2 188
Собственно говоря переработанная версия рулетки, которая была в Phoenix'е.
В принципе и в чистом овере она тоже есть, но никак не переделанная и вроде ничем не отличающаяся от того что было в фениксе, т.е. сделана в виде банального сервиса.
В свое время я полностью избавлялся от того трэша, что в фениксе/овере лежит в services датапака, переписывая это все по человечески.
Ну и собственно говоря вот ту же рулетку переписал таким вот образом.
Код:
package handler.bypass;

import l2p.commons.util.Rnd;
import l2p.gameserver.cache.HtmCache;
import l2p.gameserver.config.GamesConfig;
import l2p.gameserver.data.holder.ItemHolder;
import l2p.gameserver.enums.LogAction;
import l2p.gameserver.managers.ServerVariables;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.instances.NpcInstance;
import l2p.gameserver.network.serverpackets.components.CustomMessage;
import l2p.gameserver.network.serverpackets.components.SystemMsg;
import l2p.gameserver.templates.item.ItemTemplate;
import l2p.gameserver.utils.HtmlUtils;
import l2p.gameserver.utils.ItemUtils;
import l2p.gameserver.utils.Log;
import l2p.gameserver.utils.Strings;
import l2p.gameserver.utils.Util;

/**
 * Переработанная версия рулетки из оригинального Phoenix'а
 *
 * @author Gaikotsu
 */
public class Roulette extends ScriptBypassHandler
{
    private static final String[] _commandList = new String[] { "rouletteShow", "roulettePlay" };

    private static final String _R_ = "red";
    private static final String _B_ = "black";
    private static final String _F_ = "first";
    private static final String _S_ = "second";
    private static final String _T_ = "third";
    private static final String _E_ = "even";
    private static final String _O_ = "odd";
    private static final String _L_ = "low";
    private static final String _H_ = "high";
    private static final String _Z_ = "zero";

    private static final String[][] _numbers = {
        // # Color Dozen Column Evenness Highness
        { "0", _Z_, _Z_, _Z_, _Z_, _Z_ },
        { "00", _Z_, _Z_, _Z_, _Z_, _Z_ },
        { "1", _R_, _F_, _F_, _O_, _L_ },
        { "2", _B_, _F_, _S_, _E_, _L_ },
        { "3", _R_, _F_, _T_, _O_, _L_ },
        { "4", _B_, _F_, _F_, _E_, _L_ },
        { "5", _R_, _F_, _S_, _O_, _L_ },
        { "6", _B_, _F_, _T_, _E_, _L_ },
        { "7", _R_, _F_, _F_, _O_, _L_ },
        { "8", _B_, _F_, _S_, _E_, _L_ },
        { "9", _R_, _F_, _T_, _O_, _L_ },
        { "10", _B_, _F_, _F_, _E_, _L_ },
        { "11", _B_, _F_, _S_, _O_, _L_ },
        { "12", _R_, _F_, _T_, _E_, _L_ },
        { "13", _B_, _S_, _F_, _O_, _L_ },
        { "14", _R_, _S_, _S_, _E_, _L_ },
        { "15", _B_, _S_, _T_, _O_, _L_ },
        { "16", _R_, _S_, _F_, _E_, _L_ },
        { "17", _B_, _S_, _S_, _O_, _L_ },
        { "18", _R_, _S_, _T_, _E_, _L_ },
        { "19", _R_, _S_, _F_, _O_, _H_ },
        { "20", _B_, _S_, _S_, _E_, _H_ },
        { "21", _R_, _S_, _T_, _O_, _H_ },
        { "22", _B_, _S_, _F_, _E_, _H_ },
        { "23", _R_, _S_, _S_, _O_, _H_ },
        { "24", _B_, _S_, _T_, _E_, _H_ },
        { "25", _R_, _T_, _F_, _O_, _H_ },
        { "26", _B_, _T_, _S_, _E_, _H_ },
        { "27", _R_, _T_, _T_, _O_, _H_ },
        { "28", _B_, _T_, _F_, _E_, _H_ },
        { "29", _B_, _T_, _S_, _O_, _H_ },
        { "30", _R_, _T_, _T_, _E_, _H_ },
        { "31", _B_, _T_, _F_, _O_, _H_ },
        { "32", _R_, _T_, _S_, _E_, _H_ },
        { "33", _B_, _T_, _T_, _O_, _H_ },
        { "34", _R_, _T_, _F_, _E_, _H_ },
        { "35", _B_, _T_, _S_, _O_, _H_ },
        { "36", _R_, _T_, _T_, _E_, _H_ } };

    private static final ItemTemplate _betItem = ItemHolder.getInstance().getTemplate(57);

    /**
     * type это тип ставки, number это на что именно ставка
     * type 1: Ставка на один номер (Straight Up), number соответствует номеру, выплата 35:1
     * type 10: Column Bet, на столбец, number номер столбца, выплата 2:1, zero автоматический проигрыш
     * type 11: Dozen Bet, на дюжину, number номер дюжины, выплата 2:1, zero автоматический проигрыш
     * type 12: Red or Black, на цвет, number цвет (0 = R, 1 = B), выплата 1:1, zero автоматический проигрыш
     * type 13: Even or Odd, чет-нечет, number тип (0 = even, 1 = odd), выплата 1:1, zero автоматический проигрыш
     * type 14: Low or High, 0 = 1-18, 1 = 19-36, выплата 1:1, zero автоматический проигрыш
     */
    private static enum GameType
    {
        StraightUp,
        ColumnBet,
        DozenBet,
        RedOrBlack,
        EvenOrOdd,
        LowOrHigh;
    }

    /**
     * Возвращает множитель ставки или 0 при проигрыше
     */
    private static final int check(String betId, String[] roll, GameType type)
    {
        switch (type)
        {
            case StraightUp:
                return betId.equals(roll[0]) ? 35 : 0;

            case ColumnBet:
                return betId.equals(roll[3]) ? 2 : 0;

            case DozenBet:
                return betId.equals(roll[2]) ? 2 : 0;

            case RedOrBlack:
                return betId.equals(roll[1]) ? 1 : 0;

            case EvenOrOdd:
                return betId.equals(roll[4]) ? 1 : 0;

            case LowOrHigh:
                return betId.equals(roll[5]) ? 1 : 0;

            default:
                return 0;
        }
    }

    @Override
    public void onBypassFeedback(NpcInstance npc, Player player, String command, String[] params)
    {
        if (!GamesConfig.ALLOW_ROULETTE)
        {
            player.sendMessage("Данная услуга отключена.");
            return;
        }

        if (command.equalsIgnoreCase("rouletteShow"))
        {
            String html = HtmCache.getInstance().getNotNull("games/roulette/play.htm", player);
            html = html.replaceFirst("%min%", Util.formatAdena(GamesConfig.ROULETTE_MIN_BET));
            html = html.replaceFirst("%max%", Util.formatAdena(GamesConfig.ROULETTE_MAX_BET));
            html = html.replaceFirst("%bet_item%", _betItem.getNameRu());
            HtmlUtils.show(html, player, npc);
        }
        else if (command.startsWith("roulettePlay "))
        {
            if (params.length != 4)
            {
                player.sendPacket(SystemMsg.SYSTEM_ERROR);
                return;
            }

            GameType type = GameType.valueOf(params[1]);
            String betId = Util.parseValue(params[2].trim(), "");
            long bet = Util.parseValue(params[3], 0);

            if (bet == 0 || (type == GameType.StraightUp && (betId.length() > 2 || Integer.parseInt(betId) < 0 || Integer.parseInt(betId) > 36)))
            {
                player.sendPopupMessage("Неправильно введена ставка!");
                return;
            }

            if (bet < GamesConfig.ROULETTE_MIN_BET)
            {
                player.sendPopupMessage("Слишком маленькая ставка!");
                return;
            }
            if (bet > GamesConfig.ROULETTE_MAX_BET)
            {
                player.sendPopupMessage("Слишком большая ставка!");
                return;
            }

            if (!ItemUtils.checkItemCount(player, _betItem.getItemId(), bet, true))
                return;

            String[] roll = _numbers[Rnd.get(_numbers.length)];
            int result = check(betId, roll, type);

            String html = HtmCache.getInstance().getNotNull("games/roulette/result.htm", player);

            if (result > 0)
            {
                ItemUtils.addItem(player, _betItem.getItemId(), bet * result, true);
                ServerVariables.set("roulette", ServerVariables.getLong("roulette", 0L) - bet * result);
                html = html.replace("%result_color%", "00FF00").replace("%result%", "Вы выиграли!");
                Log.logItem(LogAction.Roulette, Strings.concat("Player ", player.getName(), " (", player.getObjectId(), ") win ", (bet * result), " ", _betItem.getNameEn(), " (result: ", result, ", betId: ", betId, ", type: ", type.toString(), ")"));
            }
            else
            {
                ItemUtils.removeItem(player, _betItem.getItemId(), bet, true);
                ServerVariables.set("roulette", ServerVariables.getLong("roulette", 0L) + bet);
                html = html.replace("%result_color%", "FF0000").replace("%result%", "Вы проиграли!");
                Log.logItem(LogAction.Roulette, Strings.concat("Player ", player.getName(), " (", player.getObjectId(), ") lose ", bet, " ", _betItem.getNameEn()));
            }

            html = html.replaceFirst("%bet%", Util.formatAdena(bet)).replaceFirst("%bet_item%", _betItem.getNameRu());
            html = html.replaceFirst("%bet_type%", new CustomMessage("Roulette." + type.toString(), player).toString());
            html = html.replaceFirst("%bet_number%", type == GameType.StraightUp ? betId : new CustomMessage("Roulette." + betId, player).toString());
            html = html.replaceFirst("%number%", roll[0]);
            html = html.replaceFirst("%color%", new CustomMessage("Roulette." + roll[1], player).toString());
            html = html.replaceFirst("%evenness%", new CustomMessage("Roulette." + roll[4], player).toString());
            html = html.replaceFirst("%column%", new CustomMessage("Roulette." + roll[3], player).toString());
            html = html.replaceFirst("%dozen%", new CustomMessage("Roulette." + roll[2], player).toString());
            html = html.replaceFirst("%highness%", new CustomMessage("Roulette." + roll[5], player).toString());
            html = html.replaceFirst("%param%", params[1] + " " + params[2] + " " + params[3]);
            HtmlUtils.show(html, player, npc);

            if (player.isGM())
                player.sendMessage("Текущий баланс рулетки: " + Util.formatAdena(ServerVariables.getLong("roulette", 0L)));
        }
    }

    public String DialogAppend_30990(Player player, Integer val)
    {
        return getHtmlAppends(val);
    }

    public String DialogAppend_30991(Player player, Integer val)
    {
        return getHtmlAppends(val);
    }

    public String DialogAppend_30992(Player player, Integer val)
    {
        return getHtmlAppends(val);
    }

    public String DialogAppend_30993(Player player, Integer val)
    {
        return getHtmlAppends(val);
    }

    public String DialogAppend_30994(Player player, Integer val)
    {
        return getHtmlAppends(val);
    }

    public String getHtmlAppends(Integer val)
    {
        if (!GamesConfig.ALLOW_ROULETTE)
            return "";

        return "<br1><button align=\"LEFT\" icon=\"NORMAL\" action=\"bypass -h npc_%objectId%_rouletteShow\"><font color=LEVEL>Сыграть в рулетку</font></button>";
    }

    @Override
    public String[] getBypasses()
    {
        return _commandList;
    }
}
параметры из конфига
Код:
    @Setting(name = "AllowRoulette")
    public static boolean ALLOW_ROULETTE = false;
    @Setting(name = "RouletteMinBet")
    public static long ROULETTE_MIN_BET = 1L;
    @Setting(name = "RouletteMaxBet")
    public static long ROULETTE_MAX_BET = 1_000_000_000L;
диалоги
Код:
play.htm
---
<html>
<body>
<center>
<img src="L2UI.SquareBlank" width=280 height=5>
Ставки от <font color=00FF00>%min%</font> до <font color=00FF00>%max%</font> <font color=F2C202>%bet_item%</font>
<img src="L2UI.SquareWhite" width=280 height=1><img src="L2UI.SquareBlank" width=280 height=3>
<table border=0 cellpadding=0 cellspacing=0>
    <tr>
        <td width=140>На число</td>
        <td width=60>Число:</td>
        <td width=60></td>
        <td width=60></td>
    </tr>
    <tr><td height=9 colspan=4></td></tr>
    <tr>
        <td width=140><edit var="bet1" width=100 height=10 length=10 /></td>
        <td width=60 align=center><edit var="number1" width=50 height=10 length=2 /></td>
        <td width=60></td>
        <td width=60><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay StraightUp $number1 $bet1" value="Ok" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
    </tr>
</table>
<img src="L2UI.SquareBlank" width=280 height=3><img src="L2UI.SquareGray" width=280 height=1><img src="L2UI.SquareBlank" width=280 height=3>
<table border=0 cellpadding=0 cellspacing=0>
    <tr>
        <td width=140>На колонку</td>
        <td width=60></td>
        <td width=60></td>
        <td width=60></td>
    </tr>
    <tr><td height=9 colspan=4></td></tr>
    <tr>
        <td width=140><edit var="bet2" width=100 height=10 length=10 /></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay ColumnBet first $bet2" value="Первая" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay ColumnBet second $bet2" value="Вторая" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay ColumnBet third $bet2" value="Третья" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
    </tr>
</table>
<img src="L2UI.SquareBlank" width=280 height=3><img src="L2UI.SquareGray" width=280 height=1><img src="L2UI.SquareBlank" width=280 height=3>
<table border=0 cellpadding=0 cellspacing=0>
    <tr>
        <td width=140>На дюжину</td>
        <td width=60></td>
        <td width=60></td>
        <td width=60></td>
    </tr>
    <tr><td height=9 colspan=4></td></tr>
    <tr>
        <td width=140><edit var="bet3" width=100 height=10 length=10 /></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay DozenBet first $bet3" value="Первая" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay DozenBet second $bet3" value="Вторая" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay DozenBet third $bet3" value="Третья" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
    </tr>
</table>
<img src="L2UI.SquareBlank" width=280 height=3><img src="L2UI.SquareGray" width=280 height=1><img src="L2UI.SquareBlank" width=280 height=3>
<table border=0 cellpadding=0 cellspacing=0>
    <tr>
        <td width=140>Красное или черное</td>
        <td width=60></td>
        <td width=60></td>
        <td width=60></td>
    </tr>
    <tr><td height=9 colspan=4></td></tr>
    <tr>
        <td width=140><edit var="bet4" width=100 height=10 length=10 /></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay RedOrBlack red $bet4" value="Красное" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay RedOrBlack black $bet4" value="Черное" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60></td>
    </tr>
</table>
<img src="L2UI.SquareBlank" width=280 height=3><img src="L2UI.SquareGray" width=280 height=1><img src="L2UI.SquareBlank" width=280 height=3>
<table border=0 cellpadding=0 cellspacing=0>
    <tr>
        <td width=140>Четное или нечетное</td>
        <td width=60></td>
        <td width=60></td>
        <td width=60></td>
    </tr>
    <tr><td height=9 colspan=4></td></tr>
    <tr>
        <td width=140><edit var="bet5" width=100 height=10 length=10 /></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay EvenOrOdd even $bet5" value="Чет" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay EvenOrOdd odd $bet5" value="Нечет" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60></td>
    </tr>
</table>
<img src="L2UI.SquareBlank" width=280 height=3><img src="L2UI.SquareGray" width=280 height=1><img src="L2UI.SquareBlank" width=280 height=3>
<table border=0 cellpadding=0 cellspacing=0>
    <tr>
        <td width=140>Высокое или низкое</td>
        <td width=60></td>
        <td width=60></td>
        <td width=60></td>
    </tr>
    <tr><td height=9 colspan=4></td></tr>
    <tr>
        <td width=140><edit var="bet6" width=100 height=10 length=10 /></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay LowOrHigh low $bet6" value="Низкое" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60 align=center><button width=54 height=16 action="bypass -h npc_%objectId%_roulettePlay LowOrHigh high $bet6" value="Высокое" fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down"></td>
        <td width=60></td>
    </tr>
</table>
<img src="L2UI.SquareBlank" width=280 height=3><img src="L2UI.SquareWhite" width=280 height=1><img src="L2UI.SquareBlank" width=280 height=3>
<table>
    <tr>
        <td width=150><font color=00FF00>На число</font></td>
        <td width=170>35 к 1 (числа от 0 до 36)</td>
    </tr>
    <tr>
        <td width=150><font color=00FF00>На колонку</font></td>
        <td width=170>2 к 1, зеро - автопроигрыш</td>
    </tr>
    <tr>
        <td width=150><font color=00FF00>На дюжину</font></td>
        <td width=170>2 к 1, зеро - автопроигрыш</td>
    </tr>
    <tr>
        <td width=150><font color=00FF00>Красное или черное</font></td>
        <td width=170>1 к 1, зеро - автопроигрыш</td>
    </tr>
    <tr>
        <td width=150><font color=00FF00>Четное или нечетное</font></td>
        <td width=170>1 к 1, зеро - автопроигрыш</td>
    </tr>
    <tr>
        <td width=150><font color=00FF00>Высокое или низкое</font></td>
        <td width=170>1 к 1, зеро - автопроигрыш</td>
    </tr>
</table>
</center>
</body>
</html>
---
---
---
result.htm
---
<html>
<body>
<img src="L2UI.SquareBlank" width=280 height=5>
<center><font name=hs12 color=%result_color%>%result%</font></center>
<img src="L2UI.SquareWhite" width=280 height=1>
<table>
    <tr><td width=150>Величина ставки:</font></td><td width=150><font color=00FF00>%bet%</font> <font color=F2C202>%bet_item%</font></td></tr>
</table>
<img src="L2UI.SquareGray" width=280 height=1>
<table>
    <tr><td width=150>Тип ставки:</td><td width=150><font color=F2C202>%bet_type%</font>, <font color=F2C202>%bet_number%</font></td></tr>
</table>
<img src="L2UI.SquareGray" width=280 height=1>
<table>
    <tr><td width=150>Выпало:</td><td width=150><font color=F2C202>%number%</font></td></tr>
</table>
<img src="L2UI.SquareGray" width=280 height=1>
<table>
    <tr><td width=150>Цвет:</td><td width=150><font color=F2C202>%color%</font></td></tr>
</table>
<img src="L2UI.SquareGray" width=280 height=1>
<table>
    <tr><td width=150>Четность:</td><td width=150><font color=F2C202>%evenness%</font></td></tr>
</table>
<img src="L2UI.SquareGray" width=280 height=1>
<table>
    <tr><td width=150>Колонка:</td><td width=150><font color=F2C202>%column%</font></td></tr>
</table>
<img src="L2UI.SquareGray" width=280 height=1>
<table>
    <tr><td width=150>Дюжина:</td><td width=150><font color=F2C202>%dozen%</font></td></tr>
</table>
<img src="L2UI.SquareGray" width=280 height=1>
<table>
    <tr><td width=150>Высота:</td><td width=150><font color=F2C202>%highness%</font></td></tr>
</table>
<img src="L2UI.SquareBlank" width=280 height=2>
<img src="L2UI.SquareWhite" width=280 height=1>
<br>
<center>
<button action="bypass -h npc_%objectId%_roulettePlay %param%" value="Играть еще раз с теми же данными" width=220 height=24 fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down">
<button action="bypass -h npc_%objectId%_rouletteShow" value="Назад" width=220 height=24 fore="L2UI_CT1.Button_DF_Small" back="L2UI_CT1.Button_DF_Small_Down">
</center>
</body>
</html>

сразу скажу - у вас не будет метода sendPopupMessage для Player - можете менять его просто на sendMessage
sendPopupMessage - это у меня модификация sendMessage, показывающая сообщение не в чате, а в виде popup-диалога посреди экрана.

Как сама рулетка выглядит в игре
Shot00061.jpg
Shot00062.jpg
 
Последнее редактирование модератором:
Назад
Сверху Снизу