2014年2月1日 星期六

【Java教學】新增NPC兌換任務系統

QUOTE:
測試修改版本Rev230

採用eclipse3.7.1版本

編譯核心




修改l1j\server\server\model\Instance\L1MerchantInstance.java


尋找以下程式碼

QUOTE:
String[] htmldata = null;


下方新增



QUOTE:
/**
* 加入william NPC兌換任務系統
*/
if( l1j.william.NpcAction.forNpcAction(pc, npcid , objid))
return;


修改l1j\server\server\clientpackets\C_NPCAction.java

尋找


QUOTE:
/*
* アクション個別処理
*/


改成


QUOTE:
/**
* 動作個別處理
* 加入william NPC兌換任務系統
*/
if( l1j.william.NpcQuest.forNpcQuest(s, pc, ((L1NpcInstance) obj), ((L1NpcInstance) obj).getNpcTemplate().get_npcId(), objid)) {
return;
}


新增l1j\william\NpcAction.java


QUOTE:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package l1j.william;

import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.StringTokenizer;

import l1j.server.L1DatabaseFactory;
import l1j.server.Server;
import l1j.server.server.model.L1Quest;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_NPCTalkReturn;

/**
* NPC兌換任務系統
*
*/
public class NpcAction {

private static ArrayList<ArrayList<Object>> aData = new ArrayList<ArrayList<Object>>();
private static boolean NO_GET_DATA = false;

public static final String TOKEN = ",";

public static void main(String a[]) {
while(true) {
try {
Server.main(null);
} catch(Exception ex) {
}
}
}

public static boolean forNpcAction(L1PcInstance pc, int npcid, int oid) {
ArrayList<?> aTempData = null;
if(!NO_GET_DATA) {
NO_GET_DATA = true;
getData();
}

L1Quest quest = pc.getQuest();

byte class_id = (byte) 0;
if (pc.isCrown()) {//TODO 王族
class_id = 1;
} else if (pc.isKnight()) {//TODO 騎士
class_id = 2;
} else if (pc.isWizard()) {//TODO 法師
class_id = 3;
} else if (pc.isElf()) {//TODO 妖精
class_id = 4;
} else if (pc.isDarkelf()) {//TODO 黑妖
class_id = 5;
} else if (pc.isDragonKnight()) {//TODO 龍騎士
class_id = 6;
} else if (pc.isIllusionist()) {//TODO 幻術師
class_id = 7;
}

for(int i=0;i < aData.size(); i++) {
aTempData = (ArrayList<?>) aData.get(i);
if((aTempData.get(0) != null && ((Integer)aTempData.get(0)).intValue() == npcid)//TODO NPC編號
&& (pc.getLevel() == ((Integer)aTempData.get(1)).intValue() || ((Integer)aTempData.get(1)).intValue() == 0)//TODO 等級
&& (((Integer)aTempData.get(2)).intValue() != 0 && ((Integer)aTempData.get(2)).intValue() == class_id || ((Integer)aTempData.get(2)).intValue() == 0)//TODO 職業
&& (((Integer)aTempData.get(3)).intValue() != 0 && pc.getTempCharGfx() == ((Integer)aTempData.get(3)).intValue() || ((Integer)aTempData.get(3)).intValue() == 0)//TODO 變身
&& (((Integer)aTempData.get(4)).intValue() != 0 && ((Integer)aTempData.get(5)).intValue() == quest.get_step(((Integer)aTempData.get(4)).intValue()) || ((Integer)aTempData.get(4)).intValue() == 0)//TODO 任務編號
&& ((int[]) aTempData.get(6) != null && (int[]) aTempData.get(7) != null && pc.getInventory().checkItem((int[]) aTempData.get(6), (int[]) aTempData.get(7)) || (int[]) aTempData.get(6) == null && (int[]) aTempData.get(7) == null)
&& ((int[]) aTempData.get(8) != null && (int[]) aTempData.get(9) != null && !pc.getInventory().checkItem((int[]) aTempData.get(8), (int[]) aTempData.get(9)) || (int[]) aTempData.get(8) == null && (int[]) aTempData.get(9) == null)) {

//TODO 顯示對話檔
if ((String[]) aTempData.get(11) != null) {
pc.sendPackets(new S_NPCTalkReturn(oid, (String) aTempData.get(10), (String[])aTempData.get(11)));
return true;
} else {
pc.sendPackets(new S_NPCTalkReturn(oid, (String) aTempData.get(10)));
return true;
}
//TODO 顯示對話檔

}
}
return false;
}

private static void getData() {
java.sql.Connection con = null;
try { 
con = L1DatabaseFactory.getInstance().getConnection(); 
Statement stat = con.createStatement();
ResultSet rset = stat.executeQuery("SELECT * FROM william_npc_action");
ArrayList<Object> aReturn = null;
String sTemp = null;
if (rset != null)
while(rset.next()) {
aReturn = new ArrayList<Object>();
aReturn.add(0, new Integer(rset.getInt("npcid")));//TODO NPC編號
aReturn.add(1, new Integer(rset.getInt("checkLevel")));//TODO 確認等級
aReturn.add(2, new Integer(rset.getInt("checkClass")));//TODO 確認職業
aReturn.add(3, new Integer(rset.getInt("checkPoly")));//TODO 確認變身
aReturn.add(4, new Integer(rset.getInt("checkQuestId")));//TODO 確認任務編號
aReturn.add(5, new Integer(rset.getInt("checkQuestOrder")));//TODO 確認任務流程

if (rset.getString("checkItem") != null && !rset.getString("checkItem").equals(""))//TODO 確認道具
aReturn.add(6, getArray(rset.getString("checkItem"), TOKEN, 1));
else 
aReturn.add(6, null);

if (rset.getString("checkItemCount") != null && !rset.getString("checkItemCount").equals(""))//TODO 確認道具數量
aReturn.add(7, getArray(rset.getString("checkItemCount"), TOKEN, 1));
else 
aReturn.add(7, null);

if (rset.getString("notHaveItem") != null && !rset.getString("notHaveItem").equals(""))//TODO 確認道具
aReturn.add(8, getArray(rset.getString("notHaveItem"), TOKEN, 1));
else 
aReturn.add(8, null);

if (rset.getString("notHaveItemCount") != null && !rset.getString("notHaveItemCount").equals(""))//TODO 確認道具數量
aReturn.add(9, getArray(rset.getString("notHaveItemCount"), TOKEN, 1));
else 
aReturn.add(9, null);

if (rset.getString("ShowHtml") != null && !rset.getString("ShowHtml").equals(""))
aReturn.add(10, new String(rset.getString("ShowHtml")));//TODO 顯示對話檔
else 
aReturn.add(10, null);
if (rset.getString("ShowHtmlData") != null && !rset.getString("ShowHtmlData").equals(""))
aReturn.add(11,getArray(rset.getString("ShowHtmlData"), TOKEN, 2));//TODO 顯示對話內容
else 
aReturn.add(11, null);

aData.add(aReturn);
}
if(con != null && !con.isClosed())
con.close();
}
catch(Exception ex){}
}

private static Object getArray(String s,String sToken,int iType) {
StringTokenizer st = new StringTokenizer(s,sToken);
int iSize = st.countTokens();
String  sTemp = null;

if(iType == 1) {
int[] iReturn = new int[iSize];
for(int i = 0;i < iSize; i++) {
sTemp = st.nextToken();
iReturn = Integer.parseInt( sTemp );
}
return iReturn;
}

if(iType == 2) {
String[] sReturn = new String[iSize];
for(int i = 0; i < iSize; i++) {
sTemp = st.nextToken();
sReturn = sTemp;
}
return sReturn;
}

if(iType == 3) {
String sReturn = null;
for(int i = 0;i < iSize; i++){
sTemp = st.nextToken();
sReturn = sTemp;
}
return sReturn;
}
return null;
}
}




新增l1j\william\NpcQuest.java




QUOTE:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package l1j.william;

import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.StringTokenizer;

import l1j.server.L1DatabaseFactory;
import l1j.server.Server;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.model.L1Quest;
import l1j.server.server.model.L1World;
import l1j.server.server.model.Instance.L1ItemInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.inventory.L1Inventory;
import l1j.server.server.serverpackets.S_NPCTalkReturn;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.templates.L1Item;

/**
* NPC兌換任務系統
*
*/
public class NpcQuest {

private static ArrayList<ArrayList<Object>> aData = new ArrayList<ArrayList<Object>>();
private static boolean NO_GET_DATA = false;

public static final String TOKEN = ",";

public static void main(String a[]) {
while(true) {
try {
Server.main(null);
} catch(Exception ex) {
}
}
}

public static boolean forNpcQuest(String s, L1PcInstance pc, L1NpcInstance npc, int npcid, int oid) {
ArrayList<?> aTempData = null;
if(!NO_GET_DATA) {
NO_GET_DATA = true;
getData();
}

L1Quest quest = pc.getQuest();

byte class_id = (byte) 0;
if (pc.isCrown()) {//TODO 王族
class_id = 1;
} else if (pc.isKnight()) {//TODO 騎士
class_id = 2;
} else if (pc.isWizard()) {//TODO 法師
class_id = 3;
} else if (pc.isElf()) {//TODO 妖精
class_id = 4;
} else if (pc.isDarkelf()) {//TODO 黑妖
class_id = 5;
} else if (pc.isDragonKnight()) {//TODO 龍騎士
class_id = 6;
} else if (pc.isIllusionist()) {//TODO 幻術師
class_id = 7;
}

for (int i=0;i < aData.size(); i++) {
aTempData = (ArrayList<?>) aData.get(i);
if ((aTempData.get(0) != null && ((Integer)aTempData.get(0)).intValue() == npcid)//TODO NPC編號
&& ((String) aTempData.get(1)).equals(s)//TODO 確認選項
&& ((((Integer)aTempData.get(2)).intValue() != 0 && pc.getLevel() >= ((Integer)aTempData.get(2)).intValue()) || ((Integer)aTempData.get(2)).intValue() == 0)//TODO 確認等級
&& ((((Integer)aTempData.get(3)).intValue() != 0 && ((Integer)aTempData.get(3)).intValue() == class_id) || ((Integer)aTempData.get(3)).intValue() == 0)//TODO 確認職業
&& ((((Integer)aTempData.get(4)).intValue() != 0 && pc.getTempCharGfx() == ((Integer)aTempData.get(4)).intValue()) || ((Integer)aTempData.get(4)).intValue() == 0)//TODO 確認變身
&& ((((Integer)aTempData.get(5)).intValue() != 0 && quest.get_step(((Integer)aTempData.get(5)).intValue()) == ((Integer)aTempData.get(6)).intValue()) || ((Integer)aTempData.get(5)).intValue() == 0)//TODO 確認任務流程
&& ((((Integer)aTempData.get(7)).intValue() != 0 && quest.get_step(((Integer)aTempData.get(7)).intValue()) != ((Integer)aTempData.get(8)).intValue()) || ((Integer)aTempData.get(7)).intValue() == 0)//TODO 確認任務流程
&& (((int[]) aTempData.get(11) != null && (int[]) aTempData.get(12) != null && !pc.getInventory().checkItem((int[]) aTempData.get(11), (int[]) aTempData.get(12))) || (int[]) aTempData.get(11) == null && (int[]) aTempData.get(12) == null)
&& (((int[]) aTempData.get(9) != null && (int[]) aTempData.get(10) != null && pc.getInventory().checkItem((int[]) aTempData.get(9), (int[]) aTempData.get(10))) || (int[]) aTempData.get(9) == null && (int[]) aTempData.get(10) == null)
) {

boolean isGet = false;
boolean isCreate = true;

//TODO 檢查身上的物品
if ((int[]) aTempData.get(13) != null && (int[]) aTempData.get(14) != null) {

int[] materials = (int[]) aTempData.get(13);
int[] counts = (int[]) aTempData.get(14);

for (int j = 0; j < materials.length; j++) {
if (!pc.getInventory().checkItem(materials[j], counts[j])) {
L1Item temp = ItemTable.getInstance().getTemplate(materials[j]);
pc.sendPackets(new S_ServerMessage(337, temp.getName() + "(" + (counts[j] - pc.getInventory().countItems(temp.getItemId()))+ ")"));//TODO \f1%0不足。
isCreate = false;
}
}

if (!isCreate) {
if ((String[]) aTempData.get(23) != null) {
pc.sendPackets(new S_NPCTalkReturn(oid, (String) aTempData.get(22), (String[])aTempData.get(23)));
} else if (aTempData.get(22) != null) {
pc.sendPackets(new S_NPCTalkReturn(oid, (String) aTempData.get(22)));
}
return true;
}

if (isCreate && ((Integer)aTempData.get(15)).intValue() == 0) {//TODO 刪除確認的道具、並給予任務道具
//TODO 刪除道具
for (int k = 0; k < materials.length; k++) {
pc.getInventory().consumeItem(materials[k], counts[k]);
}
}
}

//TODO 給予道具
if (((Integer)aTempData.get(15)).intValue() == 0 
&& (int[]) aTempData.get(16) != null && (int[]) aTempData.get(17) != null) {

int[] giveMaterials = (int[]) aTempData.get(16);
int[] giveCounts = (int[]) aTempData.get(17);

for (int l = 0; l < giveMaterials.length; l++) {
L1ItemInstance item = ItemTable.getInstance().createItem(giveMaterials[l]);

if (item.isStackable()) {////TODO 可重疊
item.setCount(giveCounts[l]);//TODO 數量
} else {
item.setCount(1);
}

if (item != null) {
isGet = true;
if (pc.getInventory().checkAddItem(item, (giveCounts[l])) == L1Inventory.OK) {
pc.getInventory().storeItem(item);
} else {
L1World.getInstance().getInventory(pc.getX(), pc.getY(),
pc.getMapId()).storeItem(item);
}

pc.sendPackets(new S_ServerMessage(143, npc.getNpcTemplate().get_name(),item.getLogName()));
}
}
}

//TODO 紀錄任務
if (((Integer)aTempData.get(18)).intValue() != 0 && ((Integer)aTempData.get(19)).intValue() != 0 && (isGet || isCreate)) {
pc.getQuest().set_step(((Integer) aTempData.get(18)).intValue(), ((Integer) aTempData.get(19)).intValue());
}

//TODO 顯示對話檔
if ((String[]) aTempData.get(21) != null && (isGet || isCreate)) {
pc.sendPackets(new S_NPCTalkReturn(oid, (String) aTempData.get(20), (String[])aTempData.get(21)));
return true;
} else if (aTempData.get(20) != null && (isGet || isCreate)) {
pc.sendPackets(new S_NPCTalkReturn(oid, (String) aTempData.get(20)));
return true;
} else {
pc.sendPackets(new S_NPCTalkReturn(oid, ""));
return true;
}
//TODO 顯示對話檔
}
}
return false;
}

private static void getData() {
java.sql.Connection con = null;
try { 
con = L1DatabaseFactory.getInstance().getConnection(); 
Statement stat = con.createStatement();
ResultSet rset = stat.executeQuery("SELECT * FROM william_npc_quest");
ArrayList<Object> aReturn = null;
String sTemp = null;
if (rset != null)
while(rset.next()) {
aReturn = new ArrayList<Object>();
aReturn.add(0, new Integer(rset.getInt("npcid")));//TODO NPC編號
sTemp = rset.getString("action");
aReturn.add(1,sTemp);
aReturn.add(2, new Integer(rset.getInt("checkLevel")));//TODO 確認等級
aReturn.add(3, new Integer(rset.getInt("checkClass")));//TODO 確認職業
aReturn.add(4, new Integer(rset.getInt("checkPoly")));//TODO 確認變身
aReturn.add(5, new Integer(rset.getInt("checkHaveQuestId")));//TODO 確認任務編號
aReturn.add(6, new Integer(rset.getInt("checkHaveQuestOrder")));//TODO 確認任務流程
aReturn.add(7, new Integer(rset.getInt("notHaveQuestId")));//TODO 確認任務編號
aReturn.add(8, new Integer(rset.getInt("notHaveQuestOrder")));//TODO 確認任務流程

if (rset.getString("checkItem") != null && !rset.getString("checkItem").equals("") && !rset.getString("checkItem").equals("0"))//TODO 確認道具
aReturn.add(9, getArray(rset.getString("checkItem"), TOKEN, 1));
else 
aReturn.add(9, null);

if (rset.getString("checkItemCount") != null && !rset.getString("checkItemCount").equals("") && !rset.getString("checkItemCount").equals("0"))//TODO 確認道具數量
aReturn.add(10, getArray(rset.getString("checkItemCount"), TOKEN, 1));
else 
aReturn.add(10, null);

if (rset.getString("notHaveItem") != null && !rset.getString("notHaveItem").equals("") && !rset.getString("notHaveItem").equals("0"))//TODO 確認道具
aReturn.add(11, getArray(rset.getString("notHaveItem"), TOKEN, 1));
else 
aReturn.add(11, null);

if (rset.getString("notHaveItemCount") != null && !rset.getString("notHaveItemCount").equals("") && !rset.getString("notHaveItemCount").equals("0"))//TODO 確認道具數量
aReturn.add(12, getArray(rset.getString("notHaveItemCount"), TOKEN, 1));
else 
aReturn.add(12, null);

if (rset.getString("material") != null && !rset.getString("material").equals("") && !rset.getString("material").equals("0"))//TODO 確認道具
aReturn.add(13, getArray(rset.getString("material"), TOKEN, 1));
else 
aReturn.add(13, null);

if (rset.getString("materialCount") != null && !rset.getString("materialCount").equals("") && !rset.getString("materialCount").equals("0"))//TODO 確認道具數量
aReturn.add(14, getArray(rset.getString("materialCount"), TOKEN, 1));
else 
aReturn.add(14, null);

aReturn.add(15, new Integer(rset.getInt("justCheckMaterial")));//TODO 只確認道具、不刪除確認的道具

if (rset.getString("GiveItem") != null && !rset.getString("GiveItem").equals("") && !rset.getString("GiveItem").equals("0"))//TODO 給予道具
aReturn.add(16, getArray(rset.getString("GiveItem"), TOKEN, 1));
else 
aReturn.add(16, null);

if (rset.getString("GiveItemCount") != null && !rset.getString("GiveItemCount").equals("") && !rset.getString("GiveItemCount").equals("0"))//TODO 給予道具數量
aReturn.add(17, getArray(rset.getString("GiveItemCount"), TOKEN, 1));
else 
aReturn.add(17, null);

aReturn.add(18, new Integer(rset.getInt("saveQuestId")));//TODO 紀錄任務編號
aReturn.add(19, new Integer(rset.getInt("saveQuestOrder")));//TODO 紀錄任務流程

if (rset.getString("ShowHtml") != null && !rset.getString("ShowHtml").equals(""))
aReturn.add(20, new String(rset.getString("ShowHtml")));//TODO 顯示對話檔
else 
aReturn.add(20, null);

if (rset.getString("ShowHtmlData") != null && !rset.getString("ShowHtmlData").equals(""))
aReturn.add(21,getArray(rset.getString("ShowHtmlData"), TOKEN, 2));//TODO 顯示對話內容
else 
aReturn.add(21, null);

if (rset.getString("ShowNotHaveHtml") != null && !rset.getString("ShowNotHaveHtml").equals(""))
aReturn.add(22, new String(rset.getString("ShowNotHaveHtml")));//TODO 顯示對話檔
else 
aReturn.add(22, null);

if (rset.getString("ShowNotHaveHtmlData") != null && !rset.getString("ShowNotHaveHtmlData").equals(""))
aReturn.add(23,getArray(rset.getString("ShowNotHaveHtmlData"), TOKEN, 2));//TODO 顯示對話內容
else 
aReturn.add(23, null);

aData.add(aReturn);
}
if(con != null && !con.isClosed())
con.close();
}
catch(Exception ex){}
}

private static Object getArray(String s,String sToken,int iType) {
StringTokenizer st = new StringTokenizer(s,sToken);
int iSize = st.countTokens();
String  sTemp = null;

if(iType == 1) {
int[] iReturn = new int[iSize];
for(int i = 0;i < iSize; i++) {
sTemp = st.nextToken();
iReturn = Integer.parseInt( sTemp );
}
return iReturn;
}

if(iType == 2) {
String[] sReturn = new String[iSize];
for(int i = 0; i < iSize; i++) {
sTemp = st.nextToken();
sReturn = sTemp;
}
return sReturn;
}

if(iType == 3) {
String sReturn = null;
for(int i = 0;i < iSize; i++){
sTemp = st.nextToken();
sReturn = sTemp;
}
return sReturn;
}
return null;
}
}




新增william_npc_action資料庫



QUOTE:
william_npc_action (與NPC對話時顯示的對話檔)。
npcid判斷NPC
checkLevel判斷等級(0 = 不判斷)
checkClass判斷職業(0 = 不判斷、1 = 王族、2 = 騎士、3 = 法師、4 = 妖精、5 = 黑妖、6 = 龍騎士、7 = 幻術師)
checkPoly判斷變身(0 = 不判斷)
checkQuestId判斷任務編號 (0 = 不判斷,與checkQuestOrder相對應)
checkQuestOrder判斷任務流程 (0 = 不判斷,與checkQuestId相對應)。
checkItem判斷攜帶的物品 (空值 = 不判斷,複數用,隔開,與checkItemCount相對應)
checkItemCount判斷攜帶的物品數量 (空值 = 不判斷,複數用,隔開,與checkItem相對應)
notHaveItem判斷沒有攜帶的物品 (空值 = 不判斷,複數用,隔開,與notHaveItemCount相對應)
notHaveItemCount判斷沒有攜帶的物品數量 (空值 = 不判斷,複數用,隔開,與notHaveItem相對應)
ShowHtml顯示對話檔
ShowHtmlData顯示對話檔內容


新增william_npc_quest資料庫
QUOTE:
william_npc_quest (設定兌換任務)


npcid判斷NPC

action判斷按下的對話檔選項

checkLevel判斷等級

checkClass判斷職業

checkPoly判斷變身

checkHaveQuestId判斷有此任務編號

checkHaveQuestOrder判斷有此任務流程

notHaveQuestId判斷沒有此任務編號

notHaveQuestOrder判斷沒有此任務流程

checkItem判斷擁有的道具

checkItemCount判斷擁有的道具數量

notHaveItem判斷不能攜帶的道具

notHaveItemCount判斷不能攜帶的道具數量

material兌換的材料

materialCount兌換的材料數量

justCheck是否只進行判斷兌換的材料、不給道具(1 = 只進行判斷)

GiveItem給予道具

GiveItemCount給予道具的數量

saveQuestId紀錄任務編號

saveQuestOrder紀錄任務流程

ShowHtml顯示對話檔

ShowHtmlData顯示對話檔內容

ShowNotHaveHtml沒有攜帶判斷的道具時顯示的對話檔(對應checkItem、checkItemCount)

ShowNotHaveHtmlData沒有攜帶判斷的道具時顯示的對話檔內容


文章出處  浪漫物語網路社區

沒有留言:

張貼留言