2013年6月1日 星期六

【Java教學】增加新地圖不用改核心

增加新地圖不用改核心
核心版本: r375
http://l1j-tw-99nets.googlecode.com/svn/trunk/

先說明一下,目前太陽神V14版、l1j-tw-99nets 還沒有這個功能,新增地圖都需要改核心
TextMapReader.java
在 MAP_INFO 陣列增加 mapid 及 座標範圍,按照以下修改,mapids 資料表增加地圖,及黑盒子maps增加 *.txt,就不用改核心了。

修改1
l1j\server\server\datatables\MapsTable.java
1-1
在開頭 import 群中插入這4行
import java.io.IOException;
import l1j.server.server.model.map.L1Map;
import l1j.server.server.model.map.L1V1Map;
import l1j.server.server.model.map.TextMapReader;

1-2
在這一行
private final Map<Integer, MapData> _maps = Maps.newMap();
下面增加
private final Map<Integer, L1Map> _loadMaps = Maps.newMap();

1-3
在這一行
_maps.put(new Integer(mapId), data);
下面增加這一段
               TextMapReader textRead = new TextMapReader();
               int xSize = data.endX - data.startX + 1;
               int ySize = data.endY - data.startY + 1;

               try {
                   L1V1Map map = new L1V1Map((short) mapId, textRead.read(mapId,
                           xSize, ySize), data.startX,
                           data.startY,
                           data.isUnderwater,
                           data.markable,
                           data.teleportable,
                           data.escapable,
                           data.isUseResurrection,
                           data.isUsePainwand,
                           data.isEnabledDeathPenalty,
                           data.isTakePets,
                           data.isRecallPets,
                           data.isUsableItem,
                           data.isUsableSkill);

                   _loadMaps.put(mapId, map);
               } catch (IOException e) {
                   _log.log(Level.SEVERE, e.getLocalizedMessage(), e);
               }

修改2
l1j\server\server\model\map\TextMapReader.java
2-1
將這一核心改成如下完整內容,不一樣的部份請刪除或註解掉
程式碼開始:
/**
*                   License
* THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
* CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE").
* THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.
* ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR
* COPYRIGHT LAW IS PROHIBITED.
*
* BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
* AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE
* MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED
* HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
*
*/
package l1j.server.server.model.map;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.server.server.datatables.MapsTable;
import l1j.server.server.utils.FileUtil;
import l1j.server.server.utils.collections.Lists;
import l1j.server.server.utils.collections.Maps;

/**
* 地圖 (maps/\d*.txt)讀取
*/
public class TextMapReader extends MapReader {

   /** 紀錄用 */
   private static Logger _log = Logger
           .getLogger(TextMapReader.class.getName());

   /** 地圖的路徑 */
   private static final String MAP_DIR = "./maps/";

   /**
    * 依照輸入大小讀取指定編號地圖
    *
    * @param mapId
    *         地圖編號
    * @param xSize
    *         X座標大小
    * @param ySize
    *         Y座標大小
    * @return byte[][]
    * @throws IOException
    */
   public byte[][] read(final int mapId, final int xSize, final int ySize)
           throws IOException {
       byte[][] map = new byte[xSize][ySize];
       LineNumberReader in = new LineNumberReader(new BufferedReader(
               new FileReader(MAP_DIR + mapId + ".txt")));

       int y = 0;
       String line;
       while ((line = in.readLine()) != null) {
           if ((line.trim().length() == 0) || line.startsWith("#")) {
               continue; // 跳過空行與註解
           }

           int x = 0;
           StringTokenizer tok = new StringTokenizer(line, ",");
           while (tok.hasMoreTokens()) {
               byte tile = Byte.parseByte(tok.nextToken());
               map[x][y] = tile;

               x++;
           }
           y++;
       }
       in.close();
       return map;
   }

   /**
    * 讀取指定編號的地圖
    *
    * @param id
    *         地圖編號
    * @return L1Map
    * @throws IOException
    */
   @Override
   public L1Map read(final int id) throws IOException {
       if (read().get(id) != null) {
           return read().get(id);
       }
       throw new FileNotFoundException("地圖編號: " + id);
   }

   /**
    * 取得所有地圖與編號的 Mapping
    *
    * @return Map
    * @throws IOException
    */
   @Override
   public Map<Integer, L1Map> read() throws IOException {
       return MapsTable.getInstance().getLoadMaps();
   }

   /**
    * 傳回所有地圖的編號
    *
    * @return ArraryList
    */
   public static List<Integer> listMapIds() {
       List<Integer> ids = Lists.newList();

       File mapDir = new File(MAP_DIR);
       for (String name : mapDir.list()) {
           File mapFile = new File(mapDir, name);
           if (!mapFile.exists()) {
               continue;
           }
           if (!FileUtil.getExtension(mapFile).toLowerCase().equals("txt")) {
               continue;
           }
           int id = 0;
           try {
               String idStr = FileUtil.getNameWithoutExtension(mapFile);
               id = Integer.parseInt(idStr);
           } catch (NumberFormatException e) {
               continue;
           }
           ids.add(id);
       }
       return ids;
   }
}
程式碼結束:

這是為達功能所以剪貼出來的,還不是最有效率的寫法,希望有大大可以加入討論研究。
如果大家覺得還不錯,也希望這個功能可以加到 [太陽神V15版]、[l1j-tw-99nets]內。

沒有留言:

張貼留言