a894985459

GMS專用 魔法轉盤修復精華

發表於 2023-6-5 22:55:39
a894985459 發表於 2023-6-5 22:55:39 | 顯示全部樓層 |閱讀模式
沒錯 又是我
這項功能僅限於國際版可使用MAGIC WHEEL 就是本日的主角

我不確定各端口的修復程度到底如何 我先以我117的來講解
首先找到你伺服器內的
recvopsGMS.properties
複製代碼

以及
sendopsGMS.properties
複製代碼
分別檢查封包是否如下
recvopsGMS.properties
MAGIC_WHEEL = 463
複製代碼


sendopsGMS.properties
MAGIC_WHEEL = 201
複製代碼


如果不是 請修正
接下來進入遊戲中後 魔法轉盤已經可以正常呼叫出來
若無法使用 請添加以下語法

找到World.java
在
public class World {
複製代碼
下方新增宣告(如有則跳過)
private static final Map<Integer, Integer> magicWheelCache = new HashMap();
複製代碼


轉到InventoryHandler.java
隨意一處增加以下語法(如有則跳過)
                 public static void UseMagicWheel(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
                                 
               if ((!chr.isAlive()) || (chr.hasBlockedInventory()) || (chr.isInBlockedMap()) || (chr.inPVP())) {
                 c.getSession().write(CWvsContext.MagicWheelAction(8));
                 return;
               }
           
               byte mode = slea.readByte();
               if ((mode == 0) && (World.hasWheelCache(chr.getId()))) {
                 World.removeFromWheelCache(chr.getId());
               } else if (mode == 2) {
                 slea.skip(4);
                 short toUseSlot = (short)slea.readInt();
                 int tokenId = slea.readInt();
                 Item toUse = chr.getInventory(GameConstants.getInventoryType(tokenId)).getItem(toUseSlot);
                 if ((toUse == null) || (toUse.getQuantity() < 1) || (toUse.getItemId() != tokenId) || tokenId != 4400000) {
                   c.getSession().write(CWvsContext.MagicWheelAction(6));
                   return;
                 }
                 if ((chr.getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.USE).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.SETUP).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.ETC).getNumFreeSlot() < 2) || (chr.getInventory(MapleInventoryType.CASH).getNumFreeSlot() < 2)) {
                   c.getSession().write(CWvsContext.MagicWheelAction(7));
                   return;
                 }
                 if (World.hasWheelCache(chr.getId())) {
                   c.getSession().write(CWvsContext.MagicWheelAction(8));
                   return;
                 }
                 MapleInventoryManipulator.removeFromSlot(c, GameConstants.getInventoryType(tokenId), toUseSlot, (short)1, false);
                 List rewards = new ArrayList();
                 int i = 0;
                 int itemid = 0;
                 while (i < 10) {
                   if (i < 6) {
                     itemid = GameConstants.normalMagicWheel[Randomizer.nextInt(GameConstants.normalMagicWheel.length)];
                     if (!rewards.contains(Integer.valueOf(itemid))) {
                       rewards.add(Integer.valueOf(itemid));
                       i++;
                     }
                   } else if (i < 9) {
                     itemid = GameConstants.rareMagicWheel[Randomizer.nextInt(GameConstants.rareMagicWheel.length)];
                     if (!rewards.contains(Integer.valueOf(itemid))) {
                       rewards.add(Integer.valueOf(itemid));
                       i++;
                     }
                   } else {
                     itemid = GameConstants.superMagicWheel[Randomizer.nextInt(GameConstants.superMagicWheel.length)];
                     if (!rewards.contains(Integer.valueOf(itemid))) {
                       rewards.add(Integer.valueOf(itemid));
                       i++;
                     }
                   }
                 }
                 Collections.shuffle(rewards);
                 int prizePos = Randomizer.nextInt(10);
                 World.addToWheelCache(chr.getId(), ((Integer)rewards.get(prizePos)).intValue());
                 c.getSession().write(CWvsContext.MagicWheelAction(3, String.valueOf(chr.getId()), rewards, prizePos));
               } else if (mode == 4) {
                 String data = slea.readMapleAsciiString();
                 if ((!data.equals(String.valueOf(chr.getId()))) || (!World.hasWheelCache(chr.getId()))) {
                   c.getSession().write(CWvsContext.MagicWheelAction(8));
                   return;
                 }
                 int itemId = World.removeFromWheelCache(chr.getId());
                 if (itemId > 0) {
                   Item item = MapleInventoryManipulator.addbyId_Gachapon(c, itemId, (short)1);
                   if (item == null) {
                     c.getSession().write(CWvsContext.MagicWheelAction(10));
                     return;
                   }
                   if (GameConstants.isSuperMagicWheel(itemId)) {
        c.getSession().write(CWvsContext.getGachaponMega(chr.getName(), " : got a(n)", item, (byte)11, "Wheel of Marvels"));
    }
                 }
               }
               else if (mode != 0) {
                 c.getSession().write(CWvsContext.MagicWheelAction(8));
               }
             }
           
複製代碼


