Anasayfa
UO Sunucular
Forumlar
Profilim
UO-Developer.COM
[EVENTS] Yüklemesi Kullanımı

Temel bir olay aşağıdaki gibi görünür:
[EVENTS defname]
code
Şimdiye kadar yaptığımız her şeye benziyor değil mi? Olaylar da aynı şekilde çalışır. Oyun içinde veya aşağıdakileri kullanarak bir script dosyası aracılığıyla kurulabilirler:
EVENTS +defname
EVENTS=defname
EVENTS -defname
Bunlar çok farklı üç komuttur. Bazı insanlar onları karıştırmaya meyillidir.

İşte yaptıkları şey:

EVENTS +DEFNAME

Olayı, karakterin olay listesine ekler. Evet, bir karakterin birden fazla eventi olabilir. Aşağıdakilerin her ikisi de karakterde çağrılan tetikleyicilere yanıt verecektir.
SRC.EVENTS +e_death_event
SRC.EVENTS +e_ctf_event
EVENTS =DEFNAME
Bu yöntem kullanılmamalıdır. Bunun yerine karakterdeki diğer tüm Eventleri silecektir.

EVENTS -DEFNAME
Bu, belirtilen Eventı karakterden kaldıracaktır.

BIR [EVENTS] KOMUT DOSYASININ VARSAYILAN NESNESI, KOMUT DOSYASININ YÜKLENDIĞI KARAKTERDIR.

Event İşleme sırası

Öğelere veya karakterlere etkinlik eklemenin birkaç yolu vardır.

Bunlar:

EVENTS +DEFNAME
Bir işlev, başka bir Event, bir oyuncu eylemi veya bir tetikleyicinin (örneğin, @Create tetikleyicisi) içinde ayarlanabilir.

TEVENTS=DEFNAME
ITEMDEF veya CHARDEF gövdesinde. Dilediğiniz kadar TEVENTS hattı olabilir.

TYPE=DEFNAME
(Yalnızca öğeler) ITEMDEF'in gövdesinde. Yalnızca BİR temel tür tanımı olabilir. TİPLER sadece Eventlar değildir, aynı zamanda öğenin bazı temel davranışlarını ve yeteneklerini de belirler.Örneğin, bir öğe donatılabilir türde değilse, donatılamaz.

DOĞRUDAN TETIKLEYICILER(DIRECT TRIGGERS)
Zavallı adamın Eventları: Eventlar genellikle bir öğeye veya karaktere eklenebilecek tetikleyicilerin çeşitliliği olduğundan. Ayrıca, ITEMDEF/CHARDEF'in kendisinde bazı tetikleyici eylemleri "sabit kodlayabilirsiniz".

ORDER OF FIRING

Şu basit kod örneklerine bakın:
[ITEMDEF i_triggertester]
ID=i_floor_wood
TYPE = t_testtype
NAME=TriggerTester
TEVENTS=e_tev_test

ON=@Create
    EVENTS +e_ev_test
   
ON=@DClick
    SERV.LOG item dclick from direct trigger
   
[TYPEDEF e_ev_test]
ON=@DClick
    SERV.LOG dclick from event
   
[TYPEDEF e_tev_test]
ON=@DClick
    SERV.LOG item dclick from tevent
   
[TYPEDEF t_testtype]
ON=@DClick
    SERV.LOG item dclick from base typedef
Bu, aşağıdaki sonuçları verir:
Öğe dEvent öğesinden
dClick Tevent
öğesinden dClick Base Type'tan
dClick Öğe dClick Doğrudan tetikleyiciden

Karakterler için de aynı:
[CHARDEF c_testorc]
ID=c_orc
NAME=TestOrc
TEVENTS=e_tev_character

ON=@Create
    STR = 100
   
ON=@NPCRestock
    EVENTS +e_ev_character
   
ON=@DClick
    SERV.LOG char dclick from direct trigger
   
[EVENTS e_tev_character]
ON=@DClick
    SERV.LOG char dclick from tevent
   
[EVENTS e_ev_character]
ON=@DClick
    SERV.LOG char dclick from event
Sonuçlar:
char dclick from event
char dclick from tevent
char dclick from direct trigger

İtem Bazlı Eventler

İki ana Event türü vardır:

ITEM EVENT
Herhangi bir oyuncu belirli bir öğeyle belirli bir şekilde etkileşime girdiğinde tetiklenir.

PLAYER EVENT
Belirli bir oyuncu herhangi bir öğeyle belirli bir şekilde etkileşime girdiğinde veya hareket etme, büyü yapma, bir öğe yapma vb. gibi belirli görevleri yerine getirme durumunda tetiklenir.

Öğe komut dosyasında, öğe varsayılan nesnedir. Oynatıcı komut dosyasında, oynatıcı varsayılan nesnedir.

Peki nedir bu Eventler? İşte bunlardan bazılarının kısa bir listesi:

@itemDClick - Oyuncu herhangi bir öğeye çift tıkladığında tetiklenir. Öğe için başvuru nesnesi ACT'dir.
@itemEquip - Oyuncu herhangi bir öğeyi kuşandığında tetiklenir. Öğe için başvuru nesnesi ACT'dir.
@itemUnEquip - Oyuncu herhangi bir öğeyi kuşandığında tetiklenir. Öğe için başvuru nesnesi ACT'dir.
@itemClick - Oyuncu herhangi bir öğeye çift tıkladığında tetiklenir. Öğe için başvuru nesnesi ACT'dir.
@itemStep - Oyuncu herhangi bir öğeye bastığında tetiklenir. Öğe için başvuru nesnesi ACT'dir.

Bu açıklamalar arasında benzer bir şey fark ettiniz mi? Eğer yapmazsan, bence geri dönüp okuma dersleri almalısın. Doğru. @item ile başlayan HERHANGİ bir komut dosyasında, ACT, üzerinde işlem yapılan öğedir. Ne dersiniz? Sizce neden buna ACT dediler?

Her durumda, @item komut dosyaları için aşağıdakiler doğrudur:

ACT = üzerinde işlem yapılan
SRC = oyunculuğu yapan karakter (Eventi olan oyuncu)
[] = oyunculuğu yapan karakter (Eventi olan oyuncu)

