天堂123首頁 | GM發布私服 | 在線人員: 931712
當前位置:天堂123>私服架設>天堂私服編寫計時地圖教學~

天堂私服編寫計時地圖教學~

發表時間:2016-10-15

1.
MapsTable.java DB化最大停留時間

尋找 MapData

增加

/**
* 計時地圖時間
*/
public int maptime;

尋找 loadMapsFromDatabase

增加

data.maptime = rs.getInt("maptime");

找個地方增加

/**
* 取回計時地圖時間
*
* @param mapId
* @return
*/
public int getMapTime(final int mapId) {
final MapData map = this._maps.get(mapId);
if (map == null) {
return 0;
}
return this._maps.get(mapId).maptime;
}

mapids.sql 增加一個 maptime欄位(單位是分鐘)
2.
L1PcIntance.java 製作欄位來儲存秒數
找個地方增加

/**
* 奇岩地監可停留時間(秒).
*/
private int _rocksPrisonTime;
/**
* 取回奇岩地監可停留時間(秒).
*
* @return
*/
public int getRocksPrisonTime() {
return this._rocksPrisonTime;
}
/**
* 設定奇岩地監使用時間.
*
* @param time
* 時間
*/
public void setRocksPrisonTime(final int time) {
this._rocksPrisonTime = time;
}
/**
* 拉斯塔巴德地監可停留時間(秒).
*/
private int _lastabardTime;
/**
* 取回拉斯塔巴德地監可停留時間(秒).
*
* @return
*/
public int getLastabardTime() {
return this._lastabardTime;
}
/**
* 設定拉斯塔巴德監獄使用時間.
*
* @param time
* 時間
*/
public void setLastabardTime(final int time) {
this._lastabardTime = time;
}

/**
* 象牙塔可停留時間(秒).
*/
private int _ivorytowerTime;
/**
* 取回象牙塔可停留時間(秒).
*
* @return
*/
public int getIvoryTowerTime() {
return this._ivorytowerTime;
}
/**
* 設定象牙塔使用時間.
*
* @param time
* 時間
*/
public void setIvoryTowerTime(final int time) {
this._ivorytowerTime = time;
}

