Geschreven door: Timo Krul (mrfan@dds.nl).
Laatste wijzigingen: Mei'95.
/e object:verb om een verb te editten.
/re om weer terug te komen in de editor na een
foutmelding.
Als je iets wilt testen van de dingen die uitgelegd worden, dan kan je een
eigen test verb maken:
@verb me:test
Met /e me:test kan je hier naar hartelust in gaan programmeren. En als je test intikt, wordt de verb dus uitgevoerd.
if (player.name == "Harry") player:tell("Wat een mooie naam."); endifIn plaats van is gelijk wil je misschien wel testen op is ongelijk dat doe je met != dus:
if (player.name != "Harry") player:tell("Jij heet dus geen Harry."); endifLet op: Vergeet nooit endif!
Er is ook een mogelijkheid om, zoals we al gezien hadden, een else te gebruiken:
if (player.name == "Harry") player:tell("Wat een mooie naam."); else player:tell("Jij heet dus geen Harry."); endifMaar misschien wil je wel op meer namen testen, dan kan je elseif gebruiken:
if (player.name == "Harry") player:tell("Wat een mooie naam."); elseif (player.name == "Frank") player:tell("Heb jij effe pech met zo'n naam."); else player:tell("Je heet geen Harry of Frank."); endif
Lekkere duidelijke uitleg he? Nee zeker... nou bekijk dit eens:
manofvrouw = player.gender == "mannelijk" ? "man" | "vrouw"; player:tell("Je bent een ", manofvrouw, ".");Aan de linkerkant van het vraagteken staat de vergelijking of de speler mannelijk is. Als dat zo is, dan levert dit het woord man op en anders het woord vrouw.
player:tell("Je bent een ", player.gender == "mannelijk" ? "man." | "vrouw.");Hint: over het algemeen is het handiger op naar de voornaamwoorden te kijken wanneer je op geslacht wilt controleren. Je weet wel, die properties als .pp, .ps, ppc, enzovoorts. Als .pp gelijk is aan "hij", dan kan je d'r vanuit gaan dat je met een mannelijke speler te maken hebt.
Bekijk nu de volgende regels eens:
ad = length(player.contents); if (ad > 1) player:tell("Je hebt ", ad, " dingen."); elseif (ad) player:tell("Je hebt 1 ding."); else player:tell("Je hebt geen dingen."); endifDit kan veel korter met:
ad = length(player.contents); player:tell("Je hebt ", ad ? ad | "geen", " ", ad == 1 ? "ding" | "dingen.");
Zo kan je bijvoorbeeld een tellertje in een while-lus gebruiken:
player:tell("De tafel van 7:"); tellertje = 1; while (tellertje < 11) player:tell(tellertje, " keer 7 is ", tellertje * 7); tellertje=tellertje + 1; endwhileVergeet endwhile niet!
Als je tellertje tot 10000 laat lopen zou je heel veel power van de computer gebruiken. Om het eerlijk te houden, krijgt iedere verb maar een bepaald aantal ticks. Op een gegeven moment zal de verb er dus dus mee ophouden met een foutmelding dat de ticks op zijn. Je kunt dit verhelpen door steeds even te wachten voordat je weer verder gaat met de verb. Dit gaat met suspend(xx) Waar xx het aantal seconden is wat je wilt wachten. Ook suspend(0) heeft effect. Dit kun je gebruiken in verbs die veel ticks eisen weer even op adem te laten komen.
Een aantal voorbeelden van lijsten:
Veel voorkomende fout:
mijnlijst = {"b", "l", "a"}; listdelete(mijnlijst, 1); player:tell(tostr(@mijnlijst);Op het eerste gezicht zou dit "la" opleveren. Echter, in de 2e regel gebeurt niet veel. Het resultaat is namelijk wel {"l", "a"} maar dit wordt nergens aan toegekend. Het programma moet er dus zo uitzien:
mijnlijst = {"b", "l", "a"}; mijnlijst = listdelete(mijnlijst, 1); player:tell(tostr(@mijnlijst);Om een hele lijst uit z'n voegen te trekken gebruik je het @ teken, je moet daarna echter wel meteen wat doen met de losse elementen, bijvoorbeeld naar een string omzetten of in een nieuwe lijst verwerken:
lijst = {}; tel = 1; while (tel < 10) lijst = {@lijst, tel}; tel = tel + 1; endwhile player:tell(tostr(@lijst));Deze verb begint met een lege lijst en voegt daar 10 keer een element aan toe.
if (#2 in connected_players()) #2:tell("Hoi, leuk dat je er bent!"); endifDeze spreekt voor zich.
alfabet = {"a", "b", "c", "d", "e", "f"}; for abc in (alfabet) player:tell(abc); endforAlles binnen de for-lus wordt net zoveel keer aangeroepen als er elementen in de lijst zijn. In dit voorbeeld verandert de variabele abc bij elke nieuwe aanroep in respectievelijk "a", "b", "c", "d", "e" en "f".
Nog een voorbeeld:
wiezijner = ""; for zoek in (connected_players()) wiezijner = ((wiezijner + zoek.name) + ","); endfor wiezijner[length(wiezijner)] = "."; player:tell("De volgende personen zijn aanwezig:"); player:tell(wiezijner);Geeft een beetje lelijke output, maar het gaat om het idee. Kijk ook eens naar de 5e regel, daar wordt op een slimme manier de laatste komma door een punt vervangen.
Wat is er leuker om zelf een generiek object te maken, waar anderen weer afstammelingen van kunnen maken? Tsja.. ik kan genoeg dingen bedenken die leuker zijn, maar daar is deze handleiding niet voor bedoeld.
Als je iets generieks gaat maken, houdt het dan zo generiek mogelijk. Ga dus niet een generieke kaas-souffle (met streepie op de e) maken, maar denk meer aan generiek etenswaar. Een simpel voorbeeld:
@maak $ding genaamd "generiek eetfrutsel":frutsel
@beschrijf frutsel als Je ziet iets eetbaars.
@verb frutsel:eet this
Doe nu @edit frutsel:eet en schrijf het volgende programma:
player:tell("Je neemt een hap van ", this.name, "."); player.location:announce(player.name, " neemt een hap van ", this.name, ".");
Zorg nu dat je dit object vruchtbaar (fertile) maakt met:
@chmod frutsel +f
Iemand anders kan nu een afstammeling maken van je frutsel:
@maak frutsel genaamd "een overheerlijke
kruisbessentaart",taart
(altijd nog beter dan bosbessentaart!)
Let op: Zorg goed voor je generieke objecten. Laat ze niet zomaar rondslingeren en wees voorzichtig met wijzigingen. Laten we een kleine uitbreiding maken op onze frutsel:
@property frutsel.grootte 3
En verander de eet-verb:
if (this.grootte) player:tell("Je neemt een hap van ", this.name, "."); player.location:announce(player.name, " neemt een hap van ", this.name, "."); this.grootte = this.grootte - 1; else player:tell(this.name, " is al helemaal opgegeten!"); endifWelnu... alles is okee denk je. Maar dat valt even tegen. D'r komt iemand langs en die maakt een afstammeling van je frutsel. Hij is heel blij en probeert d'r een hap van te nemen.
Maar dan... hij krijgt allemaal vage errors op zijn scherm! Dit komt omdat deze speler de eigenaar is van de property .grootte, maar jij bent nog steeds de eigenaar van de verb eet.
Als hij die verb aanroept, dan vraagt-ie dus eigenlijk aan jou om de property .grootte te veranderen, maar jij hebt helemaal geen recht om aan iemand anders zijn properties te zitten!
Je wilt dus dat bij het maken van een afstammeling dat de properties van de afstammeling ook van jou blijven, zodat jouw verbs die erop staan deze zonder problemen kunnen wijzigen. Dit gaat door middel van:
@chmod frutsel.grootte -c
Vanaf nu blijf je lekker zelf de eigenaar de property .grootte van afstammelingen van je frutsel.
Elk object in de metro heeft een verb adetail. Met deze verb kan een detail toegevoegd worden op een object. Dit komt dan weer in de .adetails property terecht.
Bij het toevoegen van een adetail, moet een lijst met 2 of 3 dingen worden meegegeven. De lijst bestaat als eerste uit het soort adetail in de vorm van een getal. Als tweede geef je de beschrijving in de vorm van een string. Als je gebruik maakt van het soort 1 of 3 (zie beneden), dan moet je nog een derde element in de lijst zetten. Deze derde is de tijd dat de adetail uitgewerkt is en dus uit de .adetail property gehaald wordt.
Deze tijd wordt opgegeven in het aantal secondes vanaf de jaarwisseling van het jaar 1970. Tsja, zo zit dat nou eenmaal in de MOO... dat heb ik ook niet verzonnen. Met de verb time() kan je het aantal seconden opvragen, dat verstreken is sinds dat moment.
Hier volgt een opsomming van de soorten adetails die worden gebruikt:
@maak $ding genaamd "een geheimzinnig knopje", knopje,
knop
@verb knopje:druk this none none
@edit knopje:druk
En voer het volgende programma in:
player:tell("Je drukt op het knopje..."); player.location:announce(player.name, " drukt op het knopje."); suspend(4); player:tell("Opeens valt er een hele emmer water over je heen!"); player.location:announce("Er valt een emmer water op ", player.name, "!"); player:adetail({1 , player.ppc + " kleren zijn nat!", time() + 600});Als je nu druk knopje intikt en naar jezelf kijkt, dan zie je dat je kleren nat zijn. Na 600 seconden zal die tekst weer verdwenen zijn.
Maar stel nu dat je soort 2 had gebruikt, dan loop je voor altijd met natte kleren rond. Dat is ook niet zo leuk, dus zijn er 2 manieren om adetails te verwijderen.
Met clean_this kan je de soorten 1 en 2 verwijderen. Met medic_this kan je de soorten 3 en 4 verwijderen.
Voorbeeld:
@verb me:eersteweg
@edit me:eersteweg
if (player.adetails == {}) player:tell("Er staan geen adetails op je"); else eerste = player.adetails[1]; if (eerste[1] in {1, 2}) player:clean_this(eerste); player:tell("Eerste afwasbare adetail weggehaald."); elseif (eerste[1] in {3, 4}) player:medic_this(eerste); player:tell("Eerste lichamelijke adetail weggehaald."); else player:tell("Sorry, je kan je eerste adetail niet verwijderen."); endif endifSoort nummer 6 wordt gebruikt door generieke kleding. Op de player staan de verbs trek_aan en trek_uit. Deze verbs hoef je alleen maar de tekst mee te geven. Zo kun je dus de bovenste verb uitbreiden:
if (player.adetails == {}) player:tell("Er staan geen adetails op je"); else eerste = player.adetails[1]; if (eerste[1] in {1, 2}) player:clean_this(eerste); player:tell("Eerste afwasbare adetail weggehaald."); elseif (eerste[1] in {3, 4}) player:medic_this(eerste); player:tell("Eerste lichamelijke adetail weggehaald."); elseif (eerste[1] == 6) player:trek_uit(eerste[2]); player:tell("Eerste kledingstuk uitgetrokken."); else player:tell("Sorry, je kan je eerste adetail niet verwijderen."); endif endif
En als je problemen hebt kun je altijd bij een hulpvaardige bouwvakker terecht! En (zucht...) als het echt niet anders kan bij een opperbouwvakker.