Bu durumda, SRC ve varsayılan nesnenin her ikisinin de karaktere başvurduğuna dikkat edin. BU her zaman böyle değildir. Karaktere atıfta bulunmak istiyorsanız, bir Eventde SRC yerine varsayılan nesneyi kullanma alışkanlığı edinin. Şimdi, oldukça işe yaramaz bir Evente bir göz atalım:
[EVENTS e_test_events]
ON=@itemStep
    SYSMESSAGE You have stepped on <ACT.NAME>!
    RETURN 0
Bu komut dosyasını dosyalarınızdan birine yerleştirin ve sunucunuzu yeniden senkronize edin. Şimdi oyuna girin ve şunu yazın: .xevents +e_test_events Kendinizi hedefleyin. Tebrikler, kendinize bir etkinlik yüklediniz. Bu noktadan itibaren, Eventi kaldırana kadar, bir öğenin üzerine her yürüdüğünüzde rahatsız edici bir mesaj alacaksınız. Deneyin. Etrafta dolaşın, bir şeylerin üzerinde yürüyün! "Böcek" adı verilen bir eşya yapın ve üzerlerine basarak etrafta dolaşın.

İşte size bahse girerim zaten tahmin ettiğiniz küçük bir sır:

ÜM EŞYA ETKİNLİKLERİNİN (@Timer HARIÇ) @item BIR KARŞILIĞI VARDIR.
Bu, @itemPickUp_Pack, @itemTargOn_Char, @itemTargOn_Item ve diğerlerinin hepsinin (teoride) çalışması gerektiği anlamına gelir.

Çevresel Eventler

Bu bölüm sadece bir Eventi açıklamaya hizmet eder, çünkü bazı kavramları önceden tanıtmamız gerekir. Tanıtacağımız ilk kavram SECTOR kavramıdır. Oyunda harita sadece bölgelere değil, sektörlere de ayrılıyor. Sektörler, haritanın varsayılan olarak 64 karo genişliğinde ve 64 karo yüksekliğinde olan kısımlarını temsil eder. Bölgeler arasında örtüşebilirler. Örneğin, bir sektör Britanya'nın üst köşesi ve Britanya mezarlığının çoğudur. Işık seviyesi, hava durumu ve karmaşıklık bilgileri gibi bilgileri tutarlar.

Ayrıca dünya dikey olarak bantlara ayrılmıştır ki biz bunları burada yerel alanlar olarak adlandıracağız. Bu, gün batımları sırasında ışığın gerçekçi bir şekilde solması ve gerçek bir "dönen" dünya etkisi amacıyla kullanılır.

Bu sektörleri nasıl manipüle ederiz? Herhangi bir komut dosyasında kullanabileceğiniz bir SECTOR nesnesi vardır ve bu, belirli nesnenin oturduğu sektörü ifade eder. Bu SECTOR nesnesi ÇOK sınırlı sayıda değişkene ve fonksiyona sahiptir:

KARMAŞIKLIK
SECTORdeki karakter sayısını (hem PC hem de NPC) döndürür. Bu, büyük bir efekt tabanlı senaryonuz varsa ve bir sektördeki herkesi geride bırakmak istemiyorsanız kullanışlıdır. Ayrıca, NPC'lerin kalabalık alanlarda konuşmaların büyük bölümlerini spam olarak göndermemesi için de yararlıdır. Oyunla birlikte verilen konuşma dosyalarına bakarsanız, bunun kullanımda olduğunu göreceksiniz.

MEVSİM
SECTOR'ün en ilginç özelliklerinden biri, müşterinin hangi "mevsimsel" grafikleri gösterdiğini kontrol etmesidir. Bu işleve geçirebileceğiniz değerler şunlardır:

0 İlkbahar mevsimi (bol çiçek)
1 Yaz saati sezonu (bu varsayılandır)
2 Sonbahar mevsimi (tüm ağaçların "sonbahar" yaprakları vardır ve çok sayıda mantar vardır)
3 Kış mevsimi (zemin karla kaplıdır ve ağaçların yaprağı yoktur)
4 Ölü mevsim (ağaçlarda yaprak yok, mezar taşları ve her yerde vahşet yok)

LIGHT <level>
Işık seviyesini temsil eden 0 ile 30 arasında bir değer tutar, 0 tam gün ışığı ve 30 zifiri karanlıktır. T2A öncesi istemcilerde 18 en koyu IŞIK değeridir. Ona bir değer verirseniz, ışığı o seviyeye ayarlayacaktır. Aksi takdirde, ışık seviyesini o andaki varsayılan değeri ne olursa olsun ayarlayacaktır. (Bkz. LOCALLIGHT.)

LOW
Aslında kullanılan - COMPLEXITY.LOW. Karmaşıklık "düşük" düzeydeyse 1 döndürür.

MEDIUM
Aslında kullanılan - COMPLEXITY.MEDIUM. Karmaşıklık "orta" düzeydeyse 1 döndürür.

HIGH
Aslında kullanılan - COMPLEXITY.HIGH. Karmaşıklık "yüksek" düzeydeyse 1 döndürür.

ALLCLIENTS <function call>
Bu tıpkı SERV gibi kullanılabilir. ALLCLIENTS veya SECTOR. TÜM Clientler. Burada verilen herhangi bir işlev, sektördeki herhangi bir oyuncu üzerinde yürütülecektir. Bunu kullanmak akıllıca bir şey değil, çünkü oyuncu aslında beklediğinizden farklı bir sektörde olabilir.

RAIN
Bu da sektördeki tüm oyuncular için yağmur yağdırıyor.

SNOW
Sektördeki tüm oyuncular için kar yağmasını sağlar. (SSECTOR.RAIN, ardından SECTOR.SNOW ilginçtir. Bu garip yağmur/kar karışımını elde edersiniz.)

DRY
Hem yağmuru hem de karı kapatır.

RESTOCK
Tüm spawn noktalarının kendilerini çift tıklamasına ve bölgedeki tüm spawnları sıfırlamasına neden olur. Bir şeyin ganimeti yeni değiştirdiyseniz kullanışlıdır.