/**
* 取回計時地圖使用時間
*
* @param mapid
* 玩家所在的地圖
* @return
*/
public int getMapUseTime(final int mapid) {
int result = 0;
switch (mapid) {
case 53: // 奇岩地監1F
case 54: // 奇岩地監2F
case 55: // 奇岩地監3F
case 56: // 奇岩地監4F
result = this._rocksPrisonTime;
break;
case 75: // 象牙塔1F
case 76: // 象牙塔2F
case 77: // 象牙塔3F
case 78: // 象牙塔4F
case 79: // 象牙塔5F
case 80: // 象牙塔6F
case 81: // 象牙塔7F
case 82: // 象牙塔8F
result = this._ivorytowerTime;
break;
case 450: // 拉斯塔巴德正門
case 451: // 1樓 集會場
case 452: // 1樓 突擊隊訓練場
case 453: // 1樓 魔獸君王之室
case 454: // 1樓 魔獸調教場
case 455: // 1樓 魔獸訓練場
case 456: // 1樓 魔獸召喚室
case 460: // 2樓 黑魔法修練場
case 462: // 2樓 法令軍王之室
case 463: // 2樓 法令軍王的書房
case 464: // 2樓 暗黑精靈召喚室
case 465: // 2樓 暗黑精靈棲息地
case 466: // 2樓 暗黑精靈研究室
case 470: // 3樓 惡靈祭壇
case 471: // 3樓 惡靈之主祭壇
case 472: // 3樓 傭兵訓練場
case 473: // 3樓 冥法軍訓練場
case 474: // 3樓 歐姆實驗室
case 475: // 3樓 冥法軍王之室
case 476: // 3樓 中央控制室
case 477: // 3樓 惡靈之主傭兵室
case 478: // 3樓 控制室走廊
case 490: // 地下訓練場
case 491: // 地下通道
case 492: // 暗殺軍王之室
case 493: // 地下控制室
case 494: // 地下處刑場
case 495: // 地下競技場
case 496: // 地下監獄
case 530: // 4樓 格蘭肯神殿、長老.琪娜之室
case 531: // 4樓 長老.巴塔斯之室、長老.安迪斯之室
case 532: // 4樓 庭園廣場、長老.泰瑪斯之室
case 533: // 4樓 長老.泰瑪斯之室、長老.拉曼斯之室、長老.巴陸德之室
case 534: // 4樓 長老會議廳、副神官.卡山德拉之室、真.冥皇丹特斯之室
result = this._lastabardTime;
break;
}
return result;
}
/**
* 設定地圖已使用時間.
*
* @param time
* 時間
*/
public void setMapUseTime(final int mapid, final int time) {
switch (mapid) {
case 53:// 奇岩地監1F
case 54:// 奇岩地監2F
case 55:// 奇岩地監3F
case 56:// 奇岩地監4F
this.setRocksPrisonTime(time);
break;
case 75:// 象牙塔1F
case 76:// 象牙塔2F
case 77:// 象牙塔3F
case 78:// 象牙塔4F
case 79:// 象牙塔5F
case 80:// 象牙塔6F
case 81:// 象牙塔7F
case 82:// 象牙塔8F
this.setIvoryTowerTime(time);
break;
case 450: // 拉斯塔巴德正門
case 451: // 1樓 集會場
case 452: // 1樓 突擊隊訓練場
case 453: // 1樓 魔獸君王之室
case 454: // 1樓 魔獸調教場
case 455: // 1樓 魔獸訓練場
case 456: // 1樓 魔獸召喚室
case 460: // 2樓 黑魔法修練場
case 462: // 2樓 法令軍王之室
case 463: // 2樓 法令軍王的書房
case 464: // 2樓 暗黑精靈召喚室
case 465: // 2樓 暗黑精靈棲息地
case 466: // 2樓 暗黑精靈研究室
case 470: // 3樓 惡靈祭壇
case 471: // 3樓 惡靈之主祭壇
case 472: // 3樓 傭兵訓練場
case 473: // 3樓 冥法軍訓練場
case 474: // 3樓 歐姆實驗室
case 475: // 3樓 冥法軍王之室
case 476: // 3樓 中央控制室
case 477: // 3樓 惡靈之主傭兵室
case 478: // 3樓 控制室走廊
case 490: // 地下訓練場
case 491: // 地下通道
case 492: // 暗殺軍王之室
case 493: // 地下控制室
case 494: // 地下處刑場
case 495: // 地下競技場
case 496: // 地下監獄
case 530: // 4樓 格蘭肯神殿、長老.琪娜之室
case 531: // 4樓 長老.巴塔斯之室、長老.安迪斯之室
case 532: // 4樓 庭園廣場、長老.泰瑪斯之室
case 533: // 4樓 長老.泰瑪斯之室、長老.拉曼斯之室、長老.巴陸德之室
case 534: // 4樓 長老會議廳、副神官.卡山德拉之室、真.冥皇丹特斯之室
this.setLastabardTime(time);
break;
}
}
/**
* 是否在計時地圖 <br>
*
* @return true:玩家位於限時的地圖內
*/
public boolean isInTimeMap() {
final int map = this.getMapId();
final int maxMapUsetime = MapsTable.getInstance().getMapTime(map);
return maxMapUsetime > 0;
}

3.
MySqlCharacterStorage.java 關係到人物資料儲存
尋找loadCharacter

增加

pc.setRocksPrisonTime(rs.getInt("RocksPrisonTime"));
pc.setIvoryTowerTime(rs.getInt("IvorytowerTime"));
pc.setLastabardTime(rs.getInt("LastabardTime"));

尋找

storeCharacter

SQL指令碼內增加

,RocksPrisonTime=?,IvorytowerTime=?,LastabardTime=?

執行動作增加
pstm.setInt(++i, pc.getRocksPrisonTime());
pstm.setInt(++i, pc.getIvoryTowerTime());
pstm.setInt(++i, pc.getLastabardTime());

characters.sql 增加RocksPrisonTime,IvorytowerTime,LastabardTime三個欄位

此文只分享於浪漫物語網路社區,轉載請著名作者,出處

4.
寫一個執行緒來增加或更新時間

import java.util.Calendar;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;
import l1j.server.config.Config_Server;
import l1j.server.server.datatables.MapsTable;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.L1World;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.identity.L1SystemMessageId;
import l1j.server.server.serverpackets.S_MapTimer;
import l1j.server.server.serverpackets.S_ServerMessage;

