Recipe Item System - System ghép đồ

Thảo luận trong 'World Editor' bắt đầu bởi vuongkkk, 2/2/11.

  1. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Giới thiệu hệ thống:
    - Các bạn ai cũng biết rằng rất nhiều map cần đến việc ghép đồ, nếu không muốn nói là đa số... Nhưng thực sự thì mình không ưng cái nào cả ngoài cái của Artificial.
    - Nhưng system đó chỉ giúp được bạn ghép đồ 1 cách đơn giản. Nâng cao thì còn thiếu nhiều
    - Cuối cùng mình đã quyết làm 1 hệ thống recipe item cho tất cả mọi người, nhất là map maker Việt và nay đã hoàn thiện.
    - Ghép đồ như dota luôn !!!!!! Full hòm cũng chiến :D

    How it work – Cách thức hoạt động
    Để nắm được cách config cho đúng và cách dùng system bạn cần biết về cách nó hoạt động:
    - Để mua đồ trong shop mặc dù hòm đồ đã đầy thì đồ đó phải là dạng đồ power up, tạm gọi nó là đồ giả. Vì vậy về căn bản 1 đồ sẽ cần làm 2 item (1 thật và 1 giả để trong shop = Powerup)
    - Khi mua đồ:
    + Nếu có đủ đồ thành phần tính cả đồ vừa mua thì sẽ tiến hành ghép luôn
    + Nếu ko có đủ thì sẽ tạo 1 món đồ thật dưới chân
    - Khi nhặt đồ:
    + Dù có full hòm đồ vẫn ghép được đồ dù đồ dưới đất là đồ thật, ko phải dạng powerup
    + Thực chất là đáng ra là ko có gì xảy ra được và hiện lên thông báo inventory is full
    + Nhưng do chỉnh Follow - Item range ngắn nên unit đi đến tận nơi mới có thông báo inventory
    + Nhưng do mình config thì sẽ làm mất thông báo hiện inventory full vì giờ cũng ko cần thiết có cái đó nữa. Còn nếu làm thông báo giả = SimError thì sẽ có thể bị đè lên các thông báo sẵn có của War3 trong Constant

    How to config - Chỉnh để sys hoạt động chuẩn xác
    - Chỉnh Gameplay Constants -> Follow range - Items = số bạn muốn
    - Chỉnh RecipeTrigger -> FOLLOW_ITEM_RANGE = Follow range - Items mà bạn chỉnh bên trên
    - Chỉnh Game Interface -> Sound - Inventory is full = Animation - Bolt
    - Chỉnh Game Interface -> Text - Message - Inventory is full = <Space>
    - Chỉnh MAX_NUM là số lượng thành phần tối đa cho 1 công thức trong map của bạn
    - Item giả phải là item dạng power up thuộc class power up luôn và model là ko có gì (.mdl)
    - Item thật thì class nào cũng OK nhưng đừng đặt ở class powerup
    - Item charge thì đặc biệt phải để trong class charge cả item giả lẫn item thật thì mới có thể tăng charge khi ghép hoặc mua. Ko muốn để tăng charge thì đặt chỗ khác
    - Item giả ko dùng để mua đồ mà chỉ để viết tooltip vào và trưng ra cùng thông báo ko cần mua item này để ghép đồ thì để trong class Artifact

    How to use - Cách dùng
    - Import 4 trigger: Table, RecipeItemSys, RecipeTrigger, initRecipes vào map
    - Interface:
    RIS_Result
    Là để chứa các thông số của item sản phẩm sau khi ghép
    [spoil]
    PHP:
        readonly integer rawcode
        readonly integer charge
                       boolean enabled    
    // giúp người dùng có thể tùy chỉnh xem có thể ghép ra được món đồ này hay ko kể cả có đủ đồ thành phần
        
        
    static method create takes integer itemidinteger itemcharge returns RIS_Result
            
    // item id là raw code của item sản phẩm, charge là số lượng charge @@
    [/spoil]


    RIS_Recipe
    Là để chứa các thông tin của các món đồ thành phần dùng để ghép
    [spoil]
    PHP:
        readonly RIS_Result  result  // lưu kết quả
        
    readonly integer count      // lưu số item cần để ghép (ko tính charge)
        
        
    static method create takes RIS_Result r returns RIS_Recipe
        
    // result chính là để chỉ ra item cuối cùng mà công thức này tạo thành

        
    method add takes integer id1integer id2integer c returns nothing
        
    // id1 là rawcode item thật
        // id2 là rawcode item giả và có thể để là 0 nếu đồ đó ko có ở trong shop ko cần phải mua
        // c    là số lượng charge cần để ghép. Nếu ko phải item dạng charge thì để = 0
        // id1 và id2 luôn phải đi thành cặp. Nếu 1 id1 vốn cặp với id2 khi add mà còn có id2 khác cũng cặp với id1 thì sẽ gây lỗi hệ thống
        
        
    method addMulti takes integer numinteger id1integer id2integer c returns nothing
            
    // num là số lượng item (ko phải số lượng charge) cùng loại cần
            // các thông số còn lại giống như trên
            // Nếu công thức có nhiều item giống nhau để ghép thì dùng lệnh này thay vì dùng nhiều lần lệnh add

        
    method createComponent takes real xreal ycode c returns nothing
        
    // cái này dùng để tạo ra các món đồ thật trong công thức này
        // x, y là tọa độ mà các item thành phần sẽ rớt ra
        // c là function mà code trong đó sẽ dùng để thao tác với từng món đồ thành phần sau khi tạo ra
        // trong function c thì dùng bj_lastCreatedItem để thao tác với item
    [/spoil]

    RIS_Combiner
    Là struct để tìm công thức đúng là kiểm tra có đủ item cần chưa cũng như giúp thực hiện việc ghép đồ
    [spoil]
    PHP:
        static method validate takes item it returns boolean
        
    // có tác dụng để tạo kiểm tra item it có thể dùng để ghép được hay ko
        // lệnh này buộc phải thực hiện đầu tiên!

         
    static method add takes item it returns nothing
            
    // Thêm vào 1 item vào quá trình kiểm tra đồ thành phần
        // Không được add trùng vì sẽ làm hỏng quá trình kiểm tra

         
    static method addInv takes unit u returns nothing
        
    // Thêm tất cả đồ trong hòm của unit u vào quá trình kiểm tra
        // Không được add trùng vì sẽ làm hỏng quá trình kiểm tra

        
    static method create takes RIS_Result r returns RIS_Recipe
        
    // result chính là để chỉ ra item cuối cùng mà công thức này tạo thành
    [/spoil]

    RIS_RecipeItem
    Là struct để đăng kí cặp item giả và thật để mua trong shop khi full hòm.
    Nếu cặp item giả và thật đã có trong lúc đăng kí công thức thì ko cần phải đăng kí lại bằng cái này nữa!
    [spoil]
    PHP:
        static method createPair takes integer id1integer id2 returns nothing
        
    // id1 = rawcode item thật
        // id2 = rawcode item giả trong shop
    [/spoil]

    - RecipeItemSys : chỉ mang tính là công cụ lưu giữ và xử lý thông tin ghép đồ. Không có trigger bên trong
    - RecipeTrig mới là nơi xử lý các trường hợp xảy ra trong map. Đây là cái các cậu muốn custom thì vào xem. Có Comment hướng dẫn chỗ cho cách cậu edit code trong đó rồi. Thoải mái đi, miễn đúng chỗ
    - initRecipe: Các cậu vào đây học hỏi cách đăng kí 1 công thức để ghép đồ nhé ;)

    Advantage - Điểm mạnh
    - Ko lag, số lượng công thức ghép đồ nhiều và có thể tùy chỉnh để cho hiệu quả nhất với map của bạn ;) (max = 8912 / MAX_NUM)
    - 1 item có thể có nhiều công thức ghép
    - Tăng charge ghép đồ với charge item và kết quả cho ra có thể là charge item luôn
    - Đồ thành phẩm sau khi ghép có thể tách được (disassemble)
    - Dù 1 đồ có nhiều cách ghép hay 1 cách ghép cũng có thể disassemble chuẩn

    Disadvantage - Điểm yếu
    - Các cậu cần phải biết cách dùng vjass hoặc jass
    - Phải đọc hướng dẫn thì mới dùng được. Nếu dùng sai thì đừng đổ tại system tớ hoạt động ko chuẩn. Hãy xem lại hướng dẫn = tiếng Việt đó @@

    Change Log:

    Ver 2.1:
    • Thêm 1 số trường hợp có thể xảy ra khi ghép đồ mà ver trước bỏ sót
    • Thêm chức năng disassemble
    • Thêm chức năng hiển thị message khi cố mua item ko cần phải mua
    • Đã hoàn chỉnh việc ghép đồ như dota!
    Ver 2.0:
    • Code giờ gọn hơn, dễ nhìn hơn, có lẽ là nhanh hơn 1 chút nữa :D

    Đôi lời chia sẻ
    • Nếu anh em không cần đến chuyện ghép đồ khi hòm đồ full, thì hoàn toàn có thể dùng hệ thống ghép đồ , cái của Artificial.

    Link download map demo
    RIS - Recipe Item System 2.1 demo map
     
    Chỉnh sửa cuối: 28/11/12
    [Yami] thích bài này.
  2. DylandKyo

    DylandKyo Donkey Kong

    Tham gia ngày:
    28/10/10
    Bài viết:
    358
    Ôi = Jass àk, thế thì chịu @@. Pro nào vào nhận xét và sửa lỗi giúp bạn ấy đi nào. Để mình down map demo về test thử
     
  3. kindsitinh

    kindsitinh Mr & Ms Pac-Man

    Tham gia ngày:
    13/10/08
    Bài viết:
    265
    Nơi ở:
    Hà Nội
    Sao bạn ko viết = Tiếng Việt hết đi :| ... Trên Việt dưới ANh mình thấy nó hơi kỳ kỳ @@
     
  4. DylandKyo

    DylandKyo Donkey Kong

    Tham gia ngày:
    28/10/10
    Bài viết:
    358
    Àk cái system bạn do máy mình gà hay do System nhỉ? Mà zo lag lắm @@ đi dựt dựt ??
     
  5. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Cái này thì là do jass code lam = tieng A bạn ạ. Nếu bạn có jass tiếng V nhất định mình sẽ viết. Nhiều lúc đặt tên tiếng A thấy khó khó :D
    Còn tiếng Việt là mình GUI cho các bạn mà. Chả lẽ lại tiếng Anh nữa thì sao dùng system mình đc. Còn cách dùng mình đã thức cả đêm để viết. Hi vọng các bạn dùng đc.

    Quên mất mấy cái là
    - cần jass NewGenPack để lưu system vào map. (chính xác là cần jasshelper 0.A.2.B)
    - Raw code thì ctrl+D để thấy raw code của Item.
    - Và dùng cho warcaft 3 bản 1.24+
     
  6. kindsitinh

    kindsitinh Mr & Ms Pac-Man

    Tham gia ngày:
    13/10/08
    Bài viết:
    265
    Nơi ở:
    Hà Nội
    K . Ý mình nói là đoạn này
    PHP:
    //*   If you use HandleTable instead of Table, it is the same
    //* but it uses handles as keys, the same with StringTable.
    //*
    //*  You can use Table on structs' onInit  if the struct is
    //* placed in a library that requires Table or outside a library.
    //*
    //*  You can also do 2D array syntax if you want to touch
    //* mission keys directly, however, since this is shared space
    //* you may want to prefix your mission keys accordingly:
    ---------------------------
    EDIT : SR NHầm :D ... KO đọc kỹ
     
  7. KuKulKan

    KuKulKan T.E.T.Я.I.S

    Tham gia ngày:
    2/8/09
    Bài viết:
    629
    Nơi ở:
    Quận Thủ Đức, Thành phố Hồ Chí Minh
    Good job..keep going and happy new year :D
     
  8. maixuanem

    maixuanem Mr & Ms Pac-Man

    Tham gia ngày:
    22/8/10
    Bài viết:
    182
    Nơi ở:
    Tân Binh
    Note hộ ông Vương 1 cái nữa là system của ông ẻm có sử dụng Hàm SetItemUserData() và GetItemUserData(). Ai có dùng system này thì nên chú ý để tránh gây xung đột
     
  9. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Nếu ai có xung đột thiệt thì bảo mình để chuyển từ ItemUserData thành Table luôn cho tiện. Cũng không khó lắm vì mình lười với cả nghĩ là dùng kiểu đó nhanh hơn kiểu dùng Table
     
  10. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Hiện nay mình đang bí đoạn làm sao để có thể bắt được event khi 1 unit chuyển đồ cho unit khác. Help me, please !!! . Hiện dù full hòm đồ miến là đã nằm dưới đất vẫn ghép được đồ. Còn chưa bắt được event khi chuyển đồ từ unit này sang unit kia nên chưa hoàn thiện đc ghép đồ như dota
     
  11. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    0.0s timer sau khi "losses an item", kiểm tra (Boolean) "Item - Item Is Owned", là True thì item đang ở trong inventory của unit nào đó
     
  12. [Yami]

    [Yami] Donkey Kong

    Tham gia ngày:
    29/12/07
    Bài viết:
    313
    Nơi ở:
    Ha Noi, Vietnam,
    Yeah, mình làm được hệ thống mua đồ + combine giống dota với system của bạn rồi :x
    Anw, để đạt hiệu quả cao thì nên vào Game Interfere thay đổi đoạn "Inventory is full" thành " ", sau đó xài SimError để tạo thông báo Inventory Is Full để tránh dòng ý khi nhặt đồ dưới đất khi full đồ (khi combine được) ^^
     
  13. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Ừm, thế bạn làm lại hay dùng system mình vậy. Bạn đã làm được cái mua đồ trong shop khi full hòm chưa? và tích hợp nó luôn với system ghép đồ chưa ? Rồi thì mình không làm nữa, dùng của bạn luôn. Dạo này mình bận chút nên đợi 1 tuần nữa. Mình sẽ cải tiến system này để nó nhanh hơn, code gọn hơn và tích hợp luôn simError vào nữa nếu bạn chưa làm.
     
  14. [Yami]

    [Yami] Donkey Kong

    Tham gia ngày:
    29/12/07
    Bài viết:
    313
    Nơi ở:
    Ha Noi, Vietnam,
    Đây là System của bạn sau khi tích hợp SimError:
    Mã:
    //======================================================================================
    //
    //                 ItemRecipeSys
    //             ------------------
    //
    //      Version: 1.2
    //      Author:  vuongkkk
    //
    //
    //      Dung ItemRecipeSys nhu the nao?
    //      """""""""""""""""""""""""""""""
    //
    //  ++ Them cong thuc (recipes) de ghep do
    //  ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
    //      + Chuan bi
    //       - Tao moi 1 trigger va dat ten la "initRecipes"
    //       - Them Event - Map initialization
    //       - Chuyen sang dang text
    //       - Them vao function Trig_iniRecipes_Actions doan code 
    //          de chuan bi bien cho viec khoi tao:
    //
    //              local recipe r
    //              local grpRecipe grp
    //
    //      + Tao moi 1 group of Recipes chinh la tao moi 1 tap hop cac cong thuc
    //          ghep do de tao ra cung 1 loai do
    //
    //              set grp = NewGrpRecipe('ciri',0)
    //
    //          'ciri'  la raw code cua item se thu duoc sau khi ghep do
    //          0       la charge cua item sau khi ghep
    //          Neu la item dang charge thi can nhap 1 so luong ban muon o day
    //          Khong thi se de la 0 nhu dong code vi du o tren
    //      + Tao moi 1 cong thuc ghep do nhung chua co item nguyen lieu
    //
    //              set r = recipe.create()
    //
    //      + Them vao cong thuc 1 item nguyen lieu
    //       - Neu item la 1 charge item thi ta dung dong lenh
    //
    //              call Add2Recipe('hlst',1,r)
    //
    //          'hlst'  la raw code cua item se dung lam nguyen lieu de ghep do
    //          1       la charge cua item nguyen lieu khi ghep
    //          r       la cong thuc ma ta da tao ra truoc do
    //                  giup xac dinh item nguyen lieu nay la cua cong thuc nao
    //       - Neu item la 1 item dang thuong thi dong lenh giong nhu tren 
    //          nhung tham so dau vao thu 2 se de la 0 nhu cau lenh duoi day
    //
    //              call Add2Recipe('hlst',0,r)
    //
    //       - Neu item la 1 item dang thuong nhung can nhieu hon 1 item loai do
    //          thi dong lenh la
    //
    //              call Add2RecipeWithNum('belv',3,r)
    //
    //          'belv'  la raw code cua item se dung lam nguyen lieu de ghep do
    //          3       la so luong cua item nguyen lieu can khi ghep
    //          r       la cong thuc ma ta da tao ra truoc do
    //                  giup xac dinh item nguyen lieu nay la cua cong thuc nao
    //  * Note (Chu y):
    //      Neu item la 1 item dang thuong nhung can nhieu hon 1 item loai do
    //      thi nen dung nhu truong hop thu 3 noi tren thay vi nhieu dong lenh
    //      nhu dong lenh o truong hop 2. No se sai di cong thuc ghep do
    //      Ma dung nhu truong hop 3 se do mat cong viet (hoac copy) cua ban
    //      
    //      + Hoan tat 1 cong thuc ghep do voi dong lenh 
    //
    //              call grp.addRecipe(integer(r))
    //
    //  * Note (Chu y):
    //      Ban hoan toan co the ghep 1 do = nhieu cong thuc khac nhau
    //      Moi cong thuc co thanh phan khac nhau hoac 1 so thanh phan giong nhau
    //      Neu 2 cong thuc nhau hoan toan ma ban van them vao nhom cong thuc cho
    //      ra loai item do thi loi la chac chan (hoan toan sai lech so voi binh
    //      thuong => co van de ...). Vay doan code vi du se nhu sau:
    //
    //              set grp = NewGrpRecipe('belv',0)
    //              set r = recipe.create()
    //              call Add2RecipeWithNum('rag1',2,r)
    //              call grp.addRecipe(integer(r))
    //              set r = recipe.create()
    //              call Add2Recipe('rde1',0,r)
    //              call Add2Recipe('rag1',0,r)
    //              call grp.addRecipe(integer(r))
    //
    //      Y nghia doan code tren (theo dong):
    //
    //          Tao moi 1 nhom cac cong thuc cho ra ket qua "Boots of Quel'Thalas +6"
    //          Tao moi 1 cong thuc
    //          Them vao cong thuc vua moi tao 2 nguyen lieu thuoc cung loai "Slippers of Agility +3"
    //          Dua cong thuc vao nhom cong thuc cho ra ket qua "Boots of Quel'Thalas +6"
    //          Tao moi 1 cong thuc
    //          Them vao cong thuc vua tao nguyen lieu "Ring of Protection +2", so luong: 1
    //          Them vao cong thuc vua tao nguyen lieu "Slippers of Agility +3", so luong: 1
    //          Dua cong thuc vao nhom cong thuc cho ra ket qua "Boots of Quel'Thalas +6"
    //      Vay ta da co 2 cach ghep de ra do "Boots of Quel'Thalas +6"
    //      neu ban da thuc hien buoc chuan bi =]]
    //
    //  ++ Lay lai do nguyen lieu vua dung de ghep, xoa do da ghep duoc di
    //  ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
    //
    //              call DisassembleItem (i, u)
    //
    //          i   La item ket qua tu viec ghep do ma ra
    //          u   La unit se nhan lai nguyen lieu
    //          Neu dung la 
    //
    //              call DisassembleItem (i, null)
    //
    //          ko co unit nao nhan lai nguyen lieu, nguyen lieu roi ngay tai
    //          vi tri cua item ma ta vua pha ra de lay lai nguyen lieu
    //
    //  ++ Cho phep hay khong cho phep ghep de tao ra loai item nay nua 
    //  ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
    //
    //              EnableRecipeByResult takes integer resultID, boolean flag
    //
    //          resultID    loai do ta vo hieu hoa hoac kich hoat lai tac dung de ghep ra no
    //          flag        true neu muon kich hoat , false neu muon vo hieu hoa
    //
    //                  Them vao 1 map ItemRecipeSys ra sao ?
    //                  """"""""""""""""""""""""""""""""""""
    //
    //      3 buoc :
    //          - Them 3 thu vien gom Table, TriggerUtils, ItemRecipeSys.
    //          - Tao moi cac cong thuc nhu huong dan tren.
    //          - Chinh FOLLOW_ITEM_RANGE, PICK_ITEM_RANGE va 2 gia tri
    //              co y nghia tuong duong trong "Game Constants..."
    //
    //
    //                  Hon gi so voi cac thu vien ve ghep do khac ?
    //                  """"""""""""""""""""""""""""""""""""""""""""
    //
    //          - Ghep do duoc ca khi hom do full (chi khi da co item duoi dat =.=!)
    //          - So luong toi da cac cong thuc len den: 8190 / 6 = 1365
    //          - Ho tro ghep do tu` item dang charge cung nhu tao ra item dang charge
    //
    //
    //================================================================================================
    library ItemRecipeSys initializer Init requires Table, TriggerUtils
        globals
        // This constant must be equal with game constant in map
            constant real       FOLLOW_ITEM_RANGE = 50
            constant real       PICK_ITEM_RANGE = 150
            private string      SFX_PATH = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
    
    // ---------------  Dung thay doi phia ben duoi --------------------------------------
    // x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x
    // x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x
        // system variables
            private  hashtable      IRI
            private  hashtable      recipes
            private  Table          grpResult
            constant integer        MAX_INGRE_EACH_RECIPE = 6
            constant integer        iterate = MAX_INGRE_EACH_RECIPE+1
            private  integer array  recipeGetGrp
        endglobals
        
        
        //- 3 ham duoi day giup thao tac voi du lieu lien quan viec xac dinh item thuoc recipe nao
        private function IRIAddRecipe takes integer itemID, integer recipeID returns nothing
            local integer numRecipe
            if HaveSavedInteger(IRI, itemID,0) then
                set numRecipe = LoadInteger(IRI, itemID,0)
                set numRecipe = numRecipe + 1
            else
                set numRecipe = 1
            endif
                call SaveInteger(IRI, itemID,0,numRecipe)
                call SaveInteger(IRI, itemID, numRecipe, recipeID)
        endfunction
        
        private function IRICountRecipe takes integer itemID returns integer
            return LoadInteger(IRI, itemID,0)
        endfunction
        
        private function IRIGetRecipe takes integer itemID,integer no returns integer
            return LoadInteger(IRI, itemID,no)
        endfunction
    
        // Kiem tra hom do full hay ko
        function InventoryIsFull takes unit whichUnit returns boolean
            local integer index = 0
            local integer count = 0
            local integer size = UnitInventorySize(whichUnit)
            loop
                if not(UnitItemInSlot(whichUnit, index) == null) then
                    set count = count + 1
                endif
    
                set index = index + 1
                exitwhen index == size
            endloop
            if count == size then
                return true
            endif
            return false
        endfunction
        
        // la doi tuong chua thong tin cu the cua 1 cong thuc
        struct recipe
            private integer array items[MAX_INGRE_EACH_RECIPE]
            private integer array charges[MAX_INGRE_EACH_RECIPE]
            private integer       count     = 0
                    boolean       enable    = true
            
            method addItem2Recipe takes integer itm, integer charge returns nothing
                set .items[count] = itm
                set .charges[count] = charge
                set .count = .count + 1
            endmethod
            
            method operator [] takes integer i returns integer
                return items[i]
            endmethod
            
            method operator countItems takes nothing returns integer
                return .count
            endmethod
            
            method chargeOf takes integer i returns integer
                return charges[i]
            endmethod
            
            method operator result takes nothing returns integer
                return grpRecipe(recipeGetGrp[integer(this)]).result
            endmethod
            
            method operator chargeResult takes nothing returns integer
                return grpRecipe(recipeGetGrp[integer(this)]).chargeResult
            endmethod
            
        endstruct
    
        // la 1 doi tuong giup thao tac cac thong tin lien quan den nhom' cac cong thuc
        struct grpRecipe
                    integer count  = 0
                    integer result = 0
                    integer chargeResult = 0
            
            // them 1 cong thuc vao nhom
            method addRecipe takes integer id returns nothing
                local recipe r = recipe(id)
                call SaveInteger(recipes, integer(this), .count, id)
                set recipeGetGrp[id] = integer(this)
                set .count = .count + 1
            endmethod
            
            // lay ra cong thuc theo so thu tu trong nhom
            method operator [] takes integer i returns integer
                return LoadInteger(recipes, integer(this), i)
            endmethod
            
            // enable hoac disable toan bo cac cong thuc thuoc nhom nay
            method enable takes boolean flag returns nothing
                local integer i = 0
                local recipe  r
                loop
                    set r = recipe(this[i])
                    set r.enable = flag
                    set i = i + 1
                    exitwhen i == .count
                endloop
            endmethod
        endstruct
        
        // La 1 doi tuong giup thuc hien viec ghep do
        private struct combiner
            private item    array items[iterate]
            private item    array uItems[iterate]
            private integer array itemIDs[iterate]
            private recipe        r
            private integer       haveNumI = 0
            
            // kiem tra item dang charge thi` don vao tang chi so charge
            method findChargeItem takes item i, unit u returns nothing
                local integer count = GetItemCharges(i)
                local integer j
                local item enumI
                if count > 0 then 
                    set j = 0
                    loop
                        set enumI = UnitItemInSlot(u,j)
                        if not(enumI == null) and not(enumI == i) then
                            if GetItemTypeId(enumI) == GetItemTypeId(i) then
                                set count = count + GetItemCharges(enumI)
                                call SetItemCharges(enumI, count)
                                call RemoveItem(i)
                                return
                            endif
                        endif
                        set j = j + 1
                        exitwhen j == 6
                    endloop
                endif
            endmethod
            
            // Kiem tra lan luot cong thuc co loai "item i" tham gia trong hom do cua "unit u"
            // Tra ve ID cua cong thuc tim dc, tra ve 0 neu ko tim duoc
            method findRecipe takes item i, unit u returns recipe
                local integer id = GetItemTypeId(i)
                local item enumI
                local integer recipeId
                local integer j
                local integer k
                local integer count
                set count = IRICountRecipe(id)
                call .findChargeItem(i,u)
                if count == 0 then
                    return 0
                endif
                set j = 0
                set k = 0
                loop
                    set enumI = UnitItemInSlot(u,j)
                    if not(enumI == null) and not(enumI == i) then
                        set .items[k] = enumI
                        set k = k + 1
                    endif
                    set j = j + 1
                    exitwhen j == 6
                endloop
                if i != null then
                set .items[k] = i
                set k = k + 1
                endif
                set enumI=null
                set .haveNumI=k
                set k = 1
                loop
                    set recipeId = IRIGetRecipe(id,k)
                    if .checkCompos(recipeId) then
                        return .r
                    endif
                    set k = k + 1
                    exitwhen k > count
                endloop
                return 0
            endmethod
            
            // Kiem tra co du cac thanh phan cua cong thuc co id la "recipeID"
            // Tra ve true neu dung cong thuc, false neu sai
            method checkCompos takes integer recipeID returns boolean
                local integer i = 0
                local integer j=0
                local boolean flag = true
                local recipe r = recipe(recipeID)
                
                if .haveNumI < r.countItems or r.enable == false then
                    return false
                endif
                loop
                    set .itemIDs[j] = GetItemTypeId(.items[j])
                    set j = j+1
                    exitwhen j == .haveNumI
                endloop
                loop
                    set j = 0
                    loop
                        if not(.itemIDs[j]==0) then
                            if r[i] == .itemIDs[j] then
                                if r.chargeOf(i) <= GetItemCharges(.items[j]) then
                                    set .uItems[i] = .items[j]
                                    set .itemIDs[j]=0
                                    set flag = true
                                    exitwhen true
                                endif
                            endif
                        endif
                        
                        set flag = false
                        set j = j + 1
                        exitwhen j == .haveNumI
                    endloop
                    if flag == false then
                        return false
                    endif
                    set i = i + 1
                    exitwhen i == r.countItems
                endloop
                set .r = r
                return true
            endmethod
            
            // xoa bo cac item nguyen lieu su dung de ghep do
            method removeUsedItems takes nothing returns nothing
                local integer i = 0
                local recipe  r = .r
                local integer c = 0
                loop
                    if integer(r) != 0 then
                        set c = GetItemCharges(.uItems[i])
                        if c == r.chargeOf(i) then
                            call RemoveItem(.uItems[i])
                        else
                            call SetItemCharges(.uItems[i],c - r.chargeOf(i))
                        endif
                    endif
                    set i = i + 1
                    exitwhen i==r.countItems
                    set .r = 0
                endloop
            endmethod
        endstruct
        
        function NewGrpRecipe takes integer result, integer charge returns grpRecipe
            local integer j = grpResult[result]
            local grpRecipe grp
            if j == 0 then
                set grp = grpRecipe.create()
                set grp.result = result
                set grp.chargeResult = charge
                set grpResult[result] = integer(grp)
            else
                set grp = grpRecipe(j)
            endif
            return grp
        endfunction
        
        function Add2Recipe takes integer typeI, integer charge, recipe r returns nothing
            call r.addItem2Recipe(typeI, charge)
            call IRIAddRecipe(typeI,integer(r))
        endfunction
        
        function Add2RecipeWithNum takes integer typeI, integer num, recipe r returns nothing
            local integer i = 0
            loop
                call r.addItem2Recipe(typeI, 0)
                set i = i + 1
                exitwhen i == num
            endloop
            call IRIAddRecipe(typeI,integer(r))
        endfunction
        
        function EnableRecipe takes integer recipeID, boolean flag returns nothing
            local recipe r = recipe(recipeID)
            if recipeID > 0 then
                set r.enable = flag
            endif
        endfunction
        
        function EnableRecipeByResult takes integer resultID, boolean flag returns nothing
            local grpRecipe grp = grpRecipe(grpResult[resultID])
                
            if integer(grp) > 0 then
                call grp.enable(flag)
            endif
        endfunction
        
        function DisassembleItem takes item i, unit u returns nothing
            local real x = GetItemX(i)
            local real y = GetItemY(i)
            local integer j = 0
            local recipe r
            local boolean b = IsTriggerEnabled(GetTriggeringTrigger())
            local item createdI
            
            if GetItemUserData(i) == 0 then
                return
            endif
            
            set r = recipe(GetItemUserData(i))
            if b then
                call DisableTrigger(GetTriggeringTrigger())
            endif
            call RemoveItem(i)        
            if b then
                call EnableTrigger(GetTriggeringTrigger())
            endif
            if u == null then
                loop
                    set createdI = CreateItem(r[j],x,y)
                    if r.chargeOf(j) > 0 then
                        call SetItemCharges(createdI, r.chargeOf(j))
                    endif
                    set j = j + 1
                    exitwhen j == r.countItems
                endloop
            else
                set r.enable = false
                loop
                    set createdI = UnitAddItemById(u,r[j])
                    if r.chargeOf(j) > 0 then
                        call SetItemCharges(createdI, r.chargeOf(j))
                    endif
                    set j = j + 1
                    exitwhen j == r.countItems
                endloop
                set r.enable = true
            endif
            set createdI = null
        endfunction    
        
        // la ham kiem tra va thuc hien viec ghep do cho unit u voi item de bat dau kiem tra
        public function Check takes unit u, item i returns boolean
            local combiner comb = combiner.create()
            local recipe found
            local integer charge
                set found = comb.findRecipe(i,u)
                if integer(found) == 0 then  
                    return false
                endif
                call comb.removeUsedItems()
                set charge = found.chargeResult
                set i = CreateItem(found.result,GetUnitX(u),GetUnitY(u))
                if charge > 0 then
                    call SetItemCharges(i, charge)
                endif
                call UnitAddItem(u, i)
                call SetItemUserData(i,integer(found))
                call DestroyEffect(AddSpecialEffectTarget(SFX_PATH,u,"origin"))
                call comb.destroy()
                set i = null
                set found = 0
                return true
        endfunction
        
        private function Enter_Actions takes nothing returns nothing
            local RegionTrig rTrig = RegionTrig.get(GetTriggeringTrigger())
            if GetEnteringUnit() == rTrig.spxU then            
                if Check(rTrig.spxU,rTrig.targetI) == false and InventoryIsFull(rTrig.spxU) then
                    call SimError(GetOwningPlayer(rTrig.spxU),"Inventory is full!")
                endif
                call rTrig.removeLeak()
                call rTrig.destroyChain()
            endif
        endfunction
        
        private function IssuePointOrder_Actions takes nothing returns nothing
            local MTrigger trig = MTrigger.get(GetTriggeringTrigger())
            local RegionTrig rTrig = trig.parent
                call rTrig.removeLeak()
                call trig.destroyChain()
        endfunction
        
        private function Trig_1_Actions takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local item i = GetManipulatedItem()
            call Check(u,i)        
            set u = null
            set i = null
        endfunction
        
        private function Trig_2_Actions takes nothing returns nothing
        local item i = GetOrderTargetItem()
        local unit u = GetTriggerUnit()
        local integer count = 0
        local MTrigger trig
        local RegionTrig rTrig
        
            if i == null then
                return
            endif
            if InventoryIsFull(u) then
                set rTrig = RegionTrig.create()
                call rTrig.newRegionByItem(i, PICK_ITEM_RANGE * 2,PICK_ITEM_RANGE * 2)
                if RectContainsCoords(rTrig.rt, GetUnitX(u), GetUnitY(u)) then
                if Check(u,i) == false then
                    call SimError(GetOwningPlayer(u),"Inventory is full!")
                endif
                    call rTrig.removeLeak()
                    call rTrig.destroy()
                else
                    call rTrig.removeLeak()
                    call rTrig.newRegionByItem(i, FOLLOW_ITEM_RANGE * 2,FOLLOW_ITEM_RANGE * 2)
                    call rTrig.regis(true)
                    set rTrig.spxU = u
                    call TriggerAddAction(rTrig.t, function Enter_Actions)
                    set trig = MTrigger.create()
                    call TriggerRegisterUnitEvent( trig.t, u, EVENT_UNIT_ISSUED_POINT_ORDER )
                    call TriggerAddAction(trig.t, function IssuePointOrder_Actions)
                    call rTrig.addChild(trig)
                endif
            endif
            set i = null
            set u = null
        endfunction    
        
        private function Init takes nothing returns nothing
        local integer index = 0
        local trigger t = CreateTrigger()
            loop
                if GetLocalPlayer() == Player(index) then
                    call TriggerRegisterPlayerUnitEvent(t, Player(index), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
                endif
                set index = index + 1
                exitwhen index == bj_MAX_PLAYER_SLOTS
            endloop
            call TriggerAddAction(t, function Trig_1_Actions)
            set index = 0
            set t = CreateTrigger()
            loop
                if GetLocalPlayer() == Player(index) then
                    call TriggerRegisterPlayerUnitEvent(t, Player(index), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
                endif
                set index = index + 1
                exitwhen index == bj_MAX_PLAYER_SLOTS
            endloop
            call TriggerAddAction(t, function Trig_2_Actions)
            set IRI = InitHashtable()
            set grpResult = Table.create()
            set recipes = InitHashtable()
        endfunction
    endlibrary
    
    Đây là System mua đồ tự hợp (PowerUp ^^):
    Mã:
    /*
    Cach xai`:
    Moi khi tao. 1 Item (Permanent gi gi do), thi tao them 1 Item base tu` 1 Item PowerUp (nhu sach mau' chang han)
    Sau do ghi lai RAW code cua 2 item do, goi item PowerUp la Tome, item chinh' (permanent j j do y) la Item (of course)
    Tai. Map Initializing, ghi dong` code:
    call AddItemTable(Tome_ID,Item_ID)
    Voi Tome_ID la RAW code cua Tome, Item_ID la RAW code cua Item
    Khi tao. shop, cho Shop ban Tome chu khong ban Item chinh.
    */
    library InitPowerUp initializer Init requires Table, ItemRecipeSys
        globals
            public Table ItemTable
        endglobals
        
        public function AddItemTable takes integer tomeid, integer itemid returns nothing
            set ItemTable[tomeid] = itemid
        endfunction
        
        private function GiveAction takes nothing returns nothing
            local unit a = GetBuyingUnit()   
            local item b
            local location loc = GetUnitLoc(a)
            set b = CreateItemLoc(ItemTable[GetItemTypeId(GetSoldItem())],loc)
            if InventoryIsFull(a) then
                call ItemRecipeSys_Check(a,b)
            else
                call UnitAddItem(a,b)
            endif
            set a = null
            set b = null
            call RemoveLocation(loc)
            set loc = null
        endfunction
        
        private function Init takes nothing returns nothing
            local trigger a = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ( a, EVENT_PLAYER_UNIT_SELL_ITEM )
            call TriggerAddAction( a, function GiveAction )
            set a = null
            set ItemTable = Table.create()
            call ItemTable.reset()
        endfunction
    endlibrary
    
     
  15. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Sau 1 đêm chật vật với những lỗi khá vớ vẩn. Mình xìn giới thiệu RIS ver 1.3 đã có khá nhiều thay đổi. Tất cả đã được cập nhật ở đầu trang. Cám ơn những ai đã ủng hộ mình với hệ thống này. Chả biết được bao người nữa :p
    Nhân tiện đây: nếu [Yami] vẫn còn sử dụng hệ thống này thì nên update bản mới vì với cách dùng của cậu thì nặng phần xử lý hơn vẻ mới này đấy. Còn nếu cậu vẫn cần cái mua đồ power up trong shop thì để mình tích hợp sau cho cậu nhé. Thực ra cũng đơn giản thôi nhưng mình buồn ngủ rồi :p

    ---------- Post added at 03:16 ---------- Previous post was at 02:38 ----------

    Ông nào nhanh tay quá, mình vừa post lên đã down rồi, cho mình thu hồi lại cái đó. Buồn ngủ post nhầm bản lỗi, mình post lại bản không lỗi rồi. Xin lỗi, cho mình xin thu hồi bản lỗi, down lại bản mới nè(Link down trang đầu đã được update).
    Chỉ tại mình không có time rảnh phải làm buổi đêm nên mới ra nông nỗi này :((
     
    Chỉnh sửa cuối: 16/3/11
  16. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    cậu ơi xem phụ giúp tớ tích hợp map tớ ok lắm có điều chơi muti player là desysnc(disconnect ai mua đồ) :|
     
  17. zzchaolegionzz

    zzchaolegionzz T.E.T.Я.I.S

    Tham gia ngày:
    27/9/07
    Bài viết:
    606
    Nơi ở:
    Black Parade
    bạn vươngkkk hay ai đó cho mình hỏi cái này với. vd cái RawID cũ của cái item đó là "gsou" thì khi mình copy cái đó ra để chỉnh ability thì nó thêm ID là:"l0001gsou" vậy khi mình ghi nó trong code cũng y chang cái mã của item mình copy ra là "l0001sgou" hả. vậy mình muốn thêm item, này vào hệ thống thì mình sẽ gõ thê này hả
    set grp = NewGrpRecipe('ciri',0)
    set r = Recipe.create()
    call Add2RecipeWithNum('rin1''l001gsou',1,r)
    call grp.addRecipe(integer(r))
    đây là item thành phẩm là ciri số lượng 1. cần 1 rin1 và 1 l0001gsou. đúng chưa nhỉ ;;)
     
  18. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    ^ À Với Object mới tạo, như trường hợp của bạn là "l001:sgou" thì khi vào code chỉ cần ghi là I001 là phần ở trước dấu : thôi

    ^^ ừ mình sẽ coi lại. Cám ơn bạn đã dùng system mình
     
  19. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    ^^^
    Những gì cần sửa rất đơn giản. Thay function Init ở cuối cùng của recipe item system trigger = cái như sau
    PHP:
    private function Init takes nothing returns nothing
    local integer index 
    0
    local trigger t 
    CreateTrigger()
        
    loop
        
            
    if GetPlayerSlotState(Player(index)) == PLAYER_SLOT_STATE_PLAYING then
                call TriggerRegisterPlayerUnitEvent
    (tPlayer(index), EVENT_PLAYER_UNIT_PICKUP_ITEMnull)
            endif
            
    set index index 1
            exitwhen index 
    == bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerAddAction
    (t, function Trig_1_Actions)
        
    set index 0
        set t 
    CreateTrigger()
        
    loop
            
    if GetPlayerSlotState(Player(index)) == PLAYER_SLOT_STATE_PLAYING then
                call TriggerRegisterPlayerUnitEvent
    (tPlayer(index), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDERnull)
            endif
            
    set index index 1
            exitwhen index 
    == bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerAddAction
    (t, function Trig_2_Actions)
    endfunction
    Đã update demo map ở trang đầu
     
    Chỉnh sửa cuối: 5/7/11
  20. zzchaolegionzz

    zzchaolegionzz T.E.T.Я.I.S

    Tham gia ngày:
    27/9/07
    Bài viết:
    606
    Nơi ở:
    Black Parade
    vương ơi. có lỗi rồi đây. sửa đi nhá. mình thấy sys của bạn rất hay. nhưng còn lỗi nè. vd Ring+2 armor x2 => ring+4 armor. nhưng khi vứt ra đất nó lại thành 2 cái ring +2 thế là thế nào. nó vứt ra đất phải là ring +4 chứ. sao lịa là 2 cái +2 :-j. cái này hay nữa nè :d. VD 2 cái ring+2 nhập lại thành ring +4. xong vứt ra đất thành 2 ring +2. lượm 2 ring+2 lên nó lại không nhập thành ring +4 nữa :-j
     

Chia sẻ trang này