ISDARK
"Karanlık" eşiğin altında olup olmadığını görmek için sektörün ışık seviyesini test eder.

LOCALTOD
Gerçek hayattaki saat dilimleri gibi LOCAL alanlarda tutulan bir saat var. Bu, bölgede "gece" olup olmadığını görmek için saati kontrol eder. Mutlaka karanlık olmak zorunda değildir.

YERELTOD
Bu "saat dilimi" için günün LOCAL saatini döndürür.

LOCALTIME
LOCAL saati şu şekilde döndürür: "Akşam yediyi çeyrek geçe"

LOCALLIGHT
Bu LOCAL alandaki değiştirilmemiş sektörlerdeki ışık seviyesi. Bu işlevi parametresiz çağırdığınızda LIGHT tarafından kullanılır.

Şimdi, başlangıçta tartıştığımız şeye geri dönelim.

SEKTÖR ile ilişkili etkinlik @EnvironChange. Bu şaşırtıcı derecede yararlı bir Eventdır çünkü bu sektör değişkenlerinden HERHANGİ BİRİ her değiştirildiğinde tetiklenir. Buna LOCALTIME de dahildir, yani @EnvironChange yaklaşık her on saniyede bir tetiklenir. (Sunucunuzdaki oyun saatinin hızına bağlıdır.)

Bu, @EnvironChange karakterler için tekrar eden tek Event yapar. Aslında bir tane daha var, ancak henüz REGION fonksiyonlarını öğrenmediniz. Bu çok kullanışlı
[EVENTS e_Human_Environ]
ON=@EnvironChange // 1
    IF (<FLAGS> & statf_war) // 2
        RETURN 0
    ENDIF
    IF !(<SECTOR.ISDARK>) || (<FLAGS> & statf_nightsight) // 3
        IF (<FINDLAYER.layer_hand2>) // 4
            IF (<FINDLAYER.layer_hand2.TYPE> == t_light_lit)
                FINDLAYER.layer_hand2.BOUNCE
            ENDIF
        ENDIF
        RETURN 0
    ENDIF
    // already have a lit light ? (5)
    IF (<FINDLAYER.layer_hand2>) // 6
        IF (<FINDLAYER.layer_hand2.TYPE> == t_light_lit)
            RETURN 0
        ENDIF
    ENDIF
    // type to use a torch or light source if I have one. (and it's dark) (7)
    IF (<FINDTYPE.t_light_out>) // 8
        FINDTYPE.t_light_out.EQUIP
        FINDTYPE.t_light_out.USE
    ENDIF
    RETURN 0
görünmeyebilir, ancak sphere_events_human.scp dosyasından bir komut dosyasına bir göz atalım.

Bu farklı. Bu bizim ilk oldukça karmaşık örnek komut dosyamız, bu yüzden yavaş yavaş alalım. Her şeyden önce, bunun e_Human_Environ'in defname ile bir [ETKİNLİKLER] bölümünde olduğunu görebilirsiniz. (spherechar_human.scp'ye bakarsanız, bu etkinliğin NPC'lerde çok yüklü olduğunu göreceksiniz.) Bu senaryo, karakterin ışık seviyesine bağlı olarak varsa bir meşale donatmasını sağlar. Gece olduğunda ve tüm NPC'leriniz yollarını aydınlatmak için meşalelerle şehirde dolaştığında harika bir Event. Temel olarak, bu komut dosyası aşağıdaki adımlara sahiptir:

1. SECTOR değiştiğinde etkinlik tetiklenir
2. Karakterin savaş modunda olup olmadığını, & operatörünü kullanarak bayraklarını kontrol ederek kontrol ediyoruz. Eğer öyleyse, hiçbir şey yapmasını istemiyoruz, bu yüzden senaryodan hemen geri dönüyoruz.
3. Ardından, karanlık olup olmadığını görmek için karakterin sektörünü kontrol ediyoruz. Aynı IF ifadesinde, NPC'nin gece görüşü FLAGS ayarlayıp ayarlamadığını kontrol ediyoruz. Eğer yaparsa, zaten karanlık olduğunu söyleyemez ve bu yüzden meşalesi olup olmaması önemli değildir. IF ifademizin yapısına göre SECTOR ise doğru olur. ISDARK doğru DEĞİL (!) VEYA (||) <FLAGS> & statf_nightsight doğru olarak değerlendirilir.</FLAGS>
4. Dışarısı karanlık değilse veya karakterin gece görüşü açıksa, onun bir meşale takmasını istemiyoruz, bu yüzden elini (layer_hand2) bir meşale için kontrol ediyoruz. Eğer bir tane varsa, onu karakterin sırt çantasına yerleştirmek için meşale üzerindeki BOUNCE işlevini kullanırız. Komut dosyası daha sonra geri döner.
5. Senaryonun bir sonraki bölümüne ancak dışarısı HEM karanlıksa hem de karakterin gece görüşü açık değilse ulaşılır.
6. Karakterin elinde zaten bir ışık olup olmadığını kontrol eder (layer_hand2). Varsa, betiğin çıkması için başka bir tane donatmamıza gerek yok. Bu tür komut dosyalarında her zaman böyle bir kontrol yapmalısınız. Unutmayın, @EnvironChange neredeyse her on saniyede bir yürürlüğe girecektir. Her on saniyede bir yeni bir meşale kuşanmasını istemiyoruz.
7. Senaryoda bu noktaya ulaşmanın tek olası yolu, aşağıdaki koşulların yerine getirilmiş olmasıdır: dışarısı karanlık, karakterin gece görüşü yok ve karakterin üzerinde meşale yok.
8. En son bölüm, karakterin sırt çantasında herhangi bir meşale olup olmadığını kontrol eder. Unutmayın, FINDTYPE karakterde veya herhangi bir alt kapsayıcıda (sırt çantası) belirli bir türdeki bir nesnenin (bu durumda t_light_out) ilk örneğini döndürür.

Peki, meşale içermeyen bu etkinlik için gerçek bir kullanım nedir? Eğer sphereevents.scp'ye bakarsanız, e_undead adında başka bir [EVENTS] bölümü bulacaksınız, bu da ölü yaratıkları dışarısı aydınlık olduğunda çok çok zayıf yapar ve geceleri normal güçlerini oluşturur. Normal güçlerini geçici olarak depolamak için bir TAG kullanır.

