DYNAMIC GROUP SYSTEM version 1.0 - [1.24e] Convert from Unit-Group To Unit-Aray đối với những ai yêu thích jass và vjass trong việc thiết kế custom map. Hẳn các bạn ai cũng biết kiểu dữ liệu group trong jass. group là kiểu dữ liệu khối chứa thông tin của 1 nhóm các unit có cùng điều kiện ( boolexpr ) hay không điều kiện. Nhưng để thao tác với group một cách dễ dàng và tùy biến thì rất khó bởi : - Khi pick each unit ta buộc phải sử dụng các callback function mà không được phép thêm tham số vào các hàm này. Điều này gây ra khó khăn, nhất là khi thiết kế spells, nếu làm việc với group thì không thể MUI hoàn toàn vì phải đụng chạm đến các biến globals - Khi muốn pick random 1 unit bất kì ta cũng phải sử dụng hàm BJ của bllizard rất dài dòng và rất dễ gây ra leaks Dynamic Group System ra đời nhằm mục đích khắc phục các điểm yếu trên và bảo đảm được rằng nó hoàn toàn có lợi trong việc thiết kế spells. Hơn nữa trong thuật toán chuyển đổi từ unit group sang unit array sẽ khiến chúng ta làm việc dễ dàng hơn, code ngắn hơn và không bao giờ gây ra leaks. Phần hướng dẫn cụ thể và cách sử dụng các functions, methods mình đã trình bày rất rõ ràng ngay trong trigger trong attached file bên dưới. 'Dynamic Group System' - created by Kr.Linh - Vietnam - version 1.0 [1.24e+] - 2012 - credit : KrCoder@yahoo.com
- không có tham số có khó khăn hay không thì có lẽ tùy vào người làm, và dùng tham số global ở trường hợp này không sao cả với người dùng vJass thì việc truyền tham số lại càng dễ, một struct có thể truyền nhiều tham số và chỉ cần qua một global integer. làm với group có thể MUI hay không là do người làm, và nói vậy thì không thể có local group? phần lớn thì: Mã: loop set p = FirstOfGroup(g) exitwhen p==null call GroupRemoveUnit(g,p) //... other actions with "p" (picked unit) endloop nên việc truyền tham số là không cần thiết. - không dài dòng và hàm của Blizzard KHÔNG leak, ngoài ra hàm lấy random unit là một BJ có ích p.s: Blizzard chứ không phải bllizard edit: theo như demo map thì chỉ có thể có 8 group kiểu này?
Thêm 1 system ra đời, maker nhẹ người đi được 1 tí ^^. Đã test và có 1 vài ý kiến thế này Khi pick each unit ta buộc phải sử dụng các callback function mà không được phép thêm tham số vào các hàm này. Điều này gây ra khó khăn, nhất là khi thiết kế spells, nếu làm việc với group thì không thể MUI hoàn toàn vì phải đụng chạm đến các biến globals Vậy các boolexpr để truyền vào cho các Method trong SYS đó thì sao nhỉ ?, giả sử có 1 điều kiện GetWidgetLife(target) >= 0.405, trong khi cũng không thể nào truyền tham số cho target được, vậy cũng phải dùng 1 temp Global, mà đã vậy thì callback ngại gì không dùng luôn nhỉ. Khi muốn pick random 1 unit bất kì ta cũng phải sử dụng hàm BJ của bllizard rất dài dòng và rất dễ gây ra leaks Chưa chắc à Còn vấn đề làm spell thì hiện hầu như mọi người đều dùng temp globals khi xử lí boolexpr với callback function, bạn nghi ngờ tính MUI của nó à, bạn yên tâm, nếu dùng đúng thì nó chỉ được dùng trong 1 lần xử lí duy nhất, vậy nên dù có cast spell nhanh cỡ nào, dùng Timer tốc độ cao, thì CPU của bạn cũng xử lí theo 1 trình tự, không có bị "xung đột" đâu ^^.
có 1 điều mình mạn phép nói , khi cậu đã bỏ thời gian viết 1 system rồi tại sạo lại không làm sẵn một ví dụ trong đó ?
Ý tưởng không tồi đâu, từ lâu mình đã khó chịu với cái kiểu dùng callback vô tội vạ của war3, nhiều cái luôn làm nó phức tạp hơn rất nhiều mặc dù chả cần thiết, còn việc phải động đến global thì ko ý kiến... <- cái này vô hại. Xăm soi 1 hồi thì thấy code của bạn... khá đẹp :) API thì chưa có thời gian phân tích, hy vọng đều là O(1)
oái.... thế cái này http://www.wc3c.net/showthread.php?t=104464 dùng để làm gì vậy hả mấy bác... em xài nó màk hk bk array hay hk...
@dh_g : mình xin lỗi, mình đã định làm 1 ví dụ rồi, nhưng mấy ngày qua bị bệnh, hết làm nổi nên upload lên luôn với lại mình nghĩ là mình đã có giải thích cụ thể các hàm và công dụng của nó ngay trong trigger rồi, nếu biết sơ về vjass thì vẫn có thể hiểu mà @dorae.Mun : không phải đâu, cái groupUtils đó vẫn là sử dụng cho group bình thường, vẫn phải dùng callback mà pick every unit, random unit thì vẫn vậy... @All : 1 diều mình có thể khẳng định khi cho ra đời hệ thống này là, code sẽ ngắn gọn hơn nhiều ( ít nhất là không phải tạo thêm mớ hàm callback, vừa lộn xộn vừa làm code khó hiểu và sau này muốn update cũng...hơi mệt )
đây là box WE kiểu như chỉ về cách làm map hay gì thôi. và không phải là 1 box để post system như nước ngoài. vì vậy có số comment đó cũng gọi là nhiều lắm rồi
Thích comment hả. Ờ này thì comment: Suggestion - nhưng do ko có demo sử dụng nên vẫn chưa thân thiện API - Nice code but API is not... KickOutUnit ??? What about removeUnit ? GetFirstUnit? just firstUnit is enough for me - Cách đặt tên method theo kiểu viết hoa chữ cái đầu câu có thể khiến cậu khó nhìn và phân biệt method với function Algorithm - trước hết về cái group base của blizzard thì tớ ko chắc có chậm hơn unit array hay ko.... nhưng việc cậu phải convert qua lại giữa 2 cái này là chậm hơn chỉ group rồi. - Về cái dinamic thì tớ chưa thấy đâu vì sys này đòi hỏi phải config cái maxinstance để đạt hiệu quả tối đa về số lượng unit trong 1 cái dynamic group cũng như số lượng group. Thế sao cậu ko làm như thế này <<<<< - Cụ thể hơn về thuật toán cũng như cách giải bài toán trong sys của cậu là ở function KickOutUnit Đầu tiên .IsUnitExist(t) đã là loop tất cả cái group 1 lần rồi. Sau đó cậu vãn phải loop lại 1 lần nữa để tìm lại index của unit đó để mà set null Tại sao ko đơn giản là cuối cái function return false rồi nếu tìm gặp unit đó thì xử lý nó rồi return true như funciton IsUnitExist? PHP: loop exitwhen i == scount if( .u[i] == t ) then set .u[i] = null set .count = .count - 1 if( i <= .ctake ) then set .ctake = .ctake - 1 endif if( i != scount - 1 ) then set j = i loop exitwhen j == .count set .u[j] = .u[j + 1] set j = j + 1 endloop set .u[scount - 1] = null endif set i = scount - 1 // this's safe endif Cái này là thuật toán dồn và cậu lại phải loop. Thế tại sao cậu ko làm như sau có phải là nhanh ko? set .u=.u[.count - 1] set .u[.count - 1] = null set .count = .count - 1 ctake lúc này dù sao cũng ko có ảnh hưởng gì cả. - Còn cái Clear của cậu được chạy cả khi khởi tạo và khi destroy. Thế là thừa rồi. Vì nếu ko destroy thì thì creat sẽ ko đụng lại cái cũ của cậu mà nếu đã destroy thì lại chả clear rồi mà phải clear lại lúc create. Error: - cái này thì tớ mới chỉ coi code ( vì chỉ có mỗi code thôi ) thì dùng 1 cách normal nhất có thể thì ko có lỗi ... - Nhưng cái cách để lấy ra lần lượt các unit trong group của cậu có vấn đề. PHP: /* 'example' : local unit u = null *//* loop *//* set u = g.TakeUnit() <= unit u se mang lan luot gia tri cac unit trong DGS *//* exitwhen u == null <= khi di hêt tât ca các unit có trong DGS thì giá tri tra *//* vê se bang null ( ta dùng cách này de kêt thúc loop ) *//* <'do anything u want'> *//* : *//* : *//* <'..................'> *//* endloop Thử tưởng tượng nếu có 2 cái KickOutUnit trong vòng loop trên thì chắc chắn sẽ có 1 unit bị lấy lại 2 lần! Điều này hoàn toàn có thể xảy ra khi code spell AOE. Đây là do vấn đề ctake của cậu - Mà cậu nghĩ system của cậu thì ko leak ư. Hơi nhầm. Nếu cậu ko destroy hay clear thì ko chỉ là leak đâu mà sẽ có nảy sinh cả lỗi nữa cơ Cuối cùng hi vọng cậu ko nghĩ rằng tớ chặt chém gì cậu. Thực ra tớ chém thật đấy nhưng mang tính góp ý thôi. @dh-g: Box này là box WE giúp thảo luận các vấn đề khi làm map. Post system thì có gì sai? Nói thế để dhg biết mà tránh vào spam thôi. Tớ mà là mod thì cậu ăn nhiều thẻ lắm rồi
việc pick unit thì vẫn phải qua group cũ rồi convert ra group này, rõ ràng là chậm hơn so với group thường, sử dụng với tần số cao thì... performance drop lúc pick unit vẫn phải truyền tham số với boolexpr thôi, nếu dùng system này mà không cần thì cho ví dụ cái, với: DGSEnumUnitsInRange(real x,real y,real range,boolexpr filter) chẳng hạn thật sự số lần tôi phải dùng callback (ví dụ: ForGroup chẳng hạn) đếm trên đầu ngón tay, ngoài ra dùng loop với FirstOfGroup cả. chém y vài lần là bị kêu "hận y thấu xương", sao mà dám chém nữa?