/**
* 計時地圖執行緒
*
* @author Psnnwe
*
*/
public final class MapTimerThread extends Thread {

/**
* 實例
*/
private static MapTimerThread _instance;

/**
* 提示信息.
*/
private static final Logger LOG = Logger.getLogger(MapTimerThread.class
.getName());

/**
* 取回實例
*
* @return
*/
public static MapTimerThread getInstance() {
if (_instance == null) {
_instance = new MapTimerThread();
_instance.start();
}
return _instance;
}

/**
* 日曆
*
* @return
*/
private Calendar getRealTime() {
final TimeZone tz = TimeZone.getTimeZone(Config_Server.TIME_ZONE);
final Calendar cal = Calendar.getInstance(tz);
return cal;
}

/**
* 地圖時間檢查
*
* @param pc
*/
private void MapTimeCheck(final L1PcInstance pc) {
// 玩家所在的地圖
final int map = pc.getMapId();
// 地圖限制時間(秒數)
final int maxMapUsetime = MapsTable.getInstance().getMapTime(map) * 60;
final Calendar time = this.getRealTime();
// 取回今年的第幾天
int dayofyear = time.get(Calendar.DAY_OF_YEAR);
if (dayofyear == 365) {
dayofyear += 1;
}
// 使用秒數(取餘數)
final int entertime = pc.getMapUseTime(map) % 100000;
// 使用日期(取整數)
final int enterday = pc.getMapUseTime(map) / 100000;
if (entertime > (maxMapUsetime)) {
this.teleport(pc);
} else if (enterday < dayofyear) {
// 不同天-更新日期
pc.setMapUseTime(map, time.get(Calendar.DAY_OF_YEAR) * 100000);
} else {
this.message(pc);
pc.setMapUseTime(map, pc.getMapUseTime(map) + 1);
// 已使用時間(秒)
final int usetime = pc.getMapUseTime(map) % 100000;
// 剩餘時間(秒)
final int can_useTime = (maxMapUsetime - usetime);
if ((entertime % 60) == 0) {// 計時器顯示(1分鐘來一次就好了= = )
pc.sendPackets(new S_MapTimer(can_useTime));
}
}
}

/**
* 時間提示訊息
*
* @param pc
*/
private void message(final L1PcInstance pc) {
// 玩家所在的地圖
final int map = pc.getMapId();
// 地圖限制時間(秒數)
final int maxMapUsetime = MapsTable.getInstance().getMapTime(map) * 60;
// 取回地圖使用時間(秒) --- (取餘數(不取日期))
final int time = pc.getMapUseTime(map) % 100000;
final int usetime = maxMapUsetime - time; // 秒數
S_ServerMessage msg = null;
switch (usetime) {
case 10800:
msg = new S_ServerMessage(L1SystemMessageId.$1526,
String.valueOf(3));
break;
case 7200:
msg = new S_ServerMessage(L1SystemMessageId.$1526,
String.valueOf(2));
break;
case 3600:
msg = new S_ServerMessage(L1SystemMessageId.$1526,
String.valueOf(1));
break;
case 1800:
msg = new S_ServerMessage(L1SystemMessageId.$1527,
String.valueOf(30));
break;
case 900:
msg = new S_ServerMessage(L1SystemMessageId.$1527,
String.valueOf(15));
break;
case 600:
msg = new S_ServerMessage(L1SystemMessageId.$1527,
String.valueOf(10));
break;
case 300:
msg = new S_ServerMessage(L1SystemMessageId.$1527,
String.valueOf(5));
break;
case 120:
msg = new S_ServerMessage(L1SystemMessageId.$1527,
String.valueOf(2));
break;
case 60:
msg = new S_ServerMessage(L1SystemMessageId.$1527,
String.valueOf(1));
break;
case 10:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(10));
break;
case 9:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(9));
break;
case 8:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(8));
break;
case 7:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(7));
break;
case 6:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(6));
break;
case 5:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(5));
break;
case 4:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(4));
break;
case 3:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(3));
break;
case 2:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(2));
break;
case 1:
msg = new S_ServerMessage(L1SystemMessageId.$1528,
String.valueOf(1));
break;
default:
break;
}
pc.sendPackets(msg);
}

@Override
public void run() {
System.out.println("╠》載入 - 計時地圖執行緒。");
while (true) {
try {
for (final L1PcInstance pc : L1World.getInstance()
.getAllPlayers()) {
if ((pc == null) || (pc.getNetConnection() == null)) {
continue;
} else {
if (pc.isDead()) {// 死亡不計時
continue;
} else {
if (pc.isInTimeMap()) {// 離開地圖不計時
this.MapTimeCheck(pc);
}
}
}
}
final int time = 1 * 1000;
Thread.sleep(time);// 1秒一次
} catch (final Throwable e) {
LOG.log(Level.WARNING, e.getLocalizedMessage(), e);
}
}
}