Bölümün sonunda @EnvironChange etkinliği için başka bir kullanım göreceksiniz. Bunun periyodik bir Event olduğu gerçeğinden yararlanıyorum (yani, çok tekrar ediyor).

Ve düşünmeniz için son bir tavsiye:

Ortamı değiştiren işlevleri (yani mevsimi, hava durumunu, ışığı değiştirme) @EnvironChange tetiğinin içinden çağırırken dikkatli olun.

SECTOR özellikleri değiştiğinde @EnvironChange'in yangınları tetiklediğini hatırlıyor musunuz? Aşağıdaki komut dosyasını kullanırsanız ne olabileceğini düşünüyorsunuz?
// Bunu çalıştırma!
ON=@EnvironChange
    SECTOR.LIGHT += 1
    RETURN 0
Ne olacağını görüyor musunuz? Tetik ateşlendiğinde sektörün ışığı 1 artacak, ancak bu olduğunda ortam değiştiği için tetik tekrar ateşlenecek ve bu ışığın tekrar artmasına neden olacak, bu da tetiğin tekrar ateşlenmesine neden olacak, bu da ışığın tekrar artmasına neden olacak. Oldukça açık bir şekilde, bu iyi bir şey değildir ve sunucunuz bu
ON=@EnvironChange
    IF (<SECTOR.LIGHT> != 5)
        SECTOR.LIGHT = 5
    ENDIF
    RETURN 0
komut dosyası çalıştıktan birkaç saniye sonra çökecek veya donacaktır. @EnvironChange tetikleyicisi altındaki ortamı değiştirmekte ısrar etmeniz gerekiyorsa, sunucunun sonsuz bir döngüye girmesini önleyecek koşullu bir ifade koymalısınız.
ON=@EnvironChange
    IF (<SECTOR.LIGHT> != 5)
        SECTOR.LIGHT = 5
    ENDIF
    RETURN 0
Bu, ışık seviyesini 5'e ayarlayacaktır, ancak yalnızca zaten 5 değilse Sphere, ışığı zaten sahip olduğu değere ayarlarsanız tetiği tekrar ateşlemeyecek kadar zekidir, ancak fikir açık olmalıdır.

İleri Düzey Komut Kullanımı

Bir bölgedeki tüm sektörlere atıfta bulunmanın bir yolu var. Tüm sektörlerde bir işlev çalıştıracağı için biraz ALLCLIENTS gibi çalışır. Bu, tüm bölge için mevsimi değiştirmenin iyi bir yoludur. Bir bölge başka bir bölge içinde yer alıyorsa (örneğin, Britanya Toprakları içinde yer alıyorsa), bu komutu çevredeki bölgede kullanırsanız etkilenecektir

REGION.SECTORS

Örneğin:

REGION.SECTORS SEASON 3

Bu, bölgedeki tüm sektörleri "kış" mevsimine sokacaktır. Sektörlerin bölgelerle "örtüşebileceğini" unutmayın, bu da çevredeki diğer bölgelerde de biraz kış geçirebileceğiniz anlamına gelir.

Tıklama Eventleri

@DClick, @Click ve @Profile
Bu Eventlar, çok fazla özel amaca sahip oldukları için şaşırtıcı bir şekilde az kullanılmaktadır. İşte yaptıklarının bir özeti:

@Click
Kullanıcı başka biri tarafından tıklandı.

@Dclick
Kullanıcı birisi tarafından çift tıklandı.

@Profile
Birisi kullanıcının profiline bakmaya çalışıyor.

Şimdi, bunlar RETURN değerinin son derece önemli olduğu üç Eventdır. Hepsinin, aşağıdakiler gibi çok beklenen varsayılan eylemleri vardır:

@Click Karakterin adı başının üzerinde belirir (Bir allnames makrosu @Click olarak sayılır)
@DClick Karakterin kağıt bebeği ortaya çıkar
@Profile Karakterin kişisel profili açılır

Şimdi, bu Eventlerden herhangi birinden 0 veya 2 döndürürseniz, varsayılan eylem gerçekleşecektir. Kullanıcının adı her zamanki gibi açılır veya kağıt bebeği tıklayıcının ekranında görünür. Ancak bunun olmasını istemediğiniz durumlar vardır. Örneğin, özel büyülerimden biri için, kullanıcının belirli bir süre boyunca herhangi bir yaratığa çift tıklamasına ve o oyuncuya ateş topu atmasına izin veren bir etkinlik oluşturdum.

İşte @Click Eventı için örnek bir komut dosyası. Bu, öldürmeleri belirli bir miktarın üzerindeyse, tıklandığında [MURDERER]'ı oyuncunun adının üzerine koyar. Sunucum Talocon'da da benzer bir şey vardı, yeni oyuncular (belirli bir seviyenin altında becerilere sahip oyuncular) bir [NEWBIE] etiketi ve belirli korumalar aldı.
[EVENTS e_murderer]
ON=@Click
    IF (<KILLS> > 5)
        MESSAGE [MURDERER]
    ENDIF
    RETURN 0  // Adını göster
Metnin varsayılan nesnenin üzerinde görünmesi için burada SYSMESSAGE veya SAY yerine bir mesaj kullanmak istiyoruz. Bu durumda, bu etkinliği içeren oynatıcı budur. SRC, tıklamayı yapan oyuncu olur. Birisi kendisini tıklarsa aynı olabilir, ancak genellikle durum böyle değildir.

(Unutmayın, Eventları yüklemek için oyun içi .events +e_murderer komutunu kullanıyoruz. Bir komut dosyasında nokta olmadan aynı komutu kullanırız.)

Oyuncunun adının gerçekten görüntülenmesi için bu etkinlikten geri dönüyoruz. Oyuncunun adını başının üzerine koymak için kolayca bir mesaj kullanabilirdik, ancak bu gerekli belirli renkte olmazdı.

