Arcane.pl
Portal twórców map i modów:
WarCraft 3 StarCraft 2 i innych gier
Napisano: 01.05.2010
Ten tutorial pokazuje jak posługiwac sie Jass'em w Swiecie wara, wiec zaczynamy!
1. Najpierw czego potrzebujemy to edytor JASS (JASSCraft 1.1.2 jest najlepszy)

To teraz tak ogolnikowo o pisaniu w JASSie
1. W pierw deklarujemy zmienna, ktora jest typem gracza i od razu przypisuje sie jej wartosc gracza sterowanego przez usera
| globals player user = PlayerEx(1) //Graczem jest Gracz 1 - czerwony endglobals |
2. W Jassie mamy dwa rodzaje dostepu do jednostek i udoskonalen ras
- tzw RAWCODE (mozna w edytorze sobie takie kody zdobyc
- I konwersje RAWCODE'ow przez JASSCrafta - ta opcja jest wygodniejsza
3. Po zdeklarowaniu zmiennej mozemy przystapic do pisania glownego kodu SI stosujac poznizsza formule
| function main takes nothing returns nothing call CampaignAI(ZIGGURAT_1,null) //glowne zaopatrzenie zywnosci call SetReplacements(2,2,3) // tego jeszcze nierozpracowalem :? set campaign_wood_peons = 2 // liczba robotnikow ktora zbiera drewno |
3. Mamy juz wroga dla SI i Wykaz robotnikow dla kompa, teraz bedziemy pisac instrukcje do szkolenia jednostek i budowy budynkow.
| call SetBuildUnitEx( 1, 1, 1, ACOLYTE ) call SetBuildUnitEx( 0, 0, 1, NECROPOLIS_1 ) call SetBuildUnitEx( 0, 0, 1, CRYPT ) call SetBuildUnitEx( 0, 0, 5, ZIGGURAT_1 ) call SetBuildUnitEx( 0, 0, 1, GRAVEYARD ) call SetBuildUnitEx( 0, 0, 1, UNDEAD_ALTAR ) call SetBuildUnitEx( 0, 0, 1, NECROPOLIS_2 ) call SetBuildUnitEx( 0, 0, 1, DAMNED_TEMPLE ) call SetBuildUnitEx( 0, 0, 4, ZIGGURAT_2 ) call SetBuildUnitEx( 2, 2, 2, UNDEAD_BARGE ) call SetBuildUnitEx( 5, 5, 5, ACOLYTE ) |
Dzięki takiemu szkoleniu otrzymamy calkiem niezla armie, zauwazcie ze w funkcjach sa trzy rozne cyferki oddzielone przecinkami, oznacza to ile ma byc wyszkolonych jednostek na danym poziomie trudnosci gry (1 cyferka - poziom latwy, 2 cyferka - poziom normalny, 3 cyferka - poziom trudny)
Ok - szkolenie jednostek mamy za soba, teraz wypadaloby ustawic obroncow bazy, uzywasie do tego funkcji
| call CampaignDefenderEx(l,n,t, unit) |
Przy pisaniu tej formulki nalezy literki 'l,n,t' zastapic cyframi (patrz wyzej), a w miejsce 'unit' podac ID jednostki (RAWCODE, lub konwersja RAWCODE)
Zrobmy tak, zeby bazy bronili po jednm ghulu, necromancie i banshee na kazdym poziomie trudnosci.
| call CampaignDefenderEx( 1, 1, 1, GHOUL ) call CampaignDefenderEx( 1, 1, 1, BANSHEE ) call CampaignDefenderEx( 1, 1, 1, NECRO ) |
Teraz pierwsze tego typu wyszkolone jednostki beda bronic obozu i zostana pominiete podczas przygotowania fali uderzeniowej, w ich miejsce zostana doszkolone nowe jednostki.
Wazne, aby zawsze po wpisaniu rozbudowy obozu uzyc tej funkcji
| call WaitForSignal() |
Dzieki temu komputer zostanie poinformowany o tym czy moze juz atakowac wroga - takim triggerem (nie edytor triggerow w WE)
moze byc na przyklad wyzszy level udoskonalen.
Jezeli komp ostanie taki sygnal to rozpocznie przygotowanie oblezenia. Mozesz mu wtedy zaimplementowac niewielki oddzial zwiadowczy
| call InitAssaultGroup() call CampaignAttackerEx( 2,2,4, GHOUL ) call CampaignAttackerEx( 2,2,4, BANSHEE ) call SuicideOnPlayerEx(M3,M3,M2,user) |
w Funkcji
| call SuicideOnPlayerEx |
M oznacza Minute, a cyferka jest mnoznikiem minuty (wtedy zapis by wygladal tak (M*2) i to jest opoznienie ataku na poszczegolnych poziomach trudnosci. (poziom latwy i normalny - delay 2minuty, na hardzie 3minuty).
W ten sposob przygotowywujemy kilka roznych fal (3-5 wystarczy), aby skrypt sie nie zakoczyl,
to robi sie cos takiego
| loop call InitAssaultGroup() call CampaignAttackerEx( 3,3,5, NECRO ) call CampaignAttackerEx( 3,3,4, CRYPT_FIEND ) call CampaignAttackerEx( 1,1,2, MEAT_WAGON ) call SuicideOnPlayerEx(M5,M5,M3,user) call InitAssaultGroup() call CampaignAttackerEx( 5,5,7, GHOUL ) call CampaignAttackerEx( 3,3,4, BANSHEE ) call SuicideOnPlayerEx(M5,M5,M3,user) endloop endfunction |
To jest narazie czesc pierwsza i ten skrypt bedziemy udoskonalac. Ponizej znajduje sie pelny skrypt dla nieumarlych.
ABY SKRYPT ZADZIALAL TO ZAPISUJEMY GO Z ROZSZERZENIEM .aiPotem to importujemy do mapy, ustawiamy komputerowego gracza i dajemy mu w cholere surowcow i funcja w edytorze wyzwalaczy startujemy SI
| Wydarzenia - Map Initialization Warunki - brak Akcje: SI - start campaign AI for (tu wybieramy gracza sterowanego przez kompa) SI - Send AI Command (0,1) for player - (nie pamietam czy ta akcja dokladnie tak brzmi, ale cos takiego jest) |
NA DZIS KONIEC.
-------------------------------------------------------------------------------------
Oto dzialajace demo skryptu (wskazowki wyzej jak je uruchomic)
globals player user = PlayerEx(1) endglobals //============================================================================ // main //============================================================================ function main takes nothing returns nothing call CampaignAI(ZIGGURAT_1,null) call SetReplacements(2,2,3) set campaign_wood_peons = 2 call SetBuildUnitEx( 1, 1, 1, ACOLYTE ) call SetBuildUnitEx( 0, 0, 1, NECROPOLIS_1 ) call SetBuildUnitEx( 0, 0, 1, CRYPT ) call SetBuildUnitEx( 0, 0, 5, ZIGGURAT_1 ) call SetBuildUnitEx( 0, 0, 1, GRAVEYARD ) call SetBuildUnitEx( 0, 0, 1, UNDEAD_ALTAR ) call SetBuildUnitEx( 0, 0, 1, NECROPOLIS_2 ) call SetBuildUnitEx( 0, 0, 1, DAMNED_TEMPLE ) call SetBuildUnitEx( 0, 0, 4, ZIGGURAT_2 ) call SetBuildUnitEx( 2, 2, 2, UNDEAD_BARGE ) call SetBuildUnitEx( 5, 5, 5, ACOLYTE ) call CampaignDefenderEx( 1, 1, 1, GHOUL ) call CampaignDefenderEx( 1, 1, 1, BANSHEE ) call CampaignDefenderEx( 1, 1, 1, NECRO ) call SetBuildUpgrEx( 1,1,1, UPG_FIEND_WEB ) call SetBuildUpgrEx( 0,0,1, UPG_NECROS ) call SetBuildUpgrEx( 0,0,1, UPG_BANSHEE ) call SetBuildUpgrEx( 1,1,1, UPG_SKEL_LIFE ) call WaitForSignal() //*** WAVE 1 *** call InitAssaultGroup() call CampaignAttackerEx( 2,2,4, GHOUL ) call CampaignAttackerEx( 2,2,4, BANSHEE ) call SuicideOnPlayerEx(M3,M3,M2,user) call SetBuildUpgrEx( 0,0,1, UPG_UNHOLY_STR ) call SetBuildUpgrEx( 0,1,1, UPG_CR_ATTACK ) //*** WAVE 2 *** call InitAssaultGroup() call CampaignAttackerEx( 3,3,4, CRYPT_FIEND ) call CampaignAttackerEx( 2,2,4, NECRO ) call SuicideOnPlayerEx(M5,M5,M3,user) call SetBuildUpgrEx( 0,0,1, UPG_UNHOLY_ARMOR) call SetBuildUpgrEx( 0,0,1, UPG_CR_ARMOR ) call SetBuildUpgrEx( 1,1,1, UPG_NECROS ) call SetBuildUpgrEx( 1,1,1, UPG_BANSHEE ) //*** WAVE 3 *** call InitAssaultGroup() call CampaignAttackerEx( 3,3,5, GHOUL ) call CampaignAttackerEx( 3,3,5, BANSHEE ) call SuicideOnPlayerEx(M5,M5,M3,user)
//*** WAVE 4 *** call InitAssaultGroup() call CampaignAttackerEx( 3,3,5, GHOUL ) call CampaignAttackerEx( 2,2,4, CRYPT_FIEND ) call CampaignAttackerEx( 1,1,2, BANSHEE ) call SuicideOnPlayerEx(M5,M5,M3,user) call SetBuildUpgrEx( 1,1,2, UPG_UNHOLY_STR ) call SetBuildUpgrEx( 1,1,2, UPG_CR_ATTACK ) //*** WAVE 5 *** call InitAssaultGroup() call CampaignAttackerEx( 4,4,5, GHOUL ) call CampaignAttackerEx( 1,1,2, MEAT_WAGON ) call CampaignAttackerEx( 2,2,3, NECRO ) call SuicideOnPlayerEx(M5,M5,M3,user) call SetBuildUpgrEx( 1,1,2, UPG_UNHOLY_ARMOR) call SetBuildUpgrEx( 1,1,2, UPG_CR_ARMOR ) //*** WAVE 6 *** call InitAssaultGroup() call CampaignAttackerEx( 5,5,7, GHOUL ) call CampaignAttackerEx( 3,3,4, BANSHEE ) call SuicideOnPlayerEx(M5,M5,M3,user) //*** WAVE 7+ *** loop call InitAssaultGroup() call CampaignAttackerEx( 3,3,5, NECRO ) call CampaignAttackerEx( 3,3,4, CRYPT_FIEND ) call CampaignAttackerEx( 1,1,2, MEAT_WAGON ) call SuicideOnPlayerEx(M5,M5,M3,user) call InitAssaultGroup() call CampaignAttackerEx( 5,5,7, GHOUL ) call CampaignAttackerEx( 3,3,4, BANSHEE ) call SuicideOnPlayerEx(M5,M5,M3,user) call InitAssaultGroup() call InitAssaultGroup() call CampaignAttackerEx( 3,3,5, GHOUL ) call CampaignAttackerEx( 2,2,4, CRYPT_FIEND ) call CampaignAttackerEx( 2,2,3, BANSHEE ) call CampaignAttackerEx( 1,1,2, NECRO ) call SuicideOnPlayerEx(M5,M5,M3,user) endloop endfunction |
[color=green]Aktualizacja nizej[/color]
Wiec zaczynamy: Uczymy Kel'thuzada zdolnosci Lisza.
| function SetHero takes integer order, integer heroid returns nothing |
W ten sposob rozpoczynamy funkcje, zmienna order to kolejnosc szkolonych herosow przez AI, a zmienna heroid to identyfikator jednostki.
Musimy sprawdzic czy Kel'thuzad jest pierwszym herosem, a wiemy ze jest pierwszym (z reszta jedynym)
| if (order == 1) then set hero_id = heroid if (heroid == 'Uktl') then set skills1[ 1] = 'AUfn' set skills1[ 2] = 'AUfu' set skills1[ 3] = 'AUdr' set skills1[ 4] = 'AUfn' set skills1[ 5] = 'AUfu' set skills1[ 6] = 'AUdd' set skills1[ 7] = 'AUdr' set skills1[ 8] = 'AUfn' set skills1[ 9] = 'AUfu' set skills1[10] = 'AUdr' endif endif |
W pierwszej czesci instrukcji warunkowej IF/THEN sprawdzamy czy kolejnosc ma wartosc 1, jesli tak, to trzeba zmienna lokalna hero_idprzyrownac do zmiennejheroid
Tutaj nieuzywamy juz stalych z pliku common.ai, tylko rawcode
No wiec, jezeli warynek hero_id == heroid
to zmiennej heroid przypisujemy wartosc Uktl. To jest rawcode dla Kelthuzada w postaci Lisza. W ten sposob mamy juz wszystko co trzeba, ale musi sie uczyc zdolnosci, a SI narazie nie wie jakie Lisz ma zdolnosci. Dlatego uzywa sie fukcji
| set_skill[level] == 'rawcode zdolnosci' |
Gdy w skrypcie SI mamy zadeklarowanego herosa i jego zdolnosci to przy kazdym awansie na wyzszy level bedzie sie uczyl zdolnosci z funkcji.
Spojrzcie tu:
| set skills1[ 1] = 'AUfn' //Na 1 levelu nauczy sie Novy Mrozu set skills1[ 2] = 'AUfu' //Na 2 levelu nauczy sie Zbroi mrozu set skills1[ 3] = 'AUdr' //Na 3 levelu nauczy sie mrocznego rytualu set skills1[ 4] = 'AUfn' //ITD. set skills1[ 5] = 'AUfu' set skills1[ 6] = 'AUdd' //na 6 levelu juz opanuje Smierc i Rozklad set skills1[ 7] = 'AUdr' set skills1[ 8] = 'AUfn' set skills1[ 9] = 'AUfu' set skills1[10] = 'AUdr' |
UWAGA! Skrypt nie zadziala, jezeli index Lisza nie bedzie rowny 1, jezeli pierwszym bohaterem jest ktos inny, a Lisz jest drugi, to kod powinien wygladac tak:
| set skills2[ 1] = 'AUfn' set skills2[ 2] = 'AUfu' set skills2[ 3] = 'AUdr' set skills2[ 4] = 'AUfn' set skills2[ 5] = 'AUfu' set skills2[ 6] = 'AUdd' set skills2[ 7] = 'AUdr' set skills2[ 8] = 'AUfn' set skills2[ 9] = 'AUfu' set skills2[10] = 'AUdr' |
Podsumowujac, narazie wiemy jak uczyc kelthuzada (lisza), ale narazie to nie zadziala, brakuje nam jeszcze 2 funkcji:
1. Sprawdzania indexu herosa na 3 rozne sposoby
2. Zwracanie wartosci poziomu herosa podczas awansu na wyzszy level.
Ad 1.
| function SelectHeroes takes nothing returns nothing local integer roll = GetRandomInt(1,100) call SetHero( 1, 'Uktl' ) endfunction |
Ad 2.
| function ChooseHeroSkill takes nothing returns integer local integer curHero = GetHeroId() local integer level = GetHeroLevelAI() if (level > max_hero_level) then set max_hero_level = level endif if (curHero == hero_id) then return skills1[level] elseif (curHero == hero_id2) then return skills2[level] elseif (curHero == hero_id3) then return skills3[level] endif return 0 endfunction |
Narazie na dzis to wszystko, jutro ciag dalszy. Cały kod powinien tak wygladac
| function SetHero takes integer order, integer heroid returns nothing if (order == 1) then set hero_id = heroid if (heroid == 'Uktl') then set skills1[ 1] = 'AUfn' set skills1[ 2] = 'AUfu' set skills1[ 3] = 'AUdr' set skills1[ 4] = 'AUfn' set skills1[ 5] = 'AUfu' set skills1[ 6] = 'AUdd' set skills1[ 7] = 'AUdr' set skills1[ 8] = 'AUfn' set skills1[ 9] = 'AUfu' set skills1[10] = 'AUdr' endif endif endfunction //=========================================================================== function SelectHeroes takes nothing returns nothing local integer roll = GetRandomInt(1,100) call SetHero( 1, 'Uktl' ) endfunction //=========================================================================== function ChooseHeroSkill takes nothing returns integer local integer curHero = GetHeroId() local integer level = GetHeroLevelAI() if (level > max_hero_level) then set max_hero_level = level endif if (curHero == hero_id) then return skills1[level] elseif (curHero == hero_id2) then return skills2[level] elseif (curHero == hero_id3) then return skills3[level] endif return 0 endfunction |
|
Na Forum jest 10 użytkowników :: 0 zarejestrowany i 10 gości (oparte na użytkownikach aktywnych przez ostatnie 5 minut) Zarejestrowani użytkownicy: W ciagu ostatnich 24 godzin forum odwiedziło 0 użytkowników: |