SPEC_PROGide kirjutamise HOWTO (by Seem) Sisukord: 1. Üldine möla 1.0 Diskleimer 1.1 Eeldused sellest tekstist arusaamiseks 1.2 Sissejuhatus SPEC_PROGidesse 2. SPEC_PROGi kuju 2.0 Tavalise SPEC_PROGi kuju 2.1 Lähteväärtused 2.2 Tagastatavad väärtused 3. Triggeritest 3.0 Triggerite tabelid 4. Muu 4.0 Stoniale spetsiifilised muutujad 5. Näited 5.0 Näited ____________________________________________ 1.0 Diskleimer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Kogu see tekst on higi, vere ja pisaratega kirjutatud Stonia Immortali Seem(kodanikunimega Siim Vahtre) poolt. Kuna see tekst on kirjutatud ühise hüvangu jaoks, siis olen mina, kui copyright holder, selle välja lasknud GNU Free Documendation Licence all. (vt. http://www.gnu.org/licenses/fdl.txt) Igasugune kriitika, kommentaarid, parandused, küsimused jms järgneva kirjatüki kohta palun ilma häbenemata kritseldada minu e-kasti aadressile. Sobivad nii "siim (ätt) pld.ttu.ee" kui ka "am88b (ätt) linux.ee". ____________________________________________ 1.1 Eeldused sellest tekstist arusaamiseks. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ma eeldan, et inimene, kes seda teksti loeb, oskab vähemalt lihtsamaid C programme juba teha. Väga abiks oleks ka mõne suvalise MUDi koodi siseelu tundmine, kuid seda selle teksti lugemine otseselt ei eelda. Kellel C kohta teadmisi pole ning ka mingid muud kogemused programmeerimise kui sellise kohta puuduvad, siis nemad ilmselt järgnevast tekstist suurt midagi aru ei saa. Neile, kes aga siiski tahavad sellest aru saada, soovitan soojalt lugeda üht toredat ~200(?) leheküljelist kollaste kaantega ja sinise pealkirjaga Külim'i poolt välja antud raamatut "Programmeerimine C - keeles" (Viktor Leppikson). ___________________________________________ 1.2 Sissejuhatus SPEC_PROGidesse ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Põhimõtteliselt on tehtud nüüd selline süsteem, kus iga teatud sündmuse korral konkreetse mobi/ruumi/objektiga antakse võimalus sellel objektil/ruumil/ mobil olukorras käituda nii, nagu seda ette näeb tema SPEC_PROG(edaspidi SP). See on suhteliselt sarnane MOB_PROGidele, kuid ressursinõudlikus SPde puhul on MOB_PROGidega võrreldes _tunduvalt_ väiksem ning samas võimalusi on rohkem. Kahjuks on ka SPEC_PROGide süntaks seega tunduvalt raskem. ____________________________________________ 2.0 Tavalise SPEC_PROGi kuju ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tavalise spec_progi kuju on järgnev: P.S: Esimese CHAR_DATA *ch asemel võib olla midagi muud, kui tegemist oleks ruumi või objprogiga. Täpsemalt sellest aga hiljem. bool (CHAR_DATA *ch, CHAR_DATA *victim, void *vo, int trigger) { <... muutujate deklaratsioonid ...> switch (trigger) { case MINGI_TRIGGER: { <... mis juhtub MINGI_TRIGGER puhul ...> return ; } case MINGIMUU_TRIGGER: { <... mis juhtub MINGIMUU_TRIGGER puhul ...> return ; } default: return ;} } Muidugi keegi otseselt ei käsi case kasutada. Vabalt võib olla seal hoopis if näiteks. Teoorias võib ju triggeri kontrolli päris ära jätta: bool spec_mob_bonkija (CHAR_DATA *ch, CHAR_DATA *victim, void *vo, int trigger) { act( "$n bonks at $sself for being such a moron.",ch,NULL,NULL,TO_ROOM); return T_OK; } Eelneva progiga mob lihtsalt annab endale alati vastu pead, misiganes siis ka juhtuks. (st. teoreetiliselt ta ainult endale pähe taobki koguaeg). Kui oleks sinna ette lisanud "if (trigger==CHAT_TRIGGER)" siis oleks tulemuseks see, et mob oleks bonkinud endale vastu pead alati kui keegi temaga rääkida üritab. ____________________________________________ 2.1 SPEC_PROGi lähteväärtused ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nüüd selgitab pisut definitsioone. Nagu eelnevas punktis sai mainitud, algab iga funktsioon vastavalt oma olemusele (oleneb kas ta on obj/room/mob prog) järgneva reaga: bool (CHAR_DATA *ch, CHAR_DATA *victim, void *vo, int trigger) bool (OBJ_DATA *obj, CHAR_DATA *victim, void *vo, int trigger) bool (ROOM_DATA *room, CHAR_DATA *victim, void *vo, int trigger) Lihtsustatult on need järgnevad: ch - viide MOBile, kelle prog käivitub. obj - viide OBJile, mille prog käivitub. room - viide ROOMile, mille prog käivitub. victim - viide "kaasosalisele". Näiteks give progi puhul see, kes oli andja, mobmemory puhul see, keda rünnata tahetakse jne. vo - muutuja, mis on iga triggeri puhul erinev. Give progi puhul on selleks objekt, mis anti, spelli puhul spell, mida castiti jne. trigger - mis trigger täpselt käivitati Lisan veel niipalju, et esimene muutuja (vastavalt kas "ch/obj/room") ja muutuja "trigger" on ALATI olemas, samas "vo" ja "victim" võivad vastavalt triggeri olemusele olemas olla kuid võivad ka puududa. (Puudumise korral on tegemist lithsalt NULLpointeriga) ____________________________________________ 2.2 SPEC_PROGi tagastatavad väärtused ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Selgitan siin mida täpselt tähendavad tagastavate väärtuste puhul makrod T_OK ja T_SPEC. Target on siinkohal obj/room/mob mille SPEC_PROGiga tegu T_OK saadetakse tagasi juhul kui: * target ei oma ühtegi SPi * target ei reageeri vastavale triggerile * SP käivitamise viga (OBJ polnud olemas, MOB polnud tegelikult MOB jne) * trigger käivitati ning SP tegi midagi suhteliselt "tavalist" T_SPEC saadetakse tagasi ainult juhul kui: * trigger _kindlasti_ käivitati ning midagi _ERILIST_ juhtus Mis see "eriline" täpselt on, oleneb triggerist. Triggeri kutsunud funktsioon toimetab alati selle järgi kas talle saadeti tagasi T_OK või T_SPEC. Kui saadeti T_OK siis jätkab funktsioon oma tööd nagu poleks midagi juhtunud. Aga kui saadeti tagasi T_SPEC siis saab funktsioon aru, et midagi ERILIST juhtus ning ta peab käituma veidi teistmoodi. Vajalik on see näiteks juhul kui PULSE_TRIGGERi puhul mob ära sureb. Funktsioon ei saa ju edasi toimetada surnud mobiga. Seega peabki sellisel juhul alati PULSE_TRIGGERi SP puhul saata tagasi T_SPEC. Täpselt kumba kasutada tuleb selgub järgnevates tabelites. ____________________________________________ 3.0 Triggerite tabel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Mõningad MOB triggerid: = Trigger ===== ch ======= victim ===== vo ==== T_SPEC === PULSE | mob | | | mob suri MEMORY | ründaja | rynnatav | | GIVE | obj saaja | obj andja | obj | KILL | tapja | surija | | LOOK | vaadatav | vaataja | | FLEE | kakleja | fleeja | | BRIBE | raha andja | raha saaja | summa | CAST | mob | castija | spell | Mõningad OBJ triggerid: = Trigger ===== obj ======= victim ==== vo ===== T_SPEC =========== MOUNT | obj1 | mountija | obj2 | mountimine õnnestus DRAG | obj | dragija | | dragimine oli "eriline" PRESS | obj | pressija | | pressimine õnnestus RECITE | obj | reciteja | target | Mõningad ROOM triggerid: = Trigger ==== room ====== victim ==== vo ===== T_SPEC =========== PULSE | room | victim n | | n sai surma GREET | room | siseneja | | GONE | room | kaduja | | (P.S: PULSE = iga round lihtsalt niisama käivituv trigger) Tegemist oli vaid mõne üksiku progiga. Tegelikult on triggereid tunduvalt rohkem kuid ma lihtsalt ei jõua praegu kõiki ära kirjeldada. Uute triggerite lisamine on äärmiselt kerge, niiet tasub vaid soovi ja initsiatiivi üles näidata ning saab ka uus trigger tehtud. Triggeriks sobib praktiliselt igasugune "sündmus" mis võib objekti/ruumi/mobiga juhtuda. ____________________________________________ 4.0 Stoniale spetsiifilsed muutujad ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Kirjutamata. ____________________________________________ 5.0 Näited ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ http://stonia.ttu.ee/builder/sp_example.c Lisan ka mõned pisut vananenud näited, mis teoorias töötaksid kenasti juhul, kui lisada funktsiooni algusesse õige päis ning teha kogu sellest jutust seal üks suur PULSE_TRIGGER. http://stonia.ttu.ee/builder/adept.c http://stonia.ttu.ee/builder/cleric.c http://stonia.ttu.ee/builder/dragon.c http://stonia.ttu.ee/builder/fido.c http://stonia.ttu.ee/builder/janitor.c http://stonia.ttu.ee/builder/mayor.c http://stonia.ttu.ee/builder/poison.c http://stonia.ttu.ee/builder/puff.c http://stonia.ttu.ee/builder/thief.c