Học về Jass với newbie rất oải vì ko có code mẫu, tut thì cứ như quăng cho mọi người copy vào map, tới lúc muốn chỉnh sửa thành trigger khác hoặc dùng làm lõi cho trigger khác thì sao ? Cần phải có hiểu biết cơ bản về code thì mới được. Newbie cần tìm những đoạn jass thật ngắn để học, đừng đụng đến những trigger dài cỡ trang A4, bằng ko thì tiêu, chưa học mà đã hết muốn học. Ở đây mình có đoạn mẩu để các bạn tiện làm quen, vì nó cực ngắn: Mô tả: Khi có một con unit với ID là hfoo chạy vào một cái rect thì sẽ chết với điều kiện là unit đó phải của player 3 Code: Mã: function DieuKien takes nothing returns boolean if ( not ( GetOwningPlayer(GetTriggerUnit()) == Player(2) ) ) then // Neu unit di vao ko phai la cua player 3 thi cho ket qua la sai, neu ko thi la dung return false endif return true endfunction function HanhDong takes nothing returns nothing call KillUnit( GetTriggerUnit() ) // hanh dong giet unit triggering endfunction //=========================================================================== function InitTrig_Chet takes nothing returns nothing // chu y ko doi ten cua function nay nha set gg_trg_Chet = CreateTrigger( ) // Chet la ten cua trigger nay // Dong tren la theo cong thuc ko co j de noi call TriggerRegisterEnterRectSimple( gg_trg_Chet, gg_rct_LocationChet ) // evnet khi co unit di vao Rect LocationChet call TriggerAddCondition( gg_trg_Chet, Condition( function DieuKien ) ) // them dieu kien vao bang function DieuKien, chi thuc hien trigger HanhDong neu dieu kien la dung call TriggerAddAction( gg_trg_Chet, function HanhDong ) // goi function HanhDong co san o tren endfunction Ứng dụng : Bạn có thể sử dụng trigger này cho những trường hợp sau : 1. Spell : khi cast vào đất sẽ có một cái vòng nhỏ mà chỉ có team mình mới thấy, unit phe đối nghịch nếu chạy vào sẽ bị stun x giậy. 2. Tạo một rect rồi sắp xếp như một hang động, khi có unit nào chạy vào thì sẽ được đưa đi đâu đó, hoặc remove. 3. Ứng dụng trong map tower defense, khi unit chạy đến cuối dường thì remove. Bạn cũng có thể tự dùng vào việc khác. Trigger đơn giản thứ hai: Mô tả : Cứ mỗi giây tạo một unit hfoo tại một rect và lênh nó di chuyển tới rect khác Code: Mã: function HanhDongTao takes nothing returns nothing local location vitriralinh // khai bao bien vitrilinh la bien local, phai khai bao truoc khi dung nha set vitriralinh = GetRectCenter(gg_rct_LocationRa) // set bien vitrilinh tai trung tam rect LocationRa call CreateNUnitsAtLoc( 1, 'hfoo', Player(2), vitriralinh, bj_UNIT_FACING ) // tao 1 unit voi ID la hfoo cho player 2 tai vitriralinh, goc nhin cai mat la goc mac dinh set vitriralinh = null // cho bien thanh null thoi, ko gi phai ban set vitriralinh = GetRectCenter(gg_rct_LocationChet) //tiep tuc dung bien tren nhung set tai trung tam Rect LocationChet, dung lai bien nay de khoi khao bao them, mac cong call IssuePointOrderLoc( GetLastCreatedUnit(), "move", vitriralinh ) // lenh cho unit vua tao chay toi vitriralinh set vitriralinh = null // cho thanh null thoi endfunction //Trigger nay don gian nen ko them dieu kien vao, neu thich ban co the them cung dc function InitTrig_Tao takes nothing returns nothing set gg_trg_Tao = CreateTrigger( ) call TriggerRegisterTimerEventPeriodic( gg_trg_Tao, 1 ) // dieu kien la moi giay thuc hien trigger nay mot lan, cho phu hop voi cac map linh ra don dap nhu TD call TriggerAddAction( gg_trg_Tao, function HanhDongTao ) // goi trigger hanh dong tao linh voi ten HanhDongTao o phia tren endfunction Ứng dụng : 1. Đây là một trong những trigger cốt lõi của một map AoS hoặc Tower Defense, Hero Defense, đương nhiên là dùng trong những map này, nếu bạn muốn cứ mỗi đơn vị thời gian lại tạo unit ra 2. Sử dụng trong trường hơp bạn muốn điều khiển đường đi của unit từ Rect A qua B, từ B qua C, từ C lại về A ( hoặc đến D...) 3. Cái lợi trong trigger này chỉ là bớt đi 1 biến toàn cục để thay bằng 1 biến cục bộ, đỡ phải tạo nhiều biến chứ không có giá trị thực tiễn, chỉ có giá trị học thuật. P/s: Tom đào mộ ghê quá Với lại forum có chút vấn đề về việc sửa bài thì ko chuyển qua chức năng mở rộng dc, phải tự gõ cặp lệnh Mã: mới xong.
Dạo qua topic hỏi đáp thì thấy có một số bạn hỏi về việc ghép 2 mon đồ giống nhau sẽ cho ra món cần ghép nhưng chưa thấy có ai trả lời, cứ dẫn qua hướng dẫn của rongdovn. Sử dụng code đó của rongdovn đúng là hay, nhưng trong trường hợp ghép từ 2 món giống nhau thì còn chưa dc. Cần phải tìm một giải pháp khác. Nhân vụ Tom đào mộ lần này mình muốn hướng dẫn thật kỹ cho các bạn nào cần về vụ này, cố gắng rút gọn hết mức có thể. Có những trường hợp sau: 1. Mua 2 món A roi mua món B tự ra C, không cần mua recipe. 2. Mua 2 món A rồi mua B, rồi mua recipe sẽ cho ra món C, nếu ko đủ các món thành phần thì sẽ cho ra cuốn sách. mỗi trường hơp trên lại phân thành 1. việc ghép đồ khi full thùng đồ rồi mua recipe vẫn dc, nếu đó là món cuối cùng trong công thức ghép, nếu full mà chưa đủ đồ thành phần thì đồ mua đó sẽ tự động rớt xuống. 2. ko thể mua thêm đồ ghép khi thùng đồ full. Vì lý do cần ngắn gọn hết mức và phù hợp với nhiều người còn ngại Jass, mình trình bày phương pháp dc sử dụng nhiều nhất: mua 2 món A cộng với món B rồi mua recipe sẻ cho ra món C, nếu ko dủ đồ thành phần thì cho ra cuốn sách, chỉ ghép dc khi thùng đồ còn trống. Phương pháp: Ở đây mình tạo ra 5 món item : món A món B món C ( giả ) : chỉ dùng để add Shop, ko hề có tính năng gì cả món C thiệt : đây chính là món mà ta sẽ ghép ra món D : chính là cuốn sách công thức ghép là 2 món A cộng một món B và recipe ra C Mình sử dụng 2 trigger: Trigger 1 : khi mua món C giả vào thì dc cuốn sách, dù bạn có đủ đồ thành phần hay ko. Trigger 2 : Bạn sẽ có món C nếu như đủ đồ thành phần, với việc trong người có recipe hay cuốn sách đều dc. Code trigger 1 : Mã: function DieuKienDoiItem takes nothing returns boolean if ( not ( UnitHasItemOfTypeBJ(GetTriggerUnit(), 'I002') == true ) ) then // dung dieu kien neu ko phai item I002 thi cho ket qua sai, I002 la mon do C gia return false endif return true endfunction function HanhDongDoiItem takes nothing returns nothing // trigger nay dung de remove item C gia thay vao do la item cuon sach, chính la mon D local unit unitghepdo // khai bao bien cuc bo unitghepdo voi type la unit set unitghepdo = GetManipulatingUnit() // set cho bien unitghepdo la unit dang cam item C gia call RemoveItem( GetItemOfTypeFromUnitBJ(unitghepdo, 'I002') ) // dong tren la dung de remove item C gia voi ID la I002 call UnitAddItemByIdSwapped( 'I004', unitghepdo ) // tao mot item cuon sach voi ID la I004 cho unit dang dung ghep do set unitghepdo = null // xai xong thi cho no null, ma thuc ra ban cung chang can tao bien local unitghepdo lam gi, minh tao ra cho gon thoi endfunction //=========================================================================== function InitTrig_EpDo1 takes nothing returns nothing // cai nay la trigger lien ket cac trigger tren lai cho hoan chinh set gg_trg_EpDo1 = CreateTrigger( ) // chi la theo cong thuc thoi call TriggerRegisterAnyUnitEventBJ( gg_trg_EpDo1, EVENT_PLAYER_UNIT_PICKUP_ITEM ) // event khoi chay trigger nay la khi unit nhan dc 1 item call TriggerAddCondition( gg_trg_EpDo1, Condition( function DieuKienDoiItem ) ) // them dieu kien vao, chinh la function DieuKienDoiItem o tren call TriggerAddAction( gg_trg_EpDo1, function HanhDongDoiItem ) // neu dieu kien la dung se chay function HanhDonhDoiItem o tren endfunction Code trigger 2 : Mã: function Trig_EpDo2_Func001Func001Func001C takes nothing returns boolean // function nay dung de kiem tra slot 1 va 2 cua unit co mon A hay ko, mon nay co ID la I000 if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 1)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 2)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func002C takes nothing returns boolean // tuong tu cho slot 1 va 3, kiem tra xem co mon A if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 1)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 3)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func003C takes nothing returns boolean // va duong nhien la kiem tra cho slot 1 va 4 co mon A hay ko if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 1)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 4)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func004C takes nothing returns boolean // kiem tra slot 1 va 5 if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 1)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 5)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func005C takes nothing returns boolean // tiep tuc cho slot 1 va 6, cu lam tuan tu cho nhung slot con lai if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 1)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 6)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func006C takes nothing returns boolean // kiem tra cho slot 2 va 3 if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 2)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 3)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func007C takes nothing returns boolean // kiem tra tiep tuc cho slot 2 va 4 if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 2)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 4)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func008C takes nothing returns boolean // kiem tra cho slot 2 va 5 // ban cu lam lan luot cho cac slot con lai, theo quy tac canh cay, cai nao da kiem tra roi thi ko kiem tra lai nua if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 2)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 5)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func009C takes nothing returns boolean if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 2)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 6)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func010C takes nothing returns boolean if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 3)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 4)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func011C takes nothing returns boolean if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 3)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 5)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func012C takes nothing returns boolean if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 3)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 6)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func013C takes nothing returns boolean if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 4)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 5)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func014C takes nothing returns boolean if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 4)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 6)) == 'I000' ) ) then return false endif return true endfunction function Trig_EpDo2_Func001Func001Func015C takes nothing returns boolean if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 5)) == 'I000' ) ) then return false endif if ( not ( GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 6)) == 'I000' ) ) then return false endif return true endfunction // khi kiem tra den slot 5 va 6 thi coi nhu da kiem tra xong // nhung trigger duoi la de lien ket cac condition lai sao cho phai dong thoi ca hai mon do A hien dien trong hom do // rat quan trong do, neu ko thi se ko phai la condition " and ", tuc la co mon A and mon A function Trig_EpDo2_Func001Func001C takes nothing returns boolean if ( Trig_EpDo2_Func001Func001Func001C() ) then // mon A phai cung xuat hien o slot 1 va 2, nhung if phia duoi la cho cac slot con lai return true endif if ( Trig_EpDo2_Func001Func001Func002C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func003C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func004C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func005C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func006C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func007C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func008C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func009C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func010C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func011C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func012C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func013C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func014C() ) then return true endif if ( Trig_EpDo2_Func001Func001Func015C() ) then return true endif return false endfunction function Trig_EpDo2_Func001C takes nothing returns boolean if ( not Trig_EpDo2_Func001Func001C() ) then return false endif if ( not ( UnitHasItemOfTypeBJ(GetManipulatingUnit(), 'I001') == true ) ) then // kiem tra them coi co and them mon B hay ko, mon nay co ID la I001 return false endif if ( not ( UnitHasItemOfTypeBJ(GetManipulatingUnit(), 'I004') == true ) ) then // va duong nhien phai co mon D, tuc la cuon sach thi moi cho ghep // tai sao phai mon D, vi mon C gia khi mua vao se remove va cho ra mon D return false endif return true endfunction function Trig_EpDo2_Conditions takes nothing returns boolean // tong hop lai cac condition tren, 15 or ( 15 truong hop xuat hien cua mon A ) cua 2 and ( cung xuat hien 2 mon A trong thung, roi and voi 2 mon B va D if ( not Trig_EpDo2_Func001C() ) then return false endif return true endfunction function Trig_EpDo2_Actions takes nothing returns nothing //cai nay la hanh dong ne, sau khi cac dieu kien or va and phia tren dung local unit unitghepdo // khai bao bien local location chounitghepdo // nhu tren set unitghepdo = GetManipulatingUnit() // set cho 2 bien do set chounitghepdo = GetUnitLoc(unitghepdo) // thuc ra den day thi ko quan trong nua roi vi chi can remove cac mon do thanh phan de cho ra non ghep cuoi cung // quan trong la mot dong dieu kien o tren, ban phai hieu cai nao or, cai nao and call RemoveItem( GetItemOfTypeFromUnitBJ(unitghepdo, 'I000') ) call RemoveItem( GetItemOfTypeFromUnitBJ(unitghepdo, 'I000') ) call RemoveItem( GetItemOfTypeFromUnitBJ(unitghepdo, 'I001') ) call RemoveItem( GetItemOfTypeFromUnitBJ(unitghepdo, 'I004') ) // remove 2 mon A, mot mon B va remove mon D ( chinh la cuon sach do ) call UnitAddItemByIdSwapped( 'I003', unitghepdo ) // tao item C that cho unit dang ghep do call AddSpecialEffectLocBJ( chounitghepdo, "Abilities\\Spells\\Items\\AIam\\AIamTarget.mdl" ) // them hieu ung vao call DestroyEffect( GetLastCreatedEffectBJ() ) set chounitghepdo = null set unitghepdo = null // huy effect va set bien cho bang null thoi endfunction //=========================================================================== function InitTrig_EpDo2 takes nothing returns nothing // trigger nay dung de lien ket cac trigger tren set gg_trg_EpDo2 = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_EpDo2, EVENT_PLAYER_UNIT_PICKUP_ITEM ) call TriggerAddCondition( gg_trg_EpDo2, Condition( function Trig_EpDo2_Conditions ) ) call TriggerAddAction( gg_trg_EpDo2, function Trig_EpDo2_Actions ) // kiem tra dieu kien, goi hanh dong, vay la xong roi do endfunction Chú ý : 1. Đã hướng dẫn rất kỹ cho từng dòng hoặc cho từng function, hoặc cho một nhóm các function cùng chức năng, đọc từng dòng sẽ hiểu 2. Bạn chỉ việc dán vào map rồi chỉnh sửa các ID của Item lại cho phù hợp, vì ko dùng biến toàn cục nên sẽ ko xuất hiện them biến nào trong map, hoặc lỗi trigger ko chạy dc. 3. Có map dán kèm, cứ download về quan sát. 4. Bạn nào dùng system này, vui lòng credit, để bảo vệ tài nguyên Việt, vì cái này dc dùng trong một số item ghép map mình, chia sẻ thế này để các bạn ứng dụng vào map, nếu sau đó có người thấy mình xài trong map mình, lại bảo mình chôm ( mặc dù của mình ) Map nè View attachment Guide Map.rar Trong map này mình có kèm sẵn 2 trigger đã làm về tạo unit và hủy unit đã hướng dẫn ở trên, gõ iseedeadpeople để thấy rõ Nếu bạn nào có những đoạn jass ngắn xin post lên tại đây để các bạn tham khảo, cứ khư khư giữ mãi thì tội cho người mới quá
lạy hồn! bạn làm GUI thì post GUI, đừng có convert ra JASS rồi bảo là JASS, nhức cả mắt! và cái vụ ghép item giống nhau gì đó, cái link của rongdo không hoạt động? sao không trả lời vào đó? post ở đây là sai chủ đề đó nếu thấy hữu dụng tôi sẽ dẫn link vào topic tổng hợp, việc gì phải post ở đây? --- mà: bạn thấy tôi đào mộ nhưng không làm sao, thấy khó chịu? tôi viết bài đó để nhắc nhở một mem (đã quote bài đó) và với các tutorial, nếu bài đào lên có giá trị thì tôi cho đào, không thì xóa luôn, ok?
Dù gì thì bác Tom cũng mắc công đào lên rồi, vì vậy, ai biết nhiều về jass, biết ít về jass, không biết gì về jass, chỉ biết GUI, hoặc chưa biết GUI(cái này chỉ dành cho thiên tài, không biết GUI, cũng không biết Jass mà mò vào topic này, đọc được và hiểu được thì chỉ có thiên tài, cho nên cái này là thừa, nhưng mà vẫn nên nhắc tới, vì chắc gì trong bõ WE này không có thiên tài, nhể?), vào topic, đóng góp theo hình thức mà em cho là từ trước tới giờ chưa ai nghĩ ra (ngoài em, hoặc có nghĩ ra cũng không ai biết là họ nghĩ ra) đó là: 1. Post spell, hoặc system, hoặc cái gì đó liên quan tới code, chia làm 2 phần, 1 phần là GUI, còn 1 phần là Jass. (cấm tuyệt đối convert từ GUI sang Jass rồi đem lên đây làm 2 phần ) Phần này có thể coi là tut, có giải thích cụ thể càng tốt. 2. Các bạn chưa biết gì về jass, biết GUI nhiều, hoặc ít (cái này nói ở trên rồi, nhưng nhắc lại cho rõ), có thể post spell GUI, do chính mình làm (đã MUI hoặc chưa được MUI), thì các bác giỏi jass, hoặc biết chút ít về jass, hoặc là không biết gì về jass nhưng có thể convert được spell đó ra jass (tự convert, không convert kiểu bác ở trên = =) thì convert ra, và tất nhiên cũng nên có phần giải thích. Phần này thì chắc như kiểu request, đại loại thế. Chủ yếu là các bạn không biết jass, nhưng biết GUI, vì làm ra spell đó, nên biết rõ hoạt động của nó, từ đó convert sang jass sẽ giúp các bạn dễ hiểu hơn spell của họ một phần nào trong ngôn ngữ jass.(Chắc vậy) Còn ai có cái tư tưởng, làm GUI được thì làm, ham hố jass làm gì thì em xin nói trước, cái này là để làm quen với jass, chứ không phải làm những thứ mà GUI không làm được. Nếu thực hiện được như vậy, thì chúng ta đã làm đúng theo mục đích của topic đó là "GUI to Jass" (cả nghĩa đen lẫn nghĩa bóng, ........ cơ mà không có nghĩa bóng ) PS: các mem có đồng ý không nào, mod có đồng ý không nào.
làm gì các bạn mắng xối xả tội mình thế Topic là GUI to JASS, cần phải cho các mem thấy sự liên hệ, cũng như những đặc trưng, chứ xoáy vào khác biệt thì cũng như ko thôi Hơn nữa, dựa sườn GUI thì có gì sai đâu
liên hệ? từ bài viết trên quả thực tôi không thấy sự liên hệ gì cả Mã: function Trig_EpDo2_Func001Func001Func001C takes nothing returns boolean đây là cái gì? liên hệ với gì? còn scope, library,... ? tôi đâu nói cần, ít nhất thì cái fuction trên có thể: Mã: function CheckItem_I000 takes nothing returns boolean // function nay dung de kiem tra slot 1 va 2 cua unit co mon A hay ko, mon nay co ID la I000 local boolean ok = false local unit u = GetManipulatingUnit() //ca item o slot 1 va slot 2 phai la I000 if GetItemTypeId(u,1) == 'I000' and GetItemTypeId(u,2) == 'I000' then set ok = true endif set u = null return ok endfunction có dễ nhìn hơn không? ----- và do code của bạn "nhức mắt" như vây nên tôi chưa đọc kỹ cách làm của bạn cho "ghép 2 item giống nhau" là: check các item ở slot: (hơi dài nên tôi cho vào spoil) [spoil] 1 2 1 3 1 4 1 5 1 6 2 3 2 4 2 5 2 6 3 4 3 5 3 6 4 5 4 6 5 6 [/spoil] có cần thiết phải dài dòng vậy không?
anh TOM đã đào một rồi thì làm luôn vài Tut về Method - Library - Handle ...v..v.. hoặc cái nào là cần thiết cho việc làm 1 Spell = Jass thì anh làm Tut đi cho tụi e học với .. đi qua mấy trang nước ngoài học thì chữ hiểu chữ không .. coi đau đầu +_+. Mà phải công nhận bên đó thảo luận về JASS nhiều thật , vừa nhiều lại vừa chuyên nghiệp nữa.. Giờ nhân tiện nói tới Jass em có một số vấn đề không hiểu. Đó là dùng các System. hiện nay e thấy nhiều người Pro làm các System cho các vấn đề mà nhiều người gặp phải nhưng không hiểu cách sử dụng như thế nào. Dòm vô thấy họ viết thư viên từa lưa nhưng không hiểu cách sử dụng như thế nào. Cái System đầu tiên được "diện kiến" là TimerUtils được truyền từ KuKuiLan kêu mình học vẹt các làm Spell = Jass trước đi.. tuy cũng có 1 số kĩ năng cơ bản của lập trình nhưng những thứ cao siêu như cái TimerUtils thì lại không nhìn ra gì hết.. 1 chữ mù . Với lại cách sử dụng thì sử dụng theo mẫu có sẵn chứ thực chất cũng không hiểu gì .. nên mạo mụi lên đây hỏi.. không biết những người biết Jass và Pro Jass trên 4rum mình có ai có thể bỏ chút thời gian mô tả một vài hệ thống hỗ trợ tốt cho việc làm Spell, và nếu được có thể Add một số ví dụ để đưa đường dẫn lối cho nhiều anh em yêu WE hơn đến với JASS.. Hiện tại thì e chỉ biết làm Spell MUI đơn giản = cách Convert từ GUI sang JASS và sửa biến thành local cộng thêm làm 1 số skill đơn giản với TimerUtils ... nhưng phức tạp hơn thì thực sự không biết làm sao. @raivor : Tui không đồng ý ở quan điểm "Cấm tuyệt đối không được Convert từ GUI sang JASS " .. bạn phải hiểu muốn học JASS thì phải bắt đầu từ GUI.. vì GUI cũng từ JASS mà ra thôi . Khi bạn đã rõ GUI thì việc convert từ GUI sang JASS sẽ giúp bạn giải quyết rất nhiều vấn đề khi mới học JASS.. làm một Spell muốn MUI từ GUI bạn phải sử dụng biến mảng toàn cục hoặc custom value .. còn MUI ở JASS bạn sử dụng biến cục bộ local nên sẽ không ảnh hưởng gì khi một spell được cast cùng lúc từ nhiều đối tượng.. vì biến này chỉ thực hiện lệnh ở trong 1 cục bộ Function đó thôi, không chạy ra ngoài được. Vì thế mới học người ta thường Convert từ GUI sang JASS để biết đường mà thay đổi từ biến Global thành biết local để cho Spell nó MUI. Do đó Với người mới học JASS muốn làm Spell thì chỉ có con đường duy nhất là đi từ GUI thôi.. còn việc bạn học JASS , biết JASS nhưng không convert từ GUI ra cũng khó lòng làm được. Cho nên cấm nó coi như không học. Bạn có thể tham khảo một vài ví dụ của anh HyaTHa_dk ở Topic này http://forum.gamevn.com/showthread.php?216534-Jass-ngon-ngu-co-ban-cua-War-3-Cac-ban-vao-tham-khao để thử làm spell JASS cơ bản xem. mấy cái này làm MUI khá dễ ^^.
cấm "convert GUI -> JASS rồi post", hiểu không? nói thật: hồi mới học JASS, tôi chưa nhớ được các hàm, đều convert từ GUI ra mới lấy được tên hàm. nói cấm là cấm cái này: Mã: function Trig_EpDo2_Func001Func001Func001C takes nothing returns boolean function Trig_EpDo2_Func001Func001Func002C takes nothing returns boolean function Trig_EpDo2_Func001Func001Func003C takes nothing returns boolean function Trig_EpDo2_Func001Func001Func004C takes nothing returns boolean thấy chưa? có cần thiết phải dài như vậy không? và Mã: if ( not ( [U]GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 1)) == 'I000'[/U] ) ) then return false endif cái điều kiện đó là điều kiện cần ở đây, tại sao phải not để nó false (rồi return false) từ GUI ra nên nó như vậy đã viết JASS thì phải bỏ các thứ dư thừa đi Mã: if ( [U]GetItemTypeId(UnitItemInSlotBJ(GetManipulatingUnit(), 1)) == 'I000'[/U] ) then return true endif không phải cứ local là MUI ngay được đâu
Mình thì không biết mấy ver trước của newgen ra sao, chứ JNG1.5d có một công cụ rất hữu ích, đó là Function List, việc tìm kiếm các hàm trong Function List không hề khó nếu như bạn đã quen với GUI. Trừ khi nào bí lắm mới phải convert từ GUI sang Jass. Cái thứ 2, khi convert từ GUI ra Jass, ở một số spell phức tạp, trigger của bạn sẽ dài hàng "cây số", chưa kể rất khó nhìn, vì đâu đâu cũng function, còn ngồi edit lại cho nó giống với Jass chứ không còn là "Convert từ GUI sang Jass" thì thà mình ngồi mò các hàm rồi tự viết ra còn hơn. Tuy nhiên, các bạn học jass thế nào là quyền của các bạn, nhưng khi đã post bài hướng dẫn người khác (ở đây đa số là những người đã quen với GUI) mà post một phần là GUI còn một phần là "Convert GUI sang Jass" thì không phải bạn đang làm chuyện dư thừa , vì thế, ý mình ở đây, là spell ở dạng GUI là làm theo cách của GUI, còn Jass thì làm theo cách của Jass. Là như vậy đó, đừng hiểu lầm ý của mình lần nữa. À nhân tiện cho em hỏi, khi tạo một struct, thì có thể dùng struct đó ở một function "không thuộc" struct đó được không? nếu được thì việc dùng function với dùng method, cái nào tốt hơn. Và khi cho chạy timer trong một function thì làm sao để "pick unit" trong group khi đã "add unit vào group" trong function "chính"(là function kiểu dùng để khai báo ấy)
Mã: function Trig_Blizzard_Run_Copy_Conditions takes nothing returns boolean if ( not ( GetUnitTypeId(GetDyingUnit()) == 'h00X' ) ) then return false endif if ( not ( GetUnitAbilityLevelSwapped('A003', GetDyingUnit()) > 0 ) ) then return false endif if ( not ( GetUnitUserData(GetDyingUnit()) > 0 ) ) then return false endif return true endfunction Cho mình hỏi cách làm ngắn đoạn code này với. biết làm với 1 điều kiện nhưng 2 điều kiện trở lên thì hẻm biết ^^
Như này: Mã: [B]function[/B] TrigConditions(vậy cho ngắn) [B]takes [COLOR="#336699"]nothing[/COLOR] returns [COLOR="#336699"]boolean[/COLOR][/B] [B]local [COLOR="#336699"]unit[/COLOR][/B] u [COLOR="#8B4513"]=[/COLOR] [COLOR="#800080"]GetDyingUnit[/COLOR][COLOR="#8B4513"]()[/COLOR] [B]local [COLOR="#336699"]integer[/COLOR][/B] id [COLOR="#8B4513"]=[/COLOR] [COLOR="#800080"]GetUnitTypeId[/COLOR][COLOR="#8B4513"]([/COLOR]u[COLOR="#8B4513"])[/COLOR] [B]local [COLOR="#336699"]integer[/COLOR][/B] lvl [COLOR="#8B4513"]=[/COLOR] [COLOR="#800080"]GetUnitAbilityLevel[/COLOR][COLOR="#8B4513"]([/COLOR]u, [I][U][B]'A003'[/B][/U][/I][COLOR="#8B4513"])[/COLOR] [B]local [COLOR="#336699"]integer[/COLOR][/B] v [COLOR="#8B4513"]=[/COLOR] [COLOR="#800080"]GetUnitUserData[/COLOR][COLOR="#8B4513"]([/COLOR]u[COLOR="#8B4513"])[/COLOR] [B]if[/B] [COLOR="#8B4513"]([/COLOR]id [COLOR="#8B4513"]==[/COLOR] [I][U][B]'h00X'[/B][/U][/I][COLOR="#8B4513"])[/COLOR] [B]and[/B] [COLOR="#8B4513"]([/COLOR]lvl > [COLOR="#0000CD"]0[/COLOR][COLOR="#8B4513"])[/COLOR] [B]and[/B] [COLOR="#8B4513"]([/COLOR]v > [COLOR="#0000CD"]0[/COLOR][COLOR="#8B4513"])[/COLOR] [B]then[/B] [B]return[/B] [COLOR="#0000CD"]true[/COLOR] [B]endif[/B] [B] return[/B] [COLOR="#0000CD"]false[/COLOR] [B]endfunction[/B]
PHP: scope Impale initializer ImpaleInit globals private integer IdSpell = 'A014' private integer IdDummy = 'h018' private integer IdSpellDum = 'A037' endglobals private function Conditions takes nothing returns boolean return GetSpellAbilityId() == IdSpell endfunction private function Actions takes nothing returns nothing local unit cast = GetTriggerUnit() local unit u local location castloc = GetUnitLoc(cast) local location target = GetSpellTargetLoc() local location temploc local real angle = AngleBetweenPoints(castloc, target) local integer A = -2 local integer lv = GetUnitAbilityLevel(cast,IdSpell) loop exitwhen A > 2 set temploc = PolarProjectionBJ(castloc, 50, angle+ ( 20.00 * A )) call CreateUnitAtLoc(GetOwningPlayer(cast),IdDummy,castloc,angle) set u = GetLastCreatedUnit() call UnitAddAbility(u, IdSpellDum) call SetUnitAbilityLevel(u, IdSpellDum, lv ) call IssuePointOrderLoc(u, "impale", temploc) call UnitApplyTimedLife(u, 'BTLF', 3) call RemoveLocation(temploc) set temploc = null set u = null set A = A + 1 endloop call RemoveLocation(target) call RemoveLocation(castloc) call RemoveLocation(temploc) set cast = null set target = null set castloc = null set temploc = null set u = null endfunction //=========================================================================== private function ImpaleInit takes nothing returns nothing local trigger t = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( t, Condition( function Conditions ) ) call TriggerAddAction( t, function Actions ) endfunction endscope Xin hỏi đoạn code trên này sai chỗ nào mà khi cast spell thì tự nhiên con Caster lại bị add Spell luôn chứ không phải là cung Unit U = GetLastCreatedUnit được Add spell.. với lại cast Spell thì con Caster bị Add ExpiredTimer nên nó ra đi luôn ngay sau đó. không hiểu đoạn trên sai chỗ nào mà đoạn code nó không làm việc đúng thế +_+
Create unit như vậy không hợp với jass, với lại nên hạn chế dùng biến location. Mã: scope Impale initializer ImpaleInit globals private integer IdSpell = 'A014' private integer IdDummy = 'h018' private integer IdSpellDum = 'A037' endglobals private function Conditions takes nothing returns boolean return GetSpellAbilityId() == IdSpell endfunction private function Actions takes nothing returns nothing local unit cast = GetTriggerUnit() local unit u[COLOR="#FF0000"] local unit target = GetSpellTargetUnit() local real x = GetUnitX(cast) local real y = GetUnitY(cast) local real tx = GetUnitX(target) local real ty = GetUnitY(target) local real dx local real dy local real angle = bj_RADTODEG*Atan2(ty - y, tx - x)[/COLOR] local integer A = -2 local integer lv = GetUnitAbilityLevel(cast,IdSpell) loop exitwhen A > 2 [COLOR="#FF0000"]set dx = x + 50*(Cos(angle*bj_DEGTORAD)+20*A) set dy = y + 50*(Sin(angle*bj_DEGTORAD)+20*A) set u = CreateUnit(GetOwningPlayer(cast), IdDummy, x, y, angle)[/COLOR] call UnitAddAbility(u, IdSpellDum) call SetUnitAbilityLevel(u, IdSpellDum, lv ) call IssuePointOrder(u, "impale", dx, dy) call UnitApplyTimedLife(u, 'BTLF', 3) set u = null set A = A + 1 endloop set cast = null set target = null set u = null endfunction //=========================================================================== private function ImpaleInit takes nothing returns nothing local trigger t = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( t, Condition( function Conditions ) ) call TriggerAddAction( t, function Actions ) endfunction endscope Cơ mà, có cần thiết phải có dòng "set temploc = PolarProjectionBJ(castloc, 50, angle+ ( 20.00 * A ))" không tại sao không lấy location của target luôn?
đơn giản là vì: CreateUnitAtLoc KHÔNG trả về GetLastCreatedUnit() Mã: call CreateUnitAtLoc(GetOwningPlayer(cast),IdDummy,castloc,angle) set u = GetLastCreatedUnit() nên là Mã: set u = CreateUnitAtLoc(GetOwningPlayer(cast),IdDummy,castloc,angle) và dùng location cũng được, nhưng sẽ đến lúc tự thấy rằng dùng x, y (real) tốt hơn. lấy luôn là sao?
Ok thanks hai bác.. trong lúc chưa tìm hiểu nguyên nhân vì sao thì mình dùng tạm CreateNUnitsAtLoc .. bây giờ thì lấy được rồi.. :). dùng x,y tránh phải khai báo location nên tránh được việc bị leak hả???
đơn giản thế này: x, y là real, không leak location là handle, leak (nếu không remove) vậy thôi. ngoài ra, việc xử lý (process) với real nhanh hơn location
bj_RADTODEG*Atan2(ty - y, tx - x) set dx = x + 50*(Cos(angle*bj_DEGTORAD)+20*A) set dy = y + 50*(Sin(angle*bj_DEGTORAD)+20*A) mình không hiểu mấy thứ này lắm.. bạn nói kĩ hơn được không .. vì sao khi khai real angle lại phải dùng cái này.