İşte @DClick olayının bir örneği. Bu etkinliğin etkisi, oyuncuların loncalarının dışındakilerin kağıt bebeklerini görmesini engellemektir. Ayrıca burada iki kişinin aynı loncada olup olmadığını nasıl kontrol edeceğinizi de öğreneceksiniz.
ON=@DClick
    IF (<SRC.UID> == <UID>) // oyuncu kendi kendine mi çift tıkladı?
        RETURN 0
    ELSEIF (<SRC.MEMORYFINDTYPE.memory_guild.LINK.UID>) && (<SRC.MEMORYFINDTYPE.memory_guild.LINK> == <MEMORYFINDTYPE.memory_guild.LINK>)
        SRC.SYSMESSAGE You are in the same guild.  You may view this paperdoll.
        RETURN 0 // let them see the paperdoll*****
    ENDIF
    RETURN 1         // Yapma
Bu olayı parçanızda kullanmak ister misiniz bilmiyorum. Unutmayın, parçanızın nasıl olduğu size kalmış!

Belki de en çok kullanılmayan etkinlik @Profile. Bir sunucudaki çeşitli uygulamalar için inanılmaz derecede yararlı olabilir.
ON=@Profile
    DIALOG d_info
    RETURN 1
Bölüm 8'de diyaloglar hakkında bilgi edinmiş olmalısınız. Şimdilik, bu komut dosyasının SRC ekranında (profil tıklayıcı) d_info adlı bir iletişim kutusunun görünmesini sağlayacağını bilmeniz gerekir. Belki de bu iletişim kutusunda, profili tıklanan kişi hakkında bilgi olabilir. Aşağıdaki gibi bir IF ifadesi eklemek isteyebilirsiniz:
ON=@Profile
    IF (<SRC.ISGM>)
        DIALOG d_info_gm
    ELSE
        DIALOG d_info
    ENDIF
Bu, önce kullanıcının bir GM olup olmadığını kontrol eder ve farklı miktarda bilgi görüntüler. Bölüm 8'de bu iletişim kutusunun görünümünü en ayrıntılı düzeye kadar nasıl özelleştirebileceğinizi gördünüz.

Bunlar, bu Eventlerin uygulamalarından sadece birkaçı. Tahmin edebileceğiniz gibi, SPHERE'deki her şeyde olduğu gibi, uygulamalar sınırsızdır.

NPC Bazlı Eventler

Bir etkinliğin bir oyuncuda mı yoksa sadece NPC'lerde mi kullanılabileceğini nasıl anlarız? Unutmayın, " NPC ", bir canavar, bir satıcı, bir bankacı veya herhangi bir şey olsun, bilgisayar tarafından kontrol edilen herhangi bir karakter anlamına gelir.

Eh, oldukça kolay bir yol var. Yalnızca NPC'ye özel bazı etkinliklerin bir listesine bakalım:
@NPCAcceptItem   // NPC öğeyi kabul eder (ihtiyaçlar)
@NPCHearGreeting // hear greeting (can be triggered by most speech i found)*****
@NPCHearNeed     // Birisi istediğim (ihtiyaç duyduğum) bir şeyden bahsediyor
@NPCHearUnknown  // oldukça açık
@NPCRefuseItem   // NPC bunu istemiyor (ihtiyaçlar)
@NPCRestock      // satıcı / npc stokları .. Otomatik olarak on=@Create'de çağrılır
@NPCSeeNewPlayer // yeni oyuncuyu görün
@NPCSeeWantItem  // istediğim (ihtiyaç duyduğum) bir şey görmek
Bunlar benim yorumlarım değil. Fark edeceğiniz başka bir şey de, bazılarının bu ihtiyaç kavramı hakkında yorum yapmasıdır. Bunu da bu bölümde ele alacağız. Aslında, neden önce bunu ele almıyoruz?

Bir NPC komut dosyasına bakarsanız, DESIRES adlı bir özelliğe sahip olacaktır. Şuna benzer bir şey:
DESIRES=i_gold
Bu, NPC'nin altın istediği anlamına gelir. Altın elde etmek bu NPC'nin bir ihtiyacıdır. Aksi takdirde mutlu olmazdı. Ve bir NPC'yi sinirlendirdiğinizde ne olduğunu hepimiz biliyoruz. ("Kapa çeneni ve savaş, korkak!" diyorlar.) Diğer NPC ihtiyaçları, örneğin, ateş elementalleri için ateş veya kargalar için t_crops'dir. Bazen koyun gibi hayvanlar için bile t_grass vardır. Ama insanların yemek yemesine gerek yok. İhtiyacı olan tek şey para. Bir NPC'nin sattığı herhangi bir öğeyi de kabul edeceğine inanıyorum.

Artık bu arzular ve ihtiyaçlar kavramını anladığınıza göre, işte bu Eventlerin daha açıklayıcı bir listesi:
@NPCAcceptItem   - NPC'ye bir öğe bırakılır ve bu NPC'nin ihtiyaçlarından biri olarak tanımlanır. RETURN 1, öğeyi geldiği yere geri döndürür. Öğe ACT'de saklanır.
@NPCHearGreeting - Kendisiyle daha önce konuşmamış olan biri doğrudan bu NPC ile konuşuyor. NPC, oyuncunun kendisiyle konuştuğunu kısa bir süre için hatırlayacaktır. (Hafıza ile ilgili sonraki bölümlere bakın.)
@NPCHearNeed     Birisi NPC'nin ihtiyaçlarından birinin adını söylüyor. "Altın" gibi. Bu durumda, değişken <needname> söylenen ihtiyacın adını yazdıracaktır.
@NPCHearUnknown  - Birisi NPC'nin anlamadığı bir şey söylüyor. "Hı?" ve "Seni anlamıyorum!" sesleri de buradan geliyor.
@NPCRefuseItem   - NPC'ye ihtiyacı olmayan bir eşya düşer. Öğe, geldiği yere geri döndürülür. Öğe ACT'de saklanır.
@NPCRestock      - Bu yaklaşık her yarım saatte bir gerçekleşir. AL ve SAT öğeleri, NPC'nizde olmasını istediğiniz herhangi bir ganimet ve kıyafetle birlikte bu etkinliğin altına yerleştirilmelidir. Bu aynı zamanda NPC'nin yaratılması için de çağrılır (çünkü teknik olarak ilk kez yeniden stokluyor).
@NPCSeeNewPlayer - NPC etkinliklerinin en kullanışlısı olan bu etkinlik, NPC daha önce görmediği bir oyuncuyu gördüğünde ateş eder. Bu etkinlikten RETURN 1, NPC'nin oyuncuyu gördüğünü hatırlamasını önleyecek ve RETURN 0, hatırlamasına izin verecektir.
@NPCSeeWantItem  - NPC yerde istediği bir şey görür ve ona doğru yürür