/**
* 傳送處理.(這邊只舉例奇岩地監)
*
* @param pc
*/
private void teleport(final L1PcInstance pc) {
final int map = pc.getMapId();
if ((map == 53) || (map == 54) || (map == 55) || (map == 56)) {
final int locx = 33427;
final int locy = 32822;
final int mapid = 4;
final int heading = 5;
L1Teleport.teleport(pc, locx, locy, mapid, heading, true);
}
}
}

5.
GameServer.java 讓MapTimerThread伴隨伺服器啟動
尋找initialize

方法內找地方增加

MapTimerThread.getInstance();

6.
封包的處理(ctrl+q)

import l1j.server.server.model.Instance.L1PcInstance;
/**
* 地圖剩餘時間(ctrl+q)
*
* @author Psnnwe
*
*/
public class S_MapTimerOutextends ServerBasePacket {
private byte[] _byte = null;
private static final String S_MAP_TIMER_OUT = "[S] S_MapTimerOut";
/**
* ctrl+Q中地圖剩餘時間
*/
public static final int DISPLAY_MAP_TIME = 159;
/**
* ctrl+Q顯示剩餘時間
*
* @param pc
*/
public S_MapTimerOut(final L1PcInstance pc) {
this.writeC(Opcodes_Server.S_OPCODE_PACKETBOX);
this.writeC(DISPLAY_MAP_TIME);
this.writeD(3);// 組數
this.writeD(1);// 排序
this.writeS("$12125"); // 奇岩監獄
final int g_time = pc.getRocksPrisonTime() % 100000;
final int g_maxTime = 10800; // 3小時(秒)
final int g_newTime = g_maxTime - g_time;
this.writeD(g_newTime);
this.writeD(2);
this.writeS("$6081"); // 象牙塔
final int i_time = pc.getIvoryTowerTime() % 100000;
final int i_maxTime = 3600; // 1小時(秒)
final int i_newTime = i_maxTime - i_time;
this.writeD(i_newTime);
this.writeD(3);
this.writeS("$12126"); // 拉斯塔巴德地監
final int l_time = pc.getLastabardTime() % 100000;
final int l_maxTime = 43200; // 12小時(秒)
final int l_newTime = l_maxTime - l_time;
this.writeD(l_newTime);
}
@Override
public byte[] getContent() {
if (this._byte == null) {
this._byte = this.getBytes();
}
return this._byte;
}
@Override
public String getType() {
return S_MAP_TIMER_OUT;
}
}

7.
畫面左上角計時器

/**
* 計時地圖左上角計時器
*
* @author Psnnwe
*
*/
public final class S_MapTimer extends ServerBasePacket {
private static final String S_MAP_TIMER = "[S] S_MapTimer";
/**
* 位元組
*/
private byte[] _byte;
/**
* 顯示定時器地圖的剩餘時間
**/
public static final int MAP_TIMER = 153;
/**
* 地圖計時器
*
* @param value
* 剩餘的時間(秒)
*/
public S_MapTimer(final int value) {
this.writeC(Opcodes_Server.S_OPCODE_PACKETBOX);
this.writeC(MAP_TIMER);
this.writeH(value);
}
@Override
public byte[] getContent() {
if (this._byte == null) {
this._byte = this.getBytes();
}
return this._byte;
}
@Override
public String getType() {
return S_MAP_TIMER;
}
}

8.
C_NPCAction.java NPC傳送
寫法不同請自行變通,在此只舉例奇岩 (注意是否再 if (obj instanceof L1NpcInstance) 判斷內)

case 自行輸入:
if (s.equalsIgnoreCase("teleportURL")) {
pc.sendPackets(new S_NPCTalkReturn(npc.getId(),"merlin2"));
}
if (s.equalsIgnoreCase("teleport giranD")) { // 傳送至奇岩地監
final Calendar time = this.getRealTime();
final int entertime = pc.getRocksPrisonTime() % 100000;
final int enterday = pc.getRocksPrisonTime() / 100000;
final int dayofyear = time.get(Calendar.DAY_OF_YEAR);
final int maxtime = 3 * 60 * 60;// 最多可停留的時間10800(秒)
final int onehour = 1 * 60 * 60;// 1小時(3600秒)
if ((entertime >= maxtime) && (enterday == dayofyear)) {
pc.sendPackets(new S_ServerMessage(
L1SystemMessageId.$1522, "3"));
htmlid = "";
return;
} else {
if (enterday < dayofyear) {
pc.setRocksPrisonTime(dayofyear * 100000);
}
if (pc.getInventory().consumeItem(L1ItemId.ADENA,
1000)) { // 檢查身上金幣是否足夠
final int a = entertime % 60;
if (a == 0) {
final int b = (maxtime - entertime)
/ onehour; // 取回小時
pc.sendPackets(new S_ServerMessage(
L1SystemMessageId.$1526, "" + b
+ ""));
} else if ((maxtime - entertime) < onehour) { // 不到一小時
final int c = maxtime - entertime;
pc.sendPackets(new S_ServerMessage(
L1SystemMessageId.$1527, "" + c
+ ""));
}
L1Teleport.teleport(pc, 32806, 32735,
(short) 53, 5, true);
} else {
PacketCreate.getInstance().sendSinglePackets(
pc, L1SystemMessageId.$189);
return;
}
}
}
break;


