UNIT PROPERTIES BONUS EXTRAS SYSTEM ( UPBE ) Version : BETA Creator : Kr.Linh I./ Lời nói đầu : Mấy ngày qua post cái Dynamic Group System và Items Limiter System không được mọi người ủng hộ cho lắm.:) Hôm nay mạo muội post thêm 1 system nữa ( không biết gọi là system có đúng không, nếu có gì sai an hem thẳng thắng góp ý nha ). Đối với dân làm map chắc hẳn trước đây các bạn cũng đã biết về EGUI ( giao diện đồ họa nâng cao ). Trong đó mình đã tìm thấy một vài thư viện như là : Bonus, UnitProperties,… chứa các hàm có chức năng “cộng” hoặc “trừ” các thông số thuộc tính của heroes ( Damage, Armor, Strength, Agility, Intelligence, Max Life, Max Mana, Attack Speed, Movement Speed ) là các thuộc tính không thể dùng trigger để chỉnh sửa trực tiếp được. Tuy nhiên khi sử dụng các hàm như BonusDamage, Armor… thì con số Bonus mình đưa vào khi cho ra thì lại không như mình mong muốn ( ra 1 số khác, cái này có lẽ do mình không biết xài ^^ ) hoặc là bị giới hạn. Nói chung là hệ thống Bonus đó không đủ tiêu chuẩn cho việc làm Map. Nhân lúc mình đang có 1 project thiết kế 1 map, để phục vụ cho nhu cầu, mình đã viết ra hẳn 1 hệ thống Bonus hoàn toàn mới ( tất nhiên cách thức thì vẫn dựa trên các Abilities trong Object Editor để thực hiện việc “cộng” hoặc “trừ” Bonus – cái này mình vẫn phải cám ơn các bác ở nước ngoài đã nãy ra ý tưởng này cho các hậu bối như em học hỏi và phát triển ). Trong phần file đính kèm có hình ảnh minh họa, bạn hãy click để xem thử nha. Tuy nhiên trong quá trình thiết kế hệ thống này, mình phát hiện nếu bắt chước các bác tiền bối – người sáng tạo ra Bonus trước đây sử dụng các đoạn external commands tự định sẵn thì nếu gặp người chỉ có nhu cầu sử dụng Bonus thấp hoặc chỉ một vài loại Bonus nhất định thì sẽ làm tốn thời gian load map bởi các Object được tạo ra quá nhiều mà không cần sử dụng tới. Đó là nguyên nhân mình bắt đầu thiết kế ra 1 công cụ ( ứng dụng phần mềm chạy trên nền .NET ) có khả năng tự động tạo ra các chuỗi external tùy theo số lượng Bonus người dùng muốn và tùy theo từng loại Bonus đính kèm Hướng dẫn cài đặt hệ thống cho map luôn : UNIT PROPERTIES BONUS EXTRAS – OBJECT CREATOR version BETA Tuy nhiên tool này được viết trên nền .NET 3.5 nên máy bạn phải cài .NET framework 3.5 mới chạy được. Đây là link download .NET framework 3.5 : http://download.microsoft.com/download/6/0/f/60fc5854-3cb8-4892-b6db-bd4f42510f28/dotnetfx35.exe II./ Ưu Nhược điểm : - Ưu : + Làm việc với các loại Bonus : Damage, Armor, Strength, Agility, Intelligence, Max Life, Max Mana, Attack Speed, Movement Speed. + Có khả năng add ( cộng ), subtract ( trừ ), Modify ( thay đổi, chỉnh sửa ), GetBonusValue ( Bonus được “cộng” hoặc “trừ” bởi chính hệ thống này, các Bonus khác thì không thể lấy được ), Clear, Clear All các loại Bonus trên. + Khả năng chính xác 100% ( map-maker cho add nhiêu sẽ ra bấy nhiêu, không nhiều hơn cũng không ít hơn ). + Sử dụng UPBE - Object Creator có khả năng tùy biến giới hạn bonus tùy theo map-maker giúp giảm thời gian load map. + Bonus Damage, Armor, Str, Agi, Int, Att-Speed có khả năng làm việc chính xác trên số Bonus lớn mà không phải sử dụng quá nhiều Ability Objects ( giảm thời gian load map ) - Nhược : + Max Life + Max Mana + MoveSpeed vì các loại abilities dùng cho hệ thống không có khả năng thiết lập cấp độ trên unit ( Max Life, Max Mana ) và không có khả năng xếp chồng ( non-Stackable ) nên để chính xác 100% phải sử dụng khá nhiều Abilities cùng loại. Điều này khiến Map load rất lâu. Nên khi sử dụng phải chú ý sử dụng giới hạn vừa đủ. + Attack Speed và Movement Speed thì có thể được cộng bao nhiêu cũng được nhưng bị giới hạn bởi war như Move Speed Maximum luôn là 522. III./ Cài đặt và sử dụng : - Phần hướng dẫn cài đặt và sử dụng đã được đính kèm theo chương trình UPBE – OBJECT CREATOR bằng tiếng Việt. Có thể vừa làm vừa xem hướng dẫn luôn. - Còn nếu không mở chương trình mà muốn sử dụng luôn các external commands có sẵn thì chỉ cần bước sau : -> Mở file “UnitPropertiesBonusEx.w3x” bằng Jassnewgenpack5d ( yêu cầu có jasshelper 0.A.2.B ) -> Copy "UnitPropertiesBonusExBase Category" và Copy luôn con unit Preloader trong Object Editor -> Mở map bạn ra, dán tất cả vào đó ( kể cả con dummy Preloader ), Save lại -> tạo 1 trigger bất kì -> convert sang custom script -> copy tất cả các đoạn external commands từ templates dán vào đó -> Save lại lần nữa ( lần này save map sẽ hơi lâu hơn lần trước ) -> Close map -> Mở lại map -> Disable cái trigger chứa các external commands lúc nãy đi -> save lại lần nữa. -> cuối cùng mở lại map “UnitPropertiesBonusEx.w3x”, xem ở thư mục “Trigger for User Copies” có chứa các thư viện Bonus cho từng loại. Bạn muốn dùng loại nào hay nhiều loại thì cứ copy cái mình cần dán vào map của bạn, chỉnh sửa lại các giá trị trong thẻ globals...endglobals cho phù hợp ( có hướng dẫn trong chương trình UPBE - Object Creator, và các giá trị định sẵn trong các file trong thư mục Object Templates ), save lại rồi thưởng thức ^^. - Trong "UnitPropertiesBonusExBase Category” có phần functions tutorial, vào đó xem hướng dẫn sử dụng các hàm. File đã được đính kèm bên dưới. Nếu bạn nào không chạy được UPBE - Object Creator và làm biếng download .NET framework 3.5 thì mở thư mục Object Templates copy mấy dòng external save vào map và chỉnh sửa các biến giá trị cho phù hợp trong cặp thẻ globals...endglobals
Với max HP và max MP, đúng là có bug với 2 ability trên, tuy nhiên có thể lợi dụng được: http://www.thehelper.net/forums/showthread.php/81466-Set-Unit-Maximum-HP-and-Mana chỉ cần 1 max HP ability và 1 max MP ability --- với move speed thì: 23 ability, mỗi ability có 50 level :o 522 speed rồi còn vừa đủ sao nữa? dùng cái này cho move speed: http://www.thehelper.net/forums/showthread.php/169030-SpeedMod http://www.thehelper.net/forums/showthread.php/133708-MoveSpeedX (có thể qua cả max 522) thì tốt hơn --- attack speed min là -80%, max là +400% nhưng system làm thừa ra một chút không sao vì khó có thể bắt user hoàn toàn sử dụng system để tăng/giảm AS ---------- Về độ chính xác của BonusMod trong EGUI thì tôi không có ý kiến vì tôi không dùng EGUI. Về giới hạn thì tôi chắc chắn có thể tăng/giảm, có lẽ bạn chưa tìm hiểu kỹ. hai điều trên có lẽ phải đợi người sử dụng EGUI/BonusMod vào xác minh.
tớ nghĩ là không cần .NET 3.5 tại vì tớ vào folder Object Templates\Creating Agility Objects.rtf thấy trong file đó nó chỉ là //! external ObjectMerger w3a Aamk AG01 anam "Bonus Agility" aher 0 aite 1 alev 9 arac "other" Ihid 1 1 Istr 1 0 Iint 1 0 Ihid 2 1 Istr 2 0 Iint 2 0 Ihid 3 1 Istr 3 0 Iint 3 0 Ihid 4 1 Istr 4 0 Iint 4 0 Ihid 5 1 Istr 5 0 Iint 5 0 Ihid 6 1 Istr 6 0 Iint 6 0 Ihid 7 1 Istr 7 0 Iint 7 0 Ihid 8 1 Istr 8 0 Iint 8 0 Ihid 9 1 Istr 9 0 Iint 9 0 Iagi 1 1 Iagi 2 2 Iagi 3 3 Iagi 4 4 Iagi 5 5 Iagi 6 6 Iagi 7 7 Iagi 8 8 Iagi 9 9 ansf "(decimal 1)" vụ này mình có thể import trực tiếp trên map và chạy ví dụ trong hướng dẫn của tớ , tại tớ nghĩ rằng không cần phải cài đặt bên ngoài như thế còn BonusMod thì thật sự là không hoạt động được.(đã thử trong EGUI) còn về system của cậu tớ cảm thấy nó rất là rắc rối(có thể tại vì nó nhiều raw id chăng?).
confirm là bonus mod có thể thay đổi giới hạn đc. cái movespeedx tom post ko có bản sử dụng autoindex nhỉ, ko biết đổi require thành autoindex có đc ko :s
vì AIDS thịnh hành hơn autoindex ấy mà =]], (tất nhiên là có thể! tớ tin cậu làm dc đấy ) hay cậu có thể sử dụng sys này Mã: library MoveSpeedXGUI /* v1.0.0.1 ************************************************************************************* * by Purgeandfire * This library allows you to set unit movement speeds beyond 522 without bugs. * This is an extension of the library MoveSpeedX, but is formatted for GUI use. * ************************************************************************************ * * SETTINGS Exemple Custom script: set i = GetUnitMoveSpeedX(u) */ globals private constant real PERIOD = 0.03125 // This is the period on which all units will be run. // If you lower this value, movement bonuses will be smoother, // but will require more processing power (lag more). // Also, the lower this is, the higher the move speed can be // before it starts bugging on waypoints. The lowest valid // period is 0.00125. A period of 0.00625 is very robust. private constant real MARGIN = 0.01 // This is the margin of approximation when comparing reals. // You will most likely not need to change this. endglobals /* ************************************************************************************ * * Functions * * function GetUnitMoveSpeedX takes unit whichUnit returns real * - Returns a unit movement speed. The GUI function will * - not return the correct value. This function will always * - return the correct value regardless of whether the unit * - has a movement speed beyond 522. * ************************************************************************************ * * HOW TO IMPLEMENT * * 1. Copy the trigger MoveSpeedXGUI. * 2. Paste it into your map. * 3. Open "Advanced -> Gameplay Constants". * 4. Checkmark "Use Custom Gameplay Constants". * 5. Find the field, "Movement - Unit Speed - Maximum", change * that to 522. * 6. Find the field, "Movement - Unit Speed - Minimum", hold * shift and click, and change it to 0. * 7. Read HOW TO USE. * ************************************************************************************ * * HOW TO USE * * This system will automatically work by itself. You can use the * normal GUI function for modifying unit movement speeds. Simply * use "Unit - Set Movement Speed", input whatever value you want, * and you are good to go! It will handle values beyond 522 by itself. * * HOWEVER, the GUI function will not return correct values if a unit * has a movement speed greater than 522. To fix this, use the function * GetUnitMoveSpeedX to return the correct value. A sample is given in * the trigger "Speed Change" in the test map. * ************************************************************************************/ private function ApproxEqual takes real A, real B returns boolean return (A >= (B - MARGIN)) and (A <= (B + MARGIN)) endfunction private module M private static integer ic = 0 private static integer ir = 0 static hashtable hash = InitHashtable() thistype next thistype prev unit curr real speed real x real y method destroy takes nothing returns nothing set this.next.prev = this.prev set this.prev.next = this.next set .prev = ir set ir = this call RemoveSavedInteger(hash, 0, GetHandleId(.curr)) endmethod private static method periodic takes nothing returns nothing local thistype this = thistype(0).next // first instance in list local real nx = 0 // the x-coordinate after tick local real ny = 0 // the y-coordinate after tick local real dx = 0 // distance between new-x and old-x local real dy = 0 // distance between new-y and old-y local real d = 0 // distance between new point and old point local unit u // unit being affected loop exitwhen this == 0 set u = .curr set nx = GetUnitX(u) set ny = GetUnitY(u) if (not IsUnitPaused(u)) and GetUnitAbilityLevel(u, 'BSTN') == 0 and GetUnitAbilityLevel(u, 'BPSE') == 0 then if not ApproxEqual(nx, .x) or not ApproxEqual(ny, .y) then set dx = nx - .x set dy = ny - .y set d = SquareRoot(dx * dx + dy * dy) set .x = nx + dx / d * .speed set .y = ny + dy / d * .speed call SetUnitX(u, .x) call SetUnitY(u, .y) endif endif set this = this.next endloop set u = null endmethod static method create takes unit whichUnit, real newSpeed returns thistype local thistype this = ir if this == 0 then set ic = ic + 1 set this = ic else set ir = .prev endif set this.next = thistype(0).next set thistype(0).next.prev = this set thistype(0).next = this set this.prev = 0 set this.curr = whichUnit set this.speed = (newSpeed - 522) * PERIOD set this.x = GetUnitX(whichUnit) set this.y = GetUnitY(whichUnit) call SaveInteger(hash, 0, GetHandleId(whichUnit), this) return this endmethod static method update takes unit whichUnit, real newSpeed returns nothing local thistype this = 0 if HaveSavedInteger(hash, 0, GetHandleId(whichUnit)) then set this = LoadInteger(hash, 0, GetHandleId(whichUnit)) if newSpeed > 522 then set this.speed = (newSpeed-522)*PERIOD else call this.destroy() endif elseif newSpeed > 522 then call thistype.create(whichUnit, newSpeed) endif endmethod private static method onInit takes nothing returns nothing call TimerStart(CreateTimer(), PERIOD, true, function thistype.periodic) endmethod endmodule private struct MoveSpeedStruct extends array implement M endstruct function GetUnitMoveSpeedX takes unit whichUnit returns real if HaveSavedInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit)) then return (MoveSpeedStruct(LoadInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit))).speed/PERIOD)+522 endif return GetUnitMoveSpeed(whichUnit) endfunction function SetUnitMoveSpeedX takes unit whichUnit, real newSpeed returns nothing call MoveSpeedStruct.update(whichUnit, newSpeed) endfunction hook SetUnitMoveSpeed SetUnitMoveSpeedX endlibrary
chưa chắc là aids đã thịnh hành hơn autoindex đâu nhé cậu có dùng cái buff framework nào ko? cái tốt nhất mà tớ biết yêu cầu autoindex cơ. nói trắng ra thì nó là abuff và ( hình như) cả thiên kiếm và havoc đều dùng . các stuffs đến từ jesus4lyf đều tốt ngoại trừ cái buffstruct. đấy là lí do tớ chọn autoindex
@ Tom : thanks anh Tom vì có lẽ ở phần maxHP, maxMP, AS và MS mình làm giống như Dmg, Armor cho user tự ý muốn thêm bao nhiêu thì thêm nhưng mà mình vẫn đặt giới hạn bên trong mình làm theo kiểu thiết kế nội dung cách chơi cho map ấy, thí dụ creep ăn 1 cái cây thì AS, MS tăng dần nhưng tăng quá 400 là đã thấy bay vù vù rồi, về phần MS thì các bạn cứ đặt max là 550 cũng được, ít ai làm hơn 522 lắm ( mình để lên 900 vậy thui ) Đúng là trong egui có thể tăng/giảm nhưng đối với 1 user bình thường ( chỉ biết dùng trigger và function thôi ) thì khi gọi thử 1 hàm add Bonus Damage 100 bonus chẳng hạn thì kết quả là 120, add 20 armor ra 40, vậy đối với người đó chẳng phải là quá rắc rối sao? còn system của mình thì add nhiêu ra nhiêu, lại còn có phần mềm cho user tuỳ biến nữa, hướng dẫn cũng đầy đủ ( chỉ thiếu demo map ), như thế chẳng phải là dễ dàng hơn với người đó rồi sao??? đọc hướng dẫn, làm theo, cài đặt xong, gọi hàm -> OK. Như vậy mà không làm được thì người đó phải học lại basic rồi. @ All : nhưng mình chắc chắn là ở properties Damage, Armor, Str, Agi, Int thì hoàn toàn không có giới hạn. @ dh_g : mình nghĩ là không có gì rắc rối hết, mình có ghi hướng dẫn khá cụ thể nếu bạn chạy được Object Creator mình viết. Mấy cái dòng external đó chẳng qua mình muốn user thoải mái hơn khỏi phải copy từng ability, enable cái trigger chứa external đó, save lại, close map, mở ra, disable cái trigger đó đi là xong, cài còn lại là tuỳ user muốn giới hạn bao nhiêu thì sửa ở trong cặp globals...endglobals thôi. còn cái gọi là import trực tiếp thì không hản như cậu nói. Như tớ đã nói thì mấy cái dòng external đó là tuỳ theo mức độ giới hạn bonus của user mà ra, giới hạn bao nhiêu thì external phải khác, mấy cái đó chỉ là ví dụ thôi. Còn việc nhiều rawcode id thì có lẽ bạn quan tâm quá mức rồi, mấy cái này bạn để ý làm gì, chỉ cần gọi hàm là xong, nếu thực sự phải để ý rawcode thì có lẽ tốc độ load map khi vào game sẽ thay đổi. cái này mình tạo ra thực sự là do nhà mình không có NET, không biết thực tế bên ngoài thế nào, nên làm luôn cái sys này tự xài cho project luôn. Sẵn tiện pót lên cho anh em dùng mà, mình nghĩ nó không phải là vô ích đâu.
đọc cho kỹ vào, màu đỏ hẳn hoi đấy: cài .NET framework để chạy cái exe, cái file exe là cái để tạo ra cái code external, ngoài ra có thể chỉnh giới hạn rồi mới tạo code. làm biếng download cái .NET framework thì hãy dùng cái template p.s: trong cái template có sẵn, mấy global có "private", cái này nếu không cho vào library/scope thì lỗi nên bỏ đi vì sợ nhiều người không biết sửa HAVOC lúc đầu sử dụng AIDS nhưng sau chuyển sang AutoIndex Thiên Kiếm thì không rõ. còn MoveSpeedX sử dụng AutoIndex, chờ đó, để tôi thử sửa xem. ----------- vậy là BonusMod trong EGUI bị lỗi?
không biết phải lỗi hay cho mình không biết xài hay không? nhưng mình thấy có vẻ còn rắc rối hơn cái của mình nữa. Nếu mình có gì sai mong các bác thông cảm bỏ qua.
@Tom_Kazansky: cái này là MoveSpeedXGUI mà không cần đến autoindex hay AIDS, vậy không tiên ư cần gì phải remake lại cái mới Mã: library MoveSpeedXGUI /* v1.0.0.1 ************************************************************************************* * by Purgeandfire * This library allows you to set unit movement speeds beyond 522 without bugs. * This is an extension of the library MoveSpeedX, but is formatted for GUI use. * ************************************************************************************ * * SETTINGS Exemple Custom script: set i = GetUnitMoveSpeedX(u) */ globals private constant real PERIOD = 0.03125 // This is the period on which all units will be run. // If you lower this value, movement bonuses will be smoother, // but will require more processing power (lag more). // Also, the lower this is, the higher the move speed can be // before it starts bugging on waypoints. The lowest valid // period is 0.00125. A period of 0.00625 is very robust. private constant real MARGIN = 0.01 // This is the margin of approximation when comparing reals. // You will most likely not need to change this. endglobals /* ************************************************************************************ * * Functions * * function GetUnitMoveSpeedX takes unit whichUnit returns real * - Returns a unit movement speed. The GUI function will * - not return the correct value. This function will always * - return the correct value regardless of whether the unit * - has a movement speed beyond 522. * ************************************************************************************ * * HOW TO IMPLEMENT * * 1. Copy the trigger MoveSpeedXGUI. * 2. Paste it into your map. * 3. Open "Advanced -> Gameplay Constants". * 4. Checkmark "Use Custom Gameplay Constants". * 5. Find the field, "Movement - Unit Speed - Maximum", change * that to 522. * 6. Find the field, "Movement - Unit Speed - Minimum", hold * shift and click, and change it to 0. * 7. Read HOW TO USE. * ************************************************************************************ * * HOW TO USE * * This system will automatically work by itself. You can use the * normal GUI function for modifying unit movement speeds. Simply * use "Unit - Set Movement Speed", input whatever value you want, * and you are good to go! It will handle values beyond 522 by itself. * * HOWEVER, the GUI function will not return correct values if a unit * has a movement speed greater than 522. To fix this, use the function * GetUnitMoveSpeedX to return the correct value. A sample is given in * the trigger "Speed Change" in the test map. * ************************************************************************************/ private function ApproxEqual takes real A, real B returns boolean return (A >= (B - MARGIN)) and (A <= (B + MARGIN)) endfunction private module M private static integer ic = 0 private static integer ir = 0 static hashtable hash = InitHashtable() thistype next thistype prev unit curr real speed real x real y method destroy takes nothing returns nothing set this.next.prev = this.prev set this.prev.next = this.next set .prev = ir set ir = this call RemoveSavedInteger(hash, 0, GetHandleId(.curr)) endmethod private static method periodic takes nothing returns nothing local thistype this = thistype(0).next // first instance in list local real nx = 0 // the x-coordinate after tick local real ny = 0 // the y-coordinate after tick local real dx = 0 // distance between new-x and old-x local real dy = 0 // distance between new-y and old-y local real d = 0 // distance between new point and old point local unit u // unit being affected loop exitwhen this == 0 set u = .curr set nx = GetUnitX(u) set ny = GetUnitY(u) if (not IsUnitPaused(u)) and GetUnitAbilityLevel(u, 'BSTN') == 0 and GetUnitAbilityLevel(u, 'BPSE') == 0 then if not ApproxEqual(nx, .x) or not ApproxEqual(ny, .y) then set dx = nx - .x set dy = ny - .y set d = SquareRoot(dx * dx + dy * dy) set .x = nx + dx / d * .speed set .y = ny + dy / d * .speed call SetUnitX(u, .x) call SetUnitY(u, .y) endif endif set this = this.next endloop set u = null endmethod static method create takes unit whichUnit, real newSpeed returns thistype local thistype this = ir if this == 0 then set ic = ic + 1 set this = ic else set ir = .prev endif set this.next = thistype(0).next set thistype(0).next.prev = this set thistype(0).next = this set this.prev = 0 set this.curr = whichUnit set this.speed = (newSpeed - 522) * PERIOD set this.x = GetUnitX(whichUnit) set this.y = GetUnitY(whichUnit) call SaveInteger(hash, 0, GetHandleId(whichUnit), this) return this endmethod static method update takes unit whichUnit, real newSpeed returns nothing local thistype this = 0 if HaveSavedInteger(hash, 0, GetHandleId(whichUnit)) then set this = LoadInteger(hash, 0, GetHandleId(whichUnit)) if newSpeed > 522 then set this.speed = (newSpeed-522)*PERIOD else call this.destroy() endif elseif newSpeed > 522 then call thistype.create(whichUnit, newSpeed) endif endmethod private static method onInit takes nothing returns nothing call TimerStart(CreateTimer(), PERIOD, true, function thistype.periodic) endmethod endmodule private struct MoveSpeedStruct extends array implement M endstruct function GetUnitMoveSpeedX takes unit whichUnit returns real if HaveSavedInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit)) then return (MoveSpeedStruct(LoadInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit))).speed/PERIOD)+522 endif return GetUnitMoveSpeed(whichUnit) endfunction function SetUnitMoveSpeedX takes unit whichUnit, real newSpeed returns nothing call MoveSpeedStruct.update(whichUnit, newSpeed) endfunction hook SetUnitMoveSpeed SetUnitMoveSpeedX endlibrary @GrudgeBoy: thật sự là BonusMod không thể xài được trong EGUI có thể tại nó lỗi P/S: trình độ em bây giờ tạm có thể nói là cao hơn 1 bậc nhờ có chú vương dạy bảo vài jass cơ bản đủ khả năng make 1 system tồi chăng
Đúng là trong system này cái Att-S, M-S, và MaxHP, MP không pro hơn mấy cái sys khác nhưng đảm bảo rằng Damage, Armor, Hero Att rất pro, vừa sử dụng ít raw code vừa có giới hạn rất cao ( 999.999.999 ) xài đã luôn
Vậy cải thiện thêm mấy cái đấy đi bạn, cơ mà dùng ít abi mà lại có cái giới hạn khủng thế kia á :-O Mình tưởng mấy cái system kiểu này cái nào cũng giống nhau ở cái công thức "power of 2" ?!
@Tom_Kazansky: vậy là BonusMod trong EGUI bị lỗi? BonusMod trong EGUI ko lỗi mà là lỗi của chính EGUI. @GrudgeBoy: Mấy ngày qua post cái Dynamic Group System và Items Limiter System không được mọi người ủng hộ cho lắm Cậu có nói đi thì tớ phải nói lại là ko biết mọi ng` thế nào. Nhưng mình rất ủng hộ các map maker làm jass cũng như dùng jass. Cậu làm system thực sự là 1 điều hiếm thấy của toàn bộ map maker Việt (nói ko hề có ngoa dụ) nên mình ủng hộ bằng cách góp ý cho cậu. Cậu đừng cho nó là ko ủng hộ. Nếu ko ủng hộ tớ đã chả vào comment. Tớ rất bùn vì tớ có làm vài cái system mà ko có ai báo lỗi hay góp ý cho mình về code hay thuật toán cũng như cách giải quyết cả... Còn người dùng chắc đếm trên đầu ngón tay của 1 bản tay... @GrudgeBoy: người sáng tạo ra Bonus trước đây sử dụng các đoạn external commands tự định sẵn thì nếu gặp người chỉ có nhu cầu sử dụng Bonus thấp hoặc chỉ một vài loại Bonus nhất định thì sẽ làm tốn thời gian load map bởi các Object được tạo ra quá nhiều mà không cần sử dụng tới. Nếu cậu cho rằng thừa và ko dùng đến thì có thể đơn giản là xóa cái thừa đi. Cùng so sánh 2 system Dung lượng code - của cậu thực ra dài hơn của BonusMod vì của tên kia còn có system hỗ trợ regen mana, hp và cả regen theo % nữa. Tốc độ thực thi code - của cậu chậm hơn của BonusMod vì cậu dùng Hashtable còn người ta dùng Indexer để lưu, bù lại vì có Indexer nên code của BonusMod lại có vẻ dài hơn. Nhưng map maker thì hầu như ai cũng dùng Indexer nên ko lo thừa code... - BonusMod có hỗ trợ SIGHT_RANGE còn của cậu 0 Thuật toán: Cậu Bonus cho từng hàng đơn vị 1 (hàng đơn vị, hàng chục, hàng trăm,...) Còn BonusMod thì cộng lũy thừa của 2 Ví dụ cụ thể với + 999 một chỉ số nào đó coi như việc thao tác với số bonus max là như nhau và ko tính chuyện lưu lại số bonus hiện tại cũng như số bonus trước đó = 0 Bonus của GrudgeBoy sẽ làm như sau: - Loop 3 lần để biết 999 là số có 3 chữ số (trong này có phép toán chia và cộng) - Loop 3 lần để search từ 1 đến i để tìm ra ability rawid add ability + set ability level: add abil hàng đơn vị và set level = 9, tương tự cho các hàng đơn vị chục và trăm Tính trừ lấy dư cho lần lặp tiếp theo Bonus của Earth-Fury sẽ làm như sau: Nếu maxBonus là 1024 thì: Loop i=10: amount =999 < 1024(2^10)=powersOf2 (đã được tính từ trước) bỏ quaLoop i=9: amount =999 > 512(2^9) +512(add ability) amount = 999-512= 487 Loop i=8: amount =487 > 256(2^8) +256(add ability) amount = 487-256= 231 .... Loop i=5: amount =39 > 32(2^5) +32(add ability) amount = 39-32= 7 Loop i=4: amount =7 < 16(2^4) bỏ qua Loop i=4: amount =7 > 6(2^3) +6(add ability) amount = 7-6= 1 .... Loop i=0: amount =1 == 1(2^0) +1(add ability) amount = 1-1= 0 => Việc thực thi bonus có thể nhanh hơn 1 chút so với BonusMod tùy lượng bonus max và số cần bonus. Số cần bonus càng lớn thì càng nhanh hơn so với BonusMod Cách lưu số bonus hiện tại -Trừ BONUS_MANA_REGEN và BONUS_LIFE_REGEN_PERCENT do tự code nên lưu giá trị qua Indexer. BonusMod trực tiếp kiểm tra các rawid của bonus ability để lấy ra số (ngược với cách từ số ra abil ở trên) - Của cậu thì lưu ra hẳn 1 struct với vài cái array interger và vài cái integer count + Hashtable => vậy cách của cậu tốn RAM hơn và khi lấy ra với lưu vào thì chậm hơn sys BonusMod Về cách sử dụng - Để thay đổi số lượng bonus Max UnitPropertiesBonusEx cần dùng kèm 1 tool và phải down cả .Net framework để thay đổi số lượng max ability bonus BonusMod đã có code để gen ra cái và chỉ cần config lại mỗi cái Ability Count ! - API thì có lẽ BonusMod là thân thiện hơn với tớ BonusMod: AddUnitBonus(unit, typeid , amount) UnitPropertiesBonusEx: UnitAddBonus$Type$(unit, amount) - Message để debug cũng như code kiểm soát hành động người dùng chắc chắn BonusMod hơn vì UnitPropertiesBonusEx ko có Thêm vài góp ý:- UnitRemoveAbility là kiểu gì nó cũng mất nên cậu ko cần phải UnitMakeAbilityPermanent = false - search từ 1 đến i để tìm ra ability rawid !? Tại sao ko lưu vào đúng level và lấy ra index như là số hàng trăm là ở index 3 số hàng nghìn ở index 4 ??? Bonus cho ai đọc post tớ:-Sight range tăng theo từng 128 đơn vị 1. Tức là sight range nếu = 0 và từ từ + thêm 1 sau 1 khoảng thời gian thì tới khi sight = 128 mới rộng ra lần đầu tiên và tới 256 mới rộng ra thêm lần thứ 2 - Ability của war3 ko hỗ trợ BONUS_MANA_REGEN và BONUS_LIFE_REGEN_PERCENT nên phải dùng code - BonusMod có thể được thấy ở đây
@vuongkkk : rất cám ơn về comments của cậu và thực sự bài viết của cậu là một loạt các kinh nghiệm cho tôi. thú thật thì BonusMod của nước ngoài chuyên nghiệp hơn, nhưng thực sự để sử dụng được ( đối với map maker chưa có kinh nghiệm về jass + lập trình ) thì mình chắc chắn là khó sử dụng hơn vì đối với họ, họ cần sự chính xác tuyệt đối ( còn tốc độ nhanh chậm ) thì cũng ít quan tâm ( nói chung chỉ cần kết quả ), do vậy nếu họ nhập 1 số integer để bonus damage chẳng hạn, thì kết quả nhận được thấy khác thì họ đâu có nghĩ là 2 lũy thừa mấy đâu, nên mục đích thực sự khi mình make cái sys này là để dễ sử dụng và chính xác tuyệt đối ( đối với gà + pro ). Nhưng cậu có công nhận rằng một điều rằng BonusMod của mấy bác nước ngoài chỉ giới hạn đến 1023, nhưng của tôi tuy chậm hơn, code dài hơn, sử dụng nhiều raw code hơn nhưng giới hạn có thể lên được đến 999.999.999 điểm bonus không? còn về cái tool tôi làm cho user chẳng qua vì nghĩ cho user thôi, xài ít load ít ( vì cần sử dụng preloader ) nên lục load map sẽ mất nhiều thời gian hơn, nếu không tôi cho luôn giới hạn lên 999.999.999 điểm vô templates down về xài luôn khỏi mất công, cũng được vậy hi hi . Dù sao cũng rất thanks bài viết của cậu. vì đã ủng hộ cho tôi.
Theo như thuật toán cũng như ví dụ tớ đã nêu thì cách bonus của họ sẽ ra được đúng số bonus mình cần. Nếu cậu thấy sai thì như tớ đã nói là sai do EGUI. Cậu nên down thử cái demo trong link tớ đưa ở bài trên để xác thực Công nhận là có lẽ cái của cậu có lẽ sẽ ít hơn hẳn về số lượng ability objects vì để BonusMod lên được tới giới hạn 1.048.576(2^20) điểm thì sẽ cần 20x2 ability(cho cả số âm nữa) thì của cậu để lên tới giới hạn 9.999.999 thì chỉ cần có 7x2 ability (cho cả số âm) mà thôi. - Nhưng nếu tốc độ thực thi code khá quan trọng(để tránh tình trạng sụt FPS). Đặc biệt với 1 số map có lượng code cần thực thi là liên tục và cao. - Mình cũng muốn cậu biết rằng tăng thêm vài object cũng ko có tăng thời gian load map nhiều lắm đâu. Map dota 6.1 chỉ load trong vòng 40s sau khi đã optimate 1 phần, trong khi chưa opt thì cần tới 5 phút. => Từ 2 điều này mình muốn các map maker nên biết cân bằng giữa tốc độ load map với tốc độ thực thi code Nhận xét cuối cùng của mình khi so sánh giữa 2 system này là độ chênh lệch về tốc độ load map, tốc độ xử lý, dung lượng code và độ ngốn ram chệnh lệch nhau rất ít (ko đủ để nhận ra) nên dùng system nào là tùy tâm. Được cái lợi hơn khi dùng system nước ngoài là hợp với ai thích bonus với 1 số lớn và được support = tiếng Việt Rất vui khi được đón thêm 1 jass-er về box WE
@vuongkkk : như đã nói thì mình làm cái sys này chủ yếu là áp dụng cho 1 project map mình đang tiến hành, nên những gì mình làm thì mình nghĩ có lẽ chỉ phù hợp với map mình thôi ( có lẽ hơi cá nhân ), nên sẵn tiện upload lên cho anh em test và góp ý. Rất vui khi được đón nhận sản phẩm của mình. mà sao cái items Limiter SYS không có ai comment nhỉ? mình thấy nó cũng đâu tồi đâu ta.