Şimdi bu Eventlerın kullanımına ilişkin bazı örnekler görelim. SPHERE ile birlikte gelen örnekler ,yani 55i paketindeki sphereevents.scp'de çok büyük ve karmaşıktır ve hangi yanıtın verileceğini belirlemek için birçok sektör karmaşıklığı ve karma sorunuyla ilgilenir. Her etkinliğin yaklaşık 30 potansiyel sözlü yanıtı vardır.

İşte en yararlı Eventler olarak gördüğüm şeyi kullanan daha basit bir örnek. Bu, örneğin, ona özel yetenekler kazandırmak için yeni bir NPC'ye yerleştirilebilir. Bu NPC hareketsiz dururken görünmez olduğunu varsayacağız. Aslında son bölümde, bu NPC için tamamlanmış komut dosyasını göreceksiniz.

[code] ON=@NPCSeeNewPlayer
    IF (<DISTANCE> > 5) // Oyuncu 5 adımdan daha uzaktaysa
        RETURN 1  // Onu hatırlamıyorum, bu yüzden olay yaklaştığında ateşleniyor
    ENDIF
    // Sadece 5 adımdan daha yakın olursa bu kadar ilerleyebiliriz.
    SAY Boo!
    INVIS 0
    ATTACK // Etkinliğin SRC'sine saldırır
    RETURN 0
Bu basit senaryo, sadece birkaç varyasyonla şaşırtıcı derecede çeşitli yaratıklar yaratacaktır. Anlıyor musun? Eğer yapmazsan, işte benim açıklamam:

1. NPC, daha önce gördüğünü hatırlamadığı bir oyuncuyu görür ve Event gerçekleşir.
2. Oyuncunun ne kadar uzakta olduğunu kontrol ediyoruz. DISTANCE, başvurulan nesnenin (bu durumda varsayılan nesne) etkinliğin SRC'sine (bu durumda görülen oyuncu) olan mesafeyi döndürür. Oyuncu çok uzaktaysa, NPC'nin tepki vermesini istemiyoruz. Bu etkinlik, yaratık yakındaki bir oyuncuyu ilk fark ettiği anda ateşlenir, yani oyuncunun çözünürlüğüne bağlı olarak yaklaşık 12 karo uzakta demektir. Buraya 1 döndürüyoruz, böylece NPC oyuncuyu gördüğünü unutacak ve etkinlik bir saniye kadar sonra tekrar ateşlenecek.
3. Oyuncu yeterince yakınsa, NPC belirir (INVIS 0) ve oyuncuyu korkutmak için "Boo!" der. Daha sonra ona saldırmaya devam eder. Bu ikinci bölümün sonunda 0 geri dönüyoruz çünkü oyuncuyu tekrar unutmak için NPC'ye ihtiyacımız yok.

Bu oldukça basit bir komut dosyasıdır ve hemen hemen her yararlı karakter tabanlı Eventı kullanan büyük bir örnek göreceksiniz.

@Death Event

@Death tetikleyicisinin içinden kullanabileceğiniz nesne başvuruları şunlardır:


@Death Nesneler
SRC = öldürülen
[] = öldürülen yaratık

Herhangi bir deneyimli yönetici, bu tetikleyiciyi kullanırken belirli bir engelle karşılaşmış olacaktır. Oyuncuyu kimin öldürdüğünü nasıl bilebiliriz? Uzun bir süre ACT katil olarak kabul edildi ve birçok kişi hala durumun böyle olduğuna inanıyor. Aslında, şu anda bir oyuncuya @Death bir tetikleyici ekleyecek olsaydınız, onları öldürün ve ACT'lerini kontrol edin. Büyük olasılıkla ACT'nin gerçekten de katile işaret ettiğini keşfedeceksiniz, ancak burada size ACT'nin @Death'daki katil olmadığını söylüyorum!

İstediğiniz kadar protesto edebilirsiniz, ancak ACT referansının @Death tetikleyici içinde tamamen anlamsız olduğu basit bir gerçektir. ACT, çeşitli dahili sistemler tarafından kullanılır ve farklı anlamlara gelir. Örneğin, bir oyuncunun bir eşya yapmasını ve ardından onları 0.xhit 0'ı hedeflemesini sağlarsanız, ölürler ve ACT'nin aslında oyuncunun yaptığı eşyayı işaret ettiğini keşfedeceksiniz!

Birini kimin öldürdüğünü belirlemek istiyorsanız, bunu yapmanın iki güvenli yolu vardır:

• Bir karakter diğerini öldürdüğünde tetiklenen @Kill tetiğini kullanın (bu bölümde tartışılmamıştır)
• Bir karaktere zarar veren karakterlerin tam listesine erişmenizi sağlayan ATTACKER özelliğini kullanın.

Her neyse, elimizdeki konuya geri dönelim.

Hiç Asheron's Call veya Everquest oynadınız mı? Bu oyunlardan herhangi birinde öldüğünüzde, seçtiğiniz belirli bir yere geri gönderilirsiniz, ancak ölümden önce yeri seçmelisiniz. Biz de buna benzer bir sistem yapacağız. İşte senaryo ve sonra açıklayacağım:
[PLEVEL 1]
deathpoint

[FUNCTION deathpoint]
IF (<REGION.FLAGS> & region_flag_guarded)  // Güvenlikli bir bölgede mi?
    // Eğer öyleyse, bunu yeni ölüm konumu olarak ayarlamamız gerekir.
    TAG.DEATH_LOC = <P>
    EVENTS +e_death
ENDIF
RETURN 1

[EVENTS e_death]
ON=@Death
    IF (<BRAIN>)  // We don't want this script on NPCs by accident (player brain  = 0 = false)*****
        RETURN 0
    ENDIF
    RESURRECT // Prevent death
    IF !(<ISEMPTY <TAG.DEATH_LOC>>) // TAG'ın boş/boş olmadığından emin olun
        GO <TAG.DEATH_LOC>
    ELSE  // Etiket yok, onları Britanya gibi varsayılan bir konuma gönderin
        GO Britain
    ENDIF
    RETURN 1 // Ölüm kaydedilmedi, geride ceset bırakılmadı.
Bunun biraz açıklama gerektirdiğini düşünüyorum. İlk olarak, geçmişte gördüğümüzden farklı bir fonksiyon kullanıyoruz:

Bu oyun içi bir komuttur. Oyun içinde .deathpoint yazarak kullanırsınız. Bir oyun içi işlevde nesneler aşağıdaki gibidir: İşlevi yürüten kişi SRC'dir. .deathpoint yerine .xdeathpoint yazarlarsa, bir hedef elde ederlerdi. İşlevin hedefi varsayılan nesnedir.

Oyuncu bu işlevi kullandığında, bir kasabada olup olmadığını kontrol ederiz. Bu işlevin amacı, oyuncunun öldüğünde nereye gideceğine karar vermesine izin vermektir. Korunan alan içinde olduğu sürece herhangi bir yer olabilir. Bu nedenle, korunan bir alandaysa, mevcut konumunu bir TAG'ye kaydederiz. Ayrıca etkinlik e_death oynatıcıya da yüklüyoruz. Neler olduğunu anlayana kadar gözden geçirin. Burada daha önce görmediğimiz hiçbir şey yok.

Sonraki bölüm, @Death bir Event içeren bir [EVENT] bölümüdür. Tüh! Bence bu senaryonun daha önce yapmadığımız veya yorumlarda oldukça net bir şekilde açıkladığımız şeyler olmayan tek kısmı, <ISEMPTY ...=""> Eventın ortasındaki işlevin amacı.</ISEMPTY> Diyelim ki, oyundaki garip bir şans eseri, bu oynatıcıda e_death Eventı yüklü, ancak TAG değeri var. DEATH_LOC henüz ayarlanmadı. @Death komut dosyası tetiklendiğinde (oyuncunun ölümüyle), aşağıdaki ifadeyle karşılaşırız:
GO <TAG.DEATH_LOC>
Eğer etiketi. DEATH_LOC hiçbir değeri yoktur, bu ifade anlamsızdır ve bir hata alırsınız. Bu nedenle, bir değeri olup olmadığını kontrol etmek için aşağıdaki ifadeyi kullanırız:
IF !(<ISEMPTY <TAG.DEATH_LOC>>)
Etiketin bir değeri varsa, bu, boş olmayan ve bu nedenle doğru olan korkutucu bir sayıya değerlendirilecektir. Eğer bir değeri yoksa, ifade basitçe eğer ! (<ISEMPTY&gt, ki bu elbette yanlıştır.</ISEMPTY>

@Death Eventı, akıllıca kullanıldığında güçlü bir araç olabilir. Kullanılabileceği birkaç şey daha:

1. Özel yarış yetenekleri (ör. Son Şans, Son Saldırı türü yetenekler)
2. NPC'lerin katile deneyim kazandırmak için @Death etkinliğe sahip olduğu bir seviye atlama sistemi
3. Az önce yukarıda gördüğünüz şey

Başta da söylediğim gibi, bu eğitim size ücretsiz komut dosyaları vermek için burada değil. Size NASIL senaryo yazılacağını öğretmek için burada. Her ne kadar iki bölümde daha kendiniz için ücretsiz bir senaryo alacaksınız! Bekleyebilir misin?

Combat Events

@Hit, @GetHit, @SpellEffect, @SpellCast
Bunlar bazı eğlenceli etkinlikler. Ayrıca sunucunuzun çökmesine de neden olabilirler, buna burada sadece bir dakika içinde değineceğiz. Şimdi her biriyle ilişkili nesnelere bakalım:


@HitSRC = Vurulan
karakter[] = Vurulan
karakter ACT = Vurulan karakter


@GetHitSRC = Vuruşu
yapan karakter[] = Vurulan
karakter ARGN1 = Verilen
hasar miktarı ARGN2 = Verilen hasarın türü


@SpellEffectSRC = Büyüyü
yapan karakter[] = Büyü
tarafından vurulan karakter ARGN1 = Büyü numarası (veya defname, sphere_spells.scp'ye bakın)
ARGN2 = Büyü gücü


@SpellCastSRC = Büyüyü
yapan karakter TARG = Büyünün
hedefi ARGN1 = Büyü numarası (veya defname)

Bunlar çok faydalı Eventlar, özellikle @Hit ve @SpellEffect Eventlar. İsterseniz, bir NPC'nin normal bir saldırı yerine büyü türü bir saldırı yapmasını sağlamak için @Hit kullanabilirsiniz. Size Swindler ve benim bir süre önce bulduğumuz bir örnek göstereceğim. Bir karakteri belirli büyülere karşı bağışık hale getirmek veya belirli büyülerin daha fazla hasar vermesini sağlamak için @SpellEffect kullanabilirsiniz. Karakterin belirli büyüleri yapmasını önlemek için @SpellCast kullanabilirsiniz.

İşte senaryolarımızdan birinin @Hit bölümünün tam metni:

@Hit
SRC = Vurulan karakter
[] = Vurmayı yapan karakter
ACT = Vurulan karakter


@GetHit
SRC = Vurmayı yapan karakter
[] = Vurulan karakter
ARGN1 = Yapılan hasar miktarı
ARGN2 = Yapılan hasarın türü


@SpellEffect
SRC = Büyüyü yapan karakter
[] = Büyünün çarptığı karakter
ARGN1 = Büyü Numarası (veya defname, bakınız sphere_spells.scp)
ARGN2 = Büyünün gücü


@SpellCast
SRC = Büyüyü yapan karakter
TARG = Büyünün hedefi
ARGN1 = Büyü numarası (veya defname)

Bunlar çok faydalı Eventler, özellikle @Hit ve @SpellEffect Eventlar. İsterseniz, bir NPC'nin normal bir saldırı yerine büyü türü bir saldırı yapmasını sağlamak için @Hit kullanabilirsiniz. Size Swindler ve benim bir süre önce bulduğumuz bir örnek göstereceğim. Bir karakteri belirli büyülere karşı bağışık hale getirmek veya belirli büyülerin daha fazla hasar vermesini sağlamak için @SpellEffect kullanabilirsiniz. Karakterin belirli büyüleri yapmasını önlemek için @SpellCast kullanabilirsiniz.

İşte senaryolarımızdan birinin @Hit bölümünün tam metni:
ON=@Hit
    IF !(RAND(10))
        SRC.EFFECT = 3,i_fire_column,6,31,0
        SRC.DAMAGE {20 40}
        SFX = snd_spell_flamestrike
        ELIF !(RAND(15))
        SFX = 0054
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6))> <EVAL (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6))> <EVAL (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6))> <EVAL (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6))> <EVAL (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6))> <EVAL (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6)) - (RAND(6))> <EVAL (RAND(6)) - (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6)) - (RAND(6))> <EVAL (RAND(6)) - (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6)) - (RAND(6))> <EVAL (RAND(6)) - (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6)) - (RAND(6))> <EVAL (RAND(6)) - (RAND(6))>
        SERV.NEWITEM = i_sakara_fire
        NEW.TIMER = 15
        NEW.P = <SRC.P>
        NEW.MOVE <EVAL (RAND(6)) - (RAND(6))> <EVAL (RAND(6)) - (RAND(6))>
    ENDIF
Açıkçası bu komut dosyasının geri kalanına sahip değilsiniz, ancak i_sakara_fire geçerli bir öğe olduğunu ve bir hataya neden olmayacağını bilin. Aslında, üzerine basarsanız çok fazla hasar veren, yangın alanı görünümlü bir eşyadır.

Burada birkaç ilginç şey göreceksiniz. Her şeyden önce, Swindler'ın bir IF ifadesinde RAND işlevini yaratıcı bir şekilde kullanmasıdır. Bu, özel efektlerin yalnızca nadiren gerçekleşmesini sağlar. Burada uğraştığımız iki efekt, senaryodan anlayamıyorsanız, şunlardır:
1. Oyuncuya tek bir alev darbesi (gerçekleşme şansı 10'da 1)
2. Her yere dağılmış i_sakara_fire bırakan bir patlama (15'te 1 şans)

IF ifadeleri, ilk etkinliğin gerçekleşmesi için yalnızca 10'da 1 şansımız olduğunu garanti ediyor. RAND(10) değerlendirildiğinde (bir IF'deki tüm ifadeler EVAL aracılığıyla gönderilir), 0 ile 9 arasında bir sayı seçer. Bu özel durumda, RAND(10)'un sıfır olarak değerlendirdiği 10'da 1 olasılığını arıyoruz. Bu, IF ifadesini yanlış yapar, ancak bakın, orada NOT (!) sembolü var:

IF (! false), IF (true) olur

İlk rastgele ifade sıfır ile sonuçlanırsa, alev çarpması etkisini elde ederiz. Bunu yapmanın birkaç yöntemi vardır, ancak Swindler bir EFFECT (komut listesine bakın) ifadesi ve bir miktar hasar kullanmayı seçti. Ayrıca bir ses efekti de ekledi ki bu, senaryolarımda her zaman yapmayı unuttuğum bir şeydir. Sesleriyle gerçekten oynayanlar için çok etkileyici kılıyor.

İlk ifade sıfırdan başka bir şeyle sonuçlanırsa, NOT sembolü sayesinde yanlış olur. ELIF ile başlayan bir sonraki bölüme geçiyoruz. Bu, çok sayıda öğe oluşturan ve SRC kullanan bölümdür. Davranarak, onları orijinal konumlarına göre hareket ettirmek için hareket ettirin. Bu eşyalar, bir oyuncu üzerlerine bastığında bir miktar hasara neden olan i_sakara_fire eşyalardır.

İşte biraz sorun yaşıyor olabileceğiniz kısım:
SRC.ACT.MOVE <EVAL (RAND(6)) - (RAND(6))> <EVAL (RAND(6)) - (RAND(6))>
Bu, Swindler'ın -5 ile 5 arasında değerler elde etmenin çok ilginç bir yoludur. Aynı kolaylıkla rastgele bir seçici {-6, 6} yazabilirsiniz. Bununla birlikte, Swindler'ın yöntemi, sayıların -5 veya 5'ten daha sıfıra yakın olma olasılığının daha yüksek olması nedeniyle yerleşik bir faktöre sahip gibi görünüyor. Bunun nasıl çalıştığını görelim:

RAND(X), 0 ile (X - 1) arasında bir sayı döndürür. Örneğin, RAND(9) 0 ile 8 arasında herhangi bir sayı döndürür. Yani Swindler'ın RAND(6) değerinin mümkün olan en düşük değeri 0 ve mümkün olan en yüksek değer 5'tir. Bunlardan ikisine sahip olduğumuza dikkat edin:
RAND(6) - RAND(6)

0 ile 5 arasındaki bir sayıyı diğerinden çıkarıyoruz. Biri 0 ve diğeri 5 ise, cevap 0 - 5 = -5 olacaktır. Eğer tam tersi ise, cevap 5 - 0 = 5 olacaktır. Ancak ortaya yaklaştıkça rakamlar aynı. Küçük bir sayı (3 - 2 = 1, 2 - 1 = 1, 4 - 3 = 1, vb.) alma şansı büyük olandan daha fazladır. Bu, senaryoyu daha ilginç hale getiriyor![/event][/newbie][/murderer][/events][/events][/events]

UO-Dev SPONSOR

Paylaş

XFacebook

Faydalı mı?

Bu içerik size yardımcı oldu mu?

UO-Dev SPONSOR

Henüz yorum yapılmamış. Yorum yazabilmek için giriş yapmanız gerekir.

Üyelerin oylama ortalaması (10 dışında) :

Henüz Oylanmamış

Oylar: 0

Paylaş

XFacebook

Faydalı mı?

Bu içerik size yardımcı oldu mu?