轉到CWvsContext.java
隨意一處增加以下語法(如有則跳過)
            public static byte[] MagicWheelAction(int mode) {
               return MagicWheelAction(mode, null, null, 0);
             }
           
             public static byte[] MagicWheelAction(int mode, String dataKey, List<Integer> ids, int position) {
               MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
           
               mplew.writeShort(SendPacketOpcode.MAGIC_WHEEL.getValue());
               mplew.write(mode);
               if (mode == 3) {
                 mplew.write(ids.size());
                 for (Integer i : ids) {
                   mplew.writeInt(i.intValue());
                 }
                 mplew.writeMapleAsciiString(dataKey);
                 mplew.write(position);
               }
           
               return mplew.getPacket();
             }
複製代碼
轉到MapleServerHandler.java
搜尋
case MAGIC_WHEEL:
複製代碼


檢查是否與下方語法相同
如不是直接替換
case MAGIC_WHEEL:
                InventoryHandler.UseMagicWheel(slea, c, c.getPlayer());
                break;
複製代碼


轉到GameConstants.java
隨意一處增加以下語法
             public static final int[] normalMagicWheel = { 4006000, 2050004, 3994102, 3994103, 3994104, 3994102, 3994103, 3994104, 3994105, 2430007 };
           
             public static final int[] rareMagicWheel = { 2028061, 2290285, 2049301, 2049401, 2022326, 2022193, 2049000, 2049001, 2049002 };
           
             public static final int[] superMagicWheel = { 2040804, 2049400, 2028062, 2028061, 2430144, 2430144, 2430144, 2430144, 2290285, 2049100, 2049100, 2049100, 2049100 };
           
              public static boolean isSuperMagicWheel(int itemid) {
               for (int i : superMagicWheel) {
                 if (i == itemid) {
                   return true;
                 }
               }
               return false;
             }
複製代碼
編譯後 魔法轉盤應已恢復正常

課外加碼

轉盤獎品想要透過資料庫存取可不可以?
可以 當然可以

在InventoryHandler.java
增加以下語法
public static List<Integer> getMagicWheel(int type) {//取得資料庫內轉盤獎勵
        
        Connection con = DatabaseConnection.getConnection();
        try {
            List<Integer> MagicWheel = new ArrayList<Integer>();
            PreparedStatement ps = con.prepareStatement("SELECT * FROM wheeldata WHERE type = ? ORDER BY RAND() LIMIT 10");
            ps.setInt(1, type);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
             int itemid = rs.getInt("itemid");
             MagicWheel.add(itemid);
            }
            rs.close();
            ps.close();
            return MagicWheel;
            
        } catch (Exception Ex) {
            Ex.printStackTrace();
            return null;
        }
    }
複製代碼
完成後 我們回到
UseMagicWheel
複製代碼
這項涵式來
往下找到類似這段
itemid = GameConstants.normalMagicWheel[Randomizer.nextInt(GameConstants.normalMagicWheel.length)];
複製代碼

將其修改為
itemid = new Random().nextInt(getMagicWheel(1).size());
複製代碼
各位同學請注意,請記得import Random


在往下找到
rewards.add(Integer.valueOf(itemid));
複製代碼
將其修改為
rewards.add(Integer.valueOf(getMagicWheel(1).get(itemid)));
複製代碼
一共會有3段相似的語法
按照本文修改即可

往下找到
isSuperMagicWheel
複製代碼
將
if (i == itemid) {
複製代碼
修改為
for (int i : getMagicWheel(3)) {
複製代碼


這邊主要是讓語法去判斷是不是抽到本次轉盤的大獎
如果是 則會進行轉蛋廣播


有點程式基礎的相信不用小弟指點
我還是另外講解一下思路

首先 新增的
public static List<Integer> getMagicWheel(int type) {
複製代碼
這段語法 用於存取資料庫內的獎品資料
要取得獎品List 當然要先給他要怎麼找

因此
getMagicWheel(1)
複製代碼
即是告訴語法 我要找 type = 1的獎品內容

回到上方
你告訴完語法之後 語法接收到了 那他就去資料庫把
type = 1的獎品內容全部撈出來 轉成List型態
當然我們前面有下過限制
也就是
 ORDER BY RAND() LIMIT 10
複製代碼
懂了嗎?
我告訴語法 我要type = 1的獎品內容
但我要隨機的內容 你最多只能給我10個 在多我不要
因此 當你的資料表內獎品越多
隨機出來的物品品項也就越隨機

最後回到資料庫 新增資料表名稱為
wheeldata
複製代碼

分別建立兩個Table
1.名稱為itemid 類型為int 長度11
2.名稱為type   類型為int 長度11

其餘不用管
當然你也可以新增另外的Table 用於告訴自己這是什麼獎品
並不影響語法的搜索

以上,若還有不懂請PM或回文告知

補充說明 使用轉盤的道具是
4400000、44000001、44000002這三項
目前本語法僅可使用4400000該項道具我也還在摸索如何讓三項道具都能使用
若有新消息我會在本文下方補充





瀏覽 2823 回復 2

您需要登錄後才可以回帖 登錄 | 註冊會員

返回頂部