9.
C_Rank.java 查詢的部分
增加


case 8: // 查詢指令(/入場時間)
// 取餘數(時間)
final int g_entertime = pc.getRocksPrisonTime() % 100000;
final int g_maxTime = 10800; // 3小時
int g_newTime = (g_maxTime - g_entertime) / 60;
if (g_newTime <= 0) {
g_newTime = 0;
}
final S_ServerMessage rocksPrison = new S_ServerMessage(
L1SystemMessageId.$2535, "$12125",
String.valueOf(g_newTime)); // [奇岩監獄]
pc.sendPackets(rocksPrison); // %0 : %0 : 剩餘時間 %1 分
// 取餘數(時間)
final int i_entertime = pc.getIvoryTowerTime() % 100000;
final int i_maxTime = 3600; // 1小時
int i_newTime = (i_maxTime - i_entertime) / 60;
if (i_newTime <= 0) {
i_newTime = 0;
}
final S_ServerMessage ivorytower = new S_ServerMessage(
L1SystemMessageId.$2535, "$6081", String.valueOf(i_newTime)); // [象牙塔]
pc.sendPackets(ivorytower); // %0 : %0 : 剩餘時間 %1 分
// 取餘數(時間)
final int l_entertime = pc.getLastabardTime() % 100000;
final int l_maxTime = 43200; // 12小時
int l_newTime = (l_maxTime - l_entertime) / 60;
if (l_newTime <= 0) {
l_newTime = 0;
}
final S_ServerMessage lastabard = new S_ServerMessage(
L1SystemMessageId.$2535, "$12126",
String.valueOf(l_newTime)); // [拉斯塔巴德地監]
pc.sendPackets(lastabard); // %0 : %0 : 剩餘時間 %1 分
break;
case 9: // 地圖剩餘使用時間
pc.sendPackets(new S_MapTimerOut(pc));
break;
end


10.
C_SendLocation.java 發送座標位置(更新ctrl+q的顯示)
增加


case 9: // 更新Ctrl+Q的顯示時間
pc.sendPackets(new S_MapTimerOut(pc));
break;

 
其他分類
私服技巧
玩家分享
私服架設
私服新手區
 
相關推薦
優化MYSQL數據庫減少天堂私服當機的機會!
天堂私服玩家不知道的秘密!!
天堂私服GM指令簡易列表!
一個為兒子買天幣的媽媽~淚流滿面!
一段被騙天堂帳號的回憶
揭密天堂私服電腦容易中毒的原因,以及某些私服業者惡意的行為!!
天堂私服玩家無法進入論壇與遊戲的解決方法之一!
天堂私服內LH2喝水設定詳細教學
天堂私服內建自動喝水LHZ使用教學
防止外掛特殊況狀使用喝水功能!
如何在天堂私服盟戰中發揮技巧~
教你Lineage3.0天堂不能玩私服的解決方法!
自我檢測無法玩天堂私服的原因!!
小妙招幾步驟可以幫助你更快速的玩天堂遊戲喔!!
玩天堂不關機延長電腦硬碟壽命的方法
總是打不贏別人嗎?看看天堂打架技巧教戰守則吧!!
天堂打稱號★顏色代碼★符號★教您如何使用!
超骨灰級!這些天堂技巧你知道多少?又用過多少?
怎麼上傳天堂盟徽?不會上傳天堂盟徽嗎?教您如何上傳!!
天堂各職業出生/洗血配點.洗血後配點(王族篇)
   


網站地圖關於天堂123天堂123列表免責聲明刊登廣告巴哈姆湯私服瘋私服百科天堂123粉絲團天堂123 GOOGLE+
天堂123 © http://www.playsf.net/ Corporation All Rights Reserved.