2013年6月8日 星期六

【Java教學】william系统(任務製作)

聲明william系統作者是williamchen,不知道名字說對沒有?
抱歉喔!真的找到作者了!應該是這個吧
我只是把它整合到REV853來!


[size=3]大家實驗下有沒有什麼問題!
畢竟新版本變動太大了!
很多地方不知道改得對不對!


我把變身套裝重新修改了,增加了個MR選項!!
所以要重新下!



步驟1(兌換任務): 修改C_RequestNPCAction.java

//在程式的開頭加上這一行

import java.util.ArrayList;//  add  william-兌換物品1/2

// 找出if(s.equalsIgnoreCase(\"buy\") , 然後以底下的code取代之


//  add    william-兌換物品2/2
    ArrayList aReturn = l1j.william.misc.forRequestNPCAction(s, pc);

    if( 1==((Integer)aReturn.get(0)).intValue() )
    {
     if( aReturn.get(1)!=null )
      htmlid = (String) aReturn.get(1);
     if( aReturn.get(2)!=null )
       htmldata = (String[]) aReturn.get(2);
     
     if( aReturn.get(3)!=null )
      materials = (int[])aReturn.get(3);
     if( aReturn.get(4)!=null )
      counts = (int[])aReturn.get(4);
     if( aReturn.get(5)!=null )
      createitem = (int[])aReturn.get(5);
     if( aReturn.get(6)!=null )
      createcount = (int[])aReturn.get(6);
    }else if (s.equalsIgnoreCase(\"buy\")) {
//end



步驟2(武器魔法): 修改 L1Attack.java

1//L1Attack.java程式的開頭加上這一行 ,加在package之後
    import java.util.ArrayList;//end  william-攻擊plugin的功能 1/4

2 找到 private static Logger _log = Logger.getLogger(L1Attack.class.getName());
    之後加上這一行  
//  add    william-攻擊plugin的功能 2/4
  private ArrayList aPlugin = null;
//end
3 找到public L1Attack(L1Character attacker, L1Character target) {
     ....
    }
下麵加上
   //    add    william-攻擊plugin的功能 3/4
    aPlugin = l1j.william.misc.forL1AttackPlugin(_calcType,attacker, target);
//end
4 找到public void Commit() {
    之後加上
//    add    william-攻擊plugin的功能 4/4
    try{
       if( aPlugin!=null ){
        if( aPlugin.get(0)!=null )
          _isHit = ((Boolean)aPlugin.get(0)).booleanValue();
        if( aPlugin.get(1)!=null )
          _damage += ((Integer)aPlugin.get(1)).intValue();
        if( aPlugin.get(2)!=null )
          _drainMana += ((Integer)aPlugin.get(2) ).intValue();
        
       }  
      }catch(Exception ex){} 
//end



步驟3(成套變身): 修改L1ArmorSet.java
1》找出
       static {
    L1ArmorSetImpl impl;
  接下來加上
//  add    william-成套變身1/2    
    L1ArmorSetImpl impl;
    ArrayList aC_ArmorSetData = l1j.william.misc.getC_ArmorSetData();
    ArrayList aTempData = null;
    for(int i=0;i<aC_ArmorSetData.size();i++ ) {
      try{
      aTempData = (ArrayList) aC_ArmorSetData.get(i);
      impl = new L1ArmorSetImpl((int[])aTempData.get(0) );
      impl.addEffect(new PolymorphEffect( ((Integer) aTempData.get(1)).intValue() ));
      impl.addEffect(new StatBonusEffect(((Integer) aTempData.get(4)).intValue(), ((Integer) aTempData.get(5)).intValue(), ((Integer) aTempData.get(6)).intValue(), ((Integer) aTempData.get(7)).intValue(), ((Integer) aTempData.get(8)).intValue(), ((Integer) aTempData.get(9)).intValue()));
      //對應上面StatBonusEffect(int str, int dex, int con, int wis, int cha, int intl)
      impl.addEffect(new AcHpMpBonusEffect(((Integer) aTempData.get(10)).intValue(), ((Integer) aTempData.get(11)).intValue(), ((Integer) aTempData.get(12)).intValue(), ((Integer) aTempData.get(13)).intValue(), ((Integer) aTempData.get(14)).intValue(), ((Integer) aTempData.get(15)).intValue()));
      //對應上面AcHpMpBonusEffect(int ac, int addHp, int addMp, int regenHp, int regenMp, int addMr)
      impl.addEffect(new DefenseBonusEffect(((Integer) aTempData.get(16)).intValue(), ((Integer) aTempData.get(17)).intValue(), ((Integer) aTempData.get(18)).intValue(), ((Integer) aTempData.get(19)).intValue(), ((Integer) aTempData.get(20)).intValue()));
      //對應上面DefenseBonusEffect(int defense_fire, int defense_wind, int defense_water, int defense_earth, int defense_magic)
      impl.addEffect(new ResistBonusEffect(((Integer) aTempData.get(21)).intValue(), ((Integer) aTempData.get(22)).intValue(), ((Integer) aTempData.get(23)).intValue(), ((Integer) aTempData.get(24)).intValue()));
      //對應上面ResistBonusEffect(int freeze, int sleep, int stan, int stone)
      _allSet.add(impl);      
      }catch(Exception ex){ex.printStackTrace();}
    }
//  end  william-成套變身1/2    



2  L1ArmorSet.java 最後一行加上
// william-成套變身2/2
class ResistBonusEffect implements L1ArmorSetEffect {
  private final int _freeze;
  private final int _sleep;
  private final int _stan;
  private final int _stone;

  public ResistBonusEffect(int freeze, int sleep, int stan, int stone) {
    _freeze = freeze;
    _sleep = sleep;
    _stan = stan;
    _stone = stone;
    
  }

  @Override
  public void giveEffect(L1PcInstance pc) {
    pc.add_regist_freeze(_freeze);
    pc.addRegistSleep(_sleep);
    pc.addRegistStan(_stan);
    pc.addRegistStone(_stone);
  }

  @Override
  public void cancelEffect(L1PcInstance pc) {
    pc.add_regist_freeze(-_freeze);
    pc.addRegistSleep(-_sleep);
    pc.addRegistStan(-_stan);
    pc.addRegistStone(-_stone);
  }
}

class DefenseBonusEffect implements L1ArmorSetEffect {
  private final int _defense_fire;
  private final int _defense_wind;
  private final int _defense_water;
  private final int _defense_earth;
  private final int _defense_magic;

  public DefenseBonusEffect(int defense_fire, int defense_wind, int defense_water, int defense_earth, int defense_magic) {
    _defense_fire = defense_fire;
    _defense_wind = defense_wind;
    _defense_water = defense_water;
    _defense_earth = defense_earth;
    _defense_magic = defense_magic;
  }

  @Override
  public void giveEffect(L1PcInstance pc) {
    pc.addFire(_defense_fire);
    pc.addWind(_defense_wind);
    pc.addWater(_defense_water);
    pc.addEarth(_defense_earth);
    pc.addMr(_defense_magic);
  }

  @Override
  public void cancelEffect(L1PcInstance pc) {
    pc.addFire(-_defense_fire);
    pc.addWind(-_defense_wind);
    pc.addWater(-_defense_water);
    pc.addEarth(-_defense_earth);
    pc.addMr(-_defense_magic);
  }
}
//william-成套變身2/2 END


步驟4(使用物品招怪): 找出C_RequestItemUSe.java 

找到下麵public C_RequestItemUSe(....) 這個method
  加在itemId = l1iteminstance.getItem().getItemId(); 這一行之後

  //      add    william-物品召怪
      l1j.william.misc.forRequestItemUSe(client,l1iteminstance);      
//end



步驟5 修改L1Magic.java
1 L1Magic.java程式的開頭加上這一行 ,加在package之後
   import java.util.ArrayList;//add    william-攻擊plugin的功能 1/5

2
  找到 private static Logger _log = Logger.getLogger(L1MagicInstance.class
      .getName());
    之後加上這一行  
  //  add    william-攻擊plugin的功能 2/5
  private ArrayList aPlugin = null;
//end

3》找到 private int getLeverage() {
    return _leverage;
  }
下麵加上
//  add    william-攻擊plugin的功能  
  public boolean _isHit = false; // 攻擊魔法が成功したか(ERによる回避がある。)
//  end
4》找出 
    public L1Magic(L1Character attacker, L1Character target) {
     ....
    }
    括號\"}\"之前加上這一行
//    add    william-攻擊plugin的功能 3/5
    aPlugin = l1j.william.misc.forL1MagicPlugin(_calcType,attacker, target);
//end
5》找出 
public void commit(int damage, int drainMana) {
    之後加上
//    add    william-攻擊plugin的功能 5/5
    try{
       if( aPlugin!=null ){
        if( aPlugin.get(0)!=null )
          _isHit = ((Boolean)aPlugin.get(0)).booleanValue();
        if( aPlugin.get(1)!=null )
          damage += ((Integer)aPlugin.get(1)).intValue();
        if( aPlugin.get(2)!=null )
          drainMana += ((Integer)aPlugin.get(2) ).intValue();
           }
      }catch(Exception ex){} 
//end
6 找出 
  public boolean CalcProbabilityMagic(int skillid) {
    之後加上
//    add    william-攻擊plugin的功能 4/5
    try{
       if( aPlugin!=null && aPlugin.get(3)!=null )
        return ((Boolean)aPlugin.get(3)).booleanValue();
      }catch(Exception ex){}
//end


步驟6: L1MonsterInstance.java

1》怪物發現你的講話):
   找出public void searchTarget() 這個method
   再找出
    if (targetPlayer != null) {
   接下來加上底下這一行
//      add    william-怪物發現你的講話
      l1j.william.misc.forL1MonsterTalking(this,1);
//end
2(武器進化系統):
   找出
  class Death extends Thread 
   然後再找出 int exp = get_exp(); 這一行
   接下來加上底下這一行    
//  add    william-武器進化系統
         l1j.william.misc.forL1MonsterTalking(L1MonsterInstance.this,3);
         l1j.william.misc.addWeaponExp(player , exp);      
//END

步驟7(走路時,特定物品招怪): C_RequestMoveChar.java
   找出 L1PcInstance user = client.getActiveChar(); 
   接下來加上底下這一行
//    add    william-走路時,特定物品招怪
    l1j.william.misc.forCRequestMoveChar(client);
//end


步驟8: L1NpcInstance.java中找出這一段

1(怪物逃跑講話):
   找出
  if (get_passispeed() > 0) 
  {
   在裡面加上
   //        add    william-怪逃跑講話
        l1j.william.misc.forL1MonsterTalking(this,4);
//end

2(怪物攻擊講話):
   找出 public void attackTarget 這個method
   找出
  if (attack.calcHit()) {
   將這兩行取代成
//      add    william-怪物攻擊講話
      l1j.william.misc.forL1MonsterTalking(this,2);  
//end
// 怪物講話比較彈性,有很多地方可以加


步驟9(方便增加對換NPC): NpcTable.java

1 找出
    private NpcTable() {
     _npcs = new HashMap();

    之後加上
//    add    william-方便增加對換NPC
    try{
       l1j.william.misc.forNpcTable(_npcs);
      }catch(Exception ex){ 
       ex.printStackTrace();
      }
//end

步驟10(方便增加對換NPC) NpcSpawnTable.java
    找出 

  private NpcSpawnTable() {
    FillNpcSpawnTable();

    之後加上
//    add    william-方便增加對換NPC
    int[] iGetReturn = l1j.william.misc.forNpcSpawnTable(_spawntable);
    if (iGetReturn[1] > _highestId)
    _highestId = iGetReturn[1];
//end

步驟11(方便增加對換NPC): 
    L1MerchantInstance.java public void onTalkAction(L1PcInstance player)
    找出
   String[] htmldata = null;
    之後加上
//    add    william-方便增加對換NPC
    if( l1j.william.misc.forFirstTimeTalking(player,npcid , objid) )
        return;
//end


附加步驟12L1Character.java

搜尋public boolean isAttackPosition(int x, int y, int range) {

在上面加入

//  武升    
  public void broadcastPacketToAll(ServerBasePacket packet) {
    Collection<L1PcInstance>al1pcinstance = L1World.getInstance().getAllPlayers();
      _log.finest((new StringBuilder()).append(\"players to notify : \")
              .append(al1pcinstance.size()).toString());
      for (L1PcInstance l1pcinstance1 : al1pcinstance ){
         if (l1pcinstance1 instanceof L1PcInstance) {
              L1PcInstance l1pcinstance = l1pcinstance1;
              if (l1pcinstance.getNetConnection() != null)
                  l1pcinstance.sendPackets(packet);
          }
      }
  }
//武升



步驟13: 將程式 src/l1j/william/*.java 放到相對應的目錄下 


步驟14: 匯入所有的sql檔案(檔案在sql\\*.html)

步驟15: 進行html吃檔(檔案在text\\*.html)



william系統相關介紹說明:
物品兌換的資料表為william william_2

物品附加魔法的資料表為william2

成套變身的資料表為william3, 我的範例為: 若穿上內衣以及抗魔法斗篷會變身成狼人,並伴隨屬性增加

特殊物品觸發怪物的資料表為 william4 , 我的範例為: 若身上帶有解毒藥水, 會出現史巴托來喝掉你身上的物品

特殊物品觸發怪物的資料表為 william5 , 我的範例為: 若身上帶有肉, 且在布魯迪卡洞點兩下使用,會出現史巴托

怪物說話的資料表為william6 , 我的範例為: 打史巴托的時候, 他會跟你說\"打死你\" XD

武器進化的資料表為william7, william8 , 我的範例為: 裝備著銀長劍找npc(在潘朵拉附近) 進行升級,但是要付出一些金錢 

簡單新增兌換NPC的資料表為 william9

魔法攻擊plugin的資料表為 william10

順便提一下,資料庫不做I18N(效率考量)且資料庫的設定改了,系統要重開哦

我的開發環境 java 6 , eclipse 3.3 , mysql 5.1 , navicat mysql , windows xp 
歡迎跟我討論設計手法,謝謝
特別感謝ffsaga , andy52005

資料表簡單解釋

table william { 兌換任務

command: 存放html檔案\"action\"的值, 當使用者用滑鼠選擇想要兌換的物品,就會觸發此命令
htmlid: 代表系統要使用哪種html 跟玩家溝通
htmldata: 代表html對話內容的置換
materials: 代表玩家要準備什麼東西, 若是多種物品請用逗號區隔
counts:  materials搭配, 代表此物品需要的數量, 多種請用逗號區隔,但務必一對一跟materials相應
createitem: 兌換的物品, 若是多種可以用逗號區隔
createcount: 兌換的數量,若是多種可以用逗號區隔, 但務必一對一跟createitem相應
activated_leve: 等級限制,若不限制填0

activated_timestart: 
activated_timeend:
activated_type:    
       type=1 ,
         activated_timestart填入日期,: 20071020
         activated_timeend: 填入日期,: 20071030
         代表只有在 10/20 10/30 之間才能觸發
       type=2 ,
         activated_timestart填入時間(24hr),: 9
         activated_timeend: 填入時間(24hr),:23 
         代表每天9點到23點之間才能觸發
       activated_timestartactivated_timeend都是null, 
       代表不做時間限制(此時type是甚麼都不重要)
islimit: 若為1代表只能觸發一次 , 下次再來會被拒絕, 若非1, 代表可以連續觸發任務 
justcheck:
     若為1代表只會檢查身上有沒有 materials 所指定的東西 , 並不會兌換物品,
     若身上有指定物品有則觸發 html 裡面所指定的任務
enable: 若為1代表此資料有效, 1則系統不予理會

}

table william_2 { islimit 設定為1時候, 記載使用者有執行此任務,避免連續觸發
         使用者這不用設定此table
...
}

table william2 { 武器附加魔法
weaponid: 武器編號
skillid: 技能編號
areaskill: 此技能影響的範圍
damage:  此技能傷害值
who:   0就會傷害自己, 0就傷害敵人
skillrandom: 魔法發動機率
}


table william3 { 成套變身
sets:   防具成套設定填入防具代號, 可以填入多個 , 用逗號\",\" 區隔
polyid:  變身成哪種怪請參考polymorphs 這個資料表的代號
SkillIconGFX1: 這個沒用請一律填寫35
SkillIconGFX2: 這個好像有用,若不清楚請填寫7200, 這好像跟荒神底下魔法陣有關
str: 當變身時候能力值增加
.... : 其他也是相關能力值增加
}

table william4{ 若玩家身上有特定物品,走路時,會隨機招換怪出來
materials: 代表玩家要準備什麼東西, 若是多種物品請用逗號區隔
counts:  materials搭配, 代表此物品需要的數量, 多種請用逗號區隔,但務必一對一跟materials相應
destroy: 當檢查有符合的物品,是否刪除
random:  呼叫怪的成功率
monster_id: 怪的ID
}

table william5{ 若玩家在指定的矩形還有指定的地圖上使用materials指定的物品(點兩下該物品),就招怪
materials: 代表玩家要準備什麼東西, 若是多種物品請用逗號區隔
counts:  materials搭配, 代表此物品需要的數量, 多種請用逗號區隔,但務必一對一跟materials相應
destroy: 當檢查有符合的物品,是否刪除
monster_id: 怪的ID
location_minx: 矩形x的最小值
location_miny: 矩形y的最小值
location_maxx: 矩形x的最大值
location_maxy: 矩形y的最大值
map_id:     地圖ID
}

table william6{
npc_id:  怪物ID
random:  講話機率
talktext: 講話內容
type:   1: 怪物搜尋狀態 2:攻擊狀態 3: 死亡時候講的話 4: 逃跑講得話
}

table william7{ table玩家不用維護
weapon_oid:  玩家身上的武器物件ID(Object ID), 不是武器ID
exp:     此武器目前經驗值
}

table william8{ 設定哪些武器可以升級
weapon_id:   武器ID
upgrade_exp:  升級必須的經驗值
upgrade_weapon_id: 升級之後變成哪種武器ID
materials: 代表玩家要準備什麼東西, 若是多種物品請用逗號區隔
counts:  materials搭配, 代表此物品需要的數量, 多種請用逗號區隔,但務必一對一跟materials相應
}

table william9{ 方便新增兌換任務的NPC
npcid:  自訂NPC ID , 請不要跟別的NPC ID衝突
type:  請填 L1Merchant
gfxid:  這我不知道是甚麼, 可能是人物的造型吧,不知道請填 98
name:  NPC名稱
htmlid: 觸發此NPC對話的 html , 當然玩家要有吃此檔案
htmldata: NPC講話的內容, 若要拆成多段變數, 以便對應html檔的 <var src=\"#0\">
     請用\",\"來區隔, ps . 因此講話內容, 請避開逗號這個字 \",\" , 因為是分段用的
location_x:  NPC 所在的地方
location_y:
map
}

table william10{ 魔法攻擊plugin
oid:     唯一值, 判別用.
class_name: plug-in 類別 , 改類別必須繼承 l1j.william.L1MagicPlugin
}

table william11{
除了多了一個欄位 price 之外, 其他欄位都跟 character_items
}


沒有留言:

張貼留言