HSHamsterSpeak 3W 1 3U 3 769 SCRIPTS.TXT4walkherotox 32766 2 0 0 walkherotoy 32765 2 0 0 walknpctox 32764 2 0 0 walknpctoy 32763 2 0 0 getnpcspeed 32762 1 0 setnpcspeed 32761 2 0 4 npccopynumber 32760 1 0 createglobalnpc 32402 4 0 0 0 2 globalnpcreference 32403 3 0 0 0 globalnpc 32741 3 0 0 0 swapbyname 32759 2 0 0 renamehero 32758 1 0 getherolevel 32757 1 0 gainherostat 32756 4 0 0 0 0 autosave 32755 0 stringtoglobals 32754 3 0 0 0 globalstostring 32753 3 0 0 0 showstringat 32752 3 0 0 0 centerstringat 32751 3 0 -654321 -654321 hidestring 32750 1 0 stringstyle 32749 2 0 0 stringisvisible 32748 1 0 hsd:savestring 32747 1 0 hsd:restorestring 32746 2 0 0 lastascii 32745 0 inputstring 32744 6 0 -1 0 1 -654321 -654321 currentdisplaytile 32743 2 0 0 waitforsound 32742 1 0 getenemystat 32740 2 0 0 setenemystat 32739 3 0 0 0 resetenemystat 32385 2 0 0 getenemyappearance 32737 2 0 0 setenemyappearance 32736 3 0 0 0 setvictorymusic 32735 1 0 getvictorymusic 32734 0 getdeathscript 32733 0 getloadscript 32732 0 setloadscript 32731 1 0 hsd:prefbitindex 32730 1 0 readpreferencebit 32729 1 0 writepreferencebit 32728 2 0 1 setbattlewaitmode 32727 1 1 setcaterpillarmode 32726 1 1 setnohpleveluprestore 32725 1 1 setnompleveluprestore 32724 1 1 setinnnorevivemode 32723 1 1 sethpleveluprestore 32722 1 1 setmpleveluprestore 32721 1 1 setinnrevivemode 32720 1 1 setfullheroswapmode 32719 1 1 hidebattlereadymeter 32718 1 1 hidebattlehealthmeter 32717 1 1 showbattlereadymeter 32716 1 1 showbattlehealthmeter 32715 1 1 setdebugkeysdisable 32714 1 1 setdeadheroesgainexperience 32713 1 1 setturnbasedbattlemode 32397 0 getturnbasedbattlemode 32396 0 setactivetimebattlemode 32395 0 getactivetimebattlemode 32394 0 setactivebattlepauseforanimations 32712 1 1 setcappedherostat 32711 4 0 0 0 0 getdamagecap 32710 0 setdamagecap 32709 1 0 getinventorysize 32708 0 setinventorysize 32707 1 0 extendedscancodesenabled 32706 0 getlevelcap 32705 0 setlevelcap 32704 1 0 getmaptileset 32703 0 getambientmusic 32702 0 setambientmusic 32701 1 -1 allowminimap 32700 1 1 allowsaveanywhere 32699 1 1 cancelmapnamedisplay 32698 0 setmapedgemode 32697 2 0 0 getmapedgemode 32696 0 setharmtiledamage 32695 1 0 setharmtileflash 32694 1 0 getfootoffset 32693 0 setfootoffset 32692 1 0 getinsteadofbattlescript 32691 0 setinsteadofbattlescript 32690 1 0 geteachstepscript 32689 0 seteachstepscript 32688 1 0 getonkeypressscript 32687 0 setonkeypressscript 32686 1 0 drawnpcsaboveheroes 32685 1 1 getcurrentmapautorunscript 32367 0 getcurrentmapautorunscriptargument 32364 0 readwallbit 32684 3 0 0 0 writewallbit 32683 4 0 0 0 1 daysofplay 32682 0 hoursofplay 32681 0 minutesofplay 32680 0 secondsofplay 32679 0 setdaysofplay 32678 1 0 sethoursofplay 32677 1 0 setminutesofplay 32676 1 0 setsecondsofplay 32675 1 0 firstmenuitem 32674 1 0 lastmenuitem 32673 2 0 1 waitformenu 32672 1 0 getmenuboxstyle 32671 1 0 setmenuboxstyle 32670 2 0 0 getmenutextcolor 32669 1 0 setmenutextcolor 32668 2 0 0 getmenudisabledtextcolor 32667 1 0 setmenudisabledtextcolor 32666 2 0 0 getmenumaxrows 32665 1 0 setmenumaxrows 32664 2 0 0 getmenuoffsetx 32663 1 0 setmenuoffsetx 32662 2 0 0 getmenuoffsety 32661 1 0 setmenuoffsety 32660 2 0 0 getmenuanchorx 32659 1 0 setmenuanchorx 32658 2 0 0 getmenuanchory 32657 1 0 setmenuanchory 32656 2 0 0 getmenutextalign 32655 1 0 setmenutextalign 32654 2 0 0 getmenuminchars 32653 1 0 setmenuminchars 32652 2 0 0 getmenumaxchars 32651 1 0 setmenumaxchars 32650 2 0 0 getmenuborder 32649 1 0 setmenuborder 32648 2 0 0 getmenuonclosescript 32647 1 0 setmenuonclosescript 32646 2 0 0 getmenucancelbuttonmenu 32645 1 0 setmenucancelbuttonmenu 32644 2 0 -1 getmenuitemspacing 32643 1 0 setmenuitemspacing 32642 2 0 -1 getmenubit 32641 2 0 0 setmenubit 32640 3 0 0 1 setmenuitem 32639 7 0 0 0 0 0 0 0 setmenuitemtype 32638 2 0 0 getmenuitemtype 32637 1 0 setmenuitemsubtype 32636 2 0 0 getmenuitemsubtype 32635 1 0 setmenuitemtag 32634 3 0 0 1 getmenuitemtag 32633 2 0 1 setmenuitemsettag 32632 2 0 0 getmenuitemsettag 32631 1 0 setmenuitemtogtag 32630 2 0 0 getmenuitemtogtag 32629 1 0 getmenuitembit 32628 2 0 0 setmenuitembit 32627 3 0 0 1 setmenuitemcolor 32624 2 0 0 getmenuitemcolor 32623 1 0 setmenuitemdisabledcolor 32622 2 0 0 getmenuitemdisabledcolor 32621 1 0 getnpcsprite 32620 1 0 getherosprite 32619 1 0 getherospritebyslot 32411 1 0 loadsprite 32618 3 0 0 -1 createsprite 32412 3 0 0 -1 replacesprite 32617 4 0 0 0 -1 loadenemysprite 32616 3 0 0 -1 replaceenemysprite 32615 4 0 0 0 -1 firstchildoftype 32614 2 0 0 nextsiblingoftype 32613 2 0 0 firstcontainerchild 32612 1 0 nextcontainersibling 32611 1 0 firstrectchild 32610 1 0 nextrectsibling 32609 1 0 firstspritechild 32608 1 0 nextspritesibling 32607 1 0 firsttextchild 32606 1 0 nexttextsibling 32605 1 0 firstellipsechild 32604 1 0 nextellipsesibling 32603 1 0 firstgridchild 32602 1 0 nextgridsibling 32601 1 0 firstscrollchild 32600 1 0 nextscrollsibling 32599 1 0 firstselectchild 32598 1 0 nextselectsibling 32597 1 0 firstpanelchild 32596 1 0 nextpanelsibling 32595 1 0 firstlinechild 32594 1 0 nextlinesibling 32593 1 0 getselectedchild 32592 1 0 setselectedchild 32591 2 0 0 freeslicechildren 32590 1 0 realignslice 32589 5 0 0 0 -1 -1 gentlyrealignslice 32379 5 0 0 0 -1 -1 centerslice 32588 1 0 setslicescreenx 32587 2 0 0 setslicescreeny 32586 2 0 0 setslicesize 32585 3 0 0 0 putslicescreen 32584 3 0 0 0 moveslicetoscreenpos 32378 4 0 0 0 0 setpadding 32583 2 0 0 reparenttonpc 32582 2 0 0 reparenttohero 32581 2 0 0 gentlyreparent 32377 2 0 0 lookupancestor 32376 2 0 0 dirx 32401 1 0 diry 32400 1 0 thatscriptintheotherfile 32580 0 _dummy1 32579 1 0 _dummy1<-foo 32578 1 0 _dummy2 32577 1 0 _dummy2<-foo2 32576 0 interpretertests 32575 0 elseifa 32574 1 0 elseifb 32573 1 0 elseifc 32572 1 0 elseiftests 32571 0 switcha 32570 1 0 switchb 32569 1 0 switchtests 32568 0 badbreak 32567 0 badcontinue 32566 0 orphanedblocks 32565 0 exittests 32437 0 exittests<-return0 32388 0 exittests<-return1 32387 0 exittests<-return2 32386 0 continuebreaktests 32361 0 continuebreaktests<-simplecontinuetest 32360 0 continuebreaktests<-simplebreaktest 32359 0 continuebreaktests<-conditionalcontinuetest 32358 0 continuebreaktests<-basicnestingcontinuetest 32357 0 continuebreaktests<-continue2test 32356 0 continuebreaktests<-continuewhiletest 32355 0 continuebreaktests<-breakwhiletest 32354 0 continuebreaktests<-whileforcontinue2test 32353 0 continuebreaktests<-nestedwhileforcontinuetest2 32352 0 continuebreaktests<-continuebreakdotest 32351 0 continuebreaktests<-continuebreaknesteddotest 32350 0 continuebreaktests<-continue0test 32349 0 continuebreaktests<-break0test 32348 0 continuebreaktests<-forswitchcontinue2test 32347 0 continuebreaktests<-forswitchbreak2test 32346 0 continuebreaktests<-variablecontinuetest 32345 0 continuebreaktests<-variablebreaktest 32344 0 continuebreaktests<-variablecontinuetest2 32343 0 flowtests 32564 0 parsertests 32563 0 ?s管???e 32562 0 encodingtests 32561 0 lexertests 32560 0 lexertests<-id 32559 1 0 stringtests 32558 0 stringtests<-check 32557 0 mathtests 32556 0 bitcount 32555 1 0 largermathtests 32554 0 subscripttests 32553 0 subscripttests<-sscript1 32552 0 subscripttests<-sscript2 32551 1 42 subscripttests<-sscript3 32550 0 subscripttests<-sscript3<-ssscript1 32549 1 0 subscripttests<-sscript4 32548 1 0 subscripttests<-sscript4<-ssscript 32547 1 0 subscripttests<-sscript4<-ssscript<-sssscript 32546 1 0 subscripttests<-sscript4<-ssscript<-sssscript<-ssssscript 32545 1 0 subscripttests<-breaksubscript 32544 0 subscripttests<-fib 32543 1 0 subscripttests<-sibling1 32542 1 0 subscripttests<-sibling1<-niece 32541 1 0 subscripttests<-sibling2 32540 1 0 subscriptscopetests 32539 1 0 subscriptscopetests<-sub1 32538 1 0 subscriptscopetests<-sub2 32537 1 0 subscriptscopetests<-sub2<-sub3 32536 1 0 subscriptscopetests<-sub2<-sub3<-sub4 32535 1 0 inside-outsidefib 32534 1 0 inside-outsidefib<-insidefib 32533 0 randomtests 32380 0 plotstrtests 32532 0 mapautorun 32531 0 newgame 32530 3 0 0 0 loadgame 32529 4 0 0 0 0 runtests1 32528 0 startcheckpointtimer 32527 1 0 dostartcheckpointinterval 32526 0 stopcheckpointtimer 32525 0 runtests2 32524 0 runtests3 32523 0 passedtests 32522 0 w 32521 1 1 callstack 32520 1 0 crash 32519 0 assertfailure 32518 0 schedulingtests 32517 0 ticknumber 32516 0 blockerscript 32515 0 blockerscript2 32514 0 eachtickscript 32513 0 blockingtests 32512 0 bug430tester 32511 0 checkbug430enabled 32510 0 inventorytests 32509 0 herotests 32508 0 addherohook 32410 2 0 0 removeherohook 32409 2 0 0 moveherohook 32408 3 0 0 0 heropartymanagementtests 32507 0 heroappearancetests 32506 0 heronamesembedtests 32505 0 heronamesembedhelper 32504 0 showboxnames 32503 0 herocaterpillartests 32502 0 doherocatertests 32501 1 0 suspendwalkaboutstests 32625 0 expectherowalls 32500 5 0 0 0 0 0 heroexpandlevelstests 32499 0 herostatgrowthtest 32498 0 restorehpandmp 32497 0 herostattests 32496 0 equipmenttests 32495 0 heromisctests 32494 0 npctests 32493 0 npcmovementtests 32492 1 0 npcreferencetests 32491 0 npcidtests 32490 0 npcextratests 32381 0 npctagandonetimetests 32489 0 anothernpcscript 32488 0 usenpcscripttests 32487 0 npcslicetests 32368 0 alternpctests 32486 0 getnpcspriteid 32485 1 0 getnpcspritepalette 32484 1 0 deathtests 32483 0 ondeathscript 32482 0 testharmtiledeath 32481 1 0 globalnpctests 32404 0 triggertests 32480 0 asserthurtpattern 32479 6 0 0 0 0 0 0 asserthurtpattern<-considerrank 32478 2 0 0 harmtiletests 32477 0 harmtiletests<-testdamagepatterns 32476 0 menutests 32475 0 onmenuitemuse 32474 0 onclosemenutest 32473 0 scrollthroughmenu 32472 2 0 0 menuscrolltests 32471 0 textboxtests 32470 0 shoptests 32371 0 battletests 32469 0 forcerandombattle 32468 1 1 forcenonrandombattle 32467 0 afterbattle 32466 0 insteadofbattle 32465 1 0 testbattleformationmodification 32464 0 testherocounterattacks 32463 0 attacktests 32375 0 enemytests 32462 0 timertests 32461 0 testtimerandbattleinteractions 32460 1 0 timertest1 32459 0 loopingtimertest 32458 0 timerargstest 32406 3 0 0 42 timerargstest2 32405 2 0 0 battletimertest 32457 0 pathfindingtests 32456 0 pathfindingtests<-herotile 32455 3 0 0 0 createmapoverlaycontainer 32374 0 visualizepathfromextra 32373 2 0 0 isatpos 32454 3 0 0 0 distfromleader 32453 1 0 distfrompos 32452 3 0 0 0 vehicletests 32451 0 doortests 32450 0 each-stepscript 32449 3 0 0 0 npctriggeredscript 32448 2 0 0 textboxadvancescript 32447 0 map4autorun 32446 1 0 concurrentscripttriggertests 32445 0 anothereachstepscript 32444 0 yetanothereachstepscript 32443 0 yetanothereachstepscript<-waiting 32442 0 scriptdoubletriggertests 32441 0 scripttriggertests 32440 0 slicetests 32439 0 slicehandletests 32384 0 rectslicetests 32399 0 textslicetests 32398 0 panelslicetests 32626 0 ellipseslicetests 32393 0 sliceclonetests 32392 0 removeextra 32369 2 0 0 sliceextratests 32391 0 extraarraytests 32372 0 slicecollectiontests 32438 0 slicesearchtests 32390 0 slicecollisiontests 32389 0 rootchildindex 32436 1 0 slicetreetests 32435 0 slicecorrespondencetests 32434 0 sliceblendingtests 32407 0 slicesorttests 32738 0 checkzone 32433 3 0 0 0 zonetests 32432 0 zonesrandomizedtest 32431 0 zonesrandomizedtest<-readarray 32430 3 0 0 0 zonesrandomizedtest<-writearray 32429 4 0 0 0 0 zonesrandomizedtest<-arraycountzones 32428 2 0 0 zonesrandomizedtest<-testarea 32427 0 masterpalettetests 32426 0 maptiletests 32425 0 mapstatetests 32382 0 obsoletemapdatatests 32383 0 wallcheckingtests 32424 0 wallcheckingtests<-sethitboxsize 32423 2 0 0 wallcheckingtests<-testcollide 32422 8 0 0 0 0 0 0 0 -1 wallcheckingtests<-testcorner 32421 3 0 0 0 platformtests 32370 0 saveslottests 32420 0 stringloadtests 32419 0 savegametests 32418 0 afterloadgame 32417 3 0 0 0 savegametests2 32416 0 resetgametests 32415 0 afterresetgame 32414 3 0 0 0 mapautoruntests 32366 0 simpleautorun 32365 1 0 rungametests 32413 0 SCRIPTS.BINH, walkherotox walkherotoy walknpctox walknpctoy getnpcspeed setnpcspeed npccopynumber~createglobalnpc~globalnpcreference globalnpc swapbyname renamehero getherolevel gainherostatautosavestringtoglobalsglobalstostring showstringatcenterstringat hidestring stringstylestringisvisiblehsd:savestringhsd:restorestring lastascii inputstringcurrentdisplaytile waitforsound getenemystat setenemystat~resetenemystatgetenemyappearancesetenemyappearancesetvictorymusicgetvictorymusicgetdeathscript getloadscript setloadscripthsd:prefbitindexreadpreferencebitwritepreferencebitsetbattlewaitmodesetcaterpillarmodesetnohpleveluprestoresetnompleveluprestoresetinnnorevivemodesethpleveluprestoresetmpleveluprestoresetinnrevivemodesetfullheroswapmodehidebattlereadymeterhidebattlehealthmetershowbattlereadymetershowbattlehealthmetersetdebugkeysdisablesetdeadheroesgainexperience~setturnbasedbattlemode~getturnbasedbattlemode~setactivetimebattlemode~getactivetimebattlemode!setactivebattlepauseforanimationssetcappedherostat getdamagecap setdamagecapgetinventorysizesetinventorysizeextendedscancodesenabled getlevelcap setlevelcap getmaptilesetgetambientmusicsetambientmusic allowminimapallowsaveanywherecancelmapnamedisplaysetmapedgemodegetmapedgemodesetharmtiledamagesetharmtileflash getfootoffset setfootoffsetgetinsteadofbattlescriptsetinsteadofbattlescriptgeteachstepscriptseteachstepscriptgetonkeypressscriptsetonkeypressscriptdrawnpcsaboveheroeso~getcurrentmapautorunscriptl~"getcurrentmapautorunscriptargument readwallbit writewallbit daysofplay hoursofplay minutesofplay secondsofplay setdaysofplaysethoursofplaysetminutesofplaysetsecondsofplay firstmenuitem lastmenuitem waitformenugetmenuboxstylesetmenuboxstylegetmenutextcolorsetmenutextcolorgetmenudisabledtextcolorsetmenudisabledtextcolorgetmenumaxrowssetmenumaxrowsgetmenuoffsetxsetmenuoffsetxgetmenuoffsetysetmenuoffsetygetmenuanchorxsetmenuanchorxgetmenuanchorysetmenuanchorygetmenutextalignsetmenutextaligngetmenumincharssetmenumincharsgetmenumaxcharssetmenumaxchars getmenuborder setmenubordergetmenuonclosescriptsetmenuonclosescriptgetmenucancelbuttonmenusetmenucancelbuttonmenugetmenuitemspacingsetmenuitemspacing getmenubit setmenubit setmenuitem~setmenuitemtype}getmenuitemtype|setmenuitemsubtype{getmenuitemsubtypezsetmenuitemtagygetmenuitemtagxsetmenuitemsettagwgetmenuitemsettagvsetmenuitemtogtagugetmenuitemtogtagtgetmenuitembitssetmenuitembitpsetmenuitemcolorogetmenuitemcolornsetmenuitemdisabledcolormgetmenuitemdisabledcolorl getnpcspritek getherosprite~getherospritebyslotj loadsprite~ createspritei replacespritehloadenemyspritegreplaceenemyspriteffirstchildoftypeenextsiblingoftypedfirstcontainerchildcnextcontainersiblingbfirstrectchildanextrectsibling`firstspritechild_nextspritesibling^firsttextchild]nexttextsibling\firstellipsechild[nextellipsesiblingZfirstgridchildYnextgridsiblingXfirstscrollchildWnextscrollsiblingVfirstselectchildUnextselectsiblingTfirstpanelchildSnextpanelsiblingRfirstlinechildQnextlinesiblingPgetselectedchildOsetselectedchildNfreeslicechildrenM realignslice{~gentlyrealignsliceL centersliceKsetslicescreenxJsetslicescreenyI setslicesizeHputslicescreenz~moveslicetoscreenposG setpaddingF reparenttonpcEreparenttoheroy~gentlyreparentx~lookupancestor~dirx~diryDthatscriptintheotherfileC_dummy1BfooCA_dummy2@foo2A?interpretertests>elseifa=elseifb<elseifc; elseiftests:switcha9switchb8 switchtests7badbreak6 badcontinue5orphanedblocks~ exittests~return0~~return1~~return2~i~continuebreaktestsh~simplecontinuetesti~g~simplebreaktesti~f~conditionalcontinuetesti~e~basicnestingcontinuetesti~d~ continue2testi~c~continuewhiletesti~b~breakwhiletesti~a~whileforcontinue2testi~`~nestedwhileforcontinuetest2i~_~continuebreakdotesti~^~continuebreaknesteddotesti~]~ continue0testi~\~ break0testi~[~forswitchcontinue2testi~Z~forswitchbreak2testi~Y~variablecontinuetesti~X~variablebreaktesti~W~variablecontinuetest2i~4 flowtests3 parsertests2?s管???e1 encodingtests0 lexertests/id0. stringtests-check., mathtests+bitcount*largermathtests)subscripttests(sscript1)'sscript2)&sscript3)% ssscript1&$sscript4)#ssscript$" sssscript#! ssssscript" breaksubscript)fib)sibling1)niecesibling2)subscriptscopetestssub1sub2sub3sub4inside-outsidefib insidefib|~ randomtests plotstrtests mapautorunnewgameloadgame runtests1startcheckpointtimerdostartcheckpointinterval stopcheckpointtimer  runtests2  runtests3  passedtests w callstackcrash assertfailureschedulingtests ticknumber blockerscriptblockerscript2eachtickscript blockingtests~ bug430tester~checkbug430enabled~inventorytests~ herotests~ addherohook~removeherohook~ moveherohook~heropartymanagementtests~heroappearancetests~heronamesembedtests~heronamesembedhelper~ showboxnames~herocaterpillartests~doherocatertestsqsuspendwalkaboutstests~expectherowalls~heroexpandlevelstests~herostatgrowthtest~restorehpandmp~ herostattests~equipmenttests~ heromisctests~npctests~npcmovementtests~npcreferencetests~ npcidtests}~ npcextratests~npctagandonetimetests~anothernpcscript~usenpcscripttestsp~ npcslicetests~ alternpctests~getnpcspriteid~getnpcspritepalette~ deathtests~ ondeathscript~testharmtiledeath~globalnpctests~ triggertests~asserthurtpattern~ considerrank~~ harmtiletests~testdamagepatterns~~ menutests~ onmenuitemuse~onclosemenutest~scrollthroughmenu~menuscrolltests~ textboxtestss~ shoptests~ battletests~forcerandombattle~forcenonrandombattle~ afterbattle~insteadofbattle~testbattleformationmodification~testherocounterattacksw~ attacktests~ enemytests~ timertests~testtimerandbattleinteractions~ timertest1~loopingtimertest~ timerargstest~timerargstest2~battletimertest~pathfindingtests~herotile~v~createmapoverlaycontaineru~visualizepathfromextra~isatpos~distfromleader~ distfrompos~ vehicletests~ doortests~each-stepscript~npctriggeredscript~textboxadvancescript~ map4autorun~concurrentscripttriggertests~anothereachstepscript~yetanothereachstepscript~waiting~~scriptdoubletriggertests~scripttriggertests~ slicetests~slicehandletests~rectslicetests~textslicetestsrpanelslicetests~ellipseslicetests~sliceclonetestsq~ removeextra~sliceextratestst~extraarraytests~slicecollectiontests~slicesearchtests~slicecollisiontests~rootchildindex~slicetreetests~slicecorrespondencetests~sliceblendingtestsslicesorttests~ checkzone~ zonetests~zonesrandomizedtest~ readarray~~ writearray~~arraycountzones~~testarea~~masterpalettetests~ maptiletests~~ mapstatetests~obsoletemapdatatests~wallcheckingtests~ sethitboxsize~~ testcollide~~ testcorner~r~ platformtests~ saveslottests~stringloadtests~ savegametests~ afterloadgame~savegametests2~resetgametests~afterresetgamen~mapautoruntestsm~ simpleautorun~ rungametestsCOMMANDS.BINM9&4CQ`q'3>L\k}"/>OXaiq  0 E Y k y " . < H Z k {   + = O [ m    + < J ^ p   ( 8 G T a o ~ ,<L[g{%4@O]k{'3@LYdt-:HXhx$4BQdv"1=M_o}(4Jc} %18HTcv%2=Q`r .@N[l(DZl~);IUi}3Lh /AU_iv %3BUbt(8HYjz "3DVh|$4GWhy  % 5 E U ` k z !!!.!&S&b&x&&&&&&&&''*'>'M']'m''''''''(( (0(M(V(h(z((((((((()2)H)^)u)))))))*'*9*K*a*t********+(+8+I+\+l+}+++++++ ,,0,P,a,t,,,,,,,,--4-L-_-q--------....K.Z.m.~......./-/B/_/x///////00%000D0X0f0x00000000 11(181M1a1v11111111 22%282O2d2x2222223&3>3R3c3v33333333 44-4=4V4g4w4444444455"505D5\5q555555556)686G6V6i6|6666666677(7D7`7p777777777818@8O8c8y88888888 9%979noopwait waitforall waitforhero waitfornpc suspendnpcs suspendplayer resumenpcs resumeplayer waitforkeywalkhero showtextboxchecktagsettagusedoorfightformationgetitem deleteitemleadergetmoney losemoneypaymoneyunequip forceequip setheroframe setnpcframesuspendoverlay playmusic stopmusickeyvalrankincaterpillar showbackdropshowmapdismountvehicleusenpcuseshopcamerafollowsherocamerafollowsnpc pancamera focuscamera waitforcameraheroxheroynpcxnpcysuspendobstructionresumeobstructionsuspendherowallssuspendnpcwallsresumeherowallswalknpcsetherodirectionsetnpcdirectiongetdefaultweaponsetdefaultweaponsuspendcatapillarresumecatapillarwaitfortextbox equipwhere teleporttomapsuspendrandomenemysresumerandomenemys getherostat resumeoverlayaddhero deletehero swapouthero swapinheroroominactivepartylockhero unlockherogameoversetdeathscript fadescreenout fadescreenin showvaluealternpc shownovalue currentmap setherospeed inventory setherostatsuspendboxadvanceresumeboxadvanceadvancetextboxsetheropositionsetnpcpositionswapbypositionfindherocheckequipmentresumenpcwallssetheroz readmapblock writemapblock readpassblockwritepassblock npcdirection herodirection resetpalette tweakpalette readcolor writecolor updatepalette seedrandomgreyscalepalettesetheropicturesetheropalettegetheropicturegetheropalette readglobal writeglobal heroiswalkingsuspendcaterpillarresumecaterpillar npcreference npcatspotgetnpcid npccopycount changenpcid createnpc deletenpc teachspell forgetspell readspell writespell knowsspell canlearnspell herobyslot herobyrankputheroputnpc putcamera heropixelx heropixely npcpixelx npcpixely camerapixelx camerapixely loadtilesetpickherorenameherobyslot readgeneral writegeneral statusscreen showminimap spellsmenu itemsmenu equipmenu ordermenuteammenu initmouse mousepixelx mousepixely mousebuttonputmouse mouseregion npcatpixel saveinslot lastsaveslotsuspendrandomenemiesresumerandomenemiessavemenu saveslotused importglobals exportglobals loadfromslot deletesave runscriptbyid npciswalkingreadgmap writegmapmapwidth mapheightreadnpc setherolevelgiveexperience herolevelled spellslearntgetmusicvolumesetmusicvolumesetformationsong heroframenpcframenpcextra setnpcextra playsound pausesound stopsound systemhour systemminute systemsecond currentmusic getheroname setheroname getitemname getmapname getattackname showstring clearstring appendascii appendnumber copystringconcatenatestrings stringlength deletechar replacecharasciifromstringpositionstring setstringbit getstringbit stringcolorstringxstringy systemday systemmonth systemyear stringcompare readenemydatawriteenemydatatrace getsongnameloadmenu keyispressedsoundisplaying searchstring trimstringstringfromtextbox expandstringjoystickbutton joystickaxiswaitforscancode savemapstate loadmapstate resetmapstatedeletemapstate partymoneysetmoneysetstringfromtableappendstringfromtablesettileanimationoffsetgettileanimationoffsetanimationstarttilesuspendmapmusicresumemapmusic checkherowall checknpcwallsettimer stoptimer readtimergetcolorsetcolorrgb extractcolormainmenu loadpalettetotalexperienceexperiencetolevelexperiencetonextlevel setexperience millisecondsopenmenu readmenuint writemenuintreadmenuitemintwritemenuitemint createmenu closemenutopmenubringmenuforward addmenuitemdeletemenuitemgetmenuitemcaptionsetmenuitemcaption getlevelmp setlevelmp bottommenu previousmenunextmenumenuitembyslotpreviousmenuitem nextmenuitemselectedmenuitemselectmenuitem parentmenu getmenuid swapmenuitemsfindmenuitemcaption findmenuid menuisopen menuitemslotoutsidebattlecure changetileset layertilesetgetformationsongaddenemytoformationfindenemyinformationdeleteenemyfromformationformationslotenemyformationslotxformationslotysetformationbackgroundgetformationbackground lastformationrandomformationformationsetfrequencyformationprobabilitycurrenttextbox getherospeedloadherosprite freespriteputslicesetspritevisiblesetspritepalettereplaceherospritesetspriteframeloadwalkaboutspritereplacewalkaboutspriteloadweaponspritereplaceweaponspriteloadsmallenemyspritereplacesmallenemyspriteloadmediumenemyspritereplacemediumenemyspriteloadlargeenemyspritereplacelargeenemyspriteloadattackspritereplaceattackspriteloadborderspritereplaceborderspriteloadportraitspritereplaceportraitsprite clonespritegetspriteframespriteframecountslicexslicey setslicex setslicey slicewidth sliceheight sethorizalign setvertalignsethorizanchor setvertanchornumberfromstring sliceissprite scriptlayer freeslice firstchild nextsiblingcreatecontainer setparentcheckparentage slicescreenx slicescreenysliceiscontainer createrect sliceisrect setslicewidthsetsliceheight getrectstyle setrectstyle getrectfgcol setrectfgcol getrectbgcol setrectbgcol getrectborder setrectborder getrecttrans setrecttransslicecollidepoint slicecollide slicecontains clampslicehorizflipspritevertflipspritespriteishorizflippedspriteisvertflipped settoppadding gettoppaddingsetleftpaddinggetleftpaddingsetbottompaddinggetbottompaddingsetrightpaddinggetrightpadding fillparentisfillingparent slicetofront slicetoback lastchild ysortchildren setsortorder sortchildrenprevioussibling getsortorder getsliceextra setsliceextra getspritetypegetspritesetnumbergetspritepalette suspendtimers resumetimerssetslicevisiblegetslicevisible sliceedgex sliceedgey createtext setslicetext gettextcolor settextcolorgetwrapsetwrap sliceistext gettextbg settextbg getoutline setoutline usemenuitem sliceatpixelfindcollidingslice parentslice childcount lookupslice resetgame sliceisvalid iteminslot setiteminslotitemcountinslotsetitemcountinslot placespriteupdateleveluplearningmoveslicebelowmovesliceabove slicechildresetheropictureresetheropalettesetsliceclippinggetsliceclipping creategrid sliceisgridsetgridcolumnsgetgridcolumns setgridrows getgridrowsshowgrid gridisshownloadslicecollection setsliceedgex setsliceedgeygetslicelookupsetslicelookuptracevalueinternalmapcurereadattackname spellslearnedallocatetimerssetnpcignoreswallsgetnpcignoreswallssetnpcobstructsgetnpcobstructs setnpcusable getnpcusable setnpcmoves getnpcmovesreadzone writezone zoneatspotzonenumberoftiles getzonename getzoneextra setzoneextrauseitem useiteminslot mouseclickloadbackdropspritereplacebackdropspritegetspritetranssetspritetranssetherobaseelementalresistherobaseelementalresistasintherototalelementalresistasintsetslicevelocityxsetslicevelocityygetslicevelocityxgetslicevelocityysetslicevelocity stopslice movesliceto movesliceby waitforslice sliceismoving createellipsesliceisellipsesetellipsebordercolsetellipsefillcolgetellipsebordercolgetellipsefillcol _checkpointmenuitembytrueslotmenuitemtrueslot getheroslice getnpcslicegetdoorxgetdoorygetdoordestinationidgetdoordestinationmap doorexistsgetattackcaptiongetrectfuzzinesssetrectfuzziness textboxline getslicetext getinputtextenableinputtextinputtextenabled setherohandx setherohandy getherohandx getherohandygetdefaultherohandxgetdefaultherohandy checkonetime setonetime microsecondsenemyelementalresistasintherozgetherostatcapsetherostatcapgetitemmaximumstacksizenpczsetnpcz dooratspot suspenddoors resumedoorsrunningondesktoprunningonmobilerunningonconsoleinputstringwithvirtualkeyboardgetitemdescriptionsetspritesetnumbergetspritedefaultpal npcisdisabled stringsprintf scripterror getscriptnamegetcallingscriptidcamerafollowsslicegetactivebattlepauseonallmenussetactivebattlepauseonallmenusdissolvespritecanceldissolvespriteisdissolvingwaitfordissolvehidevirtualgamepadshowvirtualgamepadautovirtualgamepad getvertalign gethorizalign getvertanchorgethorizanchorsetselectsliceindexgetselectsliceindex createselect sliceisselectslicechildindex createscroll sliceisscrollsetscrollbarstylegetscrollbarstylesetscrollcheckdepthgetscrollcheckdepth scrolltochildrunningonwindows runningonmacrunningonlinuxnextnpcreferenceinputstringwithmousekeyboard runningonouyashowmousecursorhidemousecursorpixelfocuscamera sendemail dumpslicetree createpanel sliceispanelgetpanelisverticalsetpanelisverticalgetpanelprimaryindexsetpanelprimaryindexgetpanelpercentasintsetpanelpercentgetpanelpixelssetpanelpixelsgetpanelpaddingsetpanelpadding debugmenumenuitematpixelrungamegetbattlecountdownsetbattlecountdowncheckwallcollisionxcheckwallcollisionymoveslicewithwallchecking textboxtextcheckgameexists pathfindnpcto npcchasesnpc cancelnpcwalkplayerissuspendednpcsaresuspendedobstructionissuspendedherowallsaresuspendednpcwallsaresuspendedcaterpillarissuspendeddoorsaresuspendedrandomenemiesaresuspendedboxadvanceissuspendedoverlayissuspendedmapmusicissuspendedtimersaresuspendedgetscreenwidthgetscreenheightsetscreenresolution mouserelease_cancelrunfast_runfastmultdivsetrectrawbordergetrectrawborder clonesliceresetformationresetformationslotsliceismaplayernpcreferencefromsliceherorankfromslice slicetype _asserteqsavescreenshot sliceisline createline getlinecolor setlinecolorforcemountvehiclecurrentvehicleidcurrentvehiclenpcpathfindheroto herochasesnpccancelherowalkmenuitemselectablemenuitemdisabledmenuitemvisiblesetlastsaveslot speakingnpckeypress newkeypressgetjoysticknamejoystickbuttoncountjoystickaxiscountjoystickhatcount findcoloroverridetickmillisecondscanceloverridetickmillisecondssuspendtextboxcontrolsresumetextboxcontrolstextboxcontrolsaresuspended menuitemcountvisiblemenuitemcountreplacesubstring decodetriggergetscancodenamegetheroslicebyslotheroslotfromslice getopacity setopacitygetblendingenabledsetblendingenabled getblendmode setblendmodegetrectopacitysetrectopacity settimerargsexpandstringsinslices heroischasing npcischasingmaxmapidgetslicelookupname getnpcpoolgracefullydismountvehicle readfoemap getenemyname setenemyname breakpointdeleteherobyslot getuicolor setuicolorgetboxstylecolorgetboxstyleedgecolorgetboxstylebordergetchildautosortsetchildautosort lastlayeridlayeridunderwalkaboutsgetglobalsoundvolumesetglobalsoundvolume healpartysetheroautobattlegetheroautobattle resizeextra extralength appendextralookupnextslicenextsliceintreewindowisfocusedshowvalueofinternalresetenemydataresetenemynamegetextrasetextraherouseslevelmpgetzonegetrectfuzzyzoomsetrectfuzzyzoomgetrectstationarypatternsetrectstationarypattern keypresstime randomchoice getstatnamesuspendwalkaboutsresumewalkaboutswalkaboutsaresuspendedforwardxforwardygetattackextra pathfindintoextraasnpcpathfindintoextraashero insertextra deleteextradeleteextrarangeisshopbuymenuemptyisshophiremenuempty innscreenreadenvironmentxboxrequestaccountpicker ps5startstory ps5endstorysetrichpresence findextraplaystationcontrollerxboxcontrollernintendocontroller32766.HSZ@ N={ Vp+ d  `+$ ' -O49N+G DJ@Zt+]hZ`d UXe ,k"Orwhsd:whohsd:n32765.HSZ@ ={ Vp, d  `,$ ' -O49N,G DJB^x,]lZ`h UXe .k$Orwhsd:whohsd:n32764.HSZ@ ={ Tl- b  ^-$4'-M49L-G DJ4Nf-]\Z`X4UXe"kOrwhsd:whohsd:n32763.HSZ@ ={ Tl. b  ^.$4'-M49L.G DJ6Rj.]`Z`\4UXe$kOrwhsd:whohsd:n32762.HSZ l b R Dhsd:who32761.HSZ  t N bhsd:who hsd:newspeed32760.HSZ %4Rz   $ &+0`;pD|Y>INXrx]`Y V[cP qt Y}w $, Ypk. Yhsd:npchsd:idhsd:copyhsd:ref32402.HSZ ! }  hsd:idhsd:xhsd:y hsd:direction32403.HSZ x  hsd:idhsd:copyhsd:allow disabled32741.HSZ  x  hsd:idhsd:copyhsd:allow disabled32759.HSZ kr!d  Z p l Z  '  0*3?2A&K`  YRUzMXT9F^ hsd:hero1 hsd:hero232758.HSZ,  zYj Z !$)c5d37^5"55BH6KR x5ZJ<T]:.crename hero: no hero with id %dhsd:whohsd:slothsd:tmp32757.HSZ , r @ Z Lhsd:who32756.HSZ 6 No~&1 T  v@  Pb@/25 8-72'>MDJL@WZ]  _f UiBT hSux{] *@5  BX< d   D!  d z  t ] \  " S #  f .X hsd:whohsd:stat hsd:changehsd:resetcurrent hsd:oldcur hsd:oldmax hsd:newcur hsd:newmax hsd:newbasehsd:cap32755.HSZ$ G: 8  Pvh^ "  +&/ 4032754.HSZ        R!$f  ,/P 28 (8B$@EK:QV d f |cixan` z @} 8  s h$P$$ F Z nl$s $*ZtpK&J6 hsd:stringID hsd:start hsd:lengthhsd:temp hsd:padding32753.HSZ4 L      v! ^ ),  47P :@ x@JtHMNS0BY^  ,s,<pv(r| n `r  z   YXi,k,b.$J hsd:stringID hsd:start hsd:lengthhsd:temp hsd:temp232752.HSZ $^    r  hsd:stringIDhsd:xhsd:y32751.HSZ 0[i  ! ',  7 JBn@FDL.:RW beg |  v y~:sBp hsd:stringIDhsd:xhsd:y32750.HSZt   h N hsd:stringID32749.HSZ ^    h hsd:stringID hsd:style32748.HSZ   f X hsd:stringID32747.HSZ( <b&/7   #L, 2p4`hsd:idhsd:sl32746.HSZ '   n i hsd:id hsd:saved32745.HSZ/  BR{9_Ci'Ms 1o/o3u5w=y3 s  A c / Q s aHJ FLXJ Z`Ahj lbrw0J, `BBhlN'&.J `Ch}| J `DhJ. `DEhnP) (!J `Fh(*"05~"@J B`GhNPHV[#fJ0 h`FHhtpvR+n|*J `Ih$J `Jh%J2 `HKhrT-,&J `Lh 2$J &`Mh24,:?1JJ4 L`JNhXtZV/R`e.pJ r`Oh~xJ `Ph J6 `LQhvX10J `RhJ  `Sh"#.J8 0`NTh<x>Z36DI2TJ V`Uhbd\jo/zJ |`Vh$J: `PWhz\54-J `XhJ `Yh&  ,J<  `R Zh | "^ 7 (-6 8J  :`  h I hJ, T FOZ _  @fk vJP  x`d  @h  h$  | p K ~J J  `  ( hf\ > 3h h "    J  `  h  4h,      &+ 6JB  8`V  t h G 5hR T DMZn _b = >fk< vJ  x`   ^hN 0 6hx Z    ~ J  `  h  7h     J4 `H f*h  |8h`#T/*/. :J <` (hKBM$9hXlZNHS`eBlq |J ~` )hh}|J8 `N l~h`hfZ32 J ` "_h V8hb  %,1 <J >` +hM O=hZ6\JUbgDns~JZ `p {h[h|UTJ `* H}h|^]hB6'J ` :h6;h b"D(- 49KJ D` h@Sh^PYdiJpuJ> `T r<hhl`98J `  *>h^@hl$RJ ` ?h  hzB $   #  * / MJf : `| |hI K \hV X F Q ^ c a@ j o `fz J  | `8hzb D J  `h   NJ  `h.  tJT  `jh vO NJ  `hX    J  & `6h`2 B, 8 = J H `hT N Z _  J j `hR,v p | 2JR  `hh tM LXJ  `hM  ~J  `4hJ^ @ J  `h$   ~J  `h*   & + JP 6 `fhB rK< H M JJ X `hd ^ j o XJ z `2h\ >   j    Jh0    ~\ Lhsd:code hsd:shift32744.HSZ$ u 8E^bt  83x+ ^.T$'32 ?B N QV$LX B dVZosmu{d=g<   * F^%$  $H P j   F V r #(&-d2@C8N&Q HV9\tkinn |zH@   {z V0  R gV^   X    V  $ N z  ^  6 ,        &) X  p 25 @ V  V w  T  x   ^bgn PYk EKr  ?y !,8 * ^ 4 jD  & hsd:str hsd:max len hsd:useexist hsd:center hsd:positionx hsd:positionyhsd:donehsd:keyhsd:show hsd:tmp str hsd:savedhsd:enable input32743.HSZ ZSJZ0%fn'-06<FI ANzhsd:tilehsd:layernumber32742.HSZ  f  Z hsd:soundid32740.HSZ   >  pb hsd:enemyIDhsd:stat32739.HSZ h  >   v hsd:enemyIDhsd:stat hsd:value32385.HSZ  >  f hsd:enemyIDhsd:stat32737.HSZ     z hsd:enemyIDhsd:appearance32736.HSZ !    hsd:enemyIDhsd:appearance hsd:value32735.HSZ !t  Thsd:song32734.HSZ >" P nB32733.HSZx "* lN @32732.HSZx "9 jL >32731.HSZl # 9r Phsd:ID32730.HSZ  |`#u d0z #) 3* j>~A<GdMNS8e]_6Xdi .p\ hsd:bitnum32729.HSZ P$$K     R* 8 t24r -7h =CE( hsd:bitnum hsd:index32728.HSZP %%Jz    0 H 02.5~;^C+AFB  T  0\_ We 8kq6Qt  hsd:bitnum hsd:value hsd:index32727.HSZl & \hsd:bit32726.HSZl ' \hsd:bit32725.HSZl x' hhsd:bit32724.HSZl ' hhsd:bit32723.HSZl p( `hsd:bit32722.HSZ ( bhsd:bit32721.HSZ ") bhsd:bit32720.HSZ ~) Zhsd:bit32719.HSZl ) bhsd:bit32718.HSZl Q* bhsd:bit32717.HSZl * dhsd:bit32716.HSZ %+ bhsd:bit32715.HSZ + dhsd:bit32714.HSZl + `hsd:bit32713.HSZl 4, rhsd:bit32397.HSZ\ ,  V32396.HSZ , t  V32395.HSZ\ 1-  X32394.HSZ x- v  X32712.HSZl - &hsd:bit32711.HSZ` ~7.cv   f!B< !$  ,/ &2>@C8INR Y_&6 H \Sjmps hsd:whohsd:stat hsd:value hsd:stat typehsd:cap32710.HSZd y/ ? J<32709.HSZl / ?l Lhsd:c32708.HSZH /%EU N  pX|I!H ,13191?32707.HSZ, 0x h   c b  %  X .1(3U? $A LOQWYW_e?g ^mT9Gs hsd:newsize32706.HSZd j1 fX32705.HSZd 1 W L>32704.HSZ0 A1: Vfv  pW&( +Q 16Phsd:cap32703.HSZd 2  L>32702.HSZ| 3 Vp F32701.HSZ ZX3Sz `" % /2" <:0 4>CG*Nhsd:song32700.HSZp 4  p V hsd:setting32699.HSZp Q4  | b hsd:setting32698.HSZ\ 4  N32697.HSZ 4  f modehsd:tile32696.HSZd A5  PB32695.HSZp |5   | b hsd:damage32694.HSZp 5   | ` hsd:colour32693.HSZd 6   J<32692.HSZp S6   r V hsd:offset32691.HSZx 6  h X32690.HSZl 6   jhsd:ID32689.HSZx E7 vX H32688.HSZl 7 v Zhsd:ID32687.HSZx 7 z\ L32686.HSZl /8 z ^hsd:ID32685.HSZp y8   h hsd:setting32367.HSZd 8  n^32364.HSZd 9 ' p32684.HSZ '9" c~   lhsd:xhsd:yhsd:bit32683.HSZ XO:&AQ c 2,   P/2nI,8=HdHKNhsd:xhsd:yhsd:bit hsd:new valuehsd:val32682.HSZd ; 3 H:32681.HSZd  < 4 J<32680.HSZd F< 5 PB32679.HSZd < 6 N@32678.HSZ +<$R^3 vjM  Lhsd:d32677.HSZ <=5T`v   l4!# &O,1Nhsd:h32676.HSZ <=5Zf|<   r5!# &U,1Thsd:m32675.HSZ <=5Xdz<   p6!# &S,1Rhsd:s32674.HSZ >$  bhsd:menuhandle32673.HSZ  s-??l> ^ &) .4p!:FI n$QTIJW,^Kchhsd:menuhandlehsd:visible onlyhsd:idx32672.HSZ @ . j  ^hsd:menuhandle32671.HSZ TA   fhsd:menuhandle32670.HSZ A   xhsd:menuhandlehsd:n32669.HSZ )B   hhsd:menuhandle32668.HSZ B   zhsd:menuhandlehsd:n32667.HSZ C  zhsd:menuhandle32666.HSZ tC  hsd:menuhandlehsd:n32665.HSZ C  fhsd:menuhandle32664.HSZ SD  xhsd:menuhandlehsd:n32663.HSZ D  fhsd:menuhandle32662.HSZ (E  xhsd:menuhandlehsd:n32661.HSZ E  fhsd:menuhandle32660.HSZ E  xhsd:menuhandlehsd:n32659.HSZ hF  fhsd:menuhandle32658.HSZ F  xhsd:menuhandlehsd:n32657.HSZ =G  fhsd:menuhandle32656.HSZ G  xhsd:menuhandlehsd:n32655.HSZ H  jhsd:menuhandle32654.HSZ ~H  |hsd:menuhandlehsd:n32653.HSZ H  hhsd:menuhandle32652.HSZ VI  zhsd:menuhandlehsd:n32651.HSZ I  hhsd:menuhandle32650.HSZ -J  zhsd:menuhandlehsd:n32649.HSZ J  bhsd:menuhandle32648.HSZ K  thsd:menuhandlehsd:n32647.HSZ jK  thsd:menuhandle32646.HSZ K  hsd:menuhandlehsd:n32645.HSZ ]L  zhsd:menuhandle32644.HSZ L hsd:menuhandlehsd:n32643.HSZ PM  nhsd:menuhandle32642.HSZ M hsd:menuhandlehsd:n32641.HSZx L7N>G    ".0 (5:EF hsd:handlehsd:bithsd:n32640.HSZ, uNan    .H "F%<+(1~ A?D <JPxVb7\ h k hsd:handlehsd:bit hsd:valuehsd:n32639.HSZ djP!0?N]  8  x P (+- >^7:< FIKv  UXZ hsd:handlehsd:type hsd:subtypehsd:tag1hsd:tag2hsd:stag hsd:togtag32638.HSZ  R   r hsd:handlehsd:n32637.HSZ sR ~ ` hsd:handle32636.HSZ R   x hsd:handlehsd:n32635.HSZ GS  f hsd:handle32634.HSZ ZS)S     % ( 03B ;>@XCN#5JO" hsd:handlehsd:n hsd:whichtag32633.HSZ \T*U     !&~ & 14@ <?tAVGL!6LQ  hsd:handle hsd:whichtag32632.HSZ sU   v hsd:handlehsd:n32631.HSZ U  d hsd:handle32630.HSZ HV   v hsd:handlehsd:n32629.HSZ V  d hsd:handle32628.HSZx LW>G    ".*0 (5:EZ hsd:handlehsd:bithsd:n32627.HSZ, uWan   B\ "Z%P+<1& A?D <JPVv7\  "h k hsd:handlehsd:bit hsd:valuehsd:n32624.HSZ Y    t hsd:handlehsd:n32623.HSZ lY   b hsd:handle32622.HSZ Y  !  hsd:handlehsd:n32621.HSZ HZ ! t hsd:handle32620.HSZ( 9[2  vSy $o).nhsd:npchsd:slhsd:tmp32619.HSZ 9$\2 PSy |l$`I).Hhsd:rankhsd:sl32411.HSZ 9]2 TSy p$dM).Lhsd:whohsd:sl32618.HSZ \ Z^5  4LB  M"%(. O:=`@RFR D\QRUX^  Ijmpv Kpbb TlS  U Wrr  d0""cZ 5  46 P %" ( 38KPch{.&load sprite(%d,%d,%d): invalid type %dhsd:type hsd:numberhsd:palhsd:tmp32412.HSZ b  j hsd:type hsd:numberhsd:pal32617.HSZ 4 QSc+B RjG   N!$'* P8;>tAtd tRORU*X* *BJfilo L} TLL< LdV X  nnc82  " : L 56  l z 16HM_dv{$)replace sprite(%d,%d,%d): invalid type %dhsd:slhsd:type hsd:numberhsd:palhsd:tmp32616.HSZt ?h,X   .M #(N 36` O>ADJI8OTH  _b Qjm^pPvFd{hsd:size hsd:numberhsd:pal32615.HSZ i0`  2 BZN" ',z 7: .PBEHKRu<W\tN gj` Rrux{IlHhsd:IDhsd:size hsd:numberhsd:pal32614.HSZ uYk4]p j   (# &+0Z; Dp >CjLO?FTY> edgj hsd:parenthsd:typehsd:sl32613.HSZ evlW`k  ~  " N+0.&%38kC |Fv<K Q]hsd:slhsd:type32612.HSZ km ft f hsd:parent32611.HSZ mep bhsd:sib32610.HSZ Qn fj \ hsd:parent32609.HSZ nef Xhsd:sib32608.HSZ #o fn ` hsd:parent32607.HSZ oej \hsd:sib32606.HSZ o fj \ hsd:parent32605.HSZ hpef Xhsd:sib32604.HSZ p fp b hsd:parent32603.HSZ @qel ^hsd:sib32602.HSZ q fj \ hsd:parent32601.HSZ ref Xhsd:sib32600.HSZ r  fn ` hsd:parent32599.HSZ r ej \hsd:sib32598.HSZ Ys  fn ` hsd:parent32597.HSZ s ej \hsd:sib32596.HSZ 3t  fl ^ hsd:parent32595.HSZ t eh Zhsd:sib32594.HSZ  u  fj \ hsd:parent32593.HSZ tu ef Xhsd:sib32592.HSZ u  H n` hsd:parent32591.HSZ qnv[  ~   c$%n6'- T05/8  KHGEK`PJ>Vv8set selected slice: 2nd slice must be a child of the 1st hsd:parent hsd:childhsd:tmp32590.HSZd GwA j  Bk ("pi) Z1#,4 : hsd:parenthsd:slhsd:next32589.HSZ lx@e  b ( 8c  Z  #r d+.1U%7<T  G#2 BePSVJ\ahsd:sl hsd:halign hsd:valign hsd:hanchor hsd:vanchor32379.HSZ Yy#8GS@o " plf    M),/25 XhKAD2JMPhsd:sl hsd:halign hsd:valign hsd:hanchor hsd:vanchorhsd:oldxhsd:oldy32588.HSZx f{ hM Lhsd:sl32587.HSZd E{%?o   $Rr\.b16^+9 :hsd:slhsd:newxhsd:oldxhsd:diff32586.HSZd E|%?p   $Rr].b16_+9 :hsd:slhsd:newyhsd:oldyhsd:diff32585.HSZ W}  t ~ uhsd:sl hsd:width hsd:height32584.HSZx M}F\ oD]'4X*/Tp8p2;jD!@ |hsd:slhsd:newxhsd:newy32378.HSZ i~=a(o  N\> 8p']/*2%7z FI6 NRUH hCLX^ hsd:slhsd:newxhsd:newy hsd:ticks hsd:offsetx hsd:offsety32583.HSZ  8&2  jDT #,/xhsd:slhsd:newpadding32582.HSZ zSy  m dhsd:slhsd:npc32581.HSZ ySy   m rhsd:sl hsd:hero rank32377.HSZ M#/;Go  .p X hm), BK58JADhsd:sl hsd:newparenthsd:oldxhsd:oldy32376.HSZ d,W_  (@ ":h+^.T%38C F<K Q]hsd:codehsd:slhsd:par32401.HSZ 0&F 7"6dir32400.HSZ 2(F  7$6dir32580.HSZ  B5[ `  {{({{ ,1{ <BDNFRW b8"djl++v++nz+ ?2[?;utf16 encoding test.hss:7: ascii from string(1, 1) ==, ,231:utf16 encoding test.hss:10: ascii from string(1, 2) == 236:utf16 encoding test.hss:13: ascii from string(1, 3) == 2489utf16 encoding test.hss:14: ascii from string(1, 4) == 6332579.HSZX  Ci32578.HSZ< C%argy132577.HSZ`  iFixasdasd32576.HSZ0 A32575.HSZ m  $(1F0 h. , 3 4 )|~ 32574.HSZh PnI@ D\P %'13,8x=x D:x32573.HSZ0 Bn;@ D;b f~!rU&+T/T 6:x32572.HSZ0 BGo;@ D;b fU#%v*T/T 6:x32571.HSZ Uo 6[ /R <>r ee)ee!-2e> =BDNFRW>Bbgiskw|==J(B======B1sssss<:<C"&+<B"L6g;E=IN elseif tests hstests.hss:62: elseif A(0) == 1 hstests.hss:63: elseif A(1) == 2 hstests.hss:64: elseif A(2) == 3 hstests.hss:65: elseif B(0) == 0 hstests.hss:66: elseif B(1) == 2 hstests.hss:67: elseif B(2) == 0 hstests.hss:68: elseif C(0) == 0 hstests.hss:69: elseif C(1) == 0 hstests.hss:70: elseif C(2) == 332570.HSZ  q:bde!#0( n7h <V02AG(fSUgc" Rhovejq"c (.LZ_av}Rx32569.HSZ$ r:`   $d0 >e<V27>fJLg_ahk2m(\frw  dd c ").CQVXZ~Rx32568.HSZ<  sAh#HmAd <:re !&(*ee4ee,8=e:HfJO(Q[S_d:oq&(vx: g"(:*Z,(MMMMM:6H(:c@ ( :*J,O(1;3?D:O<TQ (V//`//Xdi/9vh^ty({iiii}i9HO(y9odr(9$|(9*^(QQQQ Q9%H(*4,8=9H (MWO[`9*k(pzr~9O@ (33333 9x (kkkkk 9( switch tests#hstests.hss:118: switch A(0) == 101#hstests.hss:119: switch A(1) == 102#hstests.hss:120: switch A(2) == 101#hstests.hss:121: switch A(3) == 103#hstests.hss:122: switch A(4) == 103!hstests.hss:123: switch A(5) == 1"hstests.hss:124: switch A(6) == 99#hstests.hss:125: switch A(7) == 102"hstests.hss:126: switch A(8) == 99#hstests.hss:128: switch B(0) == 104#hstests.hss:129: switch B(1) == 102#hstests.hss:130: switch B(2) == 100#hstests.hss:131: switch B(3) == 103#hstests.hss:132: switch B(4) == 103!hstests.hss:133: switch B(5) == 1"hstests.hss:134: switch B(6) == 99#hstests.hss:135: switch B(7) == 100"hstests.hss:136: switch B(8) == 99"hstests.hss:137: switch B(9) == 99$hstests.hss:138: switch B(10) == 10032567.HSZP v  632566.HSZP v  <32565.HSZ0 w32437.HSZX zy$Hl ~t  gggg g~ +/ 1;3?D~OS U_Wchhstests.hss:180: return 0 == 0hstests.hss:181: return 1 == 1hstests.hss:182: return 2 == 232388.HSZD ~y >32387.HSZP ~y>32386.HSZd ~y > Z32361.HSZ, %) z#*06Vw~ +LSY_}!Bc(/5;AGe(Ijqw}4;AGg ,Mpw}%+1Op 1 R Y _ e k h~  .Fg~|  f~p :=?IAMR(]`jbnse~< 0yyyyy8@ , d~   H    "'  P25  ?  7CH D \ c~  Xcf  p  hty . `! ! ! ! ! T l b~h,pPha~\x  (+5-9>ILVNZ_jm  w  o{ >Vn`~  H;;;;;reeeee$_~KNXP\a$loq{sL?????tggggg^~o.!!!!$!V/2II<II4@EI~PSqq]qqUafq j]~ $ p!\~ " $"""""" """"'""+0""#[~'P'KNPC'C'ZC'C'R^cC'z' nqm'm'{m'm'sm''('''''' 0''''''( (8(Z~++8+++++ ,@++++#(+2,H36%,%,@%,%,8DI%,Z, PTWYM,M,cM,M,[glM,,,,,Y~..X......`...../h/////F/p9/9/9/9/ 9/j////X~l11x5811B11:FK11VY11c11[gl11wz1111|1222222B2Z2r22W~66z6om6m6m6m6m6666 66 66  66$ 66 ( - 668 ; 66E 66= I N 67.7F7^7hstests.hss:198: ctr1 == 0hstests.hss:199: ctr2 == 5hstests.hss:213: ctr1 == 1hstests.hss:214: ctr2 == 1hstests.hss:227: ctr1 == 7hstests.hss:228: ctr2 == 5hstests.hss:245: ctr1 == 9hstests.hss:246: ctr2 == 3hstests.hss:247: ctr3 == 30hstests.hss:263: ctr1 == 10hstests.hss:264: ctr2 == 1hstests.hss:278: ctr1 == 9hstests.hss:279: ctr2 == 10hstests.hss:293: ctr1 == 3hstests.hss:294: ctr2 == 5hstests.hss:313: ctr1 == 5hstests.hss:314: ctr2 == 5hstests.hss:315: ctr3 == 0hstests.hss:316: ctr4 == 0hstests.hss:337: ctr1 == 5hstests.hss:338: ctr2 == 15hstests.hss:339: ctr3 == 10hstests.hss:340: ctr4 == 0hstests.hss:360: ctr1 == 1hstests.hss:361: ctr2 == 6hstests.hss:362: ctr3 == 0hstests.hss:363: ctr4 == 1hstests.hss:389: ctr1 == 6hstests.hss:390: ctr2 == 5hstests.hss:391: ctr3 == 1hstests.hss:392: ctr4 == 1hstests.hss:410: ctr1 == 1hstests.hss:411: ctr2 == 1hstests.hss:427: ctr1 == 10hstests.hss:428: ctr2 == 10hstests.hss:459: ctr1 == 26hstests.hss:460: ctr2 == 1hstests.hss:461: ctr3 == 2hstests.hss:462: ctr4 == 12hstests.hss:493: ctr1 == 16hstests.hss:494: ctr2 == 1hstests.hss:495: ctr3 == 2hstests.hss:496: ctr4 == 13hstests.hss:515: ctr1 == 2hstests.hss:516: ctr2 == 4hstests.hss:517: ctr3 == 0hstests.hss:518: ctr4 == 0hstests.hss:537: ctr1 == 2hstests.hss:538: ctr2 == 2hstests.hss:539: ctr3 == 0hstests.hss:540: ctr4 == 1hstests.hss:567: ctr1 == 6hstests.hss:568: ctr2 == 2hstests.hss:569: ctr3 == 2hstests.hss:570: ctr4 == 1ctr1ctr2ctr3ctr432360.HSZ i~3{-   v(*i32359.HSZ i~:{&4    p/1 i32358.HSZl i~Q|=K   !,.%1 76FH0i32357.HSZ i~k}b& " 8%,*/:f3< B RTIV \ij32356.HSZ i~^ZU    %02)2  8Gb>I Orij32355.HSZ i~Xr R ~  # +%05@@B:9E Kij32354.HSZ i~Vz Px   )#.34>@.7C Iij32353.HSZ i~fx `)@ 1Z8+3:#%'@PGR Xij32352.HSZ$ i~} w  !8Zp,` 79|)2>RJ #CLRWh_j pij32351.HSZ i~kȅ Ze ~"$ -0  82=B :Rb'FMTci32350.HSZ< i~4 ##,V13Pr <v EGk?LQj \_ Egalq  |E &T+6Uu %ij32349.HSZ i~z#l   L32348.HSZ i~%  f ~   F32347.HSZd i~~ D  b $) 6 >8@K   K MSXp / E^o *eq wo6Rij32346.HSZd i~~ >  \ $) 6 >8@K   K MSX^ / E^o eq wo6:ij32345.HSZ i~W(N @ ,'`")/? 6A Gij32344.HSZ i~WN  4 &'T")/? 6A Gzij32343.HSZ` i~   ),&16A :CtIXYFP[aqvhsyijkn32564.HSZ 8$(,04 7  ; n8 i~5~ var132563.HSZL x 2;l  d $(. 9AC EK VX^Qbhhstests.hss:601: x4242+hstests.hss:603: string compare(1, $2="42")x32562.HSZP C*P32561.HSZ H} 0W` @ "$*, 9<>@JBNS^ 2* fj>lvnzencoding testshstests.hss:617: ber == 17)hstests.hss:623: ? sǮ? ??E == 42ber?ve32560.HSZ@ 0 Ś5Z}4Y~3X} / ( ,1/< <>CMEQV/bafGGpGGhtyG/uuuuu/( /2/>< /GWW'WW+0W/;R;=BLDPUC/`_`bgqiuz/^l33333/wqqqqq/7J/. 7/SS&SS*/S/::<AKCOT/_._af  p  hty "hstests.hss:635: 1 000 == id(1000))hstests.hss:636: - 1 000 == id(0 -- 1000)hstests.hss:637: 0x0 == id(0) hstests.hss:638: 0x 000 == id(0)"hstests.hss:639: 0x 100 == id(256)"hstests.hss:640: 0XABc == id(2748)%hstests.hss:641: - 0x 100 == id(-256)%hstests.hss:642: 0xffffffff == id(-1).hstests.hss:643: 0x80000000 == id(-2147483648)-hstests.hss:644: -0xabcedf0 == id(-180153840)%hstests.hss:645: -0xffffffff == id(1)"hstests.hss:646: 0x 100 == id(256)hstests.hss:647: 0b1 == id(1)Dhstests.hss:648: 0b1001010110011010011011111110101 == id(1254963189)Ehstests.hss:649: 0b11001010110011010011011111110101 == id(-892520459)#hstests.hss:650: 0o1777 == id(1023)%hstests.hss:651: -0o1777 == id(-1023)32559.HSZ\ 0 4$x32558.HSZ7 ,6:CKU[4Z @Ov@IQW(19Choy DKUz'1V]g .5?dms|  H Q W ^ e : C y  Fl ! R$p'#-%164A7I9QS4QLQp`c;kccmsccfw}cQQQFQ  Q (KQj V]]]]]Q c QQp'+0QZ};ACMMMMMEQVM Qa?cikumy~QTGGGGGwwwww_`a  < / */ / ,2/ / %6</ G 5I  U `  bh  [lr } Q. 5@ Q| o o o o o o  Q 5 Q: - - - - - - l Q 5  Q,  *  ,2  %6< G^ QO 5 Q ^ i  kq  du{ #$ &QD A5b Q  )     4 8Qͫ5>Q?D.[J !!!!$!X/*7 \QA-DI7`R77TZ77M^d7 ZgQw-i pQ-</r///// RyQ-} Q-P%C.CC06CC):@C fQS-[dfl_pvQ Q$-H;;;;;; `Q- Q-B555 555% ZQ/-7@BH;LR% Qe-<m/v//x~//q/ TQ- Q-6))))))% LQ- $*% Q= -.E!N!!PV!!IZ`!kh z Q Lz a p      '  2   4 :   - > D  'O F )c  k +v x ~ q 5  7  $ 9   C N PQ . R     c :   o$   & ,    0 6  A I  QQ  K S Y b l d p u  b! B! 5! 5!5! 5!5! 5! ! !Q ! ! Q !! !! ! " b" U" U"U" U"U"   U" String tests$hstests.hss:665: string compare(1,2)aA-hstests.hss:668: string compare(1,2) == false .~fooy .~fooY-hstests.hss:671: string compare(1,2) == false ???????%hstests.hss:678: string compare(2, 3)string length(3)'hstests.hss:683: string length(3) == 11-hstests.hss:684: ascii from string(3, 1) == 9.hstests.hss:685: ascii from string(3, 2) == 32/hstests.hss:686: ascii from string(3, 3) == 161/hstests.hss:687: ascii from string(3, 4) == 233/hstests.hss:688: ascii from string(3, 10) == 630hstests.hss:689: ascii from string(3, 11) == 241foohstests.hss:691: $1="foo" == 1barhstests.hss:692: $1+"bar" == 1a  'hstests.hss:699: string compare(95, 96) test %hstests.hss:703: string compare(1, 2)%%%%hstests.hss:708: string compare(1, 3) test %d test -24 %hstests.hss:713: string compare(1, 3) test %d%d%d%d%d test 1-2-3-4-5%hstests.hss:718: string compare(1, 3) test (%s)test (test (%s))%hstests.hss:723: string compare(1, 3) test%c  testA %hstests.hss:728: string compare(1, 3) test %x %x  test 1abcdef ffffffff %hstests.hss:733: string compare(1, 3)4hstests.hss:736: that script in the other file == 91 existing existing 42hstests.hss:747: check0hstests.hss:748: check65hstests.hss:749: check 2147483647hstests.hss:750: check -2147483648hstests.hss:751: check-1hstests.hss:752: check1234hstests.hss:753: check 65hstests.hss:755: check0065hstests.hss:756: check -65hstests.hss:758: check-065hstests.hss:759: check65 hstests.hss:761: check65 hstests.hss:762: check-65 hstests.hss:763: check-65 hstests.hss:764: check this silly example this silly example#hstests.hss:771: string equal(1, 2) is silly #hstests.hss:774: string equal(1, 2)#hstests.hss:778: string equal(1, 2)secret#hstests.hss:781: string equal(1, 2)QuxQu#hstests.hss:787: string equal(1, 2) a a#hstests.hss:792: string equal(1, 2)'This is an example of replace substringisiiss?hstests.hss:797: replace substring (1, $2="is", $3="iiss") == 2+Thiiss iiss an example of replace substringRhstests.hss:799: string equal(1, $4="Thiiss iiss an example of replace substring")AAABaaAAAACA@hstests.hss:802: replace substring (1, $2="AA", $3="CA", 2) == 2CAABaaCA/hstests.hss:804: string equal(1, $4="CAABaaCA")AaabaAaaAACAGhstests.hss:807: replace substring (1, $2="AA", $3="CA", -1, true) == 3CAabCACA/hstests.hss:808: string equal(1, $4="CAabCACA")32557.HSZ .%* c ^5 8 '%s' == '%s'32556.HSZ! pp5;]h/U}#Ks|@i2S`=`g-R} 998| A9DFooPooHTYo dfnfDDyq}DD2d6#D%%%%%pd n b,fDUU"UU&+U659fD>H@LQ\>_dDfphtyfG9D8d6(QdDddVr[DDeeeeedfb dD *,i.,D4>6BG*RrTZD\f^jodzNlfp{9D_____fzD dD9D , 0#dD)3+7<XG^JPDRKK\KKT`eKpzsdDy{z9D9D zD     *d D%).9D<F>JO*,*dZH fiDk;;u;;my~;lD_____*ddDDfD9D fFd#fD&WW0WW(49Wr DfDISKW\sF B  mFDp5 5 z5 5 r~5 *r f *D     d 69D     d: BdD- - - - - d  NdDw w  w w $)w d Z49D;  E  =IN @BYY[ 6ef]dDf  p  hty YYd yD     Yd D     math testshstests.hss:822: n == 0hstests.hss:824: n == 10hstests.hss:825: n + 5 == 15hstests.hss:826: n -- 15 == -5hstests.hss:827: n * -1 == -10 hstests.hss:828: abs(-1*n) == 10hstests.hss:829: abs(n) == 10hstests.hss:830: sign(n) == 1!hstests.hss:831: sign(n--10) == 0!hstests.hss:832: sign(-1*n) == -1hstests.hss:835: n == 11hstests.hss:837: n == 1hstests.hss:839: (m := 3) == 3hstests.hss:840: (m -= 6) == -3hstests.hss:844: n / 10 == 0!hstests.hss:845: n, mod, 10 == -9hstests.hss:846: n / 9 == -1hstests.hss:847: n, mod, 9 == 0hstests.hss:848: n / 5 == -1 hstests.hss:849: n, mod, 5 == -4hstests.hss:850: n / -9 == 1 hstests.hss:851: n, mod, -9 == 0hstests.hss:852: n / -10 == 0"hstests.hss:853: n, mod, -10 == -9hstests.hss:857: m == 9hstests.hss:858: n == 9hstests.hss:860: m == 12hstests.hss:861: n == 21hstests.hss:863: m == 11hstests.hss:864: n == 10$hstests.hss:866: another global == 0%hstests.hss:868: another global == 103hstests.hss:869: read global(@another global) == 10$hstests.hss:871: another global == 4)hstests.hss:875: multdiv(10, 20, 30) == 7+hstests.hss:876: multdiv(1, 499, 1000) == 0+hstests.hss:877: multdiv(1, 500, 1000) == 1+hstests.hss:878: multdiv(1, 501, 1000) == 1,hstests.hss:879: multdiv(-1, 500, 1000) == 0Hhstests.hss:880: multdiv(1 000 000, 1 000 000, -1 000) == -1 000 000 000?hstests.hss:881: multdiv(1 000 000, 1 000 000, 1) == 2147483647Ahstests.hss:882: multdiv(1 000 000, -1 000 000, 1) == -2147483648nm32555.HSZ8 %MDR VUUUU b H>3333 +.69 ;.0AGVY S[ ag0ioPqwjyv32554.HSZh 0&Mt+T  GGGG"Gp+- /46}}@}}8DI}+TV[]g_kp0p+{"}     !hstests.hss:895: bitcount(0) == 0*hstests.hss:896: bitcount(0x70000000) == 3*hstests.hss:897: bitcount(0x11111111) == 82hstests.hss:898: bitcount(0x107030ff) == 1+3+2+4+432553.HSZ \ Adk +Ng!CJB(  "&(*4,8=HK(MWO[`'& \p*(s{{}{{u{*' U(& 2Xo&(KKKKK$K 90.(      9(    "'  A25(7  A  9EJ  N5KW[<UKaJps(uwvR([( ,7c(l( y'(,6.:?Ksubscript testshstests.hss:908: sscript 1 == 2hstests.hss:909: var1 == 1hstests.hss:924: var1 == 5hstests.hss:926: var1 == 85hstests.hss:938: var2 == 111%hstests.hss:975: sscript4(1) == 12345hstests.hss:976: var1 == 111hstests.hss:977: a global == -2hstests.hss:989: var1 == 7 hstests.hss:990: var2 == 111 + 7hstests.hss:991: var3 == 0hstests.hss:1007: fib(10) == 55.hstests.hss:1009: inside-outside fib(10) == 55$hstests.hss:1042: sibling1(10) == 55var1var2var332552.HSZ| )n  J\32551.HSZ ). (  z%argx32550.HSZ )#b   d% 82x32549.HSZ & \  f Varg232548.HSZ )_ 5Ts  zr n aa(aa ,1a <?AG#IO  Y\f^jo|z}ooooo-hstests.hss:970: read global(@a global) == -1hstests.hss:972: v0 == 0hstests.hss:973: v1 == 1002arg1v0v132547.HSZp @$P$CV   IIII I +.06"8 >zhstests.hss:967: arg2 == 12arg2v232546.HSZ l#[߻%0N  {  !,.P 69;A!C ~Iphstests.hss:963: arg3 == 123arg3v332545.HSZ  " *5Wr   !&13  ;>@JBNS^aci3l@3:,xz} a 82dVhstests.hss:951: a global == -1hstests.hss:953: arg4 == 1234$hstests.hss:959: v4 == arg4 * 10 + 5arg4v432544.HSZ| ) L p32543.HSZ )aR\f jv (+ *<"?"06D J^RYDxret32542.HSZ )n  nret32541.HSZ JNZ(+ 1<$`DdG LMF6>R_b h< y$| ms"X Bk32540.HSZ )r[el N Rt^# & !,,70: @XKR1EN TFbtjnret32539.HSZ\  73<[|* | &*/:ADNFRWb eogsxd*P CCCCChstests.hss:1060: arg == 1hstests.hss:1062: arg == 1hstests.hss:1063: v1 == 42hstests.hss:1080: v1 == 42argv132538.HSZt ~&GRrN  AAAA"A- 0:2>C?NPXP [e]inhstests.hss:1053: arg == 2hstests.hss:1055: v1 == 0hstests.hss:1057: v1 == 63argv132537.HSZh C$-Lo  ssss s +2 5?7CH!SV XbZfkhstests.hss:1073: v1 == 0hstests.hss:1075: v1 == 0hstests.hss:1076: arg == 33argv132536.HSZl DQt /@ Hd "&+ 68:<hstests.hss:1070: arg == 100v132535.HSZ8 arg32534.HSZ V%.48HQ 2&!,b p,@>CNnx32533.HSZ e^ jnz ')(n9r<HBG~JB!-3P Vby32380.HSZ <d oL d '*0.*3$9 DFHN?RXceNgHse|cvsDsssss!\mFFDcD0 4* )D  !'  +1 T<NHQKTZ{3De{{gm{{`qw{5B{|xsF D2,(hdr 2ns r  N u=D)uu+1uu$5;uD" FIHXD QT\KVR\<?bhxe{uGDuuuuu PFD      [DyyyyyF > > t t     gD     $* . F5:fFF UX  5`c Ze k{ nDv{ { x~{ { q{  X  c   zD      X 0 c: *  D     $hstests.hss:1114: x >= -3 && x <= 10#hstests.hss:1116: x >= 2 && x <= 20#hstests.hss:1120: random(0, 0) == 0&hstests.hss:1121: random(-1, -1) == -1$hstests.hss:1123: x >= -2 && x <= -1$hstests.hss:1125: x >= -2 && x <= -1$hstests.hss:1139: x >= 25 && x <= 78hstests.hss:1143: outliers <= 2&hstests.hss:1147: random choice() == 0)hstests.hss:1149: random choice(-1) == -1hstests.hss:1154: false*hstests.hss:1158: bin1 >= 16 && bin1 <= 53*hstests.hss:1159: bin2 >= 16 && bin2 <= 53*hstests.hss:1160: bin3 >= 16 && bin3 <= 53ixoutliersbin1bin2bin332532.HSZt ( n28BLRZaf5<ELSZa18BINW]bglp 66>@HJ8>HX66 >X 6  k6pr|t26H66p(@"nd@V@-p@:p @Fp  (   ,1  >H@AC  >@Q6 h >@r_@Rhrpmwo{@^_p >>@6F@`jp@y6p V  >p  $  (- > >@   >x Q6 U  >   > O (   u6pz    | V >pI I I I I @   6p      >@ @ d @   > plotstr tests ????6autotest-plotstr.hsi:17: string is visible(0) == false6autotest-plotstr.hsi:19: string is visible(0) == falseThis isn't empty-autotest-plotstr.hsi:26: string is visible(5)+autotest-plotstr.hsi:27: string x(5) == 110+autotest-plotstr.hsi:28: string y(5) == 100*autotest-plotstr.hsi:37: string x(5) == 10*autotest-plotstr.hsi:38: string y(5) == 205autotest-plotstr.hsi:41: string x(5) == 160 -- 4 * 16)autotest-plotstr.hsi:42: string y(5) == 0This is flat yellow-on-purple5autotest-plotstr.hsi:46: string is visible(6) == trueNow it's tranparent flat white.autotest-plotstr.hsi:62: string length(6) == 05autotest-plotstr.hsi:64: string is visible(6) == trueXYZ6autotest-plotstr.hsi:69: string is visible(6) == false32531.HSZ\  n*32530.HSZ\  @(28Aw l`  #% \l6 v=??tv@HK:~TWZb  ]dL nNhrnewgame scriptarg1arg2arg3arg1arg2arg332529.HSZd 1?Ep  z n   w  "$'),. \lC 4w f~MPS  V]g.Jak^loadgame scriptslotarg1arg2arg3 hook loadgameslotarg1arg2arg332528.HSZ  r$FMQUY]aeimquy} nH (+-/;;9;;1=B;?t~~ ~@r~h~~ ~~ ~~ B~~\~~ ~ ~ ~ n~~ <~ T~ ns~ ~w~ ~ ~ ~ .~J~ r~~~4,autotest.hss:122: map autorun triggered == 132527.HSZ  xinterval32526.HSZ  ^ x  z32525.HSZP .  N32524.HSZX  ~:32523.HSZD    |32522.HSZ S  <jITESTS SUCCEEDED32521.HSZt  XN jticks32520.HSZ  q   ~ 8"( -.  F6:!0;@ d K p7TW Z|_7eg D`s T|5pue{ (j~N`\ 'D  %s -> %sstringdepthid32519.HSZX  =FMSX^ciov{  4 Xx*$,d/29. D DK$* \D*~DDDD tI .()crash() called from in testsuite: 32518.HSZ    @n ASSERT FAILURE:32517.HSZ\  +2SctDl$')2~b 6:<UUFUU>JOU\ Z^HilX\n "~z':~\ :i $scheduling tests0autotest.hss:260: check bug 430 enabled == false/autotest.hss:264: check bug 430 enabled == trueoldval32516.HSZh  V\F832515.HSZ ^    32514.HSZ( (39>aRj  EEEE$E/11/1 DGJTLX]/autotest.hss:284: ticker 1 == expected ticker 1/autotest.hss:288: ticker 1 == expected ticker 132513.HSZ m T b32512.HSZ y+3;CO[ 9BHT$+@ %'19A<IKM%% @Y  dY `gmoyq}KK%% &  YmsssssBm55555Kd(Ymyyyyy  1m",$05@YKK%% YKR%%   b>^emkumy~K  KmXmaYm    jm       I  blocking tests.autotest.hss:310: ticknumber == start tick + 2.autotest.hss:316: ticknumber == start tick + 2autotest.hss:318: ticker 1 == 0autotest.hss:320: ticker 1 == 2.autotest.hss:321: ticknumber == start tick + 4.autotest.hss:327: ticknumber == start tick + 4.autotest.hss:329: ticknumber == start tick + 7autotest.hss:330: ticker 1 == 4autotest.hss:331: ticker 2 == 26autotest.hss:335: ticker 0 == ticknumber -- start tick start tick32511.HSZ, ?, 8     'f)!/4 start tick32510.HSZ@ k $,4>LVwN "*62 ~::< H:J d: [H^`jbns  0HF ~*T :fN:r " >T 8b t\.check bug 430 enabledautotest.hss:365: ticker 2 == 2 start tick32509.HSZ [5;`:Cgn$GNp%,Ps6@ent#Eh99BX AEGISKW\imu xgG}H"9Gg9omjR *G9 6G 9lCG#__-__%16_cAR fOINGPZR^cm ,R ne\tyG{aaaa}ay R i9G9 ugGsssss99Gm gG  mJ+9G0==:==2>C=mm $TGYc[glmtwmG|gggg~gR mG m8  h F   G     $ A R R d GE E E E !E I R 4 _27G9' ' C' ' ;GL' m W9G\s s fs s ^jos  z }7G     v T    G     D  7G     R x )7Gk k k k  k R 69G  )  !-2 =gnFBI9GNXP\all9Ll PzgGm4z `[gGSSSSS@g9m#gAG#IRxGEE EEEI!RI )!G.80<A9>LGQ11[11S_d1moGt{{~{{v{l(llIRI .G     ldGWWWWWI Inventory tests+autotest.hss:386: get inventory size == 600*autotest.hss:389: item in slot(slot) == -1/autotest.hss:390: item count in slot(slot) == 0,autotest.hss:395: inventory(item:Boots) == 3/autotest.hss:396: item in slot(0) == item:Boots,autotest.hss:397: item count in slot(0) == 3.autotest.hss:399: inventory(item:Boots) == 102.autotest.hss:401: inventory(item:Boots) == 101,autotest.hss:403: inventory(item:Boots) == 0'autotest.hss:407: item in slot(0) == -1,autotest.hss:408: item count in slot(0) == 0'autotest.hss:409: item in slot(1) == -1,autotest.hss:410: item count in slot(1) == 0/autotest.hss:413: item in slot(1) == item:Boots,autotest.hss:414: item count in slot(1) == 1,autotest.hss:415: inventory(item:Boots) == 16autotest.hss:418: item in slot(lastslot) == item:Boots.autotest.hss:420: inventory(item:Boots) == 100-autotest.hss:424: inventory(item:Boots) == 95,autotest.hss:425: item count in slot(1) == 04autotest.hss:426: item count in slot(lastslot) == 959autotest.hss:430: item in slot(lastslot) == item:SteelSho4autotest.hss:431: item count in slot(lastslot) == 950autotest.hss:432: inventory(item:SteelSho) == 95,autotest.hss:433: inventory(item:Boots) == 03autotest.hss:437: item count in slot(lastslot) == 0'autotest.hss:440: item in slot(2) == -1*autotest.hss:444: item in slot(slot) == -1?autotest.hss:448: get item maximum stack size(item:Boots) == 99>autotest.hss:449: get item maximum stack size(item:Bulky) == 3,autotest.hss:451: inventory(item:Bulky) == 6,autotest.hss:452: item count in slot(0) == 3,autotest.hss:453: item count in slot(1) == 3-autotest.hss:458: inventory(item:Bulky) == 46,autotest.hss:459: item count in slot(2) == 3slotlastslot32508.HSZ  "&*.2 ~8~~qL~~~~~2~V32410.HSZL   G*5  j  ]]]]!&]z13+autotest.hss:503: hero by slot(slot) == whoslotwho32409.HSZH  F)4 p  cccc %cz02*autotest.hss:508: hero by slot(slot) == -1slotwho32408.HSZ 8LAr{ z #',0D 7= r H  QT \_Vag} r}}tz}}m~}Kr T@ ( :% 1(-7/;@K x?NSUkk_kkWchkDlL s{"autotest.hss:516: loading == false(autotest.hss:520: slot == 2 || slot == 3&autotest.hss:521: slot + old slot == 5autotest.hss:525: slot == 20autotest.hss:526: old slot >= 41autotest.hss:527: hero by slot(slot) == hero:Kitt.autotest.hss:528: hero by slot(old slot) == -1slotold slotloading32507.HSZ D 4| 1Ty 2Z3Vy.Qw .Qt#,LZ&/5\ek "IPq - P \ ~  . 5 V b   % O r y  7 d   % ZF +`Z,Afz"BZB BF $(-z:,8;=--G--?KP- A8[`bsslssdpus E  R  n_aaaaa f lYYYYY  z%).    @9>C  M  EQV  t afkgguggmy~gC` z6)))))F|ooooo      @33&33*/3 ~:?qqIqqAMRq ]bldpu   <  / / / / /  z  m m m m m +h  [ [ [ [ [ ,    !  %*   (5:  D  <HM A 0 1X]`  j  bns fT ~ >~G G G G G B;   J;     Z` ~ Wq q q q q Z d     Z   q   !  %* Z d ~5:W W DW W <HMW Z; X]  g  _kp `6{)))))  XKKKKK; B*FF15ss?ss7CHsZ* SU(`;2cnpviz*PCCCCC *; ^QQQQQ   ZM"MMMM "M--   ;0FHNARX;c   & `qS=|SS~SSwSH   KVZ* P  . Xc Z*  Z* T  2 (g35;.?ED  "rUZd\hmZ bx;}U}UUUUUE*  *Z* . XZ* hb!!!!! !Y     $ )  f4 ;9 YYC YY; G L YZ YW  Bb g 55q 55i u z 5Z;  ;    *;  , ;   Z* ~ ; q qq qq q D  ,  !  % * B` : `? I A M R Z HY]   h m {{w {{o { {Z  Y    0  ## ## #Z Y p (   B`Z` S  5    F   Z` f S `  + ; .  =9   ; A   4 E K   !EV [   e   ] i n  B`2! n!P~ ` a!a! a!a! a!! ;" !] !! !! !:" "e ` "" "" "" v"s i"i" i"i"  i"" " ""* """ . 3 "Z` #> #C #N ##P V ##I Z ` #Z` #k $p #{ ##} ##v # $r ${$ $$ $$ $Y ^%{%  %% %% % &Z* h&Y F&{&  && &&   & 'Y $'hero party management tests+autotest.hss:535: room in active party == 3*autotest.hss:542: observed hero count == 1+autotest.hss:546: room in active party == 0*autotest.hss:547: observed hero count == 4/autotest.hss:548: hero by rank(0) == hero:Freki/autotest.hss:549: hero by rank(1) == hero:Helga.autotest.hss:550: hero by rank(2) == hero:Olaf0autotest.hss:551: hero by rank(3) == hero:Frumpy4autotest.hss:553: hero by rank(0) == hero by slot(0)4autotest.hss:554: hero by rank(1) == hero by slot(1)4autotest.hss:555: hero by rank(2) == hero by slot(2)4autotest.hss:556: hero by rank(3) == hero by slot(3)*autotest.hss:559: observed hero count == 3+autotest.hss:560: room in active party == 1&autotest.hss:561: hero by rank(0) == 1&autotest.hss:562: hero by rank(1) == 2&autotest.hss:563: hero by rank(2) == 3'autotest.hss:564: hero by rank(3) == -1'autotest.hss:565: hero by slot(0) == -1&autotest.hss:566: hero by slot(1) == 1&autotest.hss:567: hero by slot(2) == 2&autotest.hss:568: hero by slot(3) == 3"autotest.hss:571: hero x(0) == h0x"autotest.hss:572: hero y(0) == h0y autotest.hss:573: hero z(0) == 0.autotest.hss:574: get hero speed(0) == h0speed*autotest.hss:575: hero direction(0) == h0d0autotest.hss:579: hero by slot(0) == hero:Styrge.autotest.hss:581: find hero(hero:Freki) == -1-autotest.hss:582: find hero(hero:Helga) == 1-autotest.hss:583: find hero(hero:Olaf) == 2-autotest.hss:584: find hero(hero:Frumpy) == 3-autotest.hss:585: find hero(hero:Styrge) == 08autotest.hss:587: rank in caterpillar(hero:Freki) == -17autotest.hss:588: rank in caterpillar(hero:Helga) == 17autotest.hss:589: rank in caterpillar(hero:Olaf) == 27autotest.hss:590: rank in caterpillar(hero:Frumpy) == 37autotest.hss:591: rank in caterpillar(hero:Styrge) == 0+autotest.hss:594: room in active party == 0autotest.hss:597: slot >= 46autotest.hss:598: rank in caterpillar(hero:Kitt) == -11autotest.hss:599: hero by slot(slot) == hero:Kitt'autotest.hss:600: hero by rank(4) == -1Styrge&autotest.hss:604: string compare(1, 2)Helga&autotest.hss:607: string compare(1, 2)Olaf&autotest.hss:610: string compare(1, 2)Frumpy&autotest.hss:613: string compare(1, 2)Kitt&autotest.hss:616: string compare(1, 2) Kittzilla&autotest.hss:620: string compare(1, 2)'autotest.hss:623: hero by slot(1) == -1,autotest.hss:624: find hero(hero:Helga) >= 4.autotest.hss:626: hero by slot(1) == hero:KittHautotest.hss:627: find hero(hero:Kitt) >> 0 && find hero(hero:Kitt) <= 30autotest.hss:629: hero by slot(0) == hero:Frumpy0autotest.hss:630: hero by slot(3) == hero:Styrge/autotest.hss:632: hero by slot(3) == hero:Helga-autotest.hss:633: find hero(hero:Styrge) >= 40autotest.hss:635: hero by slot(1) == hero:Styrge+autotest.hss:636: find hero(hero:Kitt) >= 4'autotest.hss:638: hero by slot(0) == -1/autotest.hss:641: hero by slot(0) == hero:Freki/autotest.hss:643: hero by slot(1) == hero:Helga.autotest.hss:645: hero by slot(2) == hero:Olaf0autotest.hss:647: hero by slot(3) == hero:Frumpyautotest.hss:652: slot == 0autotest.hss:655: slot >= 4'autotest.hss:657: hero by slot(0) == -1/autotest.hss:659: hero by slot(0) == hero:Frekiautotest.hss:661: slot >= 42autotest.hss:662: hero by slot(slot) == hero:Freki0autotest.hss:663: delete hero by slot(slot) == 0*autotest.hss:664: hero by slot(slot) == -1,autotest.hss:666: find hero(hero:Freki) >= 0,autotest.hss:667: find hero(hero:Freki) <= 3&autotest.hss:672: move hero count == 0&autotest.hss:675: move hero count == 2&autotest.hss:679: move hero count == 3h0xh0yh0speedh0dslot32506.HSZX  -&JS]:AJS\cjsx} .RY_ekqw*NU[*  ,*13ss=ss5AFsYQ*V YY[pQ3 ci1kumy~pQYX 1KKKKKpQQ-Q1qQ3"=1qQYM1{{ {{ {qQQ]Q1#-%16nQ33HnQHYnQQQ%oQZ3:oQYYoQQ q 2 *VpQ3m31pQY@}H133333pQQQ1qQ3 Z1qQYpY1cc!cc%*cqQQ51;E=INQ30 QY~ QQ Q3 QYj QQ pQ3 }i1     pQY| 1o o o o o pQQ Q1     qQ3F 19 9 9 9 9 qQY   1    !& qQQ 1Q17  A  9EJ YQ* YY[ 0autotest.hss:687: hero by slot(3) == hero:Frumpy9autotest.hss:693: get hero picture(2, inside battle) == 8:autotest.hss:694: get hero picture(2, outside battle) == 99autotest.hss:695: get hero picture(2, hero portrait) == 2:autotest.hss:696: get hero palette(2, inside battle) == -1;autotest.hss:697: get hero palette(2, outside battle) == -19autotest.hss:698: get hero palette(2, hero portrait) == 29autotest.hss:711: get hero picture(2, inside battle) == 0:autotest.hss:712: get hero picture(2, outside battle) == 49autotest.hss:713: get hero picture(2, hero portrait) == 7:autotest.hss:714: get hero palette(2, inside battle) == 37:autotest.hss:715: get hero palette(2, outside battle) == 1:autotest.hss:716: get hero palette(2, hero portrait) == -19autotest.hss:725: get hero picture(2, inside battle) == 8:autotest.hss:726: get hero picture(2, outside battle) == 99autotest.hss:727: get hero picture(2, hero portrait) == 2:autotest.hss:728: get hero palette(2, inside battle) == -1;autotest.hss:729: get hero palette(2, outside battle) == -19autotest.hss:730: get hero palette(2, hero portrait) == 232505.HSZ5 )Q # "+3;AJRZ`it|CQ{(7=Bp| BQW\6EKP]ch")/k%.BGu|-Nch* 3 9 > E Y ^ . = K Y g m q P   B< rl Z Y @D $ D f D     (~tZ Y&19 ~>Z YEtP!X~$Z YdZZ Yo&z+8~bB0 39R~Z Y?ELK~O   " V* YN C  v   T     W8     Z+-  /5  &9? Z JL   W Z g+e  gm  `qw pF  ^  *  x   s    v: y+        : R+ $/1 p  GIO+Z\bUflZ YwZ + l     4nJ=+=====  4^! +,  .4  '8> IK |  aci+tv|oZ YZ +       ~ D   + +}}}} }2"+%%)%%!-2%1=?   4U:W  \ |7mou:+{G,  zJ\OM+OOOOO_    bZ6)e+ )))))O x- Pr4u<>- 6DJsx+UssW]ssPagsr$zX|- <t+- +0|- `+ !1,46 <  .LhNDT7+_77ag77Zkq7   ( j  N  6      +     R! j! !!! ! ! "T"0" #"+#"#"#"#"#)#"y "(4+7}"}"A}"}"9EJ}"2U#W- "] " @#6mz#oV#uI#:+I#I#I#I#{I#I# # $N&$R$ f$ N$ $U$$$Y+$$$$$h @% % %m+ %%  %% & %}1 % %  &C &K V&M  :&S "& x&c &e &k &+v &&x ~ &&q & f' - J' 2' ' ' ' '+ '' '' ' D( r( (  ) ( ( ) f) Y)+ Y)Y) Y)Y) $ * Y)@*Z5 ,*Y8 **ZC z*YF R**ZQ *YT *"+Z_ +Yb *~0+VR+hero names embed testsOlaf,,,Olaf,,,Freki,Helga,Olaf,Frumpy,StyrgeOlaf,,,,,Olaf, Frumpy,Olaf,, Frumpy,,Olaf, Olaf,Frumpy,, ,Olaf,,FrumpyNolafOlaf,Nolaf,Frumpy,Olaf,Nolaf,,FrumpyFrumpy,Nolaf,Olaf,Frumpy,Nolaf,,OlafFreki,Helga,Nolaf,Frumpy,Styrge${H1}Helga/autotest.hss:797: string compare(1, $2="Helga")autotest.hss:803: helgaslot > 3Hagar${H1}Hagar/autotest.hss:809: string compare(1, $2="Hagar")HelgaHelgaIautotest.hss:812: string compare(get hero name(1, helgaslot), $2="Helga")${H1}Hagar/autotest.hss:815: string compare(1, $2="Hagar"),autotest.hss:820: find hero(hero:Helga) == 2Humpty${P2}Humpty0autotest.hss:826: string compare(1, $2="Humpty")HelgaHelgaAautotest.hss:829: string compare(get hero name(1, 2), $2="Helga")${P2}Humpty0autotest.hss:832: string compare(1, $2="Humpty"),autotest.hss:837: find hero(hero:Helga) == 3'autotest.hss:841: hero by slot(2) == -1'autotest.hss:843: hero by slot(0) == -16autotest.hss:845: rank in caterpillar(hero:Helga) == 1Hissy${C1}Hissy/autotest.hss:851: string compare(1, $2="Hissy")HelgaHelgaAautotest.hss:854: string compare(get hero name(1, 3), $2="Helga")${C1}Hissy/autotest.hss:857: string compare(1, $2="Hissy")${H1}${H1}Jautotest.hss:863: string compare($1="${H1}", expand string($2="${H1}", 5))${P0}${P0}Jautotest.hss:864: string compare($1="${P0}", expand string($2="${P0}", 5))${C0}${C0}Jautotest.hss:865: string compare($1="${C0}", expand string($2="${C0}", 5))${H1},${H2},${H3}${H1},${H2},${H3}bautotest.hss:866: string compare($1="${H1},${H2},${H3}", expand string($2="${H1},${H2},${H3}", 5)) Var=${V121} Var=543213autotest.hss:872: string compare(1, $2="Var=54321") Var=${V121} Var=543213autotest.hss:877: string compare(1, $2="Var=54321") Var=${V121} Var=1000014autotest.hss:883: string compare(1, $2="Var=100001")!autotest.hss:884: saveglobal == 1 Var=${V121} Var=${V121}5autotest.hss:887: string compare(1, $2="Var=${V121}")A very fine mess Cleaned up${S255} Cleaned up6autotest.hss:894: string compare(255, $1="Cleaned up")A very fine mess:autotest.hss:895: string compare(2, $1="A very fine mess")Is better than sloppy order${S2}Is better than sloppy orderEautotest.hss:901: string compare(3, $1="Is better than sloppy order")${S2}${S2}/autotest.hss:904: string compare(3, $1="${S2}")Not Over 9000!! Cleaned up String=${S3}String=Not Over 9000!!@autotest.hss:911: string compare(2, $1="String=Not Over 9000!!")h0h1h2h3 helgaslot32504.HSZ  @8W9  *0:@k Rt &(& 68<6 FH SUW]Nag&r"S}x68+-S+++++~h${C0},${C1},${C2},${C3}${P0},${P1},${P2},${P3}${H65},${H1},${H2},${H3},${H4}&autotest.hss:931: string compare(1, 4)&autotest.hss:932: string compare(2, 5)&autotest.hss:933: string compare(3, 6)32503.HSZ : $)   @  f  v   "  32502.HSZ( N; "W`f l ~ v. ,4 ?r~GJ.7AJt& (*OZwdhero caterpillar testsleader, cater=ONhero , cater=OFFi32501.HSZT Fk< &.PZdjr!(Lr~#/9>b,Rz @fDNXafBhr|7]  % I o  ( 2 V ` l v {  ( 2 9 a h  ) N X _  ! E O t ~ BLV3=Gku'/9]gqp  +  (   <`+ D,3|6ooCoo;GLo&W _b  0o Z+wLzb?????t  ,& ^> p x+( W 8+-*205?7CHn,S`<V[SSeSS]inS y||    ,FbPf2P|%%%%% ]sssss h  *|- 6 v ,CsFKUMY^fi}l|q{s> | *| ` ,bf|( | d H p+ yyyy#(yf36;E=IN Y  \acmeqvX  D b7 7 7 7 7    r      ,      : f      p    \      +! $)  3  +7< " fG JO  Y  Q]b   5or    f       u{| mT d  | P  5     $ f      b +T G G G G  G  ,% (b-} } 7} } /;@}   K  5U B^ & Nfkd)nsWW}WWuW+6,@b"  j5|D  fJ| +#W&+5-9>V,IHaLQ;;[;;S_d; o p5y   @f"k|+nxaaaaa,B - .  f f *".3+>AFPHTY6,d(gblvnzd - P  f+T,Fb9999  9  |- n  f* - |2 < 4 @ E @+P 2S X %%b %%Z f k %v,v hy ~ [[ [[ [  -   "f     ^+ P  CC CC C,   yy yy   y %  b/ F,7 ~: ? qqI qqA M R q~] B i  .~s b     ~ t  | `      "N~ *     ~ Q |A  |    $  / |  b4nt> NA A&K AAM S AAF W ] A ~tm 1p u  w Q a8A > a        f  | R at  J     t U      LQ& .A/ nb2 7 aaA aa9 E J a U |  td g nq s y l }  &`t @y 33 33 3Q A        |  4 n t N  A  A A  A A    A  ~  t&  ) .   8   0 < A   QL  :!AU !X ] !!g !!_ k p !j! { | V! !!t ! !! !! !!   ! "6"  | "" |V""+ r"  e"e" e"e" e"", "  """" ""Qa"*#A# #&a+""5""-9>"X# I D##S x#$$`|$]cl$$o $$w|$rz$$$$$% %i\$[@$% t%n%%%%%%%% %%&x%%%% %&i&#%&&#.& (1&'> '6'#F2'AIO&&Y&&Q]b&r'm X''#u'px~K'K'K'K'K' '7f&r&b&F&(Wb'B( | .(( (),((((((6)  "))  ))+)%))&))*/)* :| )*D **+L*/OaT**^**Vbg*&+ r ++| + ,++9a+++++:,  &,, ,,,,Cb,,,,,- | -- --,-Mb---- --  -4.$ .V. ,|| B..6 ..,>.WAF..P..HTY.&/ d //n //,v/ay~/////000/  0"autotest.hss:973: hero x(who) == 8#autotest.hss:976: hero y(who) == 10"autotest.hss:980: hero x(who) == 9"autotest.hss:983: hero y(who) == 8"autotest.hss:987: hero x(who) == 6"autotest.hss:989: hero x(who) == 7"autotest.hss:990: hero y(who) == 7"autotest.hss:993: hero y(who) == 9.autotest.hss:994: hero direction(who) == south%autotest.hss:995: forward x(who) == 7&autotest.hss:996: forward y(who) == 10"autotest.hss:999: hero y(who) == 8/autotest.hss:1000: hero direction(who) == south#autotest.hss:1003: hero y(who) == 9/autotest.hss:1004: hero direction(who) == south#autotest.hss:1007: hero x(who) == 5.autotest.hss:1008: hero direction(who) == west&autotest.hss:1009: forward x(who) == 4&autotest.hss:1010: forward y(who) == 9#autotest.hss:1013: hero y(who) == 8/autotest.hss:1014: hero direction(who) == north#autotest.hss:1017: hero x(who) == 6.autotest.hss:1018: hero direction(who) == east+autotest.hss:1022: hero direction(who) == d/autotest.hss:1028: hero direction(who) == north#autotest.hss:1029: hero x(who) == 6#autotest.hss:1030: hero y(who) == 9.autotest.hss:1034: hero direction(who) == east#autotest.hss:1035: hero x(who) == 5#autotest.hss:1036: hero y(who) == 9/autotest.hss:1040: hero direction(who) == south#autotest.hss:1041: hero x(who) == 5#autotest.hss:1042: hero y(who) == 8.autotest.hss:1046: hero direction(who) == west#autotest.hss:1047: hero x(who) == 6#autotest.hss:1048: hero y(who) == 8/autotest.hss:1052: hero direction(who) == north#autotest.hss:1053: hero x(who) == 6#autotest.hss:1054: hero y(who) == 9.autotest.hss:1057: hero direction(who) == east#autotest.hss:1058: hero x(who) == 5#autotest.hss:1059: hero y(who) == 9/autotest.hss:1062: hero direction(who) == south#autotest.hss:1063: hero x(who) == 5#autotest.hss:1064: hero y(who) == 8.autotest.hss:1067: hero direction(who) == west#autotest.hss:1068: hero x(who) == 6#autotest.hss:1069: hero y(who) == 8#autotest.hss:1073: hero Y(who) == 6+autotest.hss:1091: get hero speed(who) == 2'autotest.hss:1093: hero is walking(who)0autotest.hss:1094: hero is walking(who) == false+autotest.hss:1096: get hero speed(who) == 4'autotest.hss:1098: hero is walking(who)0autotest.hss:1099: hero is walking(who) == false+autotest.hss:1101: get hero speed(who) == 5'autotest.hss:1103: hero is walking(who)0autotest.hss:1104: hero is walking(who) == false,autotest.hss:1106: get hero speed(who) == 10'autotest.hss:1108: hero is walking(who)0autotest.hss:1109: hero is walking(who) == false,autotest.hss:1111: get hero speed(who) == 200autotest.hss:1113: hero is walking(who) == false$autotest.hss:1116: hero x(who) == 10#autotest.hss:1117: hero y(who) == 6+autotest.hss:1119: get hero speed(who) == 42autotest.hss:1127: hero frame(who) == (fr ,mod, 2)autotest.hss:1133: px == 140autotest.hss:1135: py == 1200autotest.hss:1140: hero pixel x(who) == 105 + ix0autotest.hss:1141: hero pixel y(who) == 105 + iy$autotest.hss:1150: hero y(who) == 10#autotest.hss:1153: hero x(who) == 6#autotest.hss:1156: hero x(who) == 4#autotest.hss:1159: hero x(who) == 4#autotest.hss:1162: hero y(who) == 9#autotest.hss:1165: hero y(who) == 9$autotest.hss:1170: hero y(who) == 11$autotest.hss:1173: hero y(who) == 11whodfrpxpyixiy32625.HSZ` H T$*0Ck6=\c)0QX{((T(+( ,(57<> A(   KPRT^Vbgt(dr(RwWWWWyW+( ( :( zt&RHj( v2R]]]] ]t(>R "(,2IA(REOGSX(  hkpWR{}v (( (t(Jc(R=====+( 8 2pR ~,(W(R+( | R %f(~5R:qqDqq<HMq ( f(_Rdnfrw (   R     0 X ( z     m Rm m m m m  ,(" W(  (( > suspend walkabouts testsheroxheroy*autotest.hss:1189: get hero speed(me) == 4/autotest.hss:1190: hero is walking(me) == false+autotest.hss:1200: walkabouts are suspended)autotest.hss:1204: px == hero pixel x(me)&autotest.hss:1205: hero is walking(me)4autotest.hss:1208: walkabouts are suspended == false)autotest.hss:1212: px <> hero pixel x(me)/autotest.hss:1216: hero is walking(me) == false*autotest.hss:1220: hero x(me) <> initial x*autotest.hss:1222: hero x(me) == initial x-autotest.hss:1225: hero direction(me) == left.autotest.hss:1227: hero direction(me) == right5autotest.hss:1229: hero pixel x(me) == initial x * 205autotest.hss:1234: hero pixel x(me) <> initial x * 20 initial xpx32500.HSZ 8Z-Y ~   qq qq$)q479?BLDPUL`c,jeknxp|*wwwww4autotest.hss:1243: check hero wall(who, north) == wn3autotest.hss:1244: check hero wall(who, east) == we4autotest.hss:1245: check hero wall(who, south) == ws3autotest.hss:1246: check hero wall(who, west) == wwwhownwewsww32499.HSZm  R2\7_%Kq5Eo 2YCjCl9b/X< E i p  , 3 V y  8 ? a  * M q   6 Y | 3V~=DKRY`e "DKkr*1RY`%HQXy6[*1U\dkryr NGAAAA A}" *".3>/@FHRJV[f<<hnp//z//r~/IV,c |p oooo!o ,.4>6BG RXZd\hm xtRzggggg # V p Fcccc c( ,1AZ> <@ K&NY[aTek rvDy77777  >  >xFkkkkk  f*n%). v 9H :<B; ; L; ; DPU;  ` Jci  s  kw|  F  Z       j s s s s s   , z4      T XG G G G G  x# &,  6  .:?  \ J, MS  ]  Uaf  q tz    |  4        p c c c c c BLZ   Z#,&,6.:? JF MSU_Wch "syv|~ >Z,MMMMM f< T&hL  \ ",$05 @dlCIKUMY^ iX|lrtKK~KKvK , V& x * "&+ 6dR9?AWWKWWCOTW _ bhjtlx} h8G.+++++C f B    !  % *  . V5 : ,L R \ T ` e ,~ 9w }   NF    R   @x ^     l    # ( j y9 ? I A M R t] b ggl ggd p u gf    < // // /         H)  ! ;;+ ;;# / 4 ;fE J YYT YYL X ] Y h m w o { *    2 r  e e  e e  e           :! !! , y!y! y!y! ! & y! !1 6 !!@ !!8 D I ! "%T Z !!d !!\ h m !b"3x ~ U"U" U"U" U" "? "" "" "&# #K ## ## ##V ## ##  #L$$ $d  $$) $$! - 2 $ %o= B %%L %%D P U % T%{` e G%G%o G%G%g s x G% % %% %% % % %% %% %X &`& S&S& S&S& S&& &&&&  &&&&&&&*/&&':?''I''AMR'Zf ' ]h'bg['['q['['iuz['2(l(((S )d)x) *())))) J*=*=*=*=*=* *** *** *!&**0**(49*+L++++L, ,kp,,z,,r~, ,,,,,, &-(----- n-4a-a-a-a-a---.V.@ .S .;22E22=IN23 F3  \3ejO3O3tO3O3lx}O3 x 333333x4 R4  h4[4[4[4[4[4 x 444444&5 `5  v5 i5i5i5i5!i5 x 5,155;553?D5O26 l6  6]bu6u6lu6u6dpuu6 x 666666>7 x7  7!77777 x 7177777 8B8888 88M88)88!-28@x ^9Y=DQ9Q9NQ9Q9FRWQ9@x 9fbi99s99kw|9@ n:h:Sx :`;s S;S;S;S;S;@x ; ;;;;;@ ;><;;;;; <<<<<!&<Sx = =9>s=s=Hs=s=@LQs=Sx =>P>>>hero exp and levels tests/autotest.hss:1261: experience to level(1) == 30/autotest.hss:1262: experience to level(2) == 710autotest.hss:1263: experience to level(3) == 1250autotest.hss:1264: experience to level(4) == 1950autotest.hss:1265: experience to level(5) == 2840autotest.hss:1266: experience to level(6) == 3960autotest.hss:1267: experience to level(7) == 5350autotest.hss:1268: experience to level(8) == 7070autotest.hss:1269: experience to level(9) == 9182autotest.hss:1270: experience to level(10) == 11762autotest.hss:1271: experience to level(11) == 14912autotest.hss:1272: experience to level(12) == 18742autotest.hss:1273: experience to level(13) == 23392autotest.hss:1274: experience to level(14) == 29022autotest.hss:1275: experience to level(15) == 35836autotest.hss:1276: experience to level(99) == 50183838"autotest.hss:1281: freki slot >= 0;autotest.hss:1282: experience to level(1, freki slot) == 30;autotest.hss:1283: experience to level(2, freki slot) == 71<autotest.hss:1284: experience to level(3, freki slot) == 125<autotest.hss:1285: experience to level(4, freki slot) == 195<autotest.hss:1286: experience to level(5, freki slot) == 284<autotest.hss:1287: experience to level(6, freki slot) == 396<autotest.hss:1288: experience to level(7, freki slot) == 535<autotest.hss:1289: experience to level(8, freki slot) == 707<autotest.hss:1290: experience to level(9, freki slot) == 918>autotest.hss:1291: experience to level(10, freki slot) == 1176>autotest.hss:1292: experience to level(11, freki slot) == 1491>autotest.hss:1293: experience to level(12, freki slot) == 1874>autotest.hss:1294: experience to level(13, freki slot) == 2339>autotest.hss:1295: experience to level(14, freki slot) == 2902>autotest.hss:1296: experience to level(15, freki slot) == 3583Bautotest.hss:1297: experience to level(99, freki slot) == 50183838!autotest.hss:1303: bram slot >= 0:autotest.hss:1304: experience to level(1, bram slot) == 30:autotest.hss:1305: experience to level(2, bram slot) == 70;autotest.hss:1306: experience to level(3, bram slot) == 121;autotest.hss:1307: experience to level(4, bram slot) == 185;autotest.hss:1308: experience to level(5, bram slot) == 264;autotest.hss:1309: experience to level(6, bram slot) == 360;autotest.hss:1310: experience to level(7, bram slot) == 475;autotest.hss:1311: experience to level(8, bram slot) == 612;autotest.hss:1312: experience to level(9, bram slot) == 775<autotest.hss:1313: experience to level(10, bram slot) == 967=autotest.hss:1314: experience to level(11, bram slot) == 1193=autotest.hss:1315: experience to level(12, bram slot) == 1458=autotest.hss:1316: experience to level(13, bram slot) == 1768=autotest.hss:1317: experience to level(14, bram slot) == 2130=autotest.hss:1318: experience to level(15, bram slot) == 2551Aautotest.hss:1319: experience to level(99, bram slot) == 36587434)autotest.hss:1322: get hero level(0) == 0)autotest.hss:1326: get hero level(0) == i@autotest.hss:1327: total experience(0) == experience to level(i).autotest.hss:1331: knows spell (0, 2) == false-autotest.hss:1333: knows spell (0, 2) == true)autotest.hss:1335: get hero level(0) == 0*autotest.hss:1336: hero levelled(0) == -101autotest.hss:1337: get hero stat(0, 12, 1) == -10-autotest.hss:1338: knows spell (0, 2) == true.autotest.hss:1340: knows spell (0, 2) == false4autotest.hss:1342: experience to next level(0) == 30(autotest.hss:1344: hero levelled(0) == 04autotest.hss:1345: experience to next level(0) == 25)autotest.hss:1347: get hero level(0) == 1(autotest.hss:1348: hero levelled(0) == 14autotest.hss:1349: experience to next level(0) == 41)autotest.hss:1351: get hero level(0) == 1(autotest.hss:1352: hero levelled(0) == 04autotest.hss:1353: experience to next level(0) == 42)autotest.hss:1355: get hero level(0) == 2(autotest.hss:1356: hero levelled(0) == 1*autotest.hss:1359: get hero level(0) == 10(autotest.hss:1360: hero levelled(0) == 14autotest.hss:1361: spells learned(0, get count) == 1,autotest.hss:1362: spells learned(0, 0) == 2+autotest.hss:1363: spells learnt(0, 0) == 1%autotest.hss:1365: hero levelled == 04autotest.hss:1366: spells learned(0, get count) == 0(autotest.hss:1370: hero levelled(0) == 0+autotest.hss:1371: total experience(0) == 8+autotest.hss:1372: total experience(1) == 8+autotest.hss:1373: total experience(2) == 8+autotest.hss:1374: total experience(3) == 8)autotest.hss:1376: get hero level(0) == 1)autotest.hss:1377: get hero level(1) == 1)autotest.hss:1378: get hero level(2) == 1)autotest.hss:1379: get hero level(3) == 1>autotest.hss:1380: total experience(find hero(hero:Kitt)) == 0,autotest.hss:1389: total experience(0) == 40,autotest.hss:1390: total experience(1) == 40+autotest.hss:1391: total experience(2) == 0,autotest.hss:1392: total experience(3) == 40,autotest.hss:1399: total experience(0) == 30,autotest.hss:1400: total experience(1) == 30,autotest.hss:1401: total experience(2) == 30,autotest.hss:1402: total experience(3) == 30&autotest.hss:1410: get level cap == 99%autotest.hss:1412: get level cap == 2)autotest.hss:1414: get hero level(0) == 2,autotest.hss:1415: total experience(0) == 714autotest.hss:1416: experience to next level(0) == 54(autotest.hss:1418: hero levelled(0) == 0)autotest.hss:1419: get hero level(0) == 20autotest.hss:1422: hero by slot(0) == hero:Freki8autotest.hss:1424: check tag(tag: freki level 0) == true=autotest.hss:1425: check tag(tag: freki level teens) == false9autotest.hss:1427: check tag(tag: freki level 0) == false=autotest.hss:1428: check tag(tag: freki level teens) == false9autotest.hss:1430: check tag(tag: freki level 0) == false<autotest.hss:1431: check tag(tag: freki level teens) == true9autotest.hss:1433: check tag(tag: freki level 0) == false<autotest.hss:1434: check tag(tag: freki level teens) == true9autotest.hss:1436: check tag(tag: freki level 0) == false=autotest.hss:1437: check tag(tag: freki level teens) == false(autotest.hss:1440: hero levelled(0) == 1*autotest.hss:1441: get hero level(0) == 20/autotest.hss:1442: get hero stat(0, 12, 1) == 10autotest.hss:1443: get hero stat(0, 12, 0) == 20*autotest.hss:1447: get hero level(0) == 420autotest.hss:1448: get hero stat(0, 12, 0) == 42<autotest.hss:1449: get hero stat(0, 0, maximum stat) == temp(autotest.hss:1450: hero levelled(0) == 1(autotest.hss:1452: hero levelled(0) == 3i freki slot bram slottemp32498.HSZ G{*06=BkrEj'0W` GPw..N.  ;..;j@..;   IPRT^Vbg.;;@..; 8 yR+++++.;@..; 'R.P;:@..; x.7Rkkkkk... GR .;. "S%,R.80<A.. f_LRSYY]YYUafY.,. kq;Rxz.. w.R.. 2 .R% % % % % .. v .Ri i i i i .T.  .R    # ..;J@..; `7>R@{{J{{BNS{.^;H@..; gnRpyyzyyr~y(.;H@..; Ryyyyy2.;H!@..; !NRy!y!y!y!y!<.;H'@..; 'Ry'y' y'y'y'F.;H-@..; -4'.R0y-y-:y-y-2>Cy-P.N;H3@..; 3W^R`y3y3jy3y3bnsy3Z.~;H9@..; 9TRy9y9y9y9y9b.;>@..; R>'RE>E>E>E>E>c.;>@..; >7R>>>>>..;B?O |? ;?hero stat growth test:autotest.hss:1467: get hero stat(0, 0, maximum stat) == 10:autotest.hss:1469: get hero stat(0, 0, maximum stat) == 13:autotest.hss:1471: get hero stat(0, 0, maximum stat) == 16:autotest.hss:1487: get hero stat(0, 0, maximum stat) == 46*autotest.hss:1489: get level mp(0, 0) == 5*autotest.hss:1490: get level mp(0, 1) == 3*autotest.hss:1491: get level mp(0, 2) == 2*autotest.hss:1492: get level mp(0, 3) == 1*autotest.hss:1493: get level mp(0, 4) == 0*autotest.hss:1494: get level mp(0, 5) == 0*autotest.hss:1495: get level mp(0, 6) == 0*autotest.hss:1496: get level mp(0, 7) == 0:autotest.hss:1517: get hero stat(0, 0, maximum stat) == 96;autotest.hss:1537: get hero stat(0, 0, maximum stat) == 161;autotest.hss:1557: get hero stat(0, 0, maximum stat) == 240;autotest.hss:1577: get hero stat(0, 0, maximum stat) == 334;autotest.hss:1597: get hero stat(0, 0, maximum stat) == 442;autotest.hss:1617: get hero stat(0, 0, maximum stat) == 564;autotest.hss:1637: get hero stat(0, 0, maximum stat) == 701;autotest.hss:1657: get hero stat(0, 0, maximum stat) == 852;autotest.hss:1673: get hero stat(0, 0, maximum stat) == 983<autotest.hss:1675: get hero stat(0, 0, maximum stat) == 100032497.HSZ dW[(  2@ S! @3 S0 6 (=EKO Vbi32496.HSZK 5]ou 3Z6Y|&/U\d*Ot#+QX~?dkqw=d 0U{ 5 Z   8 ] R [  ) N q x  % , 4 W ssB{  }{{s@{ss * @{{s /@{s @&*/@{:s |R<CooMooEQVo@{s dahrjv{@{{ XuKKKKK@{  @{: fYYYYY!ss !{NsAA)AA!-2A!=hBLDPU!:`seogsxn{s@{s h@{ ~qqqqqx{{@{{ V hI I I I I @{ c     " ?B{s-s( @{ss '7->  H  @LQ S{ss  S{s @{s f 9lsY Y }Y Y uY "s  "{2 !s Ku u u u u @{ss Y     @{s{ Dj77777@{s { !&@{{s 18B:FK@{{{ V]g_kp@{{ {S{ ~@{{ S{ j@{ @{{ @h33333S{s S{{ <@{ 3:D<HMS{ V@{{ `gqiuz"s`":!s!:J%=====@{s 3@{{ E @{:s W!(yy2yy*6;y@{:{ iFMWO[`"ss\"{s":s{}sT {GGGGG@{ @{{ H;;;;;@{s  "x{s&0(49@{ RDKMEEWEEO[`E@{{ kr|t@{s 0#####{s"s@{ss {ssK@{ss n#:aa#aa',a@{s{ 47K>H@LQ{ssd E\dW W nW W frwW {s{{ T     @{ss T!dG!G!G!G!G!@{s{ !u!!!!!@{s{ """ "" "@{s #  ""( "" , 1 "@{{{ l#< C _#_#M _#_#E Q V _#@{{ #a h ##r ##j v { #@{s F$ 9$9$ 9$9$ 9$@{{ $ $$ $$ $@{ *%  %% %% %@{:s % %% %%  %@{:{ & ! %%+ %%# / 4 %@{: x&#? F k&k&P k&k&H T Y k&@{ss 0'4d k #'#'u #'#'m y ~ #'@{{s 'E  '' '' '{ss (V { (( (( ({s{ L)e { ?)?) ?)?) ?)$*{ s *t s )) ))   )*{$ { p*' s. c*c*8 c*c*0 < A c* E ) { {L ) {  *{ s +b i ++s ++k w | + { s J+Z} , + { ++ ++ +Z , , s ,, ,, ,AZ - - s {-{- {-{- {-Z{ . `. s S.S. S.S. % S.@{ss ./0 7 !/!/A !/!/9 E J !//U sZ //d //\ h m / {ss n0 0@{{s 0  00 00 0{ss 61 { )1)1 )1)1 )1S{sss 1s 1@{ss H2* s ;2;2 ;2;2 ;2{ 2@{ss 3;  22 22  ! 2S{sss b3 3@{ss \4L9 @ O4O4J O4O4B N S O4hero stat tests0autotest.hss:1695: hero by slot(1) == hero:Helga)autotest.hss:1696: get hero level(1) == 0@autotest.hss:1697: get hero stat(1, stat:hp, current stat) == 10@autotest.hss:1698: get hero stat(1, stat:mp, current stat) == 20Aautotest.hss:1699: get hero stat(1, stat:atk, current stat) == 10Aautotest.hss:1700: get hero stat(1, stat:spd, current stat) == 30=autotest.hss:1701: get hero stat(1, stat:hp, base stat) == 10=autotest.hss:1702: get hero stat(1, stat:mp, base stat) == 20=autotest.hss:1703: get hero stat(1, stat:atk, base stat) == 9>autotest.hss:1704: get hero stat(1, stat:spd, base stat) == 302autotest.hss:1707: get hero stat cap(stat:hp) == 02autotest.hss:1708: get hero stat cap(stat:mp) == 05autotest.hss:1709: get hero stat cap(stat:atk) == 1003autotest.hss:1710: get hero stat cap(stat:spd) == 0Bautotest.hss:1713: get hero stat(1, stat:atk, current stat) == 100=autotest.hss:1714: get hero stat(1, stat:atk, base stat) == 9Bautotest.hss:1716: get hero stat(1, stat:atk, maximum stat) == 100>autotest.hss:1717: get hero stat(1, stat:atk, base stat) == 99Dautotest.hss:1719: get hero stat(1, stat:hp, current stat) == 999999Bautotest.hss:1724: get hero stat(1, stat:atk, current stat) == 1102autotest.hss:1729: get hero stat cap(stat:hp) == 5?autotest.hss:1730: get hero stat(1, stat:hp, current stat) == 5?autotest.hss:1731: get hero stat(1, stat:hp, maximum stat) == 5=autotest.hss:1732: get hero stat(1, stat:hp, base stat) == 10@autotest.hss:1733: get hero stat(1, stat:mp, current stat) == 12@autotest.hss:1734: get hero stat(1, stat:mp, maximum stat) == 12=autotest.hss:1735: get hero stat(1, stat:mp, base stat) == 20Aautotest.hss:1739: get hero stat(1, stat:atk, maximum stat) == 21?autotest.hss:1741: get hero stat(1, stat:atk, base stat) == 200Bautotest.hss:1742: get hero stat(1, stat:atk, maximum stat) == 100?autotest.hss:1745: get hero stat(1, stat:atk, base stat) == 110Aautotest.hss:1747: get hero stat(1, stat:atk, maximum stat) == 103autotest.hss:1751: get hero stat cap(stat:atk) == 04autotest.hss:1752: get hero stat cap(stat:spd) == 10Aautotest.hss:1753: get hero stat(1, stat:atk, current stat) == 10Aautotest.hss:1754: get hero stat(1, stat:atk, maximum stat) == 10Aautotest.hss:1755: get hero stat(1, stat:spd, current stat) == 10Aautotest.hss:1756: get hero stat(1, stat:spd, maximum stat) == 107autotest.hss:1762: gain hero stat(1, stat:atk, 3) == 13>autotest.hss:1763: get hero stat(1, stat:atk, base stat) == 12Aautotest.hss:1764: get hero stat(1, stat:atk, maximum stat) == 13Aautotest.hss:1765: get hero stat(1, stat:atk, current stat) == 137autotest.hss:1768: gain hero stat(1, stat:atk, 4) == 11>autotest.hss:1769: get hero stat(1, stat:atk, base stat) == 16Aautotest.hss:1770: get hero stat(1, stat:atk, maximum stat) == 11Aautotest.hss:1771: get hero stat(1, stat:atk, current stat) == 11?autotest.hss:1775: get hero stat(1, stat:hp, current stat) == 56autotest.hss:1776: gain hero stat(1, stat:hp, 6) == 16?autotest.hss:1777: get hero stat(1, stat:hp, current stat) == 8@autotest.hss:1778: get hero stat(1, stat:hp, maximum stat) == 166autotest.hss:1779: gain hero stat(1, stat:hp, -7) == 9<autotest.hss:1781: gain hero stat(1, stat:hp, 1, true) == 10@autotest.hss:1782: get hero stat(1, stat:hp, current stat) == 10@autotest.hss:1783: get hero stat(1, stat:hp, maximum stat) == 10@autotest.hss:1786: get hero stat(1, stat:hp, maximum stat) == 10=autotest.hss:1787: get hero stat(1, stat:hp, base stat) == 10@autotest.hss:1788: get hero stat(1, stat:mp, maximum stat) == 20=autotest.hss:1789: get hero stat(1, stat:mp, base stat) == 20Aautotest.hss:1790: get hero stat(1, stat:atk, current stat) == 10Aautotest.hss:1791: get hero stat(1, stat:atk, maximum stat) == 10=autotest.hss:1792: get hero stat(1, stat:atk, base stat) == 9Aautotest.hss:1793: get hero stat(1, stat:spd, current stat) == 30Aautotest.hss:1794: get hero stat(1, stat:spd, maximum stat) == 30>autotest.hss:1795: get hero stat(1, stat:spd, base stat) == 30@autotest.hss:1797: get hero stat(1, stat:hp, current stat) == 10@autotest.hss:1798: get hero stat(1, stat:mp, current stat) == 128autotest.hss:1802: get level mp(1, 0, current stat) == 18autotest.hss:1803: get level mp(1, 0, maximum stat) == 1<autotest.hss:1806: get level mp(1, level, current stat) == 0<autotest.hss:1807: get level mp(1, level, maximum stat) == 0+autotest.hss:1810: get level mp(1, 7) == 99Eautotest.hss:1814: hero uses level mp(find hero(hero:Frumpy)) == trueDautotest.hss:1815: hero uses level mp(find hero(hero:Olaf)) == falseEautotest.hss:1816: hero uses level mp(find hero(hero:Freki)) == falseEautotest.hss:1817: hero uses level mp(find hero(hero:Helga)) == false@autotest.hss:1820: get hero stat(1, stat:hp, current stat) == 102autotest.hss:1821: read preference bit(4) == false@autotest.hss:1824: get hero stat(1, stat:mp, current stat) == 208autotest.hss:1825: get level mp(1, 0, current stat) == 1?autotest.hss:1828: get hero stat(1, stat:hp, current stat) == 0@autotest.hss:1830: get hero stat(1, stat:hp, current stat) == 10@autotest.hss:1833: get hero stat(1, stat:hp, current stat) == 10level32495.HSZP) p?Ek)LSw8]@c 5Y~7>DJo .SxAHNCCBAZK  MCRT}}^}}Vbg}Zr trRy{rJR rRyyyyy<r ,TR[rTl<R_____[rrK CR %7r]0CR5?7CHrT [rT~mZR`qqjqqbnsqR ~~CR@rCC ` RSSSSS@rCr  R@rC R}}}} }@rC  R!+#/4@rr f?RFYYPYYHTYY@r 4 dkRm' ' w' ' o{' R CR     <C TR     <r CR     rr 6 [rr !R     [rT| 3#R)o o 3o o +7<o RC DGCRL  V  NZ_ @rC ~QjRqqq{qqsq@rr cRrTR urR[rTRSrCC XSrC rrR rR( ,1[rrd<CRBWWLWWDPUW@rCC `Rgqiuz@rCr R@rC "kR@rr kR@rCC nRaaaa a@rC kR   *  ".3 "CTz"TrT @rCC ZQTRXMMbMMZfkM@rCr *vTR}@rC h;TR[[[[[@rr 4LTR'''''rT@rCC ]TR@rCr BnTR55!55%*5@rC 5TR<F>JO@rr ZTRakcot"CC"C@rCC TR@rCr R@rC :kR-----@rr kR ~@rCC #R*4,8=r F r equipment tests-autotest.hss:1840: find hero(hero:Freki) == 0-autotest.hss:1841: find hero(hero:Helga) == 1-autotest.hss:1845: inventory(item:Boots) == 1:autotest.hss:1846: equip where(1, item:Boots) == slot:legs6autotest.hss:1847: check equipment(1, slot:legs) == -1Cautotest.hss:1848: check equipment(1, slot:weapon) == item:DefltWep9autotest.hss:1849: get default weapon(1) == item:DefltWep>autotest.hss:1853: check equipment(1, slot:legs) == item:Boots-autotest.hss:1854: inventory(item:Boots) == 0@autotest.hss:1856: get hero stat(1, stat:hp, current stat) == 10@autotest.hss:1857: get hero stat(1, stat:hp, maximum stat) == 13=autotest.hss:1858: get hero stat(1, stat:hp, base stat) == 10Aautotest.hss:1859: get hero stat(1, stat:spd, current stat) == 32Aautotest.hss:1860: get hero stat(1, stat:spd, maximum stat) == 32>autotest.hss:1861: get hero stat(1, stat:spd, base stat) == 300autotest.hss:1863: inventory(item:SteelSho) == 0=autotest.hss:1864: equip where(0, item:SteelSho) == slot:legs9autotest.hss:1865: equip where(1, item:SteelSho) == falseCautotest.hss:1872: check equipment(1, slot:weapon) == item:SteelSho>autotest.hss:1873: check equipment(1, slot:legs) == item:Boots0autotest.hss:1874: inventory(item:DefltWep) == 0Aautotest.hss:1875: get hero stat(1, stat:atk, current stat) == 13Aautotest.hss:1876: get hero stat(1, stat:atk, maximum stat) == 13-autotest.hss:1880: inventory(item:Boots) == 16autotest.hss:1881: check equipment(1, slot:legs) == -10autotest.hss:1887: inventory(item:SteelSho) == 1Cautotest.hss:1888: check equipment(1, slot:weapon) == item:DefltWep@autotest.hss:1890: get hero stat(1, stat:hp, current stat) == 10@autotest.hss:1891: get hero stat(1, stat:hp, maximum stat) == 10Aautotest.hss:1892: get hero stat(1, stat:spd, current stat) == 30Aautotest.hss:1893: get hero stat(1, stat:spd, maximum stat) == 30@autotest.hss:1898: get hero stat(1, stat:hp, current stat) == 10Aautotest.hss:1899: get hero stat(1, stat:spd, current stat) == 30?autotest.hss:1903: get hero stat(1, stat:hp, current stat) == 5?autotest.hss:1904: get hero stat(1, stat:hp, maximum stat) == 5@autotest.hss:1905: get hero stat(1, stat:spd, current stat) == 5@autotest.hss:1906: get hero stat(1, stat:spd, maximum stat) == 5?autotest.hss:1908: get hero stat(1, stat:hp, current stat) == 5?autotest.hss:1909: get hero stat(1, stat:hp, maximum stat) == 5@autotest.hss:1910: get hero stat(1, stat:spd, current stat) == 5@autotest.hss:1911: get hero stat(1, stat:spd, maximum stat) == 5?autotest.hss:1914: get hero stat(1, stat:hp, current stat) == 5@autotest.hss:1915: get hero stat(1, stat:hp, maximum stat) == 10Aautotest.hss:1916: get hero stat(1, stat:spd, current stat) == 30Aautotest.hss:1917: get hero stat(1, stat:spd, maximum stat) == 30@autotest.hss:1920: get hero stat(1, stat:hp, current stat) == 1032494.HSZ  3>$+Pv*Nr6ZB p ) A 0579C;GLW]7_iamrv"}77iiiii)27)<B7/////)4))R 7!&Fb17799A999EJ9)rU7[e]in)y)7fH))))@]7P77CCCC C)7)!-2) =7C  M  EQV hero misc tests0autotest.hss:1931: hero by slot(0) == hero:Freki:autotest.hss:1932: get hero hand x(0, hand:attack A) == 22:autotest.hss:1933: get hero hand y(0, hand:attack A) == 119autotest.hss:1934: get hero hand x(0, hand:attack B) == 2:autotest.hss:1935: get hero hand y(0, hand:attack B) == 17:autotest.hss:1940: get hero hand x(0, hand:attack A) == 50;autotest.hss:1941: get hero hand y(0, hand:attack A) == -25;autotest.hss:1942: get hero hand x(0, hand:attack B) == -109autotest.hss:1943: get hero hand y(0, hand:attack B) == 1:autotest.hss:1948: get hero hand x(0, hand:attack A) == 22:autotest.hss:1949: get hero hand y(0, hand:attack A) == 119autotest.hss:1950: get hero hand x(0, hand:attack B) == 2:autotest.hss:1951: get hero hand y(0, hand:attack B) == 17n32493.HSZ D "'+/37; ~6~bx ~~ }~~"~Zp~~32492.HSZ  i&/,2<EMu9CLS[`=GQVz00N 8:8B00 0 f-RZ UZ\^MMhMM`lqM.|\}}}}} 24  Np V v.:\ 4 (   .P-D#\"77,77$057@8 f4I0 X   .e,h\mwo{> "`4ZN z  -5Z\ D42| b ->\ e G!\&0(494DNN 4 Vx.[lS^\c__m__eqv_e \\XZO h8:npc movement testsn= autotest.hss:1975: npc X(n) == 3 autotest.hss:1976: npc Y(n) == 5 autotest.hss:1981: npc Y(n) == 6 autotest.hss:1985: npc X(n) == 4 autotest.hss:1989: npc Y(n) == 5 autotest.hss:1993: npc X(n) == 3 autotest.hss:1999: npc X(n) == 2+autotest.hss:2000: npc direction(n) == east autotest.hss:2003: npc Y(n) == 4,autotest.hss:2004: npc direction(n) == southn32491.HSZ ?e#Hn1Tw*Mq{ t "( gg2gg*6;g{F  H (NXP\a{l nt(vxx 82l  p_$(_____z +(6 ( xl Xz) BB,l(155;553?D5O|MR(WooaooYejo-uYxF(}. b(xlt Zl (MMMMMz t( 8 (++$++(-+zF |8(=ooGoo?KPoF[(`jbnszt B~t(55555t| (ooooo(#z (z >(11111(uuuu!&u1(6@8DI{ T (Zd\hm{ dx (~WWWWW)autotest.hss:2014: npc copy count(1) == 1)autotest.hss:2015: npc copy count(2) == 0)autotest.hss:2016: npc copy count(4) == 3autotest.hss:2019: n < 0%autotest.hss:2020: get npc id(n) == 1*autotest.hss:2021: npc copy number(n) == 0%autotest.hss:2024: get npc id(n) == 4*autotest.hss:2025: npc copy number(n) == 1 autotest.hss:2026: npc x(n) == 2!autotest.hss:2027: npc y(n) == 13autotest.hss:2030: n == 0%autotest.hss:2033: get npc id(1) == 1*autotest.hss:2034: npc copy number(1) == 0&autotest.hss:2035: get npc id(2) == -1+autotest.hss:2036: npc copy number(2) == -1%autotest.hss:2037: get npc id(3) == 3*autotest.hss:2038: npc copy number(3) == 0)autotest.hss:2040: get npc id(9000) == -1*autotest.hss:2041: get npc id(-9000) == -1.autotest.hss:2042: npc copy number(9000) == -1/autotest.hss:2043: npc copy number(-9000) == -1,autotest.hss:2044: npc copy count(9000) == 0-autotest.hss:2045: npc copy count(-9000) == 0n32490.HSZ  &,PZc x b \6!$ z1  49C;GL |W$  a.`zh Jk$99==x==p|=| v %autotest.hss:2052: get npc id(n) == 1%autotest.hss:2054: get npc id(n) == 2n32381.HSZ M{ "Kr'Bx (  +024>6BG*R U2[  e  ]in ly| X~2KKKKK | )20| 52n T0 A 2#npc extra tests)autotest.hss:2063: extra length(npc) == 3)autotest.hss:2064: npc extra(npc, 0) == 0)autotest.hss:2065: npc extra(npc, 2) == 0+autotest.hss:2067: npc extra(npc, 2) == 999+autotest.hss:2068: get extra(npc, 2) == 999,autotest.hss:2070: get extra(npc, 3) == 1000npc32489.HSZd $ K)/<IQW^ekp5X_n 7>DQq--V+-57,-BD -O8- j \-c-  \u  w-|~c R-|EEEEE#u \u \|c *-|#c: \Ru h6\|[[([[ ,1[c B<\|AKCOT \xc--- df,Nt-|wyc- H \vxc--- d -W|'  `-| \&x--- 8d2l -p_l|!__#)__-3_ \ \x--- dIuW-|Zd\hm  &~x\|}-d-  \--  \npc onetime tests,autotest.hss:2086: check onetime(3) == false,autotest.hss:2087: check onetime(4) == false+autotest.hss:2089: check onetime(3) == true,autotest.hss:2090: check onetime(4) == false+autotest.hss:2092: check onetime(3) == true+autotest.hss:2093: check onetime(4) == trueautotest.hss:2096: n == falseautotest.hss:2099: n <> false,autotest.hss:2101: check tag(10000) == falseautotest.hss:2104: n <> falseautotest.hss:2108: n == false+autotest.hss:2109: check tag(10000) == truehxhyn32488.HSZ   %0 ^  QQQQ!Qq,."autotest.hss:2118: ticknumber == 232487.HSZ 0o#0T_hLl b),.8  7;=G?KP}[] #[ >m,;q11{11s1~[ d}] qp#~q,; &];~ Li 6use npc script tests"autotest.hss:2128: ticknumber == 0"autotest.hss:2132: ticknumber == 1,autotest.hss:2139: npc script triggered == 1"autotest.hss:2140: ticknumber == 232368.HSZ 9m (8%/ B  } 0 .3\> AFJ]N: QVTHX4^ ikmsdw}Xn\< ]P i.)h\X r] ~KiKKKK !K~, npc slice testsDautotest.hss:2157: slice x(sl1) == 10 * 20 && slice y(sl1) == 8 * 20Cautotest.hss:2159: slice x(sl1) == 3 * 20 && slice y(sl1) == 4 * 20;autotest.hss:2161: slice x(sl1) == 31 && slice y(sl1) == 41n1sl132486.HSZLE 9C.4Z6@HWgpy,6cow <eow OYdnu ,6;[bf*[}&+0PWv}  / 6 U _ f n s    : A E e o w |    2 9 @ E J O V [ ` e l q v  # - 2 R \ c k p  7 Z d i 7BP  wwwww  }   H B |}  #% ~9 <ACMEQV8~a d iskw|f N  R ~*N   0t~F799999NA   N       Eyy)yy!-2yN=    $PO 8MR2_ h]bb4m  w~ wT wL 4Z`a'''''N   p 4 ( 6 <n#(d3 J; ~Cz>FLqqVqqNZ_qNj m     4|   < p  X ~  K K K K K    N      4  > r  Z  C M M M M M   &   4 "%  /  '38 f C N t FKNA A XA A P\aA  Nl w     4| R 4@  p    w         w        F  . T Z  ! ! ! !  !  ' x  / *28k k Bk k :FKk  NV   4a F4k4 `z |}ooooo N   m Nm   @@V IIII#(I#3 @@DNFRWV @(+k oyq}Nm   L@b7 UUUUU C-b   +- V!&,$L.6@9Tb1>DNFRW@pob fccpcchtyc   D L p,.{yyyyy@ \N  H @     |   @59C;GLV&@Z[ _MMiMMamrM  * \ d @       2@H ;;;;;ZN   F4   @  "  & + V:@n: > aaH aa@ L Q a4\   :\k B f@|x | oo oo~ o@4 . \~ d @    V @     4   $   . @D   # 7 7 - 7 7 % 1 6 7 Vx   @ J N   X   P \ a  8!Nl   $! !  ! !@!$  !! !! ! " >"@T"0  G"G" G"G" G"V" "@"<  "" "" "  ,# ^# f# #@#H  ##% ## ) . #  # $ $ 2$  :$ j$ r$ $   $ $ $ $+%8%- ,%T{ %% %% %,T%|%. p% %` G%G% G%G% G%@T&m  G&G& G&G& G&&4 & &@&y  && &&   &'* ' $'@:'7 ; -'-'E -'-'= I N -''4Y ' '(h ' "(@8(u y +(+( +(+({ +((N   l( ()  ( (( (( (t)N m  `)h* V* I*I* I*I* I**N   * +6+ $+  ++* ++" . 3 +R ,> C  , ,M  , ,E Q V  ,,#a v, ,R ,n s ,,} ,,u ,-#  - "-:-# *- B-Z-# J- b-R x- m k-k- k-k- k-.N  - 8..# . .R . m .... .{ 1 :1~  T1 p1',D1 !11alter npc tests#autotest.hss:2169: current map == 0.autotest.hss:2178: get npc sprite id(n2) == 133autotest.hss:2179: get npc sprite palette(n2) == -1.autotest.hss:2181: get npc sprite id(n2) == 122autotest.hss:2183: get npc sprite palette(n2) == 58autotest.hss:2189: read npc(n1, NPCStat:move speed) == 0-autotest.hss:2195: npc pixel x(n2) == ox + 10-autotest.hss:2197: npc pixel x(n2) == ox + 20,autotest.hss:2201: npc pixel y(n2) == oy + 2-autotest.hss:2203: npc pixel y(n2) == oy + 20-autotest.hss:2207: npc pixel x(n2) == ox + 16-autotest.hss:2212: npc pixel y(n2) == oy + 15(autotest.hss:2215: npc pixel x(n2) == ox(autotest.hss:2216: npc pixel y(n2) == oy-autotest.hss:2222: npc pixel x(n2) == ox + 10-autotest.hss:2223: npc pixel y(n2) == oy + 10-autotest.hss:2225: npc pixel x(n2) == ox + 20-autotest.hss:2226: npc pixel y(n2) == oy + 20,autotest.hss:2231: npc pixel x(n2) == ox + 0,autotest.hss:2232: npc pixel y(n2) == oy + 0:autotest.hss:2236: read npc(n1, NPCStat:display text) == 0)autotest.hss:2238: current text box == -1)autotest.hss:2240: current text box == 18)autotest.hss:2242: current text box == -1)autotest.hss:2247: current text box == -1Hautotest.hss:2248: read npc(n1, NPCstat:activation) == NPCactivation:use*autotest.hss:2252: hero x(me) == npc x(n2).autotest.hss:2253: hero y(me) == npc y(n2) + 1)autotest.hss:2254: current text box == -1.autotest.hss:2258: hero y(me) == npc y(n2) + 1)autotest.hss:2259: current text box == -1)autotest.hss:2263: current text box == -1)autotest.hss:2267: current text box == 18)autotest.hss:2269: current text box == -1)autotest.hss:2273: current text box == -1)autotest.hss:2276: current text box == -1)autotest.hss:2281: current text box == 18)autotest.hss:2283: current text box == -1)autotest.hss:2287: current text box == -1)autotest.hss:2291: current text box == 18)autotest.hss:2293: current text box == -1)autotest.hss:2297: current text box == 18)autotest.hss:2299: current text box == -1)autotest.hss:2303: current text box == -1)autotest.hss:2305: current text box == 18)autotest.hss:2307: current text box == -1)autotest.hss:2311: current text box == -1*autotest.hss:2318: hero x(me) == npc x(n2).autotest.hss:2319: hero y(me) == npc y(n2) + 1)autotest.hss:2321: current text box == -1)autotest.hss:2323: current text box == -1)autotest.hss:2325: current text box == -1)autotest.hss:2329: current text box == -1Hautotest.hss:2331: read npc(n1, NPCstat:activation) == NPCactivation:use7autotest.hss:2340: read npc(n1, NPCstat:give item) == 0Fautotest.hss:2342: read npc(n1, NPCstat:give item) == item:Whatsit + 1/autotest.hss:2344: inventory(item:Whatsit) == 0/autotest.hss:2347: inventory(item:Whatsit) == 1/autotest.hss:2352: inventory(item:Whatsit) == 4/autotest.hss:2357: inventory(item:Whatsit) == 4n1n2oxoy32485.HSZ s%N]  ~Sy N+. .357!!A!!9EJ!UX?autotest.hss:2381: get sprite type(spr) == spritetype:walkaboutrefslspr32484.HSZ s%N]  Sy X+8 .357++A++9EJ+UX?autotest.hss:2389: get sprite type(spr) == spritetype:walkaboutrefslspr32483.HSZ4 l l!'JSs@Gfm :AIO %%: -%13=5AF~JQRXQ1\CCfCC^joCmz%1}l%S%%% %m&%1 S%%% h %@%%% L.%1???? ?m<&%1)3+7<*mLDL1O??Y??Q]b?%mLt1wym0T1#####@% S%% X%m \1 XS% $%& S%%% \  m d 1#  -  %16 %8 mG%X ~f death tests(autotest.hss:2400: get death script == 07autotest.hss:2402: get death script == @on death scriptautotest.hss:2404: died == 0autotest.hss:2413: died == 01autotest.hss:2420: get hero stat(0, stat:hp) == 0autotest.hss:2422: died == 0autotest.hss:2424: died == 1autotest.hss:2428: died == 1autotest.hss:2430: died == 2autotest.hss:2438: died == 2autotest.hss:2445: died == 2i old maxhp32482.HSZ( e 29  Bplm $(.on death script32481.HSZ  }&E]gol d   FmB +.558550<A5~LNQTWZ\ mm2autotest.hss:2472: died == 1start hp32404.HSZ0/ $%x flx*4=Cg)Qw /U 6=Mp DKPsz"IPs'KRu| /9CHVz% , : jjDP rt+j~,j"=< r }j  }jj  lLl. l yyyy!&yT6106:l eH )KPZR^c(en 5qvx6j~ e A<e N=` xjjj  jZ%-0b38:D<HMF.X:l[`--j--bns-l~l v_____ ~jj.jj :!!!!! jyyyyyy-"&+.69>H@LQZ l\< _ dik  u  my~  v ~j    j        -      < .0 # # # # #  l b iU U )U U !-2U   }B D {jJ SY= = c= = [gl= { w8}       @ |r $  l          ^ |jj B  l        h|j Ll #.(-7/;@ |r .@W8\f^jo  | x~jjlI n4 &yj z ` jj<o//// /xjjj (jr+2<4@E FjbUi\UUfUU^joU~jjz8jr&i ~j jXl: 4$ .,/B4>6BG jXW8^KKhKK`lqKNj j4''''' =* `{j|joooooj~j88NHj"&+ 46X@ > d}j8j Mjj*,\8cmeqvr>8 d JMj=====|j  [J r8i  ++ ++  ! + =1 4 7 global npc testsBautotest.hss:2493: get sprite set number(get npc sprite(n1)) == 11Bautotest.hss:2494: get sprite set number(get npc sprite(n2)) == 15,autotest.hss:2499: npc direction(n1) == left,autotest.hss:2500: npc direction(n2) == left-autotest.hss:2504: npc direction(n1) == right,autotest.hss:2505: npc direction(n2) == leftautotest.hss:2510: n1 <> 0!autotest.hss:2511: npc x(n1) == 4!autotest.hss:2512: npc y(n1) == 3Bautotest.hss:2513: get sprite set number(get npc sprite(n1)) == 13&autotest.hss:2516: n1 == global npc(2)autotest.hss:2517: n1 <> 0"autotest.hss:2518: npc x(n1) == 11!autotest.hss:2519: npc y(n1) == 3Bautotest.hss:2520: get sprite set number(get npc sprite(n1)) == 17autotest.hss:2523: n1 <> 0"autotest.hss:2524: npc x(n1) == 11!autotest.hss:2525: npc y(n1) == 5Bautotest.hss:2526: get sprite set number(get npc sprite(n1)) == 17)autotest.hss:2530: npc copy count(2) == 36autotest.hss:2531: npc copy count(2, pool:global) == 4Bautotest.hss:2537: get sprite set number(get npc sprite(n2)) == 16Bautotest.hss:2541: get sprite set number(get npc sprite(n2)) == 13Bautotest.hss:2545: get sprite set number(get npc sprite(n2)) == 15 autotest.hss:2551: npc y(2) == 4Wautotest.hss:2555: get sprite set number(get npc sprite(global npc reference(1))) == 166autotest.hss:2562: get npc id(npc at spot(11, 3)) == 1Aautotest.hss:2566: read npc(2, npcstat:picture, pool:local) == 136autotest.hss:2568: read npc(n1, npcstat:picture) == 13Bautotest.hss:2570: read npc(2, npcstat:picture, pool:global) == 176autotest.hss:2572: read npc(n1, npcstat:picture) == 17autotest.hss:2576: n2 < 0Bautotest.hss:2577: get sprite set number(get npc sprite(n2)) == 15!autotest.hss:2580: npc y(n2) == 6Cautotest.hss:2584: read npc(0, npcstat:movespeed, pool:global) == 4Dautotest.hss:2586: read npc(0, npcstat:movespeed, pool:global) == 106autotest.hss:2591: npc copy count(0, pool:global) == 0Dautotest.hss:2592: read npc(0, npcstat:movespeed, pool:global) == 10Dautotest.hss:2594: read npc(0, npcstat:movespeed, pool:global) == 10Bautotest.hss:2600: read npc(0, npcstat:movespeed, pool:local) == 47autotest.hss:2601: read npc(n2, npcstat:movespeed) == 41autotest.hss:2604: get npc pool(n2) == pool:local2autotest.hss:2606: get npc pool(n2) == pool:global8autotest.hss:2607: read npc(n2, npcstat:movespeed) == 10oldmapoldxoldyn1n232480.HSZD  ~>32479.HSZ < P   +6A "  ~  ~&( ~13 J~<> (assert hurt pattern, test no. test nostart hph0h1h2h332478.HSZ ~''&<f  v   o"n/ Z2 -7"@NBB  B ZZ]TBDGILQX` @rBB  | u}}}}} >SBB rankslotget hero stat(slot, stat:hp)start hp -- harm amountJautotest.hss:2631: get hero stat(slot, stat:hp) == start hp -- harm amountrank harm amountslot32477.HSZ 8'/5CMWhmszB%- @ p:<jb--IK@d--Uc^`b~ Wq->%|  ^B6Y~6  j ~-l~Bb--Kd--YKfKharm tile testsFirst harmtile test runSecond harmtile test runstart hp32476.HSZh ~_"6@GLS_fkr| V' z ).'0 T <> <  l~<P <<<> <>] <  h~ o< <:v6  f ]]  >> ,] ~]< < <  < > H <  ~> <<<` ' r  ' L  <>] < D ~  w  < ]  < @  ~ l 32475.HSZ q !qw &/5BHOX^kqx5@Qv-<DMSZmu$Kt @fpvWciWcl   e q w     $ + 6 ? F N U _ f m r    # + 4 : I Q Z ` o w  @ f m u  A g n v ",2Y<^hm7A ;blt}*5>DLU^c"+6?Dj{<FPW]k!IPZ`mu~ .4AGW]jp 5D$)17W^b @GLTZz$+39 uu8 } *  u  $ 4d HB lt   $Z,. j: ~=x MU 4c f <!vD~\ uu  !  l  #uRX. `r (um l$\+->N,Fu Id Wuj0u`bhv_Zlr^}>6<uvl10F: ,u  v J   Iu &    x  ,J D   u Tu j   #)  4 7 _B  J   bX  ,bu `e esj  ,}u { &2,  R ubhuxnML upu@~Rxu: x!L*u547=0AGLb RU\u^~`ftGXjpF{ ~ 0 :B,ulf  6 @- P upu|KJu  - <* $ Du*Z,2P$6< GuuP RXJ\bLmu 6 T } |{^ {ux u" .uF< F" X %*Ru3h5;^-?EIuP`u  htnqB | u&tz2Mfu@ z2 *< 6uLB 0 "'*u0@286*<BFM`uiurul  uJ`  u>x~\| uX  u R ^  " *  f  0 x   3 8  uA  !C I  s ; M S r % + W  ^ V!n u.! j!!| u t! !! u !   "u ("b" "! !" uu t" "" u "  u#u  #^# #" "# # #$  # "$D$  *$ d$$! u $ $"% .%0 3 $b%<  H% %%K u % %&Z ]  % .& k ~& &&.w &z &u &4' && &\' u F' r'' u z' '@'  'u '4( '' 'h(. N('u (( v(I( H( H)} B) b)) )  |)0u) ) )1 u)  *H*A ,*? D &*3uO P* *W un* **g *e j *6uu * B+} u+ Z++ z+ t+9u + + u+ , ,s un, , *-t u- <  ,, ,, , -~ u- H.| . / ^/R   Q/Q/ Q/Q/   Q/ /! /a$ u ) //3 //+ 7 < / <0G 0pJ u O 00Y 00Q ] b 0 d0 0sr uu0 D1| 1  11 11 1 1 x1  k1k1 k1k1 k1 1 1  11 11 1  2 x2| L2 2 2 u  22 22   2 J3" &3%  * 334 33, 8 = 3 3H ~3K u P q3q3Z q3q3R ^ c q3 3  4|s u3 4| n4 u a4a4 a4a4 a4 4 4  44 44 4 L5 "5  55 55 5 r5 6( b6 66'6 6 6666 6 7|)6 b77'77 7:? B77L77DPU7 j8(`H8c h;8;8r;8;8jv{;8 8(8.u 88888N9'(9 Z9< 99999 9|ur9 :(9H:'": T:J ::::: :x j: :w:  :Xu&;R;(.:: 28:  j;auH;;JP;e;CTZd;  <e ; <  4<r,<ju|\<<~R<'<w&< <xu< *=v = `= D= r=  =su==={=z= &> > 8>  F> u^>}uv>>l>A>@> > > ?  ?u!:??#)0??-3? ?v>u? >@V@zGJ@ ^@ @@yY\p@ _@uk@ Ams@k@ew}j@   A @A pAAz LA A  uA A ABzuA  B MT @?uBu LB  uB BByB uCuCCuuu fCC  CBB CCz( +C C D.Dy:=C @ 4DuLJDDuTuu DDNW_@DCFcjC  D D (E@EzE HE  uTE vE EEzuE E !.5nu{BnBO E PF 6F )F)F)F)F)F FFFu FF FF F &G8G>G#@G &F GG36`GG?G9B HSGSGRSGSGJV[SG GGfi GGrGlu {GGGG}G "H4H H HuXH KHKHKHKHKH,_FurF Hu H  I Hu HHHHH FI* ,I I rI  $eIeI.eIeI&27eI IBIE KIIUIIMY^I lJ~iFJ&urJ KzuJ &K  KK|\K KLKu.K'uK  LuK $L,u,L hLuN N N~IN @O|RO vO[ ZO OO*h O lO:uwO(PyOOqOPPu :P fP P~ P "Q|P XQ i i fii ziti iiii jJj] 0ju #j#j#j#j#j  j jk.u pk k@k < @kkJkkBNSkVk k@lg kllullmy~l zl}tl ll ll lm#ml >mnm RmLm vmm)m~m mn] m.u mmmmmn]  n n*o ] oE# )oo3oo+7<o  o oVpQu @p \p@rp\_ cepepmepepeqvep u q}qr'q/qg qqqqq r8ru "r jr}dr'rxu rrrrrru ru Js}Ds'vsu isisisis is ss0u s~s menu tests=get menu id should have reported -1 for script-generated menuPuppiesKittensWalrusesOctopusPlip menu anchor x menu anchor yPuppies)failed to find first menu item by caption$found menu item that was not puppiesWalruses%found menu item that was not walruses(find menu item walrus should have failedKittensKittensWalrusesfailed to find first kittenfailed to find second kitten&found menu item that was not kitten(1)&found menu item that was not kitten(2)found the same kitten twiceKittensfound unopened menu!get menu ID mismatch vs find menufailed to find opened menu(readback of menu border thickness failed readback of menu boxstyle failed!readback of menu max chars failed!readback of menu min chars failed readback of menu offset x failed readback of menu offset y failed readback of menu anchor x failed readback of menu anchor y failed"readback of menu text align failedfailed to set menu bitfailed to unset menu bitwhy isn't the main menu open? menu bit failed to close textbox why is the main menu still open?AntelopeBuffaloCatbusDuikerTautotest.hss:2885: get menu item bit(catbus, menuitembit:hide when disabled) == true5autotest.hss:2890: menu item disabled(catbus) == true5autotest.hss:2891: menu item visible(catbus) == false8autotest.hss:2892: menu item selectable(catbus) == false5autotest.hss:2896: menu item disabled(catbus) == true4autotest.hss:2897: menu item visible(catbus) == true7autotest.hss:2898: menu item selectable(catbus) == true6autotest.hss:2902: menu item disabled(catbus) == false4autotest.hss:2903: menu item visible(catbus) == true8autotest.hss:2904: menu item selectable(catbus) == false6autotest.hss:2908: menu item disabled(catbus) == false4autotest.hss:2909: menu item visible(catbus) == true7autotest.hss:2910: menu item selectable(catbus) == true2autotest.hss:2916: selected menu item(m) == catbus2autotest.hss:2919: selected menu item(m) == duiker5autotest.hss:2920: select menu item(antelope) == true4autotest.hss:2921: select menu item(catbus) == false4autotest.hss:2922: selected menu item(m) == antelope2autotest.hss:2925: selected menu item(m) == catbus menu item settag readback failed tag 3 shouldn't be on yet (menu) tag 3 shouldn't be on now (menu)"tag 3 should be toggled off (menu)!tag 3 should be toggled on (menu)(tag 3 should be toggled off again (menu)menu item tag readback failedmenu item tag req!menu item tag req should be zero: menu item tag req readback fail:-autotest.hss:2965: extra length(buffalo) == 37autotest.hss:2967: get menu item extra(buffalo, i) == 0:autotest.hss:2969: get menu item extra(buffalo, i) == i*100autotest.hss:2970: get extra(buffalo, i) == i*105autotest.hss:2972: get menu item extra(buffalo) == 20-autotest.hss:2975: extra length(buffalo) == 0-autotest.hss:2977: extra length(buffalo) == 19autotest.hss:2978: get menu item extra(buffalo, -1) == 42Catbus, not Save!menu item subtype readback failedCatbus!Failed to open a menu from a menu%Failed to open a text box from a menumenu item type readback failed"Failed to run a script from a menumenu textcolor readback failed)iterated wrong number of menu items (all).iterated wrong number of menu items (vis only).iterated wrong number of menu items (vis only)'Even Toed Ungulate menu failed to closeclose me!menu close script readback failedmenu close script didn't runLoremIpsumDolorSitAmetSautotest.hss:3088: get menu bit(m, menubit:highlight selection background) == falseRautotest.hss:3090: get menu bit(m, menubit:highlight selection background) == true Twas brilligAnd the slithy toaves...Vautotest.hss:3106: get menu bit(m, menubit:advance text box when menu closes) == false(autotest.hss:3110: current text box == 2)autotest.hss:3112: current text box == -1Did gyre and gimbalIn the wabe...Vautotest.hss:3119: get menu bit(m, menubit:advance text box when menu closes) == falseUautotest.hss:3121: get menu bit(m, menubit:advance text box when menu closes) == true(autotest.hss:3125: current text box ==-1=autotest.hss:3130: menu item slot(selected menu item(m)) == 1*autotest.hss:3135: selected menu item == 0*autotest.hss:3139: selected menu item == 0immimainm1kitten1kitten2walruses save rowsantelopebuffalocatbusduikeroldcolcount32474.HSZ\ [ dct32473.HSZ\ [ hcl32472.HSZ ?\"zZT(-  &:=05C *IY$V\hbb (r X%2,uz o *<$( N$Pi jmenunumitemsijmi32471.HSZ+ # ^<BPX`glqv{$-X 4^m$7@JQ^jqyN.j!'@@F@@ HJ V .]V@  VPV x VV V*zt @@ `/ BN$Vt$@% %40 B738;E=INY\nF_eh__r__jv{_&@&\%VhWMMMMM2@V2, )R V e  IIII In+zB3"%6Vo;@AKCOTbV$_eV&kVpr@xaaaaza" . $V@  $@n @_ _ _ _ _  $HV @      f H8 @) ) ') ) +0)   ;> A@G  Q  IUZ ^ e> h8 |  (v  V  '       P &V2 , y~  sn   ~  @V $V  :s@VzV"$@V \s@V8z!VD$-V +0~s=@VZ zGV V,V jYdd@gVVwVV* Vfqqqqq f6     H >RV\$  V$!@$: F147++A++9EJ+ W@jUZd  fi@r.tzl~ TN+N`h@V( $V @4)@L@$@ 3@:z.  $"@ (/;@8T:@2DJXV$U[@n ahC@q.sygk}ft$@PK@AAAAA V0ZT\.@Bi   <@V'7V CV$@FVw:LS]UafXq@:}V$z@xt+++++&V&V@V&@ @~~ V>  V^ | ,V   $58@ ; !D!P!$KNV !HQX!!b!!Zfk!!v@|!!ym!m!m!m!m!Bo @/Vf !@ !menu scroll tests1autotest.hss:3196: menu item slot(mi) == numitems@autotest.hss:3197: menu item by slot(main, numitems, true) == miAautotest.hss:3198: menu item by slot(main, numitems, false) == mi6autotest.hss:3199: menu item true slot(mi) == numitems?autotest.hss:3200: menu item by true slot(main, numitems) == mi1autotest.hss:3203: mi == previous menu item(next) autotest.hss:3209: numitems == 9Aautotest.hss:3214: previous menu item(first menu item(main)) == 0Nautotest.hss:3215: next menu item(menu item by slot(main, numitems -- 1)) == 0?autotest.hss:3216: menu item by slot(main, numitems, true) == 0@autotest.hss:3217: menu item by slot(main, numitems, false) == 03autotest.hss:3218: menu item by slot(main, -1) == 08autotest.hss:3219: menu item by true slot(main, -1) == 0>autotest.hss:3220: menu item by true slot(main, numitems) == 01autotest.hss:3226: selected menu item(main) == mi a new item!4autotest.hss:3255: numitems == menu item count(main)?autotest.hss:3257: numvisitems == visible menu item count(main)autotest.hss:3265: mi == mi2"menu items not in increasing order#menuitembyslot returned hidden itemhidden items out of orderhidden items out of orderhidden items out of order@autotest.hss:3276: menu item by slot(main, numitems, false) == 0/autotest.hss:3281: menu item true slot(mi) == i2autotest.hss:3282: get menu item extra(mi, 0) == iTautotest.hss:3286: last menu item(main) == menu item by slot(main, numvisitems -- 1)_autotest.hss:3287: last menu item(main, false) == menu item by slot(main, numitems -- 1, false)<autotest.hss:3288: next menu item(last menu item(main)) == 0Cautotest.hss:3289: next menu item(last menu item(main), false) <> 09autotest.hss:3298: mi == menu item by slot(main, i, true)2autotest.hss:3299: get menu item extra(mi, 0) == imainminextinumitems numvisitemshidden1hidden2hidden3tempextrami232470.HSZ  p?EMTY]dinr "&2Xa )/OV[z)07 CC> K h RV R b  RV R@ w{>TJ}Vf R b  RV R@ &V8 R\@j ed R    RV R     R:V@ Rd+ - 8{  ;{AKCOT _  fhRAmwo{VR@!A fC _    f,RA  z<RAmmmmmV fC CJ {+#  K @ L4KA8  B  :FK RD VR @ W_Acy y my y eqvy  _  f2 bCA% % % % % R  f sRA     V  fC(  _   R  f4 CA' ' ' ' '    RA     % V D+4  textbox tests,autotest.hss:3333: (oldval, and, 2^2) == 2^2<autotest.hss:3337: checktag(tag:textbox 14 happened) == true(autotest.hss:3341: current textbox == -1<autotest.hss:3347: checktag(tag:textbox 14 happened) == true<autotest.hss:3348: checktag(tag:textbox 15 happened) == true'autotest.hss:3357: current textbox == 2(autotest.hss:3361: current textbox == -1=autotest.hss:3365: checktag(tag:textbox 14 happened) == false<autotest.hss:3367: checktag(tag:textbox 14 happened) == true=autotest.hss:3375: checktag(tag:textbox 14 happened) == false<autotest.hss:3376: checktag(tag:textbox 15 happened) == trueoldval32371.HSZ Mx 2Uz  n  %).9 >  H  @LQ \)^cmeqv\; n shop testsDautotest.hss:3387: is shop buy menu empty(shop:Boring Shop) == falseEautotest.hss:3388: is shop hire menu empty(shop:Boring Shop) == falseBautotest.hss:3389: is shop buy menu empty(shop:Empty Shop) == trueCautotest.hss:3390: is shop hire menu empty(shop:Empty Shop) == true32469.HSZ  {y*08Zkpu ,QX]$,1V]bf ..n6m* =6ACMEQVɚ;acMe j a~aacMz  a,O  a  aa..A!!!!! aj  .A0,aA##### aj  9aAssss#(s3G5.A:D<HM a<~< bCfTAqsyl}  F C. .    _A a Ca ,  iA  a .*  6   6 rA@  BH  ;LR  a ~" ~\ battle tests.autotest.hss:3401: get battle countdown == 182.autotest.hss:3409: fight formation(1) == false2autotest.hss:3410: check tag(tag:Victory) == false-autotest.hss:3412: fight formation(2) == true1autotest.hss:3413: check tag(tag:Victory) == true.autotest.hss:3415: fight formation(3) == false&autotest.hss:3418: last formation <> 4$autotest.hss:3428: not(check tag(5))autotest.hss:3433: check tag(5)autotest.hss:3438: check tag(6)32468.HSZ ~1?LYfn   "(-Ar8:l+EG,RTf_aQlt  tv Wy  F  x  Q:@Wx5J  m>(hmzt1 11111Lautotest.hss:3465: get battle countdown >= 40 && get battle countdown <= 160 formation setsxyd32467.HSZ ف  RZ 32466.HSZ0 %  (-49  Dgg    $ X `After battle script:32465.HSZ @Z!'.6=C Z     ,3  ;. rInstead of battle script() finish instead of battleform32464.HSZl0 $ \frz%06;f6Z~3X}!(JQV[`8^$Hls}5Y`e<Cf $ ) " `b lnx  0NX #####dZ4xx7x x8xfYYYYY9x'! l,x" J `~DG4@IOSSYSSQ]bSqtv4xx|6&mGo  lx  0x:@6x6x6xGh6x 7xL` 7xh`[[)[[!-2[7xGh=`CMEQV7x va`g  q  iuz  l lf x            6 5x `     5x`       5xx   &  */ 5xx :oA  K  COT 5xx`z _fm m pm m htym ;x,      :xt ;x      3xbM L3x`xl3xVl IIII Ix3x6.3))=))5AF)xX x ;x$4ejtlx}3xzB`mmmmm5xxQ5xx`<a/////7xsx 8x!+#/49xR?EGEEQEEIUZEe8x9x5Ggmsy  LxT | 7B555558974` '''' '8+1}};}}3?D}9OU_Wch6624xy{~7`89< /////7x 8$y( ,19.1<{B!!L!!DPU!p7>kq{s8dLWWWWW9Y7fx8VtyII III9{%/'387.IO!!Y!!Q]b!8msuu}uuuu97 `8viiiii9      P ! < O j *autotest.hss:3502: party money == gold + 12autotest.hss:3506: formation slot enemy(8, 1) == 80autotest.hss:3507: formation slot x(8, 1) == 100/autotest.hss:3508: formation slot y(8, 1) == 90*autotest.hss:3511: party money == gold + 2*autotest.hss:3520: party money == gold + 83autotest.hss:3528: formation slot enemy(8, 0) == -13autotest.hss:3529: formation slot enemy(8, 1) == -13autotest.hss:3530: formation slot enemy(8, 2) == -13autotest.hss:3531: formation slot enemy(8, 3) == -1*autotest.hss:3534: party money == gold + 4:autotest.hss:3539: find enemy in formation (8, 1, 0) == -1Aautotest.hss:3540: find enemy in formation (8, 1, get count) == 09autotest.hss:3542: find enemy in formation (8, 8, 0) == 49autotest.hss:3543: find enemy in formation (8, 8, 3) == 7Aautotest.hss:3544: find enemy in formation (8, 8, get count) == 43autotest.hss:3548: get formation background(8) == 13autotest.hss:3550: get formation background(8) == 08autotest.hss:3553: get formation song(8) == song:silence<autotest.hss:3555: get formation song(8) == song:same as mapNautotest.hss:3557: get formation song(8) == song:tin glazed and noncommutative3autotest.hss:3563: get formation background(8) == 18autotest.hss:3564: get formation song(8) == song:silence9autotest.hss:3565: find enemy in formation (8, 8, 0) == 0Aautotest.hss:3566: find enemy in formation (8, 8, get count) == 12autotest.hss:3567: formation slot enemy(8, 0) == 80autotest.hss:3568: formation slot x(8, 0) == 1310autotest.hss:3569: formation slot y(8, 0) == 169%dx%d2autotest.hss:3575: formation slot enemy(9, 0) == 0/autotest.hss:3576: formation slot x(9, 0) == 180autotest.hss:3577: formation slot y(9, 0) == 2013autotest.hss:3578: formation slot enemy(9, 1) == -1.autotest.hss:3579: formation slot x(9, 1) == 0.autotest.hss:3580: formation slot y(9, 1) == 03autotest.hss:3584: formation slot enemy(9, 0) == -1.autotest.hss:3586: formation slot x(9, 0) == 10autotest.hss:3587: formation slot y(9, 0) == 1672autotest.hss:3588: formation slot enemy(9, 1) == 8/autotest.hss:3589: formation slot x(9, 1) == 500autotest.hss:3590: formation slot y(9, 1) == 1902autotest.hss:3594: formation slot enemy(9, 0) == 0/autotest.hss:3595: formation slot x(9, 0) == 180autotest.hss:3596: formation slot y(9, 0) == 2012autotest.hss:3597: formation slot enemy(9, 1) == 8/autotest.hss:3598: formation slot x(9, 1) == 500autotest.hss:3599: formation slot y(9, 1) == 1902autotest.hss:3601: formation slot enemy(9, 0) == 0/autotest.hss:3602: formation slot x(9, 0) == 180autotest.hss:3603: formation slot y(9, 0) == 2013autotest.hss:3604: formation slot enemy(9, 1) == -1.autotest.hss:3605: formation slot x(9, 1) == 0.autotest.hss:3606: formation slot y(9, 1) == 0 orig goldgoldi32463.HSZp / -T]bg bA  UU UU$)U@   4;=G?KP [; [D@ lsuw [|S ;  [0autotest.hss:3614: hero by slot(0) == hero:Freki@autotest.hss:3615: get hero stat(0, stat:HP, current stat) == 10?autotest.hss:3618: get hero stat(0, stat:HP, current stat) == 632375.HSZ< dvĕ!)R[a@f <'' / :<>D5HN'Y:'J'g:rtzm~''' :     *''.:29:%% %%%'cI!':)3+7<GYI:OYQ]b:'Vhm:sII}IIuI attack testsSelfStab&autotest.hss:3631: string compare(1,2)&autotest.hss:3634: string compare(1,2)&autotest.hss:3637: string compare(1,2) Attack self&autotest.hss:3642: string compare(1,2):autotest.hss:3644: get attack extra(atk:SelfStab, 0) == 42:autotest.hss:3645: get attack extra(atk:SelfStab, 2) == 996autotest.hss:3646: get attack extra(atk:ForceRun) == 03autotest.hss:3647: get attack extra(10 + 1, 2) == 132462.HSZ  C}$*S{*39?GNv Hnw ((:02p 4(:<ccFcc>JOc0Z\b:dnfrw0.22$3:>2T0202</C://///0l0N22P CS:CCCC &C^2102P0E 2E (2fUYd:`YYbhYY[lrY0( o}:0:(0::~0:0(:yyyyy702 0 2:       60'p )/:1c c ;c c 3?Dc :0O Q:W  a  Yej <0u2x 0u ~2:     ;0 2:{ { { { { 0 0 :     00-:  enemy testsNautotest.hss:3655: enemy elemental resist as int(enemy:Data Read Test, 2) == 0Pautotest.hss:3656: enemy elemental resist as int(enemy:Data Read Test, 15) == -5Data read test'autotest.hss:3661: string compare(1, 2)Data read test2'autotest.hss:3665: string compare(1, 2)Data read test'autotest.hss:3669: string compare(1, 2)SeenGoldDuckUponHigh'autotest.hss:3677: string compare(1, 2)Fautotest.hss:3680: get enemy stat(enemy:Data Read Test, stat:HP) == 13Gautotest.hss:3682: get enemy stat(enemy:Data Read Test, stat:Hits) == 6Fautotest.hss:3684: get enemy stat(enemy:Data Read Test, stat:HP) == 13cautotest.hss:3688: get enemy appearance(enemy:Data Read Test, Enemy:PictureSize) == EnemySize:largeRautotest.hss:3689: get enemy appearance(enemy:Data Read Test, Enemy:Palette) == -1Iautotest.hss:3690: read enemy data(enemy:Data Read Test, Enemy:Item) == 1Mautotest.hss:3692: read enemy data(enemy:Data Read Test, Enemy:RareItem) == 2Qautotest.hss:3693: read enemy data(enemy:Data Read Test, Enemy:ItemPercent) == 50Qautotest.hss:3695: read enemy data(enemy:Data Read Test, Enemy:ItemPercent) == 24Qautotest.hss:3697: read enemy data(enemy:Data Read Test, Enemy:ItemPercent) == 5032461.HSZ  p^?ET^ejot%FOY_e ?HNSZ_e  C\ ~JLNPNR NLL N N N N$J 2 y~Pf\-, ~ Ned~JNNR   F~NRR &|}Ne N~      RRRR Ne *-/91=B~NMRR :Ne  jmoyq}0RRRR |N,e H%;;;;;0L ~~" 3L~ ~~" 8LD 9v  =NL  N gl ~"z g  !$ C):  +10  #5; PF =-L, Nb~"gJ jx\su{EmDi =!L NP~"^g !x=L NN read timer failed$autotest.hss:3723: timer global == 1$autotest.hss:3727: timer global == 2%autotest.hss:3733: timer global == 12%autotest.hss:3740: timer global == 22randomfight formation$timer interactions with after battle-(ab) afterbattle should have happened 3 times)timer interactions with instead of battle-(ib) afterbattle should have happened 0 times8timer interactions with after battle + instead of battle0(ab+ib) afterbattle should have happened 3 timesi32460.HSZ  u%/?Lp6_fnv?fms"e!#f+- ~579;=# I|5 Q###D\bVfle \ w#v #WzV 75  #"#8|.e f #4!#+579;9  b5  ### 2"(,2e Jfj =@d-#IKQECU[D!#| +l579;9t 9;# &  5 P  #n 6#  z K J e f   A#T  J   +  #( L#>  4         # Y#) n +1  #5; e f  FI #+ \ RX  L\b !#  9 timer should still be running!timer global should still be zerotimer should be done by nowtimer global didn't change!(bat) timer should be done by now (bat) timer global didn't change&(bat+crit) timer should be done by now%(bat+crit) timer global didn't change/(bat+crit) second timer should still be running-(bat+crit) second timer should be done by now5(bat+crit) timer global didn't change on second timertrigger battle32459.HSZp  90M <  d32458.HSZ| *9ENSe N he  tI &H~1 3537  C8e ^MK H ~32406.HSZ "'Klw~|  qqqq#q} .14>6BGRU_Wchesu-autotest.hss:3826: arg1 == timer expect arg 1-autotest.hss:3827: arg2 == timer expect arg 2autotest.hss:3829: arg3 == 0arg1arg2arg332405.HSZ u&JUl||  ____"_} -0 3=5AFe QS -autotest.hss:3834: arg1 == timer expect arg 1-autotest.hss:3835: arg2 == timer expect arg 2arg1arg232457.HSZ J (-4eff `e   ( 2Hbattle timer test:32456.HSZ( tj(?)3>b'2Xfq",3;_i;ELv4=^emr=O`qw}9^e  . W 3 \  3 : J Y h y      ' L u |   3 : [ b j '.3T}%Foy 29`#MW_&.38<BJqx")1X_DKr#*Mv} $+07X_f"-5[.5@Hn &=]gDK_ -7k7Afmu~-T{.U|8_ ) / G g ! !!)! ~  ~ "t  #'. BGQIUZtbbR  ~b% w~J====== ~b% ,   !&0(49}%% DF}b UW}% 8fh2 vt%B (~b% dW WWWWW +D~ , P7",$05 C@EGQIUZ 0~% bjUPvUUx~UUqU~ ~ &t~ [N~d f ~ < /q // // $ * /~ 5 |A C I < M S ~ ^ j l r e v | ~ .  !  ! !  ! !  ! v  d!@!dx! ! ! ! ""~ V" I" I"I" I"I"  I"~d " " "" % "" ) / "~ ": "F ""H N ""A R X "~d #c "o ""q w ""j { "## $ 2$$$+&%,<%~ % $ $$ $$ $X%t% % %% %%   %&t^&  Q&Q&& Q&Q& * / Q&  ,'} 'DA '} 'UP '} 0(f_ *(} r(n p l( ((2)t) ) )) )) )~ * * ** ** *<*tv*  i*i* i*i* i* *J+t b*+d+++t ,, +6 ++8 > ++1 B H +~ D,S 7,_ 7,7,a g 7,7,Z k q 7, r, -t %,F-t b&-.V.tx.(  k.k. k.k. k. .~ . .5 .. .. ./t // /0 /tx0 k0@ k0k0 % k0k0 ) / k0 0t0K? D 00N 00F R W 011t1o 1Xy 11{ 11t 1*2~ L2 ?2c ?2?2 ?2?2 ?2 x2 3 F3T3t3 3n 33 33 3 4t*44y4444 #4 T4 \4t48=44G44?KP4~ 4[4g44io44bsy4Q5b566tf6 66 6d77M 7 7t8 8 8 8 8 8 8~b T8G8G8G8G8G8 G8 77 8t8*/889881=B8~b D9M79Y7979[a7979Tek799v9 9~b x:k:k:k:k:k:k:t:::::::;t:4; ;~ ;;;;;;;t;;;;$;;(.; `<~ ~<>q<Jq<q<LRq<q<EV\q<t<g<q<<sy<<l}<0=4=P=~ r=e= e=e=e=e=e=t========t6>")>)>)>)> )>>t>>  > ?~( ?+>.7>>9?>>2CI>?T? ?~ @d@9p@@rx@@k|@tX@DK@K@K@K@K@A4@BA (A~ \AOAPOAOAOAOAOAtA[AAAAA B2B~ BVB~ >BzB~# bBB~+ B Bw CQJC%xC C~% COCg[CC]cCCVgmCZD DP DrDDDDDDdD pEP E|yEyEyEyEyEtEEEEEE~ FE EEEEEF F~ G6FBFFDJFF=NTFbG GglnGGxGGp|G H( H H H H H PH HHHHHH HHHHHH 0I IIIII I 0Jx&+-#J#J7#J#J/;@#J jJ~b JPJ\JJ^dJJWhnJ~ JyJJJJJJ~ K K K K K K K~ RKEKEKEKEKEKEKbK 6L~b RLEL ELELELELEL=LtL)16LL@LL8DIL~ MTL5`LLbhLL[lrL=bM NbN N N0@NNNNN=O LO OPMsOsOsOsOsO P\YPPPPP DQdpQ Q=blR R  R  S .h hG |hJbOohohYohohQ]boh h Tiir >iv~li zfi ibi,i fj Lj?j?j?j?j?j j jjjjjj j jjjjjj ,k  k k k  k k$) k lk4 Xk7=KkKkGKkKk?KPKk k[ k^dkknkkfrwk lu~k l} lDl} mUm mm bm,m (nnnnnn tn ZnMnMnMnMnMn n nnn!nn%*n n5 n 8>nnHnn@LQn 8o\ $o+_beooooogsxo zod fo7YoYoYoYoYo ou~o o Tp\p bp,p pBppppp p pLpppp p  q qX!pp+pp#/4p bq? NqdBHAqAqRAqAqJV[Aq q qi qlqfq qowb}qqqqq r *r r0r qqqqqq ~ru~Jr rWr ^sfs b(s,"s s s   ss ss   s  tu~& s t tt 4 7 t,: ~t tM P ttZ ttR ^ c t Fun ,uq v uu uux u uu~ fu u DvLv v, v v  vv vv v v v  vv vv v Dwu~!w Pw ww !!bw ^xfx #!&!b%(x xx 6!9!%x XyI! >yL!Q!1y1y[!1y1yS!_!d!1y yu~o!zy y yi}! y"z2z>z=!!!zPathfinding tests-autotest.hss:3864: dist from leader(ref) == 1"autotest.hss:3868: npc x(ref) == 8"autotest.hss:3869: npc y(ref) == 3#autotest.hss:3879: npc x(ref) == 10#autotest.hss:3880: npc y(ref) == 161autotest.hss:3885: dist from pos(ref, 15, 5) == 2(autotest.hss:3890: is at pos(ref, 14, 9)(autotest.hss:3894: is at pos(ref, 15, 8)(autotest.hss:3899: is at pos(ref, 13, 8).autotest.hss:3904: npc is walking(ref) == true/autotest.hss:3906: npc is walking(ref) == false(autotest.hss:3907: is at pos(ref, 14, 8)(autotest.hss:3912: is at pos(ref, 10, 8)'autotest.hss:3915: is at pos(ref, 9, 7)'autotest.hss:3919: is at pos(ref, 9, 7))autotest.hss:3924: is at pos(ref, 16, 18)0autotest.hss:3926: dist from pos(2, 16, 18) == 1$autotest.hss:3934: npc is walking(2)-autotest.hss:3938: npc is walking(2) == false'autotest.hss:3945: is at pos(2, 14, 15)$autotest.hss:3946: npc is walking(2)'autotest.hss:3949: is at pos(2, 14, 15)$autotest.hss:3950: npc is walking(2)+autotest.hss:3953: npc is walking(2)==false$autotest.hss:3967: npc is walking(2)'autotest.hss:3968: is at pos(2, 14, 15),autotest.hss:3969: npc pixel x(2) == 14 * 20*autotest.hss:3975: npc is walking(2)==true0autotest.hss:3976: npc pixel x(2) == 14 * 20 + 5'autotest.hss:3978: is at pos(2, 17, 15)&autotest.hss:3992: hero tile(me, 8, 7)&autotest.hss:3995: hero tile(me, 9, 7)'autotest.hss:3998: hero tile(me, 13, 5)&autotest.hss:4000: hero tile(1, 12, 5)&autotest.hss:4001: hero tile(2, 12, 6)&autotest.hss:4002: hero tile(3, 11, 6)%autotest.hss:4013: hero tile(0, 8, 7)%autotest.hss:4014: hero tile(1, 9, 7)%autotest.hss:4015: hero tile(2, 8, 8)%autotest.hss:4016: hero tile(3, 9, 8)5autotest.hss:4026: hero tile(1, hero x(0), hero y(0))%autotest.hss:4029: hero is walking(1),autotest.hss:4032: hero is walking(1)==false%autotest.hss:4047: hero is walking(0)&autotest.hss:4049: hero tile(0, 12, 7).autotest.hss:4051: hero is walking(0) == false%autotest.hss:4059: hero is walking(0)&autotest.hss:4060: hero tile(0, 12, 6)-autotest.hss:4071: hero is walking(1) == true&autotest.hss:4073: hero tile(1, 16, 7)%autotest.hss:4080: hero is walking(0).autotest.hss:4082: hero is walking(0) == false%autotest.hss:4087: hero is walking(0)%autotest.hss:4089: hero tile(0, 7, 4)%autotest.hss:4097: hero is walking(0)%autotest.hss:4098: hero is walking(0).autotest.hss:4100: hero is walking(0) == false%autotest.hss:4101: hero tile(0, 6, 5)%autotest.hss:4118: hero is walking(0)&autotest.hss:4119: hero tile(0, 14, 7).autotest.hss:4123: hero is walking(0) == false&autotest.hss:4124: hero tile(0, 14, 7)&autotest.hss:4130: hero tile(0, 14, 7)%autotest.hss:4131: hero is walking(0)&autotest.hss:4135: hero tile(0, 13, 7)%autotest.hss:4136: hero is walking(0)&autotest.hss:4139: hero tile(0, 13, 7)%autotest.hss:4140: hero is walking(0)&autotest.hss:4144: hero tile(0, 12, 7)%autotest.hss:4145: hero is walking(0),autotest.hss:4148: hero is walking(0)==false'autotest.hss:4152: is at pos(n1, 10, 8)&autotest.hss:4156: hero tile(0, 11, 8),autotest.hss:4157: hero is walking(0)==false&autotest.hss:4161: hero tile(0, 11, 8),autotest.hss:4162: hero is walking(0)==false&autotest.hss:4176: hero tile(0, 15, 5)#autotest.hss:4182: current map == 5#autotest.hss:4186: current map == 7,autotest.hss:4188: hero is walking(0)==false%autotest.hss:4189: hero tile(0, 3, 4)%autotest.hss:4194: hero tile(0, 8, 2),autotest.hss:4197: hero pixel x(0) == 8 * 20,autotest.hss:4198: hero pixel y(0) == 2 * 201autotest.hss:4201: hero pixel x(0) == 8 * 20 + 16,autotest.hss:4202: hero pixel y(0) == 2 * 20,autotest.hss:4205: hero pixel x(0) == 9 * 20,autotest.hss:4206: hero pixel y(0) == 6 * 20&autotest.hss:4208: hero tile(0, 14, 2)&autotest.hss:4209: hero tile(1, 13, 2)&autotest.hss:4210: hero tile(2, 13, 3)&autotest.hss:4211: hero tile(3, 12, 3)&autotest.hss:4217: hero tile(0, 14, 3),autotest.hss:4219: hero is walking(0)==false%autotest.hss:4220: hero tile(0, 4, 4)0autotest.hss:4228: hero pixel y(0) == 2 * 20 + 8,autotest.hss:4232: hero pixel x(0) == 4 * 204autotest.hss:4235: hero pixel y(0) == 4 * 20 + 3 * 40autotest.hss:4247: hero pixel y(0) == 2 * 20 + 8,autotest.hss:4251: hero pixel x(0) == 4 * 204autotest.hss:4253: hero pixel y(0) == 4 * 20 + 3 * 4%autotest.hss:4274: hero tile(0, 2, 6)%autotest.hss:4275: hero tile(1, 1, 6)%autotest.hss:4276: hero tile(2, 2, 7)%autotest.hss:4277: hero tile(3, 1, 7)&autotest.hss:4278: is at pos(n0, 7, 8)&autotest.hss:4279: is at pos(n1, 8, 8)%autotest.hss:4284: hero tile(0, 2, 5)&autotest.hss:4285: is at pos(n1, 4, 4)%autotest.hss:4290: hero tile(0, 8, 8)&autotest.hss:4291: is at pos(n1, 5, 4)autotest.hss:4304: result==true)autotest.hss:4306: get extra(sl, 0) == 13(autotest.hss:4307: get extra(sl, 1) == 6;autotest.hss:4308: get extra(sl, extra length(sl)--2) == 14:autotest.hss:4309: get extra(sl, extra length(sl)--1) == 3,autotest.hss:4310: extra length(sl) == 5 * 2 autotest.hss:4314: result==false,autotest.hss:4316: extra length(sl) == 2 * 2 autotest.hss:4320: result==falseautotest.hss:4325: result==true;autotest.hss:4327: get extra(sl, extra length(sl)--2) == 14:autotest.hss:4328: get extra(sl, extra length(sl)--1) == 3,autotest.hss:4329: extra length(sl) == 4 * 2autotest.hss:4333: result==trueautotest.hss:4335: result==true,autotest.hss:4337: extra length(sl) == 7 * 2.autotest.hss:4343: extra length(sl) == 3 + 5*2(autotest.hss:4344: get extra(sl, 0) == 0(autotest.hss:4345: get extra(sl, 1) == 0(autotest.hss:4346: get extra(sl, 2) == 0)autotest.hss:4347: get extra(sl, 3) == 13(autotest.hss:4348: get extra(sl, 4) == 6!autotest.hss:4356: result == true,autotest.hss:4357: extra length(sl) == 5 * 2)autotest.hss:4358: get extra(sl, 0) == 12(autotest.hss:4359: get extra(sl, 1) == 5)autotest.hss:4360: get extra(sl, 8) == 14(autotest.hss:4361: get extra(sl, 9) == 3!autotest.hss:4366: result == true,autotest.hss:4367: extra length(sl) == 9 * 2)autotest.hss:4368: get extra(sl, 0) == 12(autotest.hss:4369: get extra(sl, 1) == 5;autotest.hss:4370: get extra(sl, extra length(sl)--2) == 14:autotest.hss:4371: get extra(sl, extra length(sl)--1) == 3-autotest.hss:4377: extra length(sl) == 11 * 2"autotest.hss:4382: result == false,autotest.hss:4383: extra length(sl) == 1 * 2"autotest.hss:4388: result == false,autotest.hss:4389: extra length(sl) == 0 * 2-autotest.hss:4396: extra length(sl) == 24 * 2oldxoldyoldmaprefin0n1n2n3slresult32455.HSZ ~ 2- +v  , !'Xrankxy32374.HSZ <i#.7l  Ly m .), P4Fsl32373.HSZ0  Np  #"%+,dl~;#8>z5D P3JJ^#[ag+Xm Vsr 8Bm "n{+P+^  $+._ Py8-+sloffsetixybox32454.HSZ 2- x-j  . !'Lrefxy32453.HSZ  +,~  lNref32452.HSZ T=O -  .'*/2%8 CFIrefxydxdy32451.HSZ4+ "  cms8[bg /RY$)05Vy$).5:Yz%Hkr 4;\?FJs").?JRW`ejqv{ qq>+qy{,qP  =2  yq   q +qh,![[+[[#/4[,q6?DNFRW #Hp@lqpcczccr~c   Mq+q$[,qXeKKKKK q ~q  +qo"&+,q y6;E=IN#xqqq J^bjtlx}qsssss   +q(,q\OOOO O q q ,  R  qq Z q   +q :q?  I  AMR ,q ]qb  l  dpu -, q     .\ qO O O O O 4    - q     .8 q+ +  + +  +  q q    q q $  J ? +q ,q 5AGLj Q R +q ^c  m  eqv ,q&5qL  "8tl______ +q( !,q2,1;3?D  *<OqT^Vbg#w{J +q6V))))),qj`]]]]]  jqtx &*0 +q@EOGSX,q4ch''r''jv{'  h[[[[[ q q  +q,qREEEEE-yyyyy.#(2*6;" OS]_eXio  2zq%%%%%+q{{{{{,q-.    BWqP~57 qEHq 25qZ#]  q  q & b q r q  q   4DP= Vehicle tests+autotest.hss:4456: current vehicle id == -1/autotest.hss:4457: current vehicle npc == false3autotest.hss:4460: check tag(tag:boat tag) == false"autotest.hss:4461: hero x(me) == 4"autotest.hss:4462: hero y(me) == 4/autotest.hss:4466: current vehicle npc == false3autotest.hss:4468: check tag(tag:boat tag) == false"autotest.hss:4469: hero x(me) == 4"autotest.hss:4470: hero y(me) == 4"autotest.hss:4473: hero x(me) == 2"autotest.hss:4474: hero y(me) == 4:autotest.hss:4477: current vehicle npc == NPC reference(1)*autotest.hss:4478: current vehicle id == 02autotest.hss:4480: check tag(tag:boat tag) == true"autotest.hss:4481: hero x(me) == 2"autotest.hss:4482: hero y(me) == 2"autotest.hss:4488: hero x(me) == 0"autotest.hss:4489: hero y(me) == 0 autotest.hss:4490: npc x(1) == 0 autotest.hss:4491: npc y(1) == 0 autotest.hss:4496: npc x(1) == 0 autotest.hss:4497: npc y(1) == 0 x=%d y=%d"autotest.hss:4504: hero x(me) == 3"autotest.hss:4505: hero y(me) == 1&autotest.hss:4508: current vehicle npc+autotest.hss:4510: not(current vehicle npc)"autotest.hss:4512: hero x(me) == 3"autotest.hss:4513: hero y(me) == 13autotest.hss:4514: check tag(tag:boat tag) == false+autotest.hss:4517: not(current vehicle npc)"autotest.hss:4519: hero x(me) == 3"autotest.hss:4520: hero y(me) == 13autotest.hss:4521: check tag(tag:boat tag) == false&autotest.hss:4524: current vehicle npc"autotest.hss:4526: hero x(me) == 3"autotest.hss:4527: hero y(me) == 12autotest.hss:4528: check tag(tag:boat tag) == true"autotest.hss:4531: hero x(me) == 4"autotest.hss:4532: hero y(me) == 1 autotest.hss:4533: npc x(1) == 4 autotest.hss:4534: npc y(1) == 1+autotest.hss:4537: not(current vehicle npc)3autotest.hss:4538: check tag(tag:boat tag) == false"autotest.hss:4539: hero x(me) == 4"autotest.hss:4540: hero y(me) == 1 autotest.hss:4541: npc x(1) == 4 autotest.hss:4542: npc y(1) == 1oldxoldyoldmapn32450.HSZ$ 8KQw 0Vz6\cint@IOpw|;LQWv,Y} 0T[~ OO8+O W\^`jbns,O~\^ O ^ O V#^IIIII& .O^&OO :^#',&77 hF97^?[[I[[AMR[ OR]7^cmeqv OH``^;;;;; O n^ 7x^ 7&^  7 ~q^ qq"(qq,2q  = ?O^EOGSXO O 8OXO P y`^}+O `^,O<`^///// O7 `O 77+O"`^  OO7 hO +O$`^)3+7< G77N+OjT`^Y]]c]][gl]'O  O7  O F  OO7 f O +O `^     (O 7* +OF `^9 9 9 9 9  O7 O  OO7  O : +Oh ^^[ [  [ [ [ ,O `^$  .  &27 cBD F O7:  P [O^_  i  amr 'B}  `OX  O +O 0^     ,O :\^     O\"O PP DO^ O`  Q^"( ` p3h9[_^C[[EK[[>OU[ O` o`^^fphty O` ,`^ G 7^ O`O^ O`@O^33333 7`O^#', 7`N7`^=AAGAA?KPA GO 7`a^gqiuz 7`^}}}}} G7 `*^ `%^ Door tests!autotest.hss:4573: herox(me) == 6!autotest.hss:4574: heroy(me) == 6%autotest.hss:4577: get door x(0) == 8%autotest.hss:4578: get door y(0) == 5*autotest.hss:4579: door at spot(8, 5) == 0+autotest.hss:4580: door at spot(0, 0) == -1*autotest.hss:4581: door at spot(1, 1) == 12autotest.hss:4582: get door destination id(0) == 13autotest.hss:4583: get door destination map(0) == 4!autotest.hss:4584: door exists(0)3autotest.hss:4585: get door destination id(1) == -14autotest.hss:4586: get door destination map(1) == -1!autotest.hss:4587: door exists(1)+autotest.hss:4588: door exists(10) == false3autotest.hss:4595: current map == map:door test map!autotest.hss:4596: hero x(0) == 4!autotest.hss:4597: hero y(0) == 4!autotest.hss:4601: hero x(0) == 4!autotest.hss:4604: hero x(0) == 4!autotest.hss:4607: hero x(0) == 4!autotest.hss:4613: hero x(0) == 4!autotest.hss:4616: hero x(0) == 4"autotest.hss:4621: hero x(0) == 11!autotest.hss:4622: hero y(0) == 4screen should be faded out/autotest.hss:4626: current map == map:test townscreen should not be faded out!autotest.hss:4631: hero x(0) == 2!autotest.hss:4632: hero y(0) == 6/autotest.hss:4637: current map == map:test town4autotest.hss:4638: door exists(0, map:Door test map)9autotest.hss:4639: not(door exists(2, map:Door test map))9autotest.hss:4640: get door x(0, map:Door test map) == 118autotest.hss:4641: get door y(0, map:Door test map) == 4%autotest.hss:4642: check tag(7) == onEautotest.hss:4643: get door destination id(0, map:Door test map) == 0Rautotest.hss:4644: get door destination map(0, map:Door test map) == map:Test TownEautotest.hss:4645: get door destination id(1, map:Door test map) == 0Vautotest.hss:4646: get door destination map(1, map:Door test map) == map:Door test mapFautotest.hss:4648: get door destination id(1, map:Door test map) == -1Gautotest.hss:4649: get door destination map(1, map:Door test map) == -1Fautotest.hss:4651: get door destination id(2, map:Door test map) == -1Gautotest.hss:4652: get door destination map(2, map:Door test map) == -132449.HSZ ; :` Z +  !#-%16, AD!ISKW\f  gj!oyq}qb" !UUUUUn. !o each-step scriptautotest.hss:4662: x == hero xautotest.hss:4663: y == hero y(autotest.hss:4664: dir == hero direction,autotest.hss:4667: npc script triggered == 0-autotest.hss:4668: map autorun triggered == 0xydir32448.HSZ$ X} ;dh  "$.&27x$ BE"MWO[`oNkn"pAAzAAr~An&"qnV@3 "pP>n"CCCCCnKn" nnpc triggered scriptautotest.hss:4674: arg == -1*autotest.hss:4675: npc == npc reference(6)*autotest.hss:4678: eachstep triggered == 1-autotest.hss:4679: map autorun triggered == 0(autotest.hss:4687: current textbox == -10autotest.hss:4688: textbox script triggered == 1-autotest.hss:4689: map autorun triggered == 1argnpc32447.HSZ _ ;`/8XP   "$.&27fBG"ISKW\+g""lvnz,& "@/"     qX:"KKKKKoF" nR""&+p6Rtextbox advance script#autotest.hss:4695: current map == 4)autotest.hss:4696: hero direction == leftautotest.hss:4699: hero x == 11autotest.hss:4700: hero y == 4(autotest.hss:4703: current textbox == -1,autotest.hss:4704: npc script triggered == 1*autotest.hss:4705: eachstep triggered == 1-autotest.hss:4706: map autorun triggered == 032446.HSZ\ $#*0Sw rX   QP* 58:<F>JOP 6 Z^:`))j))bns)p~:n map 4 autorunautotest.hss:4715: arg == 42#autotest.hss:4716: current map == 40autotest.hss:4719: textbox script triggered == 1arg32445.HSZH p@IRZbky6W{bP   #')3+7<WGGqPnX~`rgiNlqsi ,'A`'SSSSS+i,}G  i  q )'      p 5i'  )  !-2 nf B=i'@Y Y JY Y BNSY  O^b'd  n  frw g H i 2 =GGt P Y'     nPc'CCCCCconcurrent script trigger tests#autotest.hss:4735: current map == 0"autotest.hss:4745: ticknumber == 0*autotest.hss:4746: get hero speed(me) == 4,autotest.hss:4775: npc script triggered == 20autotest.hss:4776: textbox script triggered == 1-autotest.hss:4777: map autorun triggered == 1"autotest.hss:4778: ticknumber == 5#autotest.hss:4784: current map == 0-autotest.hss:4786: map autorun triggered == 232444.HSZ|  ox 32443.HSZp  o~32442.HSZP ~ <32441.HSZ \5^ _hv"'-4S]cipZ+ &+, 3+-8> I+KQDU[~fNeo mq: |JI+++++o   2oI o    o +I ~ X   (oV79I<IIFII>JOIoZ N  \ oCuIxz+  +( ,8  +F 2  OI     script trigger tests-autotest.hss:4808: hero x == 6 && hero y == 6+autotest.hss:4815: (oldval, and, 2^10) == 0*autotest.hss:4821: eachstep triggered == 1*autotest.hss:4828: eachstep triggered == 3*autotest.hss:4835: eachstep triggered == 3*autotest.hss:4844: eachstep triggered == 3-autotest.hss:4847: hero x == 6 && hero y == 6oldval32440.HSZX  ! ~L~32439.HSZ| l!#'+/37;?CGKO :~~~~~<~l~~~"~N~tr~ Slice tests32384.HSZ 0Z# 6Enx%{H )!-2l=?lKNNAXAAZ`AASdjAiu z}h +=D877777E l>=8zi" dl02 >ADROQWJ[a4il 8eo*,.tSlice handle tests-autotest.hss:4886: slice is valid(0) == false%autotest.hss:4888: slice is valid(sl).autotest.hss:4890: slice is valid(sl) == false/autotest.hss:4891: slice is valid(sprite layer).autotest.hss:4892: slice is valid(-1) == false0autotest.hss:4893: slice is valid(4242) == falseautotest.hss:4903: sl2 <> slslisl232399.HSZ3 @( u&fl}#/5Y 5[ek7Afp#IUz%Kq{)OY_9_io-3W} ) 3 9 ]  jjDdrttj rv :s  l VIIIII~j*+t d*-F ~:8=-BLDPU `Gcjhrjv{^8 p~TyyyyybN,oj ~|-( ,1V<0?jD##N##FRW#btn ~psjxz<t     zFX ~ jD 77*77".37>j GJtOYQ]bDm-&vzyj~mmmmm * ~        4   X  n  a a a a a  * -2  <  4@E B PS  [h )^Sc[ [ m[ [ eqv[   7j     n 6   G      i crj r rl     ^  _ (v W j    ! n|,Nc/j4AA>AA6BGARoUrZd\hmxj  Tv6r)))))||oooooj4} X| n aaaa %a038B:FK<}Vr `|dvgrliiviinzirL$ \|reeeee* }    <r|R "EE,EE$05E@ CHRJV[f &\|t<w|////~/'r 6l|L7r?????Fr i xr""$ Rr&L v8V;$@JBNSv|^Vba$fIIpIIhtyIn x{Vz6A)))))*yp v  r   % w0 j Rv> 4A jF ''P ''H T Y '|d xg jl kkv kkn z  k  r   @x     z j! ]] ]] ]i Rect Slice tests$autotest.hss:4917: slice is rect(sl)3autotest.hss:4918: slice type(sl) == slicetype:rect4autotest.hss:4919: get rect trans(sl) == trans:solid0autotest.hss:4920: get rect fuzziness(sl) == 1005autotest.hss:4922: get rect trans(sl) == trans:hollow.autotest.hss:4923: get rect fuzziness(sl) == 04autotest.hss:4925: get rect trans(sl) == trans:fuzzy/autotest.hss:4926: get rect fuzziness(sl) == 25-autotest.hss:4927: get rect opacity(sl) == 255autotest.hss:4929: get rect trans(sl) == trans:hollow.autotest.hss:4930: get rect fuzziness(sl) == 04autotest.hss:4932: get rect trans(sl) == trans:solid0autotest.hss:4933: get rect fuzziness(sl) == 1004autotest.hss:4935: get rect trans(sl) == trans:blend-autotest.hss:4936: get rect opacity(sl) == 70/autotest.hss:4937: get rect fuzziness(sl) == 70.autotest.hss:4939: get rect opacity(sl) == 100,autotest.hss:4941: get rect opacity(sl) == 04autotest.hss:4943: get rect trans(sl) == trans:fuzzy/autotest.hss:4945: get rect fuzziness(sl) == 70-autotest.hss:4947: get rect opacity(sl) == 70/autotest.hss:4948: get rect fuzzy zoom(sl) == 12autotest.hss:4950: get rect fuzzy zoom(sl) == 1000;autotest.hss:4951: get rect stationary pattern(sl) == false:autotest.hss:4953: get rect stationary pattern(sl) == true*autotest.hss:4960: get rect style(sl) == 0+autotest.hss:4961: get rect border(sl) == 09autotest.hss:4962: get rect raw border(sl) == border:line+autotest.hss:4964: get rect style(sl) == -14autotest.hss:4965: get rect border(sl) == border:raw/autotest.hss:4966: get rect raw border(sl) == 05autotest.hss:4968: get rect border(sl) == border:none9autotest.hss:4969: get rect raw border(sl) == border:none5autotest.hss:4971: get rect border(sl) == border:line9autotest.hss:4972: get rect raw border(sl) == border:line4autotest.hss:4974: get rect border(sl) == border:raw/autotest.hss:4975: get rect raw border(sl) == 1,autotest.hss:4977: get rect border(sl) == 13/autotest.hss:4978: get rect raw border(sl) == 15autotest.hss:4980: get rect border(sl) == border:none9autotest.hss:4981: get rect raw border(sl) == border:none5autotest.hss:4983: get rect border(sl) == border:line9autotest.hss:4984: get rect raw border(sl) == border:line+autotest.hss:4989: get rect style(sl) == 14,autotest.hss:4991: get rect border(sl) == 14/autotest.hss:4992: get rect raw border(sl) == 1-autotest.hss:4993: get rect fg col(sl) == 252,autotest.hss:4994: get rect bg col(sl) == 65+autotest.hss:4996: get rect style(sl) == -1*autotest.hss:4998: get rect style(sl) == 0+autotest.hss:4999: get rect border(sl) == 09autotest.hss:5000: get rect raw border(sl) == border:line-autotest.hss:5001: get rect fg col(sl) == 249,autotest.hss:5002: get rect bg col(sl) == 33sl32398.HSZ 8j%4"(4_%KT]h!GSx 8Bgpx&&D .0.: = GIKQBU[`f JiIGn==x==p|= &G"(&Gh P3&GCCCCC? &G!, K/&G4>6BGVR8Zfcecn[Gy{tf` lka  V` 0pGa {G,` G  na( T+G0GG:GG2>CGNQRY@\QGa33k33cot3` ~Gqqqqq#t(Q` G4 a  G     p  uN  Q  a G!  +  #/4  ?& H `H 0 KGP# # Z# # R^c# n cv $ i~  Text Slice tests$autotest.hss:5014: slice is text(sl)3autotest.hss:5015: slice type(sl) == slicetype:text(autotest.hss:5017: string length(2) == 0(autotest.hss:5018: get wrap(sl) == false+autotest.hss:5019: get outline(sl) == false*autotest.hss:5020: get text color(sl) == 0'autotest.hss:5021: get text bg(sl) == 0 fee Fi foe'autotest.hss:5026: string compare(2, 3)slice width(sl)slice height(sl)(autotest.hss:5030: slice width(sl) == 48)autotest.hss:5031: slice height(sl) == 30(autotest.hss:5034: slice width(sl) == 48)autotest.hss:5035: slice height(sl) == 30'autotest.hss:5039: get wrap(sl) == true(autotest.hss:5040: slice width(sl) == 48(autotest.hss:5043: slice width(sl) == 35)autotest.hss:5044: slice height(sl) == 40)autotest.hss:5047: slice height(sl) == 40(autotest.hss:5049: slice width(sl) == 48sl32626.HSZ  :(Sy9Ejv,6F^  "_.1 ;=?E6IO Z ];;bldpub;2d2-;~hZ<;MMMMM`I;  fX;",$05jc@C:bKdNC;S}}]}}Uaf}(eqtLd|rt;     ihh; gNf,;aCh` C;#(xi3 bPanel Slice tests%autotest.hss:5065: slice is panel(sl)4autotest.hss:5066: slice type(sl) == slicetype:panel3autotest.hss:5068: get panel primary index(sl) == 05autotest.hss:5069: get panel percent as int(sl) == 50-autotest.hss:5070: get panel padding(sl) == 05autotest.hss:5071: get panel is vertical(sl) == false,autotest.hss:5072: get panel pixels(sl) == 03autotest.hss:5075: get panel primary index(sl) == 15autotest.hss:5078: get panel percent as int(sl) == 40-autotest.hss:5081: get panel padding(sl) == 4,autotest.hss:5084: get panel pixels(sl) == 54autotest.hss:5087: get panel is vertical(sl) == truesl32393.HSZ G>/7a#)17AGOU]J ##%!' 5 <? IKMSDW]jh<k%Ip//z//r~/ 5IZ0-I#####5r 5:5I ^!  5.N_.! 6 5`t<?h 5uL? 5iZ Ellipse Slice tests'autotest.hss:5100: slice is ellipse(sl)3autotest.hss:5101: get ellipse border col(sl) == 153autotest.hss:5103: get ellipse border col(sl) == 140autotest.hss:5104: get ellipse fill col(sl) == 00autotest.hss:5106: get ellipse fill col(sl) == 1sl32392.HSZ &f@);H\5FVEs} AKU`p$,V/1 -6*ADFhQT POVJkb  ejm/uuwuuo{u&oRo4 mpppmcccccD,FmL 4r Z;m''('' ,1'j> <AjN LQ\ _/dJmoqwj{\:V/m-----i h -( cTmT nOhqrmT#2b~&+m.%%8%%0<A%L ~T OWm\qqfqq^joqiz / O~ f/mYYYYYi l//Z-TT O  mD i . l  / R  T O  " %/m*  4  ,8= : iH $ b PPS H  90[-^|  gT Oj D v * ySm~      Ot ^mg g g g g D N$  v mi i i i i   /m      * i!  N i) 8 *autotest.hss:5122: next sibling(sl2) == sl<autotest.hss:5124: slice screen x(sl) == slice screen x(sl2)<autotest.hss:5125: slice screen y(sl) == slice screen y(sl2)6autotest.hss:5126: get slice extra(sl2, extra 2) == 426autotest.hss:5127: child count(sl) == child count(sl2)+autotest.hss:5130: get slice lookup(ch) < 0-autotest.hss:5131: get slice lookup(ch2) == 06autotest.hss:5134: slice type(sl) == slicetype:special*autotest.hss:5136: slice is container(sl2).autotest.hss:5137: previous sibling(sl) == sl26autotest.hss:5138: child count(sl) == child count(sl2)(autotest.hss:5141: child count(sl2) == 0)autotest.hss:5147: extra length(sl2) == 3)autotest.hss:5151: extra length(sl2) == 0-autotest.hss:5156: extra length(sl2) == 500007autotest.hss:5157: get slice extra(sl2, 49999) == 123454autotest.hss:5160: get slice extra(sl2, 49998) == 162autotest.hss:5161: get slice extra(sl, 49998) == 0slsl2chch232369.HSZ VxGP    ! )#-2bl=@ F6C Ivobjvalueidx32391.HSZ  I+R^l/Vd8Dk""" p $j1  49;"E=INdY"\(fehjrshRvj;;EEEE|E j;&\;Zh F4j;99999 @j;}}"}}&+}6 L9\;?IAMR]`b hk`HXnb;t;;~;;v; b;j` ( r`;n N}\;AAAAA9  ";!+#/4&g?B dJ JMR;T==^==Vbg=r9uB;{}}}}}}?B ">Bv V;IIIII >\; i n(autotest.hss:5188: extra length(sl) == 30autotest.hss:5191: get slice extra(sl, 2) == 1021autotest.hss:5192: get slice extra(sl, -1) == 1021autotest.hss:5193: get slice extra(sl, -3) == 100*autotest.hss:5194: get extra(sl, 2) == 102+autotest.hss:5195: get extra(sl, -1) == 102+autotest.hss:5196: get extra(sl, -3) == 1001autotest.hss:5198: get slice extra(sl, 1) == 4242,autotest.hss:5199: get extra(sl, -2) == 4242(autotest.hss:5201: extra length(sl) == 11autotest.hss:5202: get slice extra(sl, -1) == 100/autotest.hss:5204: get slice extra(sl, -1) == 0(autotest.hss:5206: extra length(sl) == 40autotest.hss:5207: get slice extra(sl, 3) == 1031autotest.hss:5210: get slice extra(sl, -1) == 9987autotest.hss:5213: get slice extra(sl, -1000000) == 100sl32372.HSZI 0:qM{"KZdp|%Nw9`5?e.U|$3=d >f.X / V }  : b  : a k  ? N X c $ 3 Y  BLqxD l` H   %: &0  r), ^;.4QQ>QQ6BGQFRT d_b ekn Bfw,z .~ jLb]]]]] Wn, bzm(  ttzgggg!g,/ 1n7A9EJUX Zb`jbns~8  reeeee  @ &v \OOOO O b",$05@ CISKW\"g jpzr~Z F99999 p  z*  ` F99(99 ,19<, rE HNXP\al ouw$"  n b Z     *,      o @  & 5     t  ` @bS S !S S %*S  5 K8>  H  @LQ  \, V_e  o  gsx  c  V  B a5 5 5 5 5   | lbo o o o o  , w              +: - "  8;  D GM  W  O[` ( k  nbt  ~  v d , P C C C C C   ;            b < $ x 'kk1kk)5:kE H,OYQ]bm, p,wyJ 4'''''b xkkkkkb,   b !%*R5b8 <%:A//K//COT/_bb 1dkssussmy~sb = b IU\ D Z;  f b "  & + 26 r9 b?   I   A M R  p]  \~` f OOp OOh t y O      ,     (     R :M      # - % 1 6 JA $D K U M Y ^ i ~l ,q qq{ qqs  q            8    ,    (   # - % 1 6 bA N D  J AAT AAL X ] Ah |r u ,z  |  ,,~ d! , WW WW W " , ,   V  B7  55 55   5 |B"  ( oo2 oo* 6 ; oMF H +S V B^ a (|i bTl q UU{ UUs  U X_     n ,   H  4y  '' '' ' n a aa aa  a+ - $8 ,; a B L D P U r` Xc h KKr KKj v { K        $ b R  8~q~ b d  ,      (" %+5-9>Zq~I @R zUZmmdmm\hmmO i| extra array tests+Make a testing slice and use its extra dataTest the 3 default elements&autotest.hss:5226: extra length(xt)==3%autotest.hss:5227: get extra(xt,0)==0%autotest.hss:5228: get extra(xt,1)==0%autotest.hss:5229: get extra(xt,2)==0Test setting data'autotest.hss:5234: get extra(xt,0)==100'autotest.hss:5235: get extra(xt,1)==101'autotest.hss:5236: get extra(xt,2)==102Test end-based indexing(autotest.hss:5238: get extra(xt,-1)==102(autotest.hss:5239: get extra(xt,-2)==101(autotest.hss:5240: get extra(xt,-3)==100Test appending+autotest.hss:5242: append extra(xt, 999)==4'autotest.hss:5243: get extra(xt,3)==999 Test resizing&autotest.hss:5246: extra length(xt)==6'autotest.hss:5247: get extra(xt,0)==100'autotest.hss:5248: get extra(xt,3)==999%autotest.hss:5249: get extra(xt,4)==0%autotest.hss:5250: get extra(xt,5)==0&autotest.hss:5252: extra length(xt)==3(autotest.hss:5253: get extra(xt,-1)==102&autotest.hss:5255: extra length(xt)==0%autotest.hss:5257: get extra(xt,0)==0%autotest.hss:5258: get extra(xt,1)==0Test extra insertion&autotest.hss:5262: extra length(xt)==2&autotest.hss:5264: extra length(xt)==3'autotest.hss:5265: get extra(xt,0)==100'autotest.hss:5266: get extra(xt,1)==111'autotest.hss:5267: get extra(xt,2)==200&autotest.hss:5269: get extra(xt,0)==99'autotest.hss:5270: get extra(xt,1)==100'autotest.hss:5271: get extra(xt,2)==111'autotest.hss:5272: get extra(xt,3)==200(Test extra insertion from negative index&autotest.hss:5275: get extra(xt,0)==99'autotest.hss:5276: get extra(xt,1)==100'autotest.hss:5277: get extra(xt,2)==111'autotest.hss:5278: get extra(xt,3)==222'autotest.hss:5279: get extra(xt,4)==200Test find extra'autotest.hss:5283: find extra(xt,1)==-1(autotest.hss:5284: find extra(xt,111)==2*autotest.hss:5285: find extra(xt,111,2)==2+autotest.hss:5286: find extra(xt,111,3)==-1(autotest.hss:5287: find extra(xt,100)==1*autotest.hss:5288: find extra(xt,100,2)==5+autotest.hss:5289: find extra(xt,100,-1)==5+autotest.hss:5290: find extra(xt,100,-4)==5+autotest.hss:5291: find extra(xt,100,-5)==1,autotest.hss:5292: find extra(xt,100,-40)==1,autotest.hss:5293: find extra(xt,100,99)==-1 Test deletion*autotest.hss:5296: delete extra(xt,3)==222*autotest.hss:5297: delete extra(xt,1)==100+autotest.hss:5298: delete extra(xt,-1)==100&autotest.hss:5299: get extra(xt,0)==99'autotest.hss:5300: get extra(xt,1)==111'autotest.hss:5301: get extra(xt,2)==200&autotest.hss:5302: extra length(xt)==3Test delete range&autotest.hss:5306: extra length(xt)==56autotest.hss:5307: delete extra range(xt, 1, 4) == 111&autotest.hss:5308: extra length(xt)==2&autotest.hss:5309: get extra(xt,0)==99'autotest.hss:5310: get extra(xt,1)==444$Delete empty range (nothing happens)&autotest.hss:5313: extra length(xt)==2&autotest.hss:5314: get extra(xt,0)==99'autotest.hss:5315: get extra(xt,1)==444&autotest.hss:5317: extra length(xt)==2&autotest.hss:5319: extra length(xt)==2&autotest.hss:5321: extra length(xt)==2&autotest.hss:5322: get extra(xt,0)==99'autotest.hss:5323: get extra(xt,1)==444Delete range from end&autotest.hss:5327: extra length(xt)==48autotest.hss:5328: delete extra range(xt, -3, -1) == 444&autotest.hss:5329: extra length(xt)==2&autotest.hss:5330: get extra(xt,0)==99'autotest.hss:5331: get extra(xt,1)==666Delete range up to end6autotest.hss:5333: delete extra range(xt, 1, 2) == 666&autotest.hss:5334: extra length(xt)==1&autotest.hss:5335: get extra(xt,0)==99Test remove extra&autotest.hss:5341: extra length(xt)==2&autotest.hss:5342: get extra(xt,0)==99&autotest.hss:5343: get extra(xt,1)==99&autotest.hss:5345: extra length(xt)==0xt32438.HSZF `6|]bhu}!L{ 2Z Ir7]!Gm :c#Io-U} 2 Y 4 [ " M v   5 \  , S ] i ffPf8np2 {nw wwwww h ph xnP{CCCCCn,f  h Xtn(,8:/f5++?++7CH+`yVf nSXK^{dnfrwrfff fnnF^f99999nlfi 8s z{dfWW%WW).W\9<ACMEQV]adikumy~B` *da l2_____{   ^'f> *0211<114@E1P{SY[e]iny|~H({n |aaaaa &  ' *".3r >L 3A{F? ? P? ? HTY?  d Ag|l  v  nz ,  0Q     t xT e^G G G G G  z Gk      v wn       L D(, +|0  :  2>C  CN Q{Vw w `w w Xdiw  Ft w||    ~ V E6 f) ) ) ) )  o 6} } } } } 2 p P     {f \ V   $  &,  06  A  DIL  V  NZ_ *gj m{r  |  t xXKKKKK>{     Zf  YYYYY*--f2<4@E2P;S{XbZfkv`Jyf~SSSSS>Yf0` hY     ta ZtYMMMMM\0 $)]47<>H@LQ0o\_dfphtyzp\MOOOOOf   ff 2, yyyy  y f f %  ) . 69 {< fB   L   D P U  ` |dc fi WWs WWk w | Wf   v { ii ii i f f   f  p V' II II  I f f '  + 0 ; |!> fD N F R W Lb ,.e k m w o {  ~< k qq qq q J k   B "X f    '  pe f cc cc   cb') , Bs. 4 6 55@ 558 D I 5'T W Y 4 _ i a m r i} {Hn B      f   .   {   i j n l R  EE( EE , 1 E< f? fE O G S X c {f fl v n z  J |* f   j v p      f 0    X {8 Y ++ ++ # ( +3 |6 < {{F {{> J O {iZ b  nd   o fr   |   t  slice collection testsautotest.hss:5363: sl3autotest.hss:5365: parent slice(sl) == sprite layer<autotest.hss:5367: check parentage(sl, sprite layer) == true3autotest.hss:5368: check parentage(sl, sl) == false=autotest.hss:5369: check parentage(sprite layer, sl) == falseEautotest.hss:5370: check parentage(sl, lookup slice(sl:root)) == true4autotest.hss:5372: check parentage(sl, sl2) == false4autotest.hss:5373: check parentage(sl2, sl) == false,autotest.hss:5376: slice is rect(sl) == true1autotest.hss:5377: is filling parent(sl) == false%autotest.hss:5378: slice x(sl) == -10%autotest.hss:5379: slice y(sl) == -20)autotest.hss:5380: slice width(sl) == 100)autotest.hss:5381: slice height(sl) == 500autotest.hss:5382: get slice visible(sl) == true(autotest.hss:5383: extra length(sl) == 3/autotest.hss:5384: get slice extra(sl, 0) == 10/autotest.hss:5385: get slice extra(sl, 1) == 20/autotest.hss:5386: get slice extra(sl, 2) == 30+autotest.hss:5387: get top padding(sl) == 1-autotest.hss:5388: get right padding(sl) == 2.autotest.hss:5389: get bottom padding(sl) == 3,autotest.hss:5390: get left padding(sl) == 41autotest.hss:5391: get slice clipping(sl) == true<autotest.hss:5392: get slice lookup(sl) == sli:my root slice/autotest.hss:5393: get rect fuzziness(sl) == 48-autotest.hss:5394: get rect fg col(sl) == 101,autotest.hss:5395: get rect bg col(sl) == 71+autotest.hss:5396: get rect style(sl) == -14autotest.hss:5397: get horiz align(sl) == edge:right4autotest.hss:5398: get vert align(sl) == edge:middle5autotest.hss:5399: get horiz anchor(sl) == edge:right2autotest.hss:5400: get vert anchor(sl) == edge:top,autotest.hss:5401: slice screen x(sl) == 310+autotest.hss:5402: slice screen y(sl) == 80autotest.hss:5405: sl2*autotest.hss:5406: parent slice(sl2) == sl/autotest.hss:5407: slice is sprite(sl2) == true?autotest.hss:5408: get sprite type(sl2) == spritetype:walkabout1autotest.hss:5409: get spriteset number(sl2) == 6/autotest.hss:5410: get sprite palette(sl2) == 1-autotest.hss:5411: get sprite frame(sl2) == 41autotest.hss:5412: get sprite trans(sl2) == false7autotest.hss:5413: sprite is horiz flipped(sl2) == true7autotest.hss:5414: sprite is vert flipped(sl2) == false5autotest.hss:5415: sprite is dissolving(sl2) == false)autotest.hss:5416: slice width(sl2) == 20*autotest.hss:5417: slice height(sl2) == 20%autotest.hss:5418: slice x(sl2) == 10%autotest.hss:5419: slice y(sl2) == -4-autotest.hss:5420: slice screen x(sl2) == 224,autotest.hss:5421: slice screen y(sl2) == 77)autotest.hss:5424: extra length(sl2) == 0)autotest.hss:5426: extra length(sl2) == 3/autotest.hss:5427: get slice extra(sl2, 0) == 0/autotest.hss:5428: get slice extra(sl2, 1) == 0/autotest.hss:5429: get slice extra(sl2, 2) == 0)autotest.hss:5432: extra length(sl2) == 1/autotest.hss:5433: get slice extra(sl2, 0) == 0-autotest.hss:5435: extra length(sl2) == 10000/autotest.hss:5438: get slice extra(sl2, 0) == 0/autotest.hss:5439: get slice extra(sl2, 2) == 01autotest.hss:5440: get slice extra(sl2, 3) == -981autotest.hss:5441: get slice extra(sl2, 4) == -981autotest.hss:5442: get slice extra(sl2, 5) == -98/autotest.hss:5443: get slice extra(sl2, 6) == 02autotest.hss:5444: get slice extra(sl2, 9997) == 04autotest.hss:5446: get slice extra(sl2, 9998) == -994autotest.hss:5447: get slice extra(sl2, 9999) == -99autotest.hss:5453: sl1autotest.hss:5454: get slice visible(sl) == false0autotest.hss:5455: is filling parent(sl) == true(autotest.hss:5460: extra length(sl) == 3.autotest.hss:5461: get slice extra(sl, 0) == 0.autotest.hss:5462: get slice extra(sl, 1) == 0.autotest.hss:5463: get slice extra(sl, 2) == 0(autotest.hss:5465: extra length(sl) == 30autotest.hss:5466: get slice extra(sl2, 0) == 100autotest.hss:5467: get slice extra(sl2, 1) == 200autotest.hss:5468: get slice extra(sl2, 2) == 30autotest.hss:5473: sl == 0slsl232390.HSZ %An5;IWcq}2S~.Q|+Kx*J[~(099Hl99AC~l99OQm]` l99 ikZhmwz Dxl99m l9982rm \l99(9t  $,%(+HT8;;;F;;>JO;Z]9r`9geeqeeiuze(0LX'?????vp09:9 !$Z'TJ47:D<HMX[9S^9eogsxZb4.~c9qqqqq9 " k     99z t  `y9 s      . !99 $ \ 194O O >O O 6BGO SyR99 R9  T[a  k  cot 9|             6 B ) ) ) ) )   ` Z              # ( 093  =  5AF v Q9J TD   adg  q  iuz     98R9P 9V nbIH  i% 4i- Slice search testsautotest.hss:5496: sl == sl1autotest.hss:5497: sl == sl11:autotest.hss:5498: next slice in tree(sl, sl1, false) == 0autotest.hss:5499: sl == sl111autotest.hss:5500: sl == sl1111?autotest.hss:5501: next slice in tree(sl, sl1, false) == sl1112autotest.hss:5502: sl == sl1112:autotest.hss:5503: next slice in tree(sl, sl1, false) == 0autotest.hss:5504: sl == 0autotest.hss:5506: sl == sl2.autotest.hss:5508: sl == lookup slice(sl:root)autotest.hss:5509: sl == 0rautotest.hss:5512: lookup next slice(sl:walkabout sprite component) == lookup slice(sl:walkabout sprite component)1autotest.hss:5515: lookup slice(14, sl1) == sl111autotest.hss:5516: sl == sl111autotest.hss:5517: sl == sl1112autotest.hss:5518: sl == 0autotest.hss:5519: sl == sl2autotest.hss:5520: sl == sl1112>autotest.hss:5526: get sprite type(sl) == spritetype:walkaboutslsl1sl11sl111sl1111sl1112sl232389.HSZ<6 (Ex vPVdq)8DJn@m N~0[>l{ ;k(UaK{ 2 b $ . TTNITT \^FdDjmo 0lTT~xzxm TTTT TTT\TjT]]]]] l&0m lT Nm D"%' l02@Jm>A *ZO&RWaYej.u 4xT}^BTQQQQQP$moTTN^ iTTn&)3+7<"GmJTT~LTV`Xdit)oTTwT: mo\T      ^ h\T@ 3 3 3 3 3  TT         > 'T n *47  A  9EJ  UXT  Zdg} } q} } iuz}  T T      \TT X     6 TTT t        TT  )   #  ', &7XTT;:TD  N  FRW b\MeToyq}\bGXZ6v)))))\X xTZ$'MM1MM)5:MEBHRU_WchIT\suxa ^QQQQQDm  \TTTVfT,|!$.&27BEXTHQT^Vbg.>ruTxTm DT lHTm 2|D\T hl m HDT 4TT"$~/2TT35T>GGHGG@LQG\D\T_ HhkTT Cnwz|  Tl  T_ _ _ _ _ !!XT (!e     n!~!TD!vT7!7!7!7! 7!P#`#%(TT&#+T4##>##6BG#$$RUTTT$%Xad$$n$$frw$V%f%TT,%%%%%%%%%XTT%T%%%%%r&&\TTH&X;&;&;&;& ;&R'b'  \(' X ''% '' ) . '''9 < T' (? H K ''U ''M Y ^ 'f(v(i l <(( o x { /(/( /(/(} /((( X( T (( (( ()N )lTT* )L*X*m 6*lTT|* v***m *+,+  \T*2 T ** **  *v+i+ `+Slice collision tests4autotest.hss:5547: slice at pixel(parent, 0, 0) == 0?autotest.hss:5548: slice at pixel(parent, 0, 0, get count) == 01autotest.hss:5566: get slice visible(sl1) == true2autotest.hss:5567: get slice visible(sl2) == false2autotest.hss:5568: get slice visible(sl3) == false1autotest.hss:5569: get slice visible(sl4) == true:autotest.hss:5571: slice at pixel(parent, 100, 200) == sl2:autotest.hss:5572: slice at pixel(parent, 105, 205) == sl28autotest.hss:5573: slice at pixel(parent, 100, 210) == 08autotest.hss:5574: slice at pixel(parent, 110, 200) == 0Cautotest.hss:5575: slice at pixel(parent, 100, 200, get count) == 1Cautotest.hss:5578: slice at pixel(parent, 104, 205, get count) == 3=autotest.hss:5579: slice at pixel(parent, 104, 205, 0) == sl2=autotest.hss:5580: slice at pixel(parent, 104, 205, 1) == sl3=autotest.hss:5581: slice at pixel(parent, 104, 205, 2) == sl4;autotest.hss:5582: slice at pixel(parent, 104, 205, 3) == 0Jautotest.hss:5585: slice at pixel(parent, 104, 205, get count, false) == 2Dautotest.hss:5586: slice at pixel(parent, 104, 205, 0, false) == sl2Dautotest.hss:5587: slice at pixel(parent, 104, 205, 1, false) == sl3Bautotest.hss:5588: slice at pixel(parent, 104, 205, 2, false) == 0Oautotest.hss:5591: slice at pixel(parent, 104, 205, get count, true, true) == 0Lautotest.hss:5593: slice at pixel(sl3, 104, 205, get count, true, true) == 11autotest.hss:5597: get slice visible(sl3) == trueOautotest.hss:5599: slice at pixel(parent, 104, 205, get count, true, true) == 2Iautotest.hss:5600: slice at pixel(parent, 104, 205, 0, true, true) == sl3Iautotest.hss:5601: slice at pixel(parent, 104, 205, 1, true, true) == sl4*autotest.hss:5609: slice height(sl5) == 20Dautotest.hss:5615: find colliding slice(parent, sl5, get count) == 3>autotest.hss:5618: find colliding slice(parent, sl5, 0) == sl2>autotest.hss:5619: find colliding slice(parent, sl5, 1) == sl3>autotest.hss:5620: find colliding slice(parent, sl5, 2) == sl4<autotest.hss:5621: find colliding slice(parent, sl5, 3) == 0>autotest.hss:5633: find colliding slice(parent, sl5, 0) == sl2<autotest.hss:5634: find colliding slice(parent, sl5, 1) == 0>autotest.hss:5638: find colliding slice(parent, sl5, 0) == sl2>autotest.hss:5639: find colliding slice(parent, sl5, 1) == sl3>autotest.hss:5640: find colliding slice(parent, sl5, 2) == sl4<autotest.hss:5641: find colliding slice(parent, sl5, 3) == 0<autotest.hss:5645: find colliding slice(parent, sl1, 0) == 0Eautotest.hss:5649: find colliding slice(parent, sl5, 0, false) == sl2Eautotest.hss:5650: find colliding slice(parent, sl5, 1, false) == sl3Cautotest.hss:5651: find colliding slice(parent, sl5, 2, false) == 0Kautotest.hss:5652: find colliding slice(parent, sl5, get count, false) == 2Pautotest.hss:5655: find colliding slice(parent, sl5, get count, true, true) == 2Jautotest.hss:5656: find colliding slice(parent, sl5, 0, true, true) == sl3Jautotest.hss:5657: find colliding slice(parent, sl5, 1, true, true) == sl4Hautotest.hss:5658: find colliding slice(parent, sl5, 2, true, true) == 0Eautotest.hss:5666: find colliding slice(parent, temp, get count) == 0parentsl1sl2sl3sl4sl5temp32436.HSZ \( )M{  |    :  #f/Y 7YY9?YY2CIYT `y\ W^7dssnssfrws Kautotest.hss:5679: sl<autotest.hss:5680: parent slice(sl) == lookup slice(sl:root) lookup codesl32435.HSZX 0= <L[hw=Dh [y  #%ww/ww'38wXy~ECGQy~TTRVN~acZy~pnrYy~`}Z #  #( $*# L` \?3#'??)/??"39?Slice tree tests@autotest.hss:5689: sprite layer == lookup slice(sl:script layer)!autotest.hss:5703: map < backdrop!autotest.hss:5704: backdrop < scr autotest.hss:5705: scr < textbox$autotest.hss:5706: textbox < stringsscrmaptextboxbackdropstrings32434.HSZ &6C9^1\(U'MV` %Ty,. *0V.L<>FN LQ\ d.fl_pv8Fd d:\*` H%d]  3 duuuu$uSy213 /6PBCAdJCCLRCCEV\Cplj~Hgmdrcc|cctcU.dDV< Vz(<` Iv.hLb .dd . XtJd"KK,KK$05K@ B<dGQIUZe g<dlvnz (<d.hLbd Uy. d<\ ,. Jd$(-]8~. ;@dEqqOqqGSXq.cfdkumy~N $ .d      t .dg g g g g  1 / 6 ) d) ) ) ) ) R k.`   dE E E E $E V. / 4 9<d>  H  @LQ V. \ | aR 'f<dkE E uE E my~E Y.@* .h Lb   <d       C.d     2  P@d     . ] .d    # @ k.3d6  @  8DI BTL@L[~fydnpviz@dR(@dx@dkkkkke.d CT DY.@vautotest.hss:5721: sl6autotest.hss:5722: npc reference from slice(sl) == npc6autotest.hss:5724: slice parent(sl) == walkabout layer2autotest.hss:5725: slice x(sl) == npc pixel x(npc)2autotest.hss:5726: slice y(sl) == npc pixel y(npc)autotest.hss:5728: sl2-autotest.hss:5729: sl2 == get npc sprite(npc)5autotest.hss:5730: npc reference from slice(sl2) == 0:autotest.hss:5736: sl && npc reference from slice(sl) == 00autotest.hss:5740: hero by slot(0) == hero:Freki(autotest.hss:5741: hero by slot(1) == -1(autotest.hss:5742: hero by slot(2) == -1(autotest.hss:5743: hero by slot(3) == -1autotest.hss:5746: slBautotest.hss:5747: slice parent(sl) == lookup slice(sl:hero layer)1autotest.hss:5748: slice x(sl) == hero pixel x(0)1autotest.hss:5749: slice y(sl) == hero pixel y(0)2autotest.hss:5750: sl == get hero slice by slot(0)0autotest.hss:5751: hero rank from slice(sl) == 00autotest.hss:5752: hero slot from slice(sl) == 0autotest.hss:5754: sl2,autotest.hss:5755: sl2 == get hero sprite(0)Pautotest.hss:5758: hero rank from slice(get npc slice(next npc reference)) == -1Pautotest.hss:5759: hero slot from slice(get npc slice(next npc reference)) == -1autotest.hss:5764: sl0autotest.hss:5765: hero rank from slice(sl) == 00autotest.hss:5766: hero slot from slice(sl) == 11autotest.hss:5768: get hero slice by slot(0) == 02autotest.hss:5769: get hero slice by slot(1) == slautotest.hss:5774: sl2autotest.hss:5775: get hero slice by slot(1) == sl0autotest.hss:5776: hero rank from slice(sl) == 10autotest.hss:5777: hero slot from slice(sl) == 1)autotest.hss:5781: get hero slice(2) == 0npcslsl2walkabout layer32407.HSZT  G$4Y9CIm(Ms 1WaB*,(.: =*B*LDPU@` (dchBjtlx}j*B]]]]]2  ,2 )B     Z4,BMMMMM   ,D&B B",$05@*x ,NQQ*BV`Xdi@t (_whB|~jk*B]]]]]b,8 ,x zB B 4i l**N("H.1*B6@8DI:T "WhB\f^jozd}*BWWWWWi wu* (p X , Bh   ~  ` ( .   -B  $  (- t 8V ;,B@I I JI I BNSI  i^ 4autotest.hss:5794: get blending enabled(sl) == false)autotest.hss:5795: get opacity(sl) == 1005autotest.hss:5796: get blend mode(sl) == blend:normal(autotest.hss:5800: get opacity(sl) == 503autotest.hss:5801: get blending enabled(sl) == true7autotest.hss:5804: get blend mode(sl) == blend:multiply4autotest.hss:5807: get blending enabled(sl) == false)autotest.hss:5808: get opacity(sl) == 1005autotest.hss:5809: get blend mode(sl) == blend:normal(autotest.hss:5813: get opacity(sl) == 507autotest.hss:5814: get blend mode(sl) == blend:multiply4autotest.hss:5819: get blending enabled(sl) == false)autotest.hss:5820: get opacity(sl) == 1005autotest.hss:5821: get blend mode(sl) == blend:normal(autotest.hss:5827: get opacity(sl) == 30(autotest.hss:5833: get opacity(sl) == 452autotest.hss:5834: get blend mode(sl) == blend:addsl collection32738.HSZ  Ѡ#1AM[gw9bit EOXahdl))'+ l997;`jmGJ Jl99SUmad l9omqLVm} 6l9)xrm P T GGGGG 9}}}}}Vy 6   ",",$05 4@7FKUMY^ &orzlN}r_____&)v]fZ`YYYYYe 2X ]H -l; ; ; ; ;  e  P < ]&, y).  8  0<A x eLX  cU  ^ 8 r m Z  pvyM M M M {M           .      b  J ~ = = = =  =  i #autotest.hss:5857: current map == 0%autotest.hss:5858: read gmap(16) == 0Wautotest.hss:5860: get child autosort(lookup slice(sl:walkabout layer)) == autosort:off%autotest.hss:5862: read gmap(16) == 2Uautotest.hss:5864: get child autosort(lookup slice(sl:walkabout layer)) == autosort:YAautotest.hss:5869: get child autosort(parent) == autosort:bottomY,autotest.hss:5873: slice y(ch1) == 100 -- 10-autotest.hss:5876: slice y(ch2) == 50 -- 10/2%autotest.hss:5879: slice y(ch3) == 800autotest.hss:5884: slice child(parent, 0) == ch20autotest.hss:5885: slice child(parent, 1) == ch40autotest.hss:5886: slice child(parent, 2) == ch30autotest.hss:5887: slice child(parent, 3) == ch1parentch1ch2ch3ch432433.HSZ "    $'* "-4 : >=' H ''JP''CTZ'Xh ehbqtw zHpQkP4^ tDLR 0 H##### pautotest.hss:5907: what > 0.autotest.hss:5909: read zone(id, x, y) == true/autotest.hss:5913: read zone(id, x, y) == falseidxyiwhat32432.HSZh4 (  IO}>cAfNU_ 2X~+PZ#Gkr 29_j 3 X } MM8UWY \ [bdfOOpOOhtyO~UW d~UW  d~bUW L-Md?????~UW :d Y G fd'1)5:~ >VEMdL11V11NZ_1~ cjdq{{{{{s{~b pMd~f }d~ fdYYYYY~ d .%d*!!4!!,8=!| HMdOooYooQ]bo mrdt~vMd'jMd]]]]]_f `H;d;;;; ; Y4F $R!'@-'d8'':@''3DJ' bfZ edprxk|F  2 d% % % % %  M t  Md      h > 'rd1 1 1 1 1 M8  6d+ + %+ + ).+  C9?dAu u Ku u COTu  R_edg  q  iuz Y8 aed+ + + + +  Y ped       $ d       n bda a a a  a && l1 R4Md9EECEE;GLEW ` cdhrjv{*Y d     d  d dd(# ^ Md M*Md0:2>C2NMdT%%^%%Vbg%rydUWM z~UW  Md~UW d~UW R%dEEEE EUWY 2d%).UW ~UW .AAdH!!R!!JV[!fh ~fh Nrdy{b~UW h~UW [dUWY $hhdV*UWM j~"UW Tx%Md,GG6GG.:?GUWY PWdZd\hm4z<~UW vdiiiiiRx}CJqhY \dOOOOO~h Md  ~h  d &  * / ~bh L: MdA ??K ??C O T ?~fh _ df p h t y ~h  d   ~ h * d   ~fh t d gg gg g~ zone tests6autotest.hss:5922: zone at spot(17, 15, getcount) == 3-autotest.hss:5923: check zone(1, 17, 15) == 1-autotest.hss:5924: check zone(2, 17, 15) == 1-autotest.hss:5925: check zone(3, 17, 15) == 0-autotest.hss:5926: check zone(5, 17, 15) == 16autotest.hss:5928: zone at spot(16, 16, getcount) == 4-autotest.hss:5929: check zone(1, 16, 16) == 0-autotest.hss:5930: check zone(2, 16, 16) == 1-autotest.hss:5931: check zone(3, 16, 16) == 0-autotest.hss:5932: check zone(4, 16, 16) == 1-autotest.hss:5933: check zone(5, 16, 16) == 1-autotest.hss:5934: check zone(7, 16, 16) == 1/autotest.hss:5937: zone number of tiles(1) == 1/autotest.hss:5938: zone number of tiles(2) == 91autotest.hss:5939: zone number of tiles(5) == 800/autotest.hss:5940: zone number of tiles(8) == 02autotest.hss:5941: zone number of tiles(9988) == 0 left edge)autotest.hss:5946: string compare(95, 96)&autotest.hss:5951: zone5 && zone5 <> 5)autotest.hss:5954: string compare(95, 96)0autotest.hss:5955: read zone(zone5, 16, 16) == 1,autotest.hss:5957: read zone(5, 16, 16) == 05autotest.hss:5959: zone number of tiles(zone5) == 800-autotest.hss:5963: get zone extra(5, 0) == 106autotest.hss:5964: get zone extra(5, 1) == -21474836485autotest.hss:5965: get zone extra(5, 2) == 21474836476autotest.hss:5966: get zone extra(5, -1) == 21474836475autotest.hss:5967: get extra(zone5, -1) == 2147483647-autotest.hss:5969: get zone extra(5, 1) == 32+autotest.hss:5970: extra length(zone5) == 3,autotest.hss:5974: extra length(zone10) == 0,autotest.hss:5976: extra length(zone10) == 1-autotest.hss:5977: get extra(zone10, -1) == 23autotest.hss:5979: extra length(get zone(11)) == 130autotest.hss:5980: get zone extra(11, 12) == 999)autotest.hss:5984: string length(95) == 0/autotest.hss:5985: get zone extra(9000, 0) == 0/autotest.hss:5986: get zone extra(9000, 1) == 00autotest.hss:5988: get zone extra(9000, 2) == 32-autotest.hss:5992: check zone(1, 17, 15) == 0-autotest.hss:5993: check zone(2, 17, 15) == 1-autotest.hss:5994: check zone(5, 17, 15) == 16autotest.hss:5995: zone at spot(17, 15, getcount) == 2-autotest.hss:5997: check zone(1, 17, 15) == 10autotest.hss:6001: check zone(1003, 16, 14) == 1/autotest.hss:6008: check zone(idx, 17, 15) == 1:autotest.hss:6010: zone at spot(17, 15, getcount) == count/autotest.hss:6015: check zone(idx, 17, 15) == 0:autotest.hss:6017: zone at spot(17, 15, getcount) == count0autotest.hss:6019: check zone(idx2, 17, 15) == 16autotest.hss:6024: zone at spot(16, 14, getcount) == 5-autotest.hss:6025: check zone(1, 16, 14) == 0-autotest.hss:6026: check zone(2, 16, 14) == 1-autotest.hss:6027: check zone(3, 16, 14) == 0-autotest.hss:6028: check zone(4, 16, 14) == 1-autotest.hss:6029: check zone(5, 16, 14) == 1-autotest.hss:6030: check zone(6, 16, 14) == 10autotest.hss:6031: check zone(1003, 16, 14) == 1zone5zone10idxidx2count32431.HSZ  n D2=BbkoM 8 X$ * ~!#& )  1 6  ? ,bMQ LY|[v!g usw * (|~ h [[[[[  (.4~ X!` n~ zQ P Tam}:MO %M;  'IKMN Y e<g6 shsub;   ~ u$  >2|~ h[[[[[    (.4~!$ X/2` 4r~ @~Q:DIP T_m{'MMG TO  <autotest.hss:6097: readarray(id, x, y) == readzone(id, x, y)<autotest.hss:6114: readarray(id, x, y) == readzone(id, x, y)xyitidnewvalue32430.HSZ` ~JEE  r d(+&-!3 9+?Tidxy32429.HSZ ~ǻ+U|  r &&8;*6="4C 1IOFv^;z6argjmT?[sx> s idxyvaluebits32428.HSZ ~0ټ+ r |+!j&\xy32427.HSZ ~%s 6>D~ "dlr#&) P ,3=5AFJ  Q_b ~loer3xzV   n=autotest.hss:6075: readarray(id, x, y) == read zone(id, x, y)Jautotest.hss:6077: zone at spot(x, y, getcount) == array count zones(x, y)xyid32426.HSZ@ &'-Z5[%Ow )/R[iwf++L+  8+8 3:ACMEQVC *S fhjJalAs}u  + ~%"Aqqqqq   3A   dE8AWWWW W8+8+ W+A( ,1+++8 ld<8AD__N__FRW_+++b rd+Alvnz8+8 A8+8 hA[[[[[8+8 A++ g A!,D.+ r08AeeBee:FKeV+ X^A`jbns++ Z~+AMMMMM8+ 8A+ A++ Zc x+ A  .%+ V F+  5^A;E=INY a+ Vc o+ 4 q.  }A{ { { { {  A     o  ( o+ J  'A= = = = = o a X h    b t   ~ n    '*    36 -9 !? EI 7API I RXI I K\bI  AKmrAt  ~  v V XAI I I I I  gA     +!tA     master palette tests3autotest.hss:6129: get color(0) == RGB(255, 0, 255)2autotest.hss:6130: get color(6) == RGB(155, 83, 3)@autotest.hss:6131: extract color(get color(19), color:red) == 37Cautotest.hss:6132: extract color(get color(19), color:green) == 139Bautotest.hss:6133: extract color(get color(19), color:blue) == 255/autotest.hss:6136: find color(255, 0, 255) == 02autotest.hss:6137: find color(0, 0, 0, 255) == 2550autotest.hss:6138: find color(0, 0, 0, 256) == 04autotest.hss:6139: find color(255, 0, 255, 1) == 1856autotest.hss:6140: find color(255, 0, 255, 185) == 1856autotest.hss:6141: find color(255, 0, 255, 186) == 2001autotest.hss:6142: find color(180, 180, 0) == 1034autotest.hss:6143: find color(512, 100, -512) == 1685autotest.hss:6146: get ui color(ui:background) == 240'autotest.hss:6147: get ui color(0) == 0+autotest.hss:6148: get ui color(255) == 2554autotest.hss:6149: get ui color(ui:MPBarFlash) == 373autotest.hss:6152: get ui color(ui:menu item) == 994autotest.hss:6156: get ui color(ui:menu item) == 240autotest.hss:6163: c1 == 14autotest.hss:6164: c2 == 159autotest.hss:6167: get ui color(ui:selected item 2) == c2Kautotest.hss:6170: (tog1 == c1 && tog2 == c2) || (tog1 == c2 && tog2 == c1)0autotest.hss:6173: get box style color(14) == 656autotest.hss:6174: get box style edge color(14) == 2520autotest.hss:6175: get box style border(14) == 1/autotest.hss:6176: get box style color(0) == 33c1c2tog1tog232425.HSZ4 |.4^$Hlw)NU_$Jn+18Xz 22>a:<2Fp >EG<99Q99IUZ9a:e2`gnGpzr~a:e 2Ga:e6:-G)))))c:< Gyyyyy' e KG       ce|[+<G1oo;oo3?Doc<mOeGU_Wchbsudas|uGasL2G?????dsucsuGds2<Bdss  G %s v02G7iiAii9EJis2s] cs| PgmGoo o yo o q}o ds2 < H 2G; ; ; ; ; : G     2 2G     ass2  G y y y y  y  26 +1G3) ) =) ) 5AF) 2 Q2GWy y ay y Yejy u2 &w2G}      2h1 2[3G[[[[[ 222@1<IGP   +2@:,2l$&f=222  _=GAKCOTj_Gcmeqv V=22^  xG2G (= maptile tests1autotest.hss:6190: read map block(6, 5, 0) == 1120autotest.hss:6191: read map block(6, 4, 0) == 96/autotest.hss:6192: read map block(6, 4, 1) == 00autotest.hss:6193: read map block(6, 4, 2) == 58@autotest.hss:6194: read pass block(6, 5) == westwall + southwall9autotest.hss:6197: read zone(zone:OneWayExit, 4, 10) == 1Bautotest.hss:6198: read pass block(4, 10) == southwall + northwall6autotest.hss:6199: read pass block(5, 10) == southwall1autotest.hss:6203: read map block(3, 2, 1) == 255/autotest.hss:6205: read map block(3, 2, 1) == 0/autotest.hss:6209: read pass block(3, 2) == 2559autotest.hss:6214: read wall bit(3, 2, east wall) == true:autotest.hss:6215: read wall bit(3, 2, west wall) == falseAautotest.hss:6218: read pass block(3, 2) == vehicle a + harm tile+autotest.hss:6222: read foe map(14, 5) == 0+autotest.hss:6223: read foe map(14, 6) == 1+autotest.hss:6224: read foe map(-1, 0) == 01autotest.hss:6228: read map block(3, 3, 0) == 1927autotest.hss:6231: animation start tile (192, 0) == 1447autotest.hss:6234: get tile animation offset(1, 0) == 0/autotest.hss:6235: currentdisplaytile(208) == 0Sautotest.hss:6236: currentdisplaytile(192) >= 144 && currentdisplaytile(192) <= 147Sautotest.hss:6237: currentdisplaytile(192) == 144 + get tile animation offset(0, 0)%autotest.hss:6248: last layer id == 21autotest.hss:6249: layer id under walkabouts == 1%autotest.hss:6253: last layer id == 11autotest.hss:6254: layer id under walkabouts == 0rem maprem xrem y32382.HSZ9 ,/ag=Gk:Cfow&Ot,5Y~Ael "Fk)M` T 9 _ f    a  eeBP  meqs}ua*qcqbq~da+qq c`8 q&SS0SS(49SlDNaFMqqT^VbgcSrqxzla aq     cb nqU U U U U  a~ }qqq q  q q  q c q#  -  %16 A ct IqOg g Yg g Q]bg  bm d  ~d P 2 a mq     c q     aqcF q9999"9-A/ 1q8B:FK-/ .Veq]!!g!!_kp!se {q-A/e -/ 8seqt -A/ eq-/ lq_____ q#( 3-A/ -;eqBLDPU-/ L:`qg??q??iuz? GqseUqq3P3-A/ bq-/ @oeq33333 |#eq*4,8=seHqNXP\a3 -A/ zreqymmmm{m-/ q q     sejqq]]]]]-A/ -/ sem3v3B-A/ (q/91=B-/ MqT^Vbg 8rqy++++{+semq}}}}}3>-A/ q-/ eq 0 eq#### %#se)0q6ww@ww8DIwxVee .TX(t-fh in~.v  y~p[6q[[[[[{eEeqZXs-8}e {eQq-  -  s! !.%! (-*!-!3 ]q>  @F  9JP T!-[H! ^d!!.it! l!cqn!w;!lq;!;!;!;!};!-!"~ z""z "|q"""""-##-# n#$.$ ~$$#q##  ##  #{e$ eq" u$u$, u$u$$ 0 5 u$$z@ $C qH $$R $$J V [ $-$\%-l P% o sf%%.z v% } -%t p% C%q C%C% C%C% C%{e% q %% %% %<&- 0&  L&h&. \&  x& V& #&q #&#&  #&#&  #&-&-p''-$ ' ' s''.2 ' 5 -(, : '@ 'qK ''M S ''F W ] '*(-h ( k :(V(.v J( y f(p ~ D( (q (( (( (-(H)- <)  nR)n). b)  ~x) \) /)q /)/) /)/) /))z ) q )) ))  )map state tests#autotest.hss:6266: current map == 00autotest.hss:6278: read map block(7, 2, 2) == 425autotest.hss:6279: read pass block(7, 2) == northwall0autotest.hss:6282: read map block(7, 2, 2) == 114autotest.hss:6283: read pass block(7, 2) == eastwall0autotest.hss:6286: read map block(7, 2, 2) == 114autotest.hss:6287: read pass block(7, 2) == eastwall0autotest.hss:6291: read map block(7, 2, 2) == 425autotest.hss:6292: read pass block(7, 2) == northwall0autotest.hss:6294: read map block(7, 2, 2) == 115autotest.hss:6295: read pass block(7, 2) == northwall4autotest.hss:6297: read pass block(7, 2) == eastwall0autotest.hss:6304: read map block(7, 2, 2) == 124autotest.hss:6305: read pass block(7, 2) == westwall0autotest.hss:6308: read map block(7, 2, 2) == 425autotest.hss:6309: read pass block(7, 2) == northwall/autotest.hss:6312: read zone(6, 16, 14) == true0autotest.hss:6313: read zone(6, 15, 14) == false-autotest.hss:6314: get zone extra(5, 0) == 100autotest.hss:6319: read zone(6, 16, 14) == false/autotest.hss:6320: read zone(6, 15, 14) == true1autotest.hss:6321: read zone(765, 10, 20) == true0autotest.hss:6324: read zone(6, 16, 14) == false/autotest.hss:6325: read zone(6, 15, 14) == true1autotest.hss:6326: read zone(765, 10, 20) == true-autotest.hss:6327: get zone extra(5, 0) == 11/autotest.hss:6331: read zone(6, 16, 14) == true0autotest.hss:6332: read zone(6, 15, 14) == false2autotest.hss:6333: read zone(765, 10, 20) == false-autotest.hss:6334: get zone extra(5, 0) == 100autotest.hss:6336: read zone(6, 16, 14) == false/autotest.hss:6337: read zone(6, 15, 14) == true1autotest.hss:6338: read zone(765, 10, 20) == true-autotest.hss:6339: get zone extra(5, 0) == 11/autotest.hss:6347: read zone(6, 16, 14) == true/autotest.hss:6348: read zone(6, 15, 14) == true1autotest.hss:6349: read zone(765, 10, 20) == true-autotest.hss:6350: get zone extra(5, 0) == 12/autotest.hss:6353: read zone(6, 16, 14) == true0autotest.hss:6354: read zone(6, 15, 14) == false2autotest.hss:6355: read zone(765, 10, 20) == false-autotest.hss:6356: get zone extra(5, 0) == 106autotest.hss:6361: npc x(npc) == 3 && npc y(npc) == 13)autotest.hss:6362: npc copy count(7) == 0)autotest.hss:6365: npc copy count(7) == 15autotest.hss:6368: npc x(npc) == 5 && npc y(npc) == 6;autotest.hss:6369: npc x(newnpc) == 1 && npc y(newnpc) == 2(autotest.hss:6374: get NPC id(npc) == -16autotest.hss:6377: npc x(npc) == 3 && npc y(npc) == 13)autotest.hss:6379: npc copy count(7) == 0+autotest.hss:6380: get NPC id(newnpc) == -15autotest.hss:6382: npc x(npc) == 5 && npc y(npc) == 6)autotest.hss:6384: npc copy count(7) == 1;autotest.hss:6385: npc x(newnpc) == 1 && npc y(newnpc) == 25autotest.hss:6390: npc x(npc) == 5 && npc y(npc) == 6;autotest.hss:6391: npc x(newnpc) == 1 && npc y(newnpc) == 26autotest.hss:6394: npc x(npc) == 3 && npc y(npc) == 13+autotest.hss:6395: get NPC id(newnpc) == -1mapstate:tilepassnpcnewnpc32383.HSZp 2%2?GR\#,NvRP !++-,F8:@ =Eb_NP `XZ:NXxbk  mokkqwkkh{kP mP &EmPV3mIIIIIPB m (#N* ,N pQ2m7ccAcc9EJc*U ]Zm_iamr* k}m*XxmKKKKK*m(=obsolete map data testsextra data test)autotest.hss:6415: string compare(95, 96)1autotest.hss:6416: extra length(get zone(5)) == 3-autotest.hss:6417: get zone extra(5, 0) == 106autotest.hss:6418: get zone extra(5, 1) == -21474836485autotest.hss:6419: get zone extra(5, 2) == 2147483647)autotest.hss:6422: string length(95) == 04autotest.hss:6423: extra length(get zone(9000)) == 3/autotest.hss:6424: get zone extra(9000, 0) == 0/autotest.hss:6425: get zone extra(9000, 1) == 0/autotest.hss:6426: get zone extra(9000, 2) == 0rem maprem xrem y32424.HSZ  ",6DUhy,Cc7E H(*J24dl v<>pxuM mJO 4]`5[b45p`(5ns5 ~45d5`555~`  h5e(6(*66686~ 6f66646~ ` 6g:7<7H7#J7~   79` 9 `9&8094`:97`B92=*9nr9K|99TW9 ~INY<[2_a P9o:qW::z&:~ot}[<_2a 9:`::::p:W:::~*<W2 :qj;t;;W;~[_ H;;`;<;2;r:<WD<P< Z<~*W <s<%<<.W<~#(1*W <:~ C=H?M`R?[PB? j? \ p??e?[h?n|?[y?{?_tb? ?  ?@?N@0@?h@@@ @y@  @@ @~W p@ibAhAjA tAyxA AA A~y @Aj:B@BBB LB%yPB dB.yhB~(y1y BkBB/HKB BSyB B^C C~CEMV\aKg BlCC{CC CyC CyC~vx~\\ CV 7j,?K (2?*F N J ` 6    : 4 $   \  l   x U T b D   T /z ` " $ *<   6 ?/ A ?"L9GR `@ ci^l6z@D P}Lx0 R\ njVL     ~/ f  @JT f #b~ ,/~@&2" IL * <[^8T fgjb~DFOUXam" v/@ /  $~ Xfz/@  / ~ HV /bl@ %(+/ 7: ~ "1=C 8DXW/dnc@ lo x{~/ ~RTZ`fr &// *&/@L ^Z v~$  // /0: L  H d~  */6/ ?B .KN*Q/D N~%'-39EW]  q/}/  /. :~lntz r 8sF` r    4 H\B.    @J * $ *d %0 5<A   O!:!X!/v!cV!R^i n  Luz !!!!"" &"~ ! #/#&#@#/H#T#h#/x##~" "#/###/# $$/.$8$~" #v$$ /$$$/$$$%/$~ "(" V$,%F%?/T%`%t%K/|%%%W/%~:<BHNTZ" %  E~.`&&6&F&P&Z&d&~y{~ &%l``cornerxcornery cornermaskwall up wall left wall right wall downvsidehside far vside far hsidexy strikedistxgodirygodirxgoygostartxstartyexpectxexpecty expect ret32370.HSZ x As7H^@  "(*4,8=HJ|L \RO(]OO_eOOXioO'z|*+(<Hd D7>(77777J(NX(AAAA A c( *".3n>@FqN$tV>PXplatform tests nonexistent=autotest.hss:6673: read environment(1, $2="nonexistent") == 0)autotest.hss:6674: string equal(1, $3="") Has_Value_42?autotest.hss:6676: read environment(1, $2="Has_Value_42") == 4242+autotest.hss:6677: string equal(1, $3="42")3autotest.hss:6680: xbox request account picker == 0'autotest.hss:6681: ps5 start story == 0%autotest.hss:6682: ps5 end story == 0statusstatus substitution32420.HSZ O7=Ehsy#,17=FLRs4Wz;\ciov{<];;BC |C J;OQ[S_dj2oq@Coo`oCoqOj$OyyyyykCoj6/qO)))))k<;Oyyyy yC* Zo;;CodoDjDCoj,GY;O\f^jokjRz;O}]]]]]P{P]OlO     r As   |O      P O  '  +0 C ;;O@  J  BNS *J ^COc= = m= = eqv= *o jB qO5 5 5 5 5 k O     o*oo.;O!!!!!jqO oj.!;O$!!.!!&27!klB;OE__O__GSX_oDDCoC \* C. ;O!!!!!*x;OkkkkkoCoj#;O}}}}}k.;O *ojn9";O%aa/aa'38akDC;OFPHTYsave slot tests-autotest.hss:6699: save slot used(1) == falseDautotest.hss:6706: import globals(1, @export global 1) == -123456789(autotest.hss:6707: export global 1 == -20autotest.hss:6709: export global 1 == -123456789'autotest.hss:6710: export global 2 == 0'autotest.hss:6720: export global 1 == 0'autotest.hss:6721: export global 2 == 08autotest.hss:6726: the global with the biggest id == 123;autotest.hss:6727: @the global with the biggest id == 50000Lautotest.hss:6730: import globals(3, @the global with the biggest id) == 1238autotest.hss:6731: the global with the biggest id == 321-autotest.hss:6734: save slot used(1) == false,autotest.hss:6735: save slot used(2) == true0autotest.hss:6739: export global 1 == -123456789*autotest.hss:6740: export global 2 == -100Mautotest.hss:6744: import globals(2, @export global 1, @export global 1) == 00autotest.hss:6745: export global 1 == -123456789'autotest.hss:6749: export global 1 == 0'autotest.hss:6750: export global 2 == 0-autotest.hss:6762: save slot used(1) == false-autotest.hss:6763: save slot used(2) == false'autotest.hss:6771: export global 1 == 0'autotest.hss:6772: export global 2 == 0'autotest.hss:6778: export global 1 == 0'autotest.hss:6779: export global 2 == 032419.HSZ* !+%gm4Z#JS]&-8_f ;BMt}%-U^f7@Hpy(17_f7@FnkkFsk  us{}xsTG{GGGGGs{ #s%{s 42 s 7{ &*0s; F=k{CMEQVSascdiWT{tWWv|WWoWi.`skpdsf{skq4sREr{EEEE Esk}!s){46</@FsQk[Vsc{npvizsQss {ssk ts{ssk  s>1{1111 "1ssk n6s>{IKQDU[ssk sH o; {z; ; |; ; u; sss x  s  {     sQkk  L s  {     sQsk  sB 5 {%5 5 '-5 5  175 sQss r K s S  {^  `f  Yjp {R rssk sp c 0{c c c c c ;s ss`S?{SSSSSJsks L{Ws#:+szs4Y{?AG:KQds\ds.s~mqf{xqqzqqsqqssst{sJksbs{s9 ksL?{!??#)??-3?s>z*FksO{Z\bUflsw6kX s{sk@s{sks`S{SSSS $Ss/kss6>){I))KQ))DU[)kkdsm{xzssxussna{aaaaassss({sV sxs{!#)-3s> ks`MS {XSSZ`SSSdjSstring load tests4autotest.hss:6790: get stat name(1, stat:hp) == trueHP-autotest.hss:6791: string compare(1, $2="HP")Hits/autotest.hss:6793: string compare(1, $2="Hits") mute register8autotest.hss:6795: string compare(1, $2="mute register")0autotest.hss:6796: get stat name(1, 16) == false+autotest.hss:6797: string compare(1, $2="") .'autotest.hss:6805: string compare(1, 2)'autotest.hss:6808: string compare(1, 2)##'autotest.hss:6811: string compare(1, 2),-1234. , 'autotest.hss:6814: string compare(1, 2)'autotest.hss:6816: string compare(1, 2).'autotest.hss:6821: string compare(1, 2)'autotest.hss:6824: string compare(1, 2) ## 'autotest.hss:6827: string compare(1, 2)'autotest.hss:6829: string compare(1, 2)##'autotest.hss:6832: string compare(1, 2) ,${V105}. ,${S3} 'autotest.hss:6835: string compare(1, 2) ,-1234. , 'autotest.hss:6838: string compare(1, 2),-1234. , 'autotest.hss:6841: string compare(1, 2)Z This box is for testing textboxline and stringfromtextbox . ## ,-1234. , 'autotest.hss:6846: string compare(1, 2) Left Bracket&autotest.hss:6851: string compare(1,2)[&autotest.hss:6854: string compare(1,2)Flee&autotest.hss:6857: string compare(1,2)Menu&autotest.hss:6860: string compare(1,2)Cancel&autotest.hss:6863: string compare(1,2)None&autotest.hss:6866: string compare(1,2)Space&autotest.hss:6869: string compare(1,2) Left Shift&autotest.hss:6872: string compare(1,2) Gamepad Bjoy:B&autotest.hss:6877: string compare(1,2) Gamepad Up&autotest.hss:6880: string compare(1,2)Gamepad Button 16&autotest.hss:6883: string compare(1,2)&autotest.hss:6888: string compare(1,2)&autotest.hss:6890: string compare(1,2) map layer0&autotest.hss:6893: string compare(1,2) Some lookup&autotest.hss:6896: string compare(1,2) Lookup-40&autotest.hss:6899: string compare(1,2)&autotest.hss:6902: string compare(1,2)32418.HSZL W 3&,2T]~ !&HOV^fmsy**@*|P  7*;=  G  ?KP [ B[rb*;geeqeeiuzesP tr*  tP(D <u}** TdH* %Vn[  .=xx=  [w[[ ,*l[6,[;1{{;{{3?D{ BBTdC\xd* ==[  = P ** =[** d" tH i 2  [l [v P* & saving/loading tests 1#autotest.hss:6913: current map == 0-autotest.hss:6915: save slot used(1) == falseThis is a green stringThis is flat yellow-on-purpleThis should be plain style,autotest.hss:6941: save slot used(1) == trueNow it's plainNow it's yellow-on-purpleLoadgame didn't happen!32417.HSZ 0268w l  #(36@8DITWaYej~.X,Mnuy!*w*l }dautotest.hss:6966: arg1 == 0autotest.hss:6967: arg2 == 0autotest.hss:6968: arg3 == 0autotest.hss:6972: arg1 == 30autotest.hss:6973: arg2 == -100autotest.hss:6974: arg3 == 0arg1arg2arg332416.HSZ 9#Hp?dDs :P Z (+/1--;--3?D-t`O RW/Yyycyy[glyu 0zw "z/     0/ ;/HF/;;;; ;SZ/)+1$5;deFK/M  W  O[` Pnpkp/rCC|CCtC   1 tVi @w FT{saving/loading tests 2.autotest.hss:6986: savegame map == current map3autotest.hss:6987: slicewidth(savegame slice) == 151autotest.hss:6990: get npc id(savegame npc) == -1'autotest.hss:6993: string is visible(5)'autotest.hss:6994: string is visible(6)0autotest.hss:6995: string is visible(8) == falseThis is a green string'autotest.hss:6997: string compare(5, 8)%autotest.hss:6998: string x(6) == 100%autotest.hss:6999: string y(6) == 110Loadgame didn't happen!32415.HSZ<   = $+17 D tv"  /reset game testsresetgame didn't happen!32414.HSZ  06:>   n v  '  0 35?7CH@ S 3V33`33Xdi3 tv ` ~LmxJt3=====x%v3kkkkk. 3*reset game testsautotest.hss:7045: arg2 == 0autotest.hss:7046: arg3 == 0resetgame didn't happen!autotest.hss:7053: arg1 == 10autotest.hss:7054: arg2 == 20autotest.hss:7055: arg3 == 0arg1arg2arg332366.HSZ 'VA(5BJQr{F~P "$+8.02,f;=` H =OHH~XHO[e]in=Oyy~.yO!!!!!o~l~' ~nOaaaaa H=map autorun tests'autotest.hss:7072: autorun counter == 1'autotest.hss:7076: autorun counter == 2'autotest.hss:7080: autorun counter == 3last maplast xlast y32365.HSZ   >C$/`  SSSS S~+-autotest.hss:7088: arg == 444arg32413.HSZ< TD @oN}@s| "')oo3oo+7<oGsIO'Y[aTek%vNsx*(~'8s='MvsRQ'EEEEEbsf' w&Ts(0.#'8##:@##3DJ#UsW]'giobsyNs*'s's'run game tests4autotest.hss:7099: check game exists($1="") == falsetest.rpg3autotest.hss:7100: check game exists($1="test.rpg")foo.rpg;autotest.hss:7101: check game exists($1="foo.rpg") == falseautotest.rpgdir:autotest.hss:7103: check game exists($1="autotest.rpgdir") autotest.hss@autotest.hss:7104: check game exists($1="autotest.hss") == false ../testgame?autotest.hss:7105: check game exists($1="../testgame") == false../testgame/autotest.rpgdirFautotest.hss:7106: check game exists($1="../testgame/autotest.rpgdir")..\testgame/Autotest.rpgdirGautotest.hss:7107: check game exists($1="..\\testgame/Autotest.rpgdir")../testgame\autotest.rpgdirGautotest.hss:7108: check game exists($1="../testgame\\autotest.rpgdir") autotest.rpg@autotest.hss:7109: check game exists($1="autotest.rpg") == false.//..\TESTGAME\autotest.RPGdirKautotest.hss:7111: check game exists($1=".//..\\TESTGAME\\autotest.RPGdir")SOURCE.LUMPEDPLOTSCR.HSD# PLOTSCR.HSD # This file holds the language definition for OHRRPGCE plotscripting. # modifying this file may have undesired/disasterous effects, # but reading it can be somewhat educational. Especially the constants. # Use same capitalisation as HSpeak does, pad to length 3 plotscr version, begin "3U ", # Version number used by hspeak to test whether this file # supports necessary features, and also causes the # display of future-version warnings in Game/Custom # or can be used by Game/Custom to change behaviour. # Only very rarely necessary to increment (don't when # new commands are added; that's detected separately), # otherwise leave alone to allow forwards compatibility. "3S " # Minimum supported version of hspeak; # Custom/Game don't care about this. end include, scancode.hsi #-------------------------------------------------------------------------- # hard coded functions define function, begin 0,noop,0 # no operation 1,wait,1,1 # wait(cycles) 2,waitforall,0 # wait for script-related walking&panning to stop 3,waitforhero,1,0 # wait for hero to stop moving 4,waitfornpc,1,0 # wait for npc to stop moving 5,suspendnpcs,0 # pause normal NPC movement 6,suspendplayer,0 # stop the player from controlling stuff (except text boxes) 7,resumenpcs,0 # resume npc automation 8,resumeplayer,0 # unlock players controls 9,waitforkey,1,-1 # wait for a keypress (scancode) 10,walkhero,3,0,2,1 # walk hero(who,direction,distance) 11,showtextbox,1,1 # show a text box 12,checktag,1,0 # returns the value of a tag 13,settag,2,0,0 # set tag(#,true/false) 15,usedoor,2,0,1 # use door(#,fade screen in and out) 16,fightformation,1,0 # fight formation(#) 17,getitem,2,0,1 # get item(item,quantity) 18,deleteitem,2,0,1 # delete item(item,quantity) 19,leader,0 # returns the current leader 20,getmoney,1,0 # get money(amount) 21,losemoney,1,0 #? lose money(amount) no checking 22,paymoney,1,0 # returns false and subtracts nothing if cannot afford 23,unequip,2,0,1 # (who,where) 24,forceequip,3,0,1,0 # (who,where,item) 25,setheroframe,2,0,0 # (who,frame) frame is 0 or 1 26,setNPCframe,2,0,0 # (who,frame) frame is 0 or 1 27,suspendoverlay,0 # turns off overhead tiles 28,playsong,1,0 # play song(#) 28,playmusic,1,0 # play song(#) 29,stopsong,0 # stop the music 29,stopmusic,0 # stop the music 30,keyval,2,0,0 # check key/joystick/virtual scancode state bits (scancode, joystick num) 31,rankincaterpillar,1,0 # finds the heros position in the caterpillar 32,showbackdrop,1,0 # showbackdrop (#) 33,showmap,0 # cancels a showbackdrop 34,dismountvehicle,0 # dismount whatever vehicle you may be riding 35,useNPC,1,0 # trigger an NPC remotely 37,useshop,1,0 #? use shop(#) 38,camerafollowshero,1,0 # make camera follow a hero 39,camerafollowsnpc,1,0 # make camera follow an npc 40,pancamera,3,0,1,2 # pan camera(direction,distance,pixelstep) 41,focuscamera,3,0,0,2 # focus camera(x,y,pixelstep) 42,waitforcamera,0 # waits for pan or focus to finish 43,herox,1,0 # returns the hero's x coordinate 44,heroy,1,0 # returns the hero's y coordinate 45,npcx,1,0 # returns the npc's x coordinate 46,npcy,1,0 # returns the npc's y coordinate 47,suspendobstruction,0 # lets heros walk through NPCs and vice versa 48,resumeobstruction,0 # restores normal obstruction behavior 49,suspendherowalls,0 # lets heros walk through walls 50,suspendNPCwalls,0 # lets heros and npcs walk through walls 51,resumeherowalls,0 # restores normal hero wall behavior 52,walknpc,3,0,2,1 # walk npc(who,direction,distance) 53,setherodirection,2,0,2 # set hero direction(who,direction) 54,setnpcdirection,2,0,2 # set npc direction(who,direction) 55,getdefaultweapon,1,0 # (who) 56,setdefaultweapon,2,0,0 # (who,item) 57,suspendcatapillar,0 # misspelled alias for backcompat 58,resumecatapillar,0 # misspelled alias for backcompat 59,waitfortextbox,0 # waits for text box to go away 60,equipwhere,2,0,0 #? (who,item) returns the slot that an item can be equipped in, or false if the hero cant equip it 61,teleporttomap,3,0,0,0 # teleport to map (map,x,y) 62,suspendrandomenemys,0 # misspelled alias for backcompat 63,resumerandomenemys,0 # misspelled alias for backcompat 64,getherostat,3,0,0,0 # returns a hero's stat (who,stat,cur/max/base stat) 65,resumeoverlay,0 # turns overhead tiles back on 66,addhero,1,0 # adds a hero to the party 67,deletehero,1,0 # deletes a hero from the party 68,swapouthero,1,0 # move a hero out of the active party 69,swapinhero,1,0 # moves a hero into the active party (if there is room) 70,roominactiveparty,0 # returns the number of empty slots in the active party (0-3) 71,lockhero,1,0 # prevents swapping of a hero 72,unlockhero,1,0 #? reverses lockhero 73,gameover,0 # returns you to the title screen 74,setdeathscript,1,0 # changes what script is run when you die 75,fadescreenout,3,0,0,0 # fade screen out (red,green,blue) 76,fadescreenin,0 # fade back to color after fade screen out 77,showvalue,-1 # display one or more numbers in the bottom left corner 77,showvalues,-1 # display one or more numbers in the bottom left corner 78,alterNPC,4,0,0,0,-1 # replaces one of an NPC's stats 79,shownovalue,0 # hide the number from showvalue 80,currentmap,0 # returns the number of the current map 81,setherospeed,2,0,4 # changes a heros walking speed 82,inventory,1,0 # returns the count of a given item 83,setherostat,4,0,0,1,0 # alters a hero's stats (who,stat,value,cur/max/base stat) 84,suspendboxadvance,0 # prevents user from advancing text boxes 85,resumeboxadvance,0 # reverses suspendboxadvance 86,advancetextbox,0 # as if the user had pressed a key 87,setheroposition,3,0,0,0 # arbitrarily set x,y 88,setNPCposition,3,0,0,0 # arbitrarily set x,y 89,swapbyposition,2,0,0 # swap two hero slots 90,findhero,1,0 # locate hero slot by hero name 91,checkequipment,2,0,1 # what is a hero equipped with? (who,where) #92,daysofplay,0 # returns the days, these opcodes remain for compatability #93,hoursofplay,0 # returns the hours #94,minutesofplay,0 # returns the minutes 95,resumeNPCwalls,0 # restores normal NPC wall behavior 96,setheroz,2,0,0 # sets the hero's vertical position 97,readmapblock,3,0,0,0 # get mapblock x,y,layer 98,writemapblock,4,0,0,0,0 # set mapblock x,y,value,layer 99,readpassblock,2,0,0 # get passblock x,y 100,writepassblock,3,0,0,0 # set passblock x,y,value 101,NPCdirection,1,0 # return an NPC's direction 102,herodirection,1,0 # return a hero's direction 103,resetpalette,0 # return the master palette to defaults 104,tweakpalette,5,0,0,0,0,255 # alter the master palette 105,readcolor,2,0,0 # return a color value 106,writecolor,3,0,0,0 # change a color value 107,updatepalette,0 # apply changes made with writecolor 108,seedrandom,1,0 #? reseed the random number generator 109,greyscalepalette,2,0,255# convert the palette to greyscale 110,setheropicture,3,0,0,1 # who,picture,type 111,setheropalette,3,0,0,1 # who,palette,type 112,getheropicture,2,0,1 # who,type 113,getheropalette,2,0,1 # who,type 114,readglobal,1,0 # index 115,writeglobal,2,0,0 # index,value 116,heroiswalking,1,0 # (who) #117,NPCiswalking,1,0 #x obsolete, backwards compatability only 118,suspendcaterpillar,0 # other heros stop following the leader, and can be manipulated separately. 119,resumecaterpillar,0 # turns catapillar party back on 120,NPCreference,4,0,0,0,0 # get an NPC reference by ID number (ID, copynumber, allowdisabled, pool) 121,NPCatspot,3,0,0,0 # get nth NPC reference on tile (X,Y,n) 122,getNPCID,1,0 # get the ID number of an NPC reference 123,NPCcopycount,2,0,0 # find out how many copys of an NPC ID are on the map 124,changeNPCID,3,0,0,-1 # given an NPC reference, changes its ID and pool 125,createNPC,5,0,0,0,2,0 # create an NPC by ID at a location and return its reference 126,destroyNPC,1,0 # destroy the referenced NPC 126,deleteNPC,1,0 # alias 127,teachspell,2,0,0 # (who,spell) tries to teach a hero a spell 128,forgetspell,2,0,0 # (who,spell) forget a learned spell 129,readspell,3,0,0,0 # (who,list,slot) returns the number of the spell in a slot 130,writespell,4,0,0,0,0 # (who,list,slot,spell) forces a hero to learn a spell 131,knowsspell,2,0,0 # (who,spell) returns true if the hero already knows this spell 132,canlearnspell,3,0,0,0 # (who,spell,learntype) returns true if the hero can learn the spell 133,herobyslot,1,0 # returns the hero ID/name of the hero at a particular slot in the party 134,herobyrank,1,0 # returns the hero ID/name of the hero at a particular rank in the caterpillar 135,puthero,3,0,0,0 #? (who,x,y) set hero pixel-position 136,putnpc,3,0,0,0 # (who,x,y) set npc pixel position 137,putcamera,2,0,0 # (x,y) set screen pixel position 138,heropixelx,1,0 #? (who) get hero pixel x 139,heropixely,1,0 #? (who) get hero pixel y 140,npcpixelx,1,0 # (who) get npc pixel x 141,npcpixely,1,0 # (who) get npc pixel y 142,camerapixelx,0 #? get camera pixel x 143,camerapixely,0 #? get camera pixel y 144,loadtileset,2,-1,-1 # load a new tileset for a map layer [](tileset, layer), or change the default tileset [](tileset), or reset tilesets [](). 145,pickhero,2,-1,0 # lets you manually pick a hero (message string, skip if alone) 146,renameherobyslot,1,0 # lets you manually rename a hero 147,readgeneral,1,0 # directly read from the in-memory array of general game data 148,writegeneral,2,0,0 # directly write to the in-memory array of general game data. If you crash your game with this command, don't be too surprised 150,statusscreen,1,0 # display the status screen for a hero 151,showminimap,0 # display the mini-map 152,spellsmenu,1,0 # display the spell menu for a hero 153,itemsmenu,0 # display the items menu 154,equipmenu,2,-1,1 # display the equip menu for a hero #155,savemenu,0 # obsolete in favor of ID 170 157,ordermenu,0 # display the order menu 158,teammenu,0 # display the team menu 159,initmouse,0 # init mouse, return true if a mouse is installed 160,mousepixelx,0 # returns mouse x coordinate on the screen 161,mousepixely,0 # returns mouse y coordinate on the screen 162,mousebutton,1,0 # returns true if the specified button is pressed 163,putmouse,2,160,100 # places the mouse at a point on the screen 164,mouseregion,4,-1,-1,-1,-1 # define the rectangle in which the mouse can move (xmin, xmax, ymin, ymax) 165,npcatpixel,3,0,0,0 # returns NPC at pixel x,y, third arg is which npc (on -1 returns number of npcs at pixel) 166,saveinslot,1,0 # save game in slot 167,lastsaveslot,0 # returns the last save slot the game was saved in, false if unsaved 168,suspendrandomenemies,0 # keeps random enemies from attacking 169,resumerandomenemies,0 # undoes suspendrandomenemies 170,savemenu,1,-1 # display the save menu 171,saveslotused,1,1 # returns true if a saved game exists in the specified slot 172,importglobals,3,1,-1,-1 # (slot) or (slot, id) or (slot, first, last) reads a range of globals from a save slot 173,exportglobals,3,1,0,50000 # (slot) or (slot, first, last) writes a range of globals to a save slot 174,loadfromslot,-1 # loads saved game from slot (slot, args...) 175,deletesave,1,1 # delete (hide from load/save screen - data not *actaully* deleted) specified slot 176,runscriptbyid,-1 # run a script by its id number and pass any number of arguments 177,NPCiswalking,1,0 # (who) returns true if walking (for real, unlike the old implementation) 178,readgmap,1,0 # read from general map data array 179,writegmap,2,0,0 # write a gmap data item 180,mapwidth,1,-1 # returns map height in tiles (map id) 181,mapheight,1,-1 # returns map width in tiles (map id) 182,readNPC,3,0,0,-1 # reads information about an NPC on the current map (corresponds to alterNPC) 183,setherolevel,3,0,0,1 # change a hero's level 184,giveexperience,2,-1,1 # (who, how much) gives a hero or the active party experience 185,herolevelled,1,0 # number of levels gained last battle/giveexperience command. 186,spellslearnt,2,0,0 # deprecated, use "spells learned" instead. 187,getmusicvolume,0 # music volume on a scale of 0-255 regardless of implementation 188,setmusicvolume,1,128 # set music volume on a scale of 0-255 #189,getformationsong,1,0 # returns the song associated with a given formation + 1 (obsoleted by opcode 307) 190,setformationsong,2,0,0 # sets the song associated with a given formation 191,heroframe,1,0 # get hero walkabout frame 192,npcframe,1,0 # get npc walkabout frame 193,npcextra,2,0,1 # get npc extra data (ref, 0 - 2) 194,setnpcextra,3,0,1,0 # set npc extra data (ref, 0 - 2, value) #195,loadsound,2,0,0 # loads a sound into a slot(slot, sfx) #DO NOT USE #196,freesound,1,1 # frees an sfx slot(slot) #DO NOT USE 197,playsound,3,1,0,0 # plays an sfx (num, loop?, preempt?) 198,pausesound,1,1 # pauses an sfx (num) (stop, but don't rewind) 199,stopsound,1,1 # stops an sfx (num) (stop, and rewind) 200,systemhour,0 201,systemminute,0 202,systemsecond,0 203,currentsong,0 203,currentmusic,0 204,getheroname,2,0,0 # (string, hero) - puts the name of hero(hero) in string(string) 205,setheroname,2,0,0 # (string, hero) - sets the name of hero(hero) to string(string) 206,getitemname,2,0,0 # (string, item) - puts the name of item(item) in string(string) 207,getmapname,2,0,0 # (string, map) - puts the name of map(map) in string(string) @obsolete("The argument isn't an attack ID or atk: constant! ", read attack name) 208,getattackname,2,0,0 #Obsolete: Takes real ID - 1 or atk: constant - 2 (string id, attack ID - 1) #209,getglobalstring,2,0,0 # (string, global) - puts the global string (global) in string(string) 210,showstring,1,0 #shows string on the bottom(stringID) 211,clearstring,1,0 #deletes the data from string(stringID) 212,appendascii,2,0,0 #adds ascii to string(stringID,ascii) 213,appendnumber,4,0,0,0,0 #adds number to string(stringID,number,minlength,zeropad) 214,copystring,2,0,0 #copies string from one to another(sourceID,destinationID) 215,concatenatestrings,2,0,0 #adds two strings(sourceID,destinationID) 216,stringlength,1,0 #returns the length of string(stringID) 217,deletechar,2,0,1 #deletes character from string(stringID,position) 218,replacechar,3,0,1,0 #replaces character in the specified string(stringID,position,ascii) 219,asciifromstring,2,0,1 #returns the ascii in the string(ascii number)(stringID,position) 220,positionstring,3,0,0,0 #move a string to a position on the screen(stringID,x,y) 221,setstringbit,3,0,0,0 #set a string bit, such as: visibility, style(stringID,bit,value) 222,getstringbit,2,0,0 #return a string bit, such as: visibility, style(stringID,bit) 223,stringcolor,3,0,-1,0 #set a string's foreground and background color(stringID,fColor,bColor) 224,stringx,1,0 #return a string's X position(stringID) 225,stringy,1,0 #return a string's Y position(stringID) 226,systemday,0 #returns system day 227,systemmonth,0 #returns system month 228,systemyear,0 #returns system year 229,stringequal,2,0,0 #returns whether two strings are the same(stringID1, stringID2) 229,stringcompare,2,0,0 #returns whether two strings are the same(stringID1, stringID2) 230,readenemydata,2,0,0 #reads enemy data(enemy,dataposition) 231,writeenemydata,3,0,0,0 #writes enemy data(enemy,dataposition,value) 232,trace,1,0 #writes the provided string to G_DEBUG.txt 233,getsongname,2,0,0 #get song name and store in string (string id, song) 234,loadmenu,2,1,1 #show loadmenu (really load/quit?, show new game) 235,keyispressed,2,0,0 #check key is down, returns true/false (scancode, joystick num) 236,soundisplaying,1,0 #checks to see if a sound is playing (soundID) #237,soundslots,0 #returns the number of slots available 238,searchstring,3,0,0,1 #Search string, (ID1,ID2,start) 239,trimstring,3,0,-1,1 #Trims the specified string, (ID, start,length) 240,stringfromtextbox,4,0,0,0,0 #(obsolete) get a line from a textbox (string, box, line, ignored) 241,expandstring,2,0,0 #expand ${Hxx}, etc in a string(ID) 242,joystickbutton,2,0,0 #returns whether a given button is pressed (button, joystick) 243,joystickaxis,3,0,100,0 #returns the axis position (axis,multiplier,joystick) 244,waitforscancode,1,0 #waits for a specific scancode (identical to waitforkey!) 245,savemapstate,2,255,255 #save map data to a temp file (savebits, customid) 246,loadmapstate,2,255,255 #load map data from a temp file (loadbits, customid) 247,resetmapstate,1,255 #reload original map data (loadbits) 248,deletemapstate,2,255,255 #delete temp map state files (deletebits, customid) 249,partymoney,0 #retrieves amount of gold 250,setmoney,1,0 #sets amount of gold 251,setstringfromtable,2,0,0 #string support function 252,appendstringfromtable,2,0,0 #string support function 253,settileanimationoffset,3,0,0,0 #set offset from starting tile (animation pattern 0/1, offset, layer) 254,gettileanimationoffset,2,0,0 #get offset from starting tile (animation pattern 0/1, layer) 255,animationstarttile,2,0,0 #tile number which this tile starts its animation pattern off as (id of a tile, layer) 256,suspendmapmusic,0 #prevent ambient music from playing on entering a map 257,resumemapmusic,0 #reverse above 258,checkherowall,2,0,0 #check passability in a direction relative to a hero 259,checknpcwall,2,0,0 #check passability in a direction relative to an NPC 260,settimer,6,0,-1,-1,-1,-1,-1#start (or modify) a timer(id, count, speed, trigger, string, flags) 261,stoptimer,1,0 #convenience for settimer(id,-1,0) 262,readtimer,1,0 #returns the count of a timer(id) 263,getcolor,1,0 #returns a 32-bit color from the master palette(index) 264,setcolor,2,0,0 #writes a 32-bit color to the master palette(index,val) 265,rgb,3,0,0,0 #mixes red, green and blue into a 32-bit color(r, g, b) 266,extractcolor,2,0,0 #extracts an RGB component from a 32-bit color(color, component) 267,mainmenu,0 #opens the main menu 268,loadpalette,1,0 #load master palette 269,totalexperience,1,0 #experience gained by a hero 270,experiencetolevel,2,0,-1 #total experience to reach a level (level,hero) 271,experiencetonextlevel,1,0 #experience to level up 272,setexperience,3,0,0,1 #set total experience (who,amount,allow spell forgetting) 273,milliseconds,0 #timer in milliseconds 274,openmenu,2,0,0 #openmenu(menuID, allow duplicate) 275,readmenuint,2,0,0 #read menu int(menuhandle,intid) 276,writemenuint,3,0,0,0 #write menu int(menuhandle,intid,n) 277,readmenuitemint,2,0,0 #read menu item int(menuitemhandle,intid) 278,writemenuitemint,3,0,0,0 #write menu item int(menuitemhandle,intid,n) 279,createmenu,0 #create a blank menu 280,closemenu,2,0,0 #close menu(handle, run close script) 281,topmenu,0 #return a handle to the topmost menu 282,bringmenuforward,1,0 #bring menu forward(menu handle) 283,addmenuitem,1,0 #add menu item(menuhandle) appends, returns menuitemhandle 284,deletemenuitem,1,0 #delete menu item(menuitemhandle) 285,getmenuitemcaption,2,0,0 #get menu item caption(menuitemhandle, string ID) 286,setmenuitemcaption,2,0,0 #set menu item caption(menuitemhandle, string ID) 287,getlevelmp,3,0,0,0 #get level mp(hero party slot, mp level, currentstat|maximumstat) 288,setlevelmp,3,0,0,0 #set level mp(hero party slot, mp level, new value) 289,bottommenu,0 #return a handle to the bottommost menu 290,previousmenu,1,0 #given a menu handle, return a handle to the menu beneath it 291,nextmenu,1,0 #given a menu handle, return a handle to the menu on top of it 292,menuitembyslot,3,0,0,true #menu item by slot(menu handle, slotnum, visible only) returns menuitemhandle 293,previousmenuitem,2,0,true #given a menuitemhandle return handle to the menu item before it 294,nextmenuitem,2,0,true #given a menuitemhandle return handle to the menu item after it 295,selectedmenuitem,1,-1 #selected menu item(menu handle) returns menuitemhandle 296,selectmenuitem,1,0 #select menu item(menu item handle) moves the cursor 297,parentmenu,1,0 #parent menu(menu item handle) returns menu handle 298,getmenuid,1,0 #menu ID(menu handle) returns the ID of the menu 299,swapmenuitems,2,0,0 #swap menu items(handle1, handle2) 300,findmenuitemcaption,4,0,0,0,1 #find menu item caption(menu handle, string ID, search after handle=false, visible only=true) 301,findmenuid,1,0 #find menu(menu ID) search open menus for menu ID and return menu handle 302,menuisopen,1,0 #menu is open(menu handle) # return true as long as the handle is still valid 303,menuitemslot,1,0 #menu item slot(menu item handle) returns a menu slot number 304,outsidebattlecure,3,0,0,-1 #backcompat only, should prefer "map cure" 305,changetileset,2,-1,-1 #similar to loadtileset. load a new tileset for a map layer [](tileset, layer), or change the default tileset [](tileset), or reset tilesets [](). 306,layertileset,1,0 #layer tileset(layer) returns tileset number in use 307,getformationsong,1,0 #returns the song associated with a given formation 308,addenemytoformation,5,0,0,85,95,-1 #add enemy to formation(formation, enemy id, x, y, slot = -1) returns slot or -1 309,findenemyinformation,3,0,0,0 #find enemy in formation(formation, enemy id, number) returns slot or -1 310,deleteenemyfromformation,2,0,0 #delete enemy from formation(formation, slot) 311,formationslotenemy,2,0,0 #formation slot enemy (formation, slot) returns enemy in slot 312,formationslotx,2,0,0 #formation slot x(formation, slot) returns x of enemy in slot 313,formationsloty,2,0,0 #formation slot y(formation, slot) returns y of enemy in slot 314,setformationbackground,4,0,0,1,0 #set formation background(formation, background, animation frames, animation ticks) 315,getformationbackground,1,0 #get formation background(formation) returns background number 316,lastformation,0 #last formation fought 317,randomformation,1,0 #pick a formation from a formation set 318,formationsetfrequency,1,0 #returns set frequency 319,formationprobability,2,0,0 #returns (as percentage) formation being picked from formation set probability 320,currenttextbox,0 #currently displayed textbox or -1 321,getherospeed,1,0 #hero walk speed (hero) 322,loadherosprite,2,0,-1 #load hero sprite (number, palette) 323,freesprite,1,0 #frees a sprite (id) 324,putslice,3,0,0,0 #change the position of a slice 325,setspritevisible,2,0,0 #alias for set slice visible 326,setspritepalette,2,0,0 #set sprite palette(id, pal) 327,replaceherosprite,3,0,0,-1 #replaces the sprite with a hero sprite (id, num, pal) 328,setspriteframe,2,0,0 #what it says on the tin(id, num) 329,loadwalkaboutsprite,2,0,-1 #load walkabout sprite (number, palette) 330,replacewalkaboutsprite,3,0,0,-1 #replaces the sprite with a walkabout sprite (id, num, pal) 331,loadweaponsprite,2,0,-1 #load weapon sprite (number, palette) 332,replaceweaponsprite,3,0,0,-1 #replaces the sprite with a weapon sprite (id, num, pal) 333,loadsmallenemysprite,2,0,-1 #load enemy sprite (number, palette) 334,replacesmallenemysprite,3,0,0,-1 #replaces the sprite with an enemy sprite (id, num, pal) 335,loadmediumenemysprite,2,0,-1 #load enemy sprite (number, palette) 336,replacemediumenemysprite,3,0,0,-1 #replaces the sprite with an enemy sprite (id, num, pal) 337,loadlargeenemysprite,2,0,-1 #load enemy sprite (number, palette) 338,replacelargeenemysprite,3,0,0,-1 #replaces the sprite with an enemy sprite (id, num, pal) 339,loadattacksprite,2,0,-1 #load attack sprite (number, palette) 340,replaceattacksprite,3,0,0,-1 #replaces the sprite with an attack sprite (id, num, pal) 341,loadbordersprite,2,0,-1 #load a textbox border (number, palette) 342,replacebordersprite,3,0,0,-1 #replaces the sprite with a textbox border (id, num, pal) 343,loadportraitsprite,2,0,-1 #load a character portrait (number, palette) 344,replaceportraitsprite,3,0,0,-1 #replaces the sprite with a character portrait (id, num, pal) 345,clonesprite,2,0, 0 #returns a copy of the given sprite(ID, pal) 346,getspriteframe,1,0 #returns the current frame number of a sprite 347,spriteframecount,1,0 #returns the number of frames a sprite has 348,slicex,1,0 #returns the x position of a slice relative to its parent 349,slicey,1,0 #returns the y position of a slice relative to its parent 350,setslicex,2,0,0 #set the x position of a slice relative to its parent 351,setslicey,2,0,0 #set the y position of a slice relative to its parent 352,slicewidth,1,0 #returns the width of a slice 353,sliceheight,1,0 #returns the height of a slice 354,sethorizalign,2,0,0 #changes the horizontal alignment of a slice to its parent 355,setvertalign,2,0,0 #changes the vertical alignment of a slice to its parent 356,sethorizanchor,2,0,0 #changes the horizontal anchor of a slice 357,setvertanchor,2,0,0 #changes the vertical anchor of a slice 358,numberfromstring,2,0,0 #look in a string for a number and return it 359,sliceissprite,1,0 #return true if the provided slice handle points to a sprite 360,spritelayer,0 #return a handle to the plotsprite layer 360,scriptlayer,0 #return a handle to the plotsprite layer 361,freeslice,1,0 #free a slice and all its children 362,firstchild,1,0 #return the first child of a slice or 0 if none 363,nextsibling,1,0 #return the next sibling of a slice or 0 if none 364,createcontainer,2,0,0 #create a container slice (width, height) 365,setparent,2,0,0 #move a slice to a new parent 366,checkparentage,2,0,0 #check to see if a slice is a child (or grandchild) of another 367,slicescreenx,1,0 #return a slice's x position relative to the screen 368,slicescreeny,1,0 #return a slice's y position relative to the screen 369,sliceiscontainer,1,0 #return true if a slice is a container 370,createrect,3,0,0,0 #create a rect slice (width, height, style) 371,sliceisrect,1,0 #return true if a slice is a rect 372,setslicewidth,2,0,0 #change the width of a resizeable slice 373,setsliceheight,2,0,0 #change the height of a resizeable slice 374,getrectstyle,1,0 #return the style of a rect slice 375,setrectstyle,2,0,0 #change the style of a rect slice 376,getrectfgcol,1,0 #return the fgcol of a rect slice 377,setrectfgcol,2,0,0 #change the fgcol of a rect slice 378,getrectbgcol,1,0 #return the bgcol of a rect slice 379,setrectbgcol,2,0,0 #change the bgcol of a rect slice 380,getrectborder,1,0 #return the border of a rect slice 381,setrectborder,2,0,0 #change the border of a rect slice 382,getrecttrans,1,0 #return the translucency of a rect slice 383,setrecttrans,2,0,0 #change the translucency of a rect slice 384,slicecollidepoint,3,0,0,0 #check a point for collision with a slice 385,slicecollide,2,0,0 #check a pair of slices for collision 386,slicecontains,2,0,0 #check if slice2 is completely inside slice1 387,clampslice,2,0,0 #move slice1 so that it is inside slice2 388,horizflipsprite,2,0,1 #flip a sprite horizontally 389,vertflipsprite,2,0,1 #flip a sprite vertically 390,spriteishorizflipped,1,0 #return true if a sprite is flipped horiz. 391,spriteisvertflipped,1,0 #return true if a sprite is flipped vert. 392,settoppadding,2,0,0 #change a slice's top-padding 393,gettoppadding,1,0 #return a slice's top-padding 394,setleftpadding,2,0,0 #change a slice's left-padding 395,getleftpadding,1,0 #return a slice's left-padding 396,setbottompadding,2,0,0 #change a slice's bottom-padding 397,getbottompadding,1,0 #return a slice's bottom-padding 398,setrightpadding,2,0,0 #change a slice's right-padding 399,getrightpadding,1,0 #return a slice's right-padding 400,fillparent,2,0,1 #make a slice fill its parent 401,isfillingparent,1,0 #returns true if a slice is set to fill 402,slicetofront,1,0 #move a slice in front of its siblings 403,slicetoback,1,0 #move a slice behind its siblings 404,lastchild,1,0 #find the last child of a parent slice 405,ysortchildren,1,0 #sort the children of a slice by Y value 406,setsortorder,2,0,0 #set sort value on a slice for sortchildren 407,sortchildren,2,0,1 #sort siblings by their setsortorder value 408,previoussibling,1,0 #return the previous sibling of a slice or 0 if none 409,getsortorder,1,0 #get sort value for sortchildren for a slice 410,getsliceextra,2,0,0 #get slice extra (0-2) data (slice, extra) 411,setsliceextra,3,0,0,0 #set slice extra (0-2) data (slice, extra, value) 412,getspritetype,1,0 #get type of a sprite slice or -1 if not 413,getspritesetnumber,1,0 #get record number of a sprite slice 414,getspritepalette,1,0 #get palette number of a sprite slice 415,suspendtimers,0 #stop all timers without resetting them 416,resumetimers,0 #makes timers paused with "suspend timers" continue 417,setslicevisible,2,0,0 #change sprite visibilty(id, vis) 418,getslicevisible,1,0 #return a slice's visibility bit 419,sliceedgex,2,0,0 #return the x pos of a given edge of a slice 420,sliceedgey,2,0,0 #return the y pos of a given edge of a slice 421,createtext,0 #create a new text slice 422,setslicetext,2,0,0 #copy a string into a text slice 423,gettextcolor,1,0 #return a text strings color 424,settextcolor,2,0,0 #change a text strings color 425,getwrap,1,0 #return true if a text slice wraps 426,setwrap,2,0,1 #change the wrapping state of a text slice 427,sliceistext,1,0 #return true if the given slice handle is a text slice 428,gettextbg,1,0 #return text background color 429,settextbg,2,0,0 #change text background color 430,getoutline,1,0 #return true if text uses outline 431,setoutline,2,0,1 #change text's outline mode 432,usemenuitem,1,0 #given a menu item handle, activate it 433,sliceatpixel,6,0,0,0,0,1,0 #find descendant or child slices containing a screen position 434,findcollidingslice,5,0,0,0,1,0 #find descendant or child slices colliding with a slice 435,parentslice,1,0 #return a slice's parent 435,sliceparent,1,0 #alias 436,childcount,1,0 #return number of children of a slice 437,lookupslice,2,0,0 #find a slice using a lookup code constant (lookup, root) 438,resetgame,-1 #reset the game (newgame args) 439,sliceisvalid,1,0 #checks for a real, non-deleted slice handle 440,iteminslot,1,0 #read inventory by position 441,setiteminslot,2,0,0 #write inventory by position 442,itemcountinslot,1,0 #read item count by position 443,setitemcountinslot,2,0,0 #write item count by position 444,putsprite,3,0,0,0 #change a sprite's position (handle, x, y) 444,placesprite,3,0,0,0 #change a sprite's position (handle, x, y) 445,updateleveluplearning,2,0,1 #refresh spells learned from level ups 446,moveslicebelow,2,0,0 #make a slice the previous sibling of another slice 447,movesliceabove,2,0,0 #make a slice the next sibling of another slice 448,slicechild,2,0,0 #the nth child of a slice, counting from 0 449,resetheropicture,2,0,1 #reset a hero's picture to their default 450,resetheropalette,2,0,1 #reset a hero's palette to their default 451,setsliceclipping,2,0,1 #set whether a slice will crop its children 452,getsliceclipping,1,0 #return whether a slice will crop its children 453,creategrid,4,0,0,1,1 #create a grid slice of a specified size 454,sliceisgrid,1,0 #true if the slice is a grid 455,setgridcolumns,2,0,1 #change grid horizontal count 456,getgridcolumns,1,0 #return the number of horizontal cells 457,setgridrows,2,0,1 #change grid vertical count 458,getgridrows,1,0 #return the number of vertical cells 459,showgrid,2,0,1 #make a grid visible 460,gridisshown,1,0 #return true if grid is visible 461,loadslicecollection,1,0 #load a collection of slices 462,setsliceedgex,3,0,0,0 #set a slice's position by an arbitrary edge 463,setsliceedgey,3,0,0,0 #set a slice's position by an arbitrary edge 464,getslicelookup,1,0 #get a slice's lookup code 465,setslicelookup,2,0,0 #change a slice's lookup code 466,tracevalueinternal,-1 #tracevalue is translated to this 467,mapcure,3,0,0,-1 #uses a cure attack on a hero 468,readattackname,2,0,0 #puts an attack name in a string (string id, atk: constant (attack id+1)) 469,spellslearned,2,0,0 #number spells and spell ids hero learnt at last battle/giveexperience command. 470,allocatetimers,1,16 #change the number of timers #471,unusedtimer,0 #find a timer id that's not in use, or allocate more 472,setnpcignoreswalls,2,0,1 #set whether an npc can pass walls (npcref, bool) 473,getnpcignoreswalls,1,0 #get whether an npc can pass walls (npcref) 474,setnpcobstructs,2,0,1 #set whether an npc obstructs (npcref, bool) 475,getnpcobstructs,1,0 #get whether an npc obstructs (npcref) 476,setnpcusable,2,0,1 #set whether an npc can be used (npcref, bool) 477,getnpcusable,1,0 #get whether an npc can be used (npcref) 478,setnpcmoves,2,0,1 #set whether an npc's movetype used (npcref, bool) 479,getnpcmoves,1,0 #get whether an npc's movetype used (npcref) 480,readzone,3,0,0,0 #test whether a tile is in a zone (zone id, x, y) 481,writezone,4,0,0,0,1 #set whether a tile is in a zone (zone id, x, y, true/false) 482,zoneatspot,3,0,0,0 #get the nth zone set at a tile (x, y, n) 483,zonenumberoftiles,1,0 #get the number of tiles in this zone (zone id) #484,drawwithzone,3,0,0,0 #write to map layer (zone id, layer num, tile) (unimplemented) #485,zonenexttilex,3,0,-1,-1 #x coordinate of next tile in zone (zone id, current x, current y) (unimplemented) #486,zonenexttiley,3,0,-1,-1 #y coordinate of next tile in zone (zone id, current x, current y) (unimplemented) # 487,getzonename,2,0,0 #read zone name (string, zone id) 488,getzoneextra,2,0,0 #get zone extra data (zone id, extra field) 489,setzoneextra,3,0,0,0 #set zone extra data (zone id, extra field, value) 490,useitem,1,0 # use an item as if you had used it from the item menu 491,useiteminslot,1,0 # use item in a given inventory slot 492,mouseclick,1,0 # returns true if the specified button is pressed (button) 493,loadbackdropsprite,1,0 # load backdrop sprite (number) 494,replacebackdropsprite,2,0,-1 # replaces the sprite with a backdrop sprite (handle, number) 495,getspritetrans,1,0 # whether the sprite is drawn transparently (handle) 496,setspritetrans,2,0,1 # set whether the sprite is drawn transparently (handle, bool) 497,setherobaseelementalresist,3,-1,0,100 # set percentage damage taken from an element (hero, element, percent) 498,herobaseelementalresistasint,2,-1,0 # percentage damage taken from an element rounded to an int (hero, element) 499,herototalelementalresistasint,2,-1,0 # percentage damage taken from an element rounded to an int (hero, element) 500,setslicevelocityx,3,0,0,-1 #set slice velocity x(sl, pixels per tick, ticks) # negative left, positive right 501,setslicevelocityy,3,0,0,-1 #set slice velocity y(sl, pixels per tick, ticks) # negative up, positive down 502,getslicevelocityx,1,0 #return x velocity in pixels per tick 503,getslicevelocityy,1,0 #return y velocity in pixels per tick 504,setslicevelocity,4,0,0,0,-1 #set both x and y velocity simultaneously (sl, x vel, y vel, ticks) 505,stopslice,1,0 #cancel all of a slice's movement 506,movesliceto,4,0,0,0,0 #move a slice until it has the new desired x and y (sl, x, y, ticks) 507,movesliceby,4,0,0,0,0 #move a slice until it has the new desired relative x and y (sl, rel x, rel y, ticks) 508,waitforslice,1,0 #wait for a slice to stop moving 509,sliceismoving,1,0 #return true if the slice has velocity or target 510,createellipse,4,0,0,-1,-1 #width, height, border color, fill color 511,sliceisellipse,1,0 #return true if the slice is an ellipse 512,setellipsebordercol,2,0,0 #change border color 513,setellipsefillcol,2,0,0 #change fill color 514,getellipsebordercol,1,0 #change border color 515,getellipsefillcol,1,0 #change fill color 516,_checkpoint,0 #dumps checkpoint screenshot for automated testing. Only works when run with the -autotest command line argument 517,menuitembytrueslot,2,0,0 #return a menu item handle, based on the order in Custom (menu handle, slot no.) 518,menuitemtrueslot,1,0 #slot no. of a menu item as it appears in Custom (menu item handle) 519,getheroslice,1,0 #get the slice representing a hero walkabout 520,getNPCslice,1,0 #get the slice representing an NPC walkabout 521,getdoorx,2,0,-1 #x coordinate of given door 522,getdoory,2,0,-1 #y coordinate of given door 523,getdoordestinationid,2,0,-1 #door id of given door's exit 524,getdoordestinationmap,2,0,-1 #map number of given door's exit 525,doorexists,2,0,-1 #returns true if the given door exists 526,getattackcaption,2,0,0 #puts an attack's caption in a string (string id, attack id+1 / attack .hsi constant) 527,getrectfuzziness,1,0 #get rect fuzz or opacity percentage 528,setrectfuzziness,2,0,50 #set rect fuzz percentange 529,textboxline,5,0,0,-1,1,0 #get a line of text from a textbox (string, box, line, expand, strip) 530,getslicetext,2,0,0 #get the contents of a text slice (string, slice) 531,getinputtext,1,0 #get user textual input since last tick (string) 532,enableinputtext,1,1 #whether to enable getinputtext (enable?) 533,inputtextenabled,0 #(undocumented) whether getinputtext is enabled 534,setherohandx,3,0,0,0 #Change hand position for battle weapons (who, frame, new x) 535,setherohandy,3,0,0,0 #Change hand position for battle weapons (who, frame, new y) 536,getherohandx,2,0,0 #Read hero hand position for battle weapons (who, frame) 537,getherohandy,2,0,0 #Read hero hand position for battle weapons (who, frame) 538,getdefaultherohandx,2,0,0 #Read default hero hand position for battle weapons (who, frame) 539,getdefaultherohandy,2,0,0 #Read default hero hand position for battle weapons (who, frame) 540,checkonetime,1,0 #returns the value of a onetime npc tag 541,setonetime,2,0,0 #set onetime npc tag(#,true/false) 542,microseconds,0 #microsecond timer 543,enemyelementalresistasint,2,0,0 #get percentage elemental damage for an enemy (id, element) 544,heroz,1,0 #a hero's Z coordinate (party slot) 545,getherostatcap,1,0 #get the cap for a stat; 0 if none (stat) 546,setherostatcap,2,0,0 #set the cap for a stat (stat, value or 0) 547,getitemmaximumstacksize,1,0 #get the maximum size of a stack of a certain item (item id) 548,npcz,1,0 #npc's Z value, in pixels (npcref) 549,setnpcz,2,0,0 #set npc's Z value, in pixels (npcref, z) 550,dooratspot,2,0,0 #get door ID on tile, or -1 (x, y) 551,suspenddoors,1,0 #doors don't trigger when stepped on 552,resumedoors,1,0 #undoes suspend doors 553,runningondesktop,0 #returns true if the device is Windows/Mac/Linux 554,runningonmobile,0 #returns true if the device is Android 555,runningonconsole,0 #returns true if the device is console (OUYA, Gamestick, FireTV, Mojo) 556,inputstringwithvirtualkeyboard,3,0,-1,-1 # (string id, max length, only player) 557,getitemdescription,2,0,0 #(string, item) - puts the description of item(item) in string(string) 558,setspritesetnumber,2,0,0 #(sprite slice handle, set num) 559,getspritedefaultpal,1,0 #(sprite slice handle) - returns default palette number 560,npcisdisabled,1,0 #(npc reference) returns true if the npc exists, but is disabled by tags or one-time use #561,unused (Don't use: should increment maxScriptCmdID when new commands added) #562,unused #563,unused #564,unused 565,stringsprintf,-1 #(dest string id, format string id, args...) Format a string, like sprintf 566,scripterror,2,-1,0 #(string id, hide frame) Show a script error 567,getscriptname,2,0,0 #(string id, script id) Get name of a script 568,getcallingscriptid,1,1 #(depth) Get ID number of a parent or ancestor script 569,camerafollowsslice,1,0 #(slice) Center camera on slice 570,getactivebattlepauseonallmenus,0 # returns true or false based on the global bitset 571,setactivebattlepauseonallmenus,1,0, #(true/false) change the global bitset (not saved) 572,dissolvesprite,6,0,0,-1,0,0,1 #(slice handle, dissolve:type, ticks, start tick, backwards, auto animate) 573,canceldissolve,1,0 #(slice handle) stop/reset dissolve 574,spriteisdissolving,1,0 #(slice handle) return true if sprite is in the middle of a dissolve state 575,waitfordissolve,1,0 #(slice handle) wait for an "dissolve sprite" command to finish (only if auto animate) 576,hidevirtualgamepad,0 # force-hide virtual gamepad on platforms that support it 577,showvirtualgamepad,0 # force-show virtual gamepad on platforms that support it 578,autovirtualgamepad,0 # automatic show/hide virtual gamepad on platforms that support it (default) 579,getvertalign,1,0 # return a slice's alignment. Compare with edge: constants 580,gethorizalign,1,0 # return a slice's alignment. Compare with edge: constants 581,getvertanchor,1,0 # return a slice's anchor. Compare with edge: constants 582,gethorizanchor,1,0 # return a slice's anchor. Compare with edge: constants 583,setselectsliceindex,2,0,0 # change the currently selected child of a select slice by index 584,getselectsliceindex,1,0 # return the index of the currently selected child of a select slice 585,createselect,2,0,0 # create a select slice of a specified size 586,sliceisselect,1,0 # true if the slice is a select 587,slicechildindex,1,0 # Return the current integer index of this slice relative to its siblings 588,createscroll,2,0,0 # create a scroll slice of a specified size 589,sliceisscroll,1,0 # true if the slice is a scroll 590,setscrollbarstyle,2,0,0 # change scroll slice scrollbar style 591,getscrollbarstyle,1,0 # return current scroll slice scrollbar style 592,setscrollcheckdepth,2,0,0 # change a scroll's child-check-depth 593,getscrollcheckdepth,1,0 # return a scroll's current child-check-depth 594,scrolltochild,3,0,0,0 # cause all the children of a Scroll Slice to move until a specific child is in view (parent, descendent, apply_padding) 594,scrolltoslice,3,0,0,0 # alias 595,runningonwindows,0 # returns true if the device is Windows 596,runningonmac,0 # returns true if the device is Mac 597,runningonlinux,0 # returns true if the device is Linux 598,nextnpcreference,1,0 # Iterating over NPCs: reference to next NPC 599,input string with mouse keyboard,2,0,-1 # pop up a virtual keyboard that responds to mouse clicks 600,runningonouya,0 # returns true if the device is OUYA (see also "running on console") 601,unhidemousecursor,0 # unhides the OS mouse cursor 601,showmousecursor,0 602,hidemousecursor,0 # hides the OS mouse cursor 603,pixelfocuscamera,3,0,0,2 # pixel focus camera(x,y,pixelstep) 604,sendemail,3,0,-1,-1 # send an email, possibly with attached saved (save slot, subject string, body string) 605,dumpslicetree,1,0 # Dump slice tree to g_debug.txt, like ctrl+F8 debug key (root slice handle) 606,createpanel,2,0,0 #x create a panel slice of a specified size 607,sliceispanel,1,0 #x return if the slice is a panel 608,getpanelisvertical,1,0 #x return true for a vertical panel slice, false for a horizontal panel slice 609,setpanelisvertical,2,0,1 #x change the vertical/horizontal orientation of a panel slice 610,getpanelprimaryindex,1,0 #x return the index (0 or 1) of the panel primary child 611,setpanelprimaryindex,2,0,0 #x change the panel primary child. must be 0 or 1 612,getpanelpercentasint,1,0 #x return slice panel primary child percentage as an integer 613,setpanelpercent,2,0,0 #x change slice panel primary child percentage 614,getpanelpixels,1,0 #x return slice panel primary child pixel size 615,setpanelpixels,2,0,0 #x change slice panel primary child pixel size 616,getpanelpadding,1,0 #x return slice panel padding 617,setpanelpadding,2,0,0 #x change slice panel padding 618,debugmenu,0 # Opens the debug menu 619,menuitematpixel,2,0,0 # The menu item at a screen position 620,rungame,1,0 # Run another game (string id) 621,getbattlecountdown,0 # Get random battle counter 622,setbattlecountdown,1,100 # Set random battle counter 623,checkwallcollisionx,7,0,0,0,0,20,20,100 # Check for wall collision (pixel x, pixel y, width, height, xgo, ygo, friction) 624,checkwallcollisiony,7,0,0,0,0,20,20,100 # Check for wall collision (pixel x, pixel y, width, height, xgo, ygo, friction) 625,moveslicewithwallchecking,4,0,0,0,100 # Move a slice by xgo,ygo or until it hits a wall (sl, xgo, ygo, friction) 626,textboxtext,4,0,0,1,0 # Get whole text from a textbox (string, box, expand, strip) 627,checkgameexists,1,-1 # Check an .rpg/.rpgdir exists (string id) 628,pathfindnpcto,4,0,0,0,0 # Make an NPC pathfind to a specific position (npc, tile x, tile y, stop after stuckticks) 629,npcchasesnpc,4,0,0,0,0 # Make an NPC chase another NPC (npc, target npc, stop when reached, stop after stuckticks) 630,cancelnpcwalk,1,0 # Cancel walknpc, pathfindnpcto, or npcchasesnpc command (npc) 631,playerissuspended,0 # return true if "suspend player" is active 632,npcsaresuspended,0 # return true if "suspend NPCs" is active 633,obstructionissuspended,0 # return true if "suspend obstruction" is active 634,herowallsaresuspended,0 # return true if "suspend hero walls" is active 635,npcwallsaresuspended,0 # return true if "suspend NPC walls" is active 636,caterpillarissuspended,0 # return true if "suspend caterpillar" is active 637,doorsaresuspended,0 # return true if "suspend doors" is active 638,randomenemiesaresuspended,0 # return true if "suspend random enemies" is active 639,boxadvanceissuspended,0 # return true if "suspend box advance" is active 640,overlayissuspended,0 # return true if "suspend overlay" is active 641,mapmusicissuspended,0 # return true if "suspend map music" is active 642,timersaresuspended,0 # return true if "suspend timers" is active 643,getscreenwidth,0 # return the x resolution of the screen 644,getscreenheight,0 # return the y resolution of the screen 645,setscreenresolution,2,0,0 # change the x,y resolution of the screen 646,mouserelease,1,0 # returns true if the specified button is was just released (button) 647,_cancelrunfast,0 # cancels the -runfast command-line option, if it is active. 648,_runfast,0 # speeds up as if the -runfast command-line option is active. 649,multdiv,3,0,0,0 # calculate int(float(a)*b/c), with rounding and clamping 650,setrectrawborder,2,0,-1 # set a rectangle slice to use a specific border sprite instead of the border for its style 651,getrectrawborder,1,0 # set a rectangle slice to use a specific border sprite instead of the border for its style 652,cloneslice,2,0,1 # Copy a slice (handle, recurse) 653,resetformation,1,0 # resets any scripted modifications to a battle formation 654,resetformationslot,2,0,0 # resets scripted modifications to a specific slot in a battle formation 655,sliceismaplayer,1,0 # Check slice type 656,npcreferencefromslice,1,0 # Return the NPC reference for an NPC slice, or else 0 657,herorankfromslice,1,0 # Return the hero rank for a hero slice, or else -1 658,slicetype,1,0 # Returns a slicetype:* constant 659,_asserteq,4,0,0,0,0 # Used in the macro expansion of assert(x==y) 660,savescreenshot,0 # Save a screenshot 661,sliceisline,1,0 # Check slice type 662,createline,3,0,0,0 # Create line slice (w, h, color) 663,getlinecolor,1,0 # Line slice color 664,setlinecolor,2,0,0 # Set line slice color 665,forcemountvehicle,1,0 # Mount a vehicle without checking mounting permissions first 666,currentvehicleid,0 # return vehicle id, or -1 if not riding 667,currentvehiclenpc,0 # return npc reference to vehicle, or 0 if not riding 668,pathfindheroto,4,0,0,0,0 # Make a hero pathfind to a specific position (hero, tile x, tile y, stop after stuckticks) 669,herochasesnpc,4,0,0,0,0 # Make a hero chase an NPC (hero, target npc, stop when reached, stop after stuckticks) 670,cancelherowalk,1,0 # Cancel walkhero, pathfindheroto, or herochasesnpc command (hero) 671,menuitemselectable,1,0 # Whether selectable and not hidden 672,menuitemdisabled,1,0 # Whether disabled 673,menuitemvisible,1,0 # Isn't hidden 674,setlastsaveslot,1,-1 # Set return value of lastsaveslot (0-1000) 675,speakingnpc,0 # NPC reference for the NPC which is currently talking 676,keypress,2,0,0 # check for new or keyrepeat key-press event, returns bool (scancode, joystick num) 677,newkeypress,2,0,0 # check for new key-press event, returns bool (scancode, joystick num) 678,getjoystickname,2,0,0 # Joystick name (string, joynum) 679,joystickbuttoncount,1,0 # Number of buttons a joystick has (might be 0 if not known) (joynum) 680,joystickaxiscount,1,0 # Number of axes a joystick has (joynum) 681,joystickhatcount,1,0 # Number of hats (eg dpads) a joystick has (joynum) 682,findcolor,4,0,0,0,0 # Index of nearest match in palette (r, g, b, searchstart) 683,overridetickmilliseconds,1,0 # change game tick speed 684,canceloverridetickmilliseconds,0 # revert tick speed back to the game default 685,suspendtextboxcontrols,0 # Prevents player from using choiceboxes 686,resumetextboxcontrols,0 # Reverses suspendtextboxcontrols 687,textboxcontrolsaresuspended,0 # Return true if "suspend textbox control" is active 688,menuitemcount,1,0 # Number of menu items in a menu, including invisible ones 689,visiblemenuitemcount,1,0 # Number of visible menu items in a menu 690,replacesubstring,5,-1,-1,-1,-1,0 # Replace text in a string (in string ID, replace what ID, with what ID, max replacements, case insensitive) 691,decodetrigger,1,0 # (Undocumented) Decode a script trigger to a script ID. Script IDs and 0 passed through. Missing scripts return 0. 692,getscancodename,3,0,0,1 # Get the name of a scancode in a string (string id, scancode, long name) 693,getheroslicebyslot,1,0 # Get the slice representing a hero walkabout 694,heroslotfromslice,1,0 # Return the hero party slot for a hero slice, or else -1 695,getopacity,1,0 # Return opacity percentage, 0-100 (slice) 696,setopacity,2,0,100 # Set slice opacity 0-100 (blendable slice, percent) 697,getblendingenabled,1,0 # True or false (slice) 698,setblendingenabled,2,0,1 # Blending (blendable slice, true/false) 699,getblendmode,1,0 # Get slice blend mode: blend:normal/blend:add/blend:multiply (slice) 700,setblendmode,2,0,0 # Set blend mode (blendable slice, blendmode) 701,getrectopacity,1,0 # Alias to "get rect fuzziness" (slice) 702,setrectopacity,2,0,50 # Set rect bg to transparent and set its opacity (slice, opacity) 703,settimerargs,-1 # Set the arguments a timer will pass to its triggered script (id, args...) 704,expandstringsinslices,2,0,0 # Expand all codes like ${H0} or ${V0} in text slices starting with a parent slice and including all child slices 705,heroischasing,1,0 # If hero is chasing an NPC, return the NPC reference 706,npcischasing,1,0 # If npc is chasing another NPC, return NPC reference 707,maxmapid,0 # Return id number of the last map 708,getslicelookupname,3,0,0,1 # Get the name of a lookup code (string id, code id, use default name) 709,getnpcpool,1,0 # given an NPC reference, return its pool number 710,gracefullydismountvehicle,0 # Dismount a vehicle, but cleanly 711,readfoemap,2,0,0 # Read a formation set (0-255) from the foe map (x, y) 712,getenemyname,2,0,0 # Get enemy name (enemyid, stringid) 713,setenemyname,2,0,0 # Change the name of an enemy (enemyid, stringid) 714,breakpoint,0 # Enter the script debugger 715,deleteherobyslot,1,0 # Delete a hero by slot number 716,getuicolor,2,0,0 # Translate a ui: constant to master pal index (color code, autotoggle) 717,setuicolor,2,0,0 # Change UI color temporarily (color code, pal index) 718,getboxstylecolor,1,0 # Box background color (box style) 719,getboxstyleedgecolor,1,0 # Box edge color (box style) 720,getboxstyleborder,1,0 # border:line or box border spriteset (box style) 721,getchildautosort,1,0 # Get slice children autosort setting, an autosort: constant (slice) 722,setchildautosort,2,0,0 # Set slice children autosort setting (slice, autosort) 723,lastlayerid,0 # The ID number of the last map layer that exists in the current map 724,layeridunderwalkabouts,0 # Get ID number of map layer under the walkabouts in the current map 725,getglobalsoundvolume,0 # Get the sfx volume setting (0-255) 726,setglobalsoundvolume,1,192 # Get sfx volume (0-255); default to 75% (default initial sfx volume) 727,healparty,1,-2 # Restore active party's HP & MP ([revive dead heroes]) 728,setheroautobattle,2,0,0 # Change a hero's auto battle setting 729,getheroautobattle,1,0 # Return true if the hero is set to auto battle 730,resizeextra,2,0,3 # Resize an object's 'extra' array (handle, length) 731,extralength,1,0 # The length of an object's 'extra' array (handle) 732,appendextra,2,0,0 # Append to an object's 'extra' array (handle, value) 733,lookupnextslice,3,0,0,0 # Next slice with lookup code (lookupcode, current, root) 734,nextsliceintree,3,0,0,1 # Next slice (current, root, visit children) 735,windowisfocused,0 # The game's window is the active one 736,showvalueofinternal,-1 # "show value of" is translated to this 737,resetenemydata,2,0,0 # Reset one element of an enemy's data (enemy id, data index) 738,resetenemyname,1,0 # Reset enemy name to original (enemy id) 739,getextra,2,0,0 # Index an object's 'extra' array (handle, index) 739,getmenuitemextra,2,0,0 # Used to be a script 740,setextra,3,0,0,0 # Set element of an object's 'extra' array (handle, index, value) 740,setmenuitemextra,3,0,0,0 # Used to be a script 741,herouseslevelmp,1,0 # Returns true if the hero uses level mp 742,getzone,1,0 # Create a zone handle (zone id) 743,getrectfuzzyzoom,1,0 # Get fuzzy zoom (slice) 744,setrectfuzzyzoom,2,0,1 # Set fuzzy zoom >= 1 (slice, zoom) 745,getrectstationarypattern,1,0 # Get whether fuzzy pattern is stationary (slice) 746,setrectstationarypattern,2,0,1 # Set whether fuzzy pattern is stationary (slice, bool) 747,keypresstime,2,0,0 # How long a key has been down, in milliseconds (scancode, player) 748,randomchoice,-1 # Return one of the args, randomly 749,getstatname,2,0,0 # Get the name of a stat, register, or "" if invalid ID (string id, stat) 750,suspendwalkabouts,0 # Suspend hero/NPC movement and logic 751,resumewalkabouts,0 # Undo suspendwalkabouts 752,walkaboutsaresuspended,0 # suspendwalkabouts called 753,forwardx,1,0 # Tile X coord in front of hero (hero rank) 754,forwardy,1,0 # Tile Y coord in front of hero (hero rank) 755,getattackextra,2,0,0 # get attack extra data (attack id + 1, 0 - 2) 756,pathfindintoextraasnpc,9,0,0,0,0,0,0,0,0,0 # pathfind, then store the results in extra data (handle, npcref, startx, starty, destx, desty, maxsearch, append, skipstart) 757,pathfindintoextraashero,8,0,0,0,0,0,0,0,0 # pathfind, then store the results in extra data (handle, startx, starty, destx, desty, maxsearch, append, skipstart) 758,insertextra,3,0,0,0 # insert a new extra value at a specific index (handle, index, value) 759,deleteextra,2,0,0 # Delete an element from an extra array, returns the deleted value (handle, index) 760,deleteextrarange,3,0,0,0 # Delete several elements of a slice at once (handle, first index, last index) 761,isshopbuymenuempty,1,0 # Is the "Buy" menu empty? (shop id) 762,isshophiremenuempty,1,0 # Is the "Hire" menu empty? (shop id) 763,innscreen,2,0,0 # Open the Inn screen for a specific price (price, skip_fade) 764,readenvironment,2,0,0 # (Console only) Read a platform info string (deststr, keystr) 765,xboxrequestaccountpicker,0# (Console only) 766,ps5startstory,0 # (Console only) 767,ps5endstory,0 # (Console only) 768,setrichpresence,2,0,-1 # (Console/Steam) Set the Friends list status (token_name strid, substitution strid) 769,findextra,3,0,0,0 # Return index of a value in an extra array, or -1 (handle, value, startindex) #770 unused #771 unused #772 unused 773,playstationcontroller,1,0 # The specified controller is a playstation-style one 774,xboxcontroller,1,0 # The specified controller is an xbox-style one 775,nintendocontroller,1,0 # The specified controller is a nintendo-style one # Don't forget to update maxScriptCmdID in const.bi when adding new commands end #-------------------------------------------------------------------------- # soft coded functions script,walkherotoX,hsd:who,hsd:n,begin if (hsd:n<>heroX(hsd:who)) then(walk hero(hsd:who,east,hsd:n--heroX(hsd:who))) end script,walkherotoY,hsd:who,hsd:n,begin if (hsd:n<>heroY(hsd:who)) then(walk hero(hsd:who,south,hsd:n--heroY(hsd:who))) end script,walkNPCtoX,hsd:who,hsd:n,begin if (hsd:n<>NPCX(hsd:who)) then(walk NPC(hsd:who,east,hsd:n--NPCX(hsd:who))) end script,walkNPCtoY,hsd:who,hsd:n,begin if (hsd:n<>NPCY(hsd:who)) then(walk NPC(hsd:who,south,hsd:n--NPCY(hsd:who))) end script,getNPCspeed,hsd:who,begin return(readNPC(hsd:who,NPCstat:movespeed)) end script,setNPCspeed,hsd:who,hsd:newspeed=4,begin alterNPC(hsd:who,NPCstat:movespeed,hsd:newspeed) end script, npc copy number, hsd:npc, begin variable(hsd:id, hsd:copy, hsd:ref) hsd:id := get NPC ID(hsd:npc) if (hsd:id < 0) then (exit returning (-1)) # No such NPC if (hsd:npc >= 0) then (exit returning (0)) # It's an NPC ID, not an NPC reference! ID refers to copy 0 # This works too, but kind of risky #while(npc reference(hsd:id, hsd:copy, true) <> hsd:npc) do (hsd:copy += 1) while(true) do ( hsd:ref := npc reference(hsd:id, hsd:copy, true) if (hsd:ref == hsd:npc) then (break) if (hsd:ref == 0) then (exit returning (-1)) hsd:copy += 1 ) return (hsd:copy) end script, create global npc, hsd:id, hsd:x=0, hsd:y=0, hsd:direction=2, begin exit returning(create npc(hsd:id, hsd:x, hsd:y, hsd:direction, pool:global)) end script, global npc reference, hsd:id, hsd:copy=0, hsd:allow disabled=0, begin exit returning(npc reference(hsd:id, hsd:copy, hsd:allow disabled, pool:global)) end # Alias to above script, global npc, hsd:id, hsd:copy=0, hsd:allow disabled=0, begin exit returning(npc reference(hsd:id, hsd:copy, hsd:allow disabled, pool:global)) end script,swapbyname,hsd:hero1,hsd:hero2,begin hsd:hero1:=findhero(hsd:hero1) hsd:hero2:=findhero(hsd:hero2) if (hsd:hero1==-1,or,hsd:hero2==-1) then (return(false)) else (return(true),swapbyposition(hsd:hero1,hsd:hero2)) end script,renamehero,hsd:who=0,begin variable(hsd:slot, hsd:tmp) hsd:slot:=findhero(hsd:who) if(hsd:slot>=0) then(return(renameherobyslot(hsd:slot))) else( hsd:tmp := hsd:save string(99) script error(string sprintf(99, $99="rename hero: no hero with id %d", hsd:who), true) hsd:restore string(99, hsd:tmp) ) end # this exploits an undocumented feature of getherostat. Don't use the # same method to set the hero level (use setherolevel instead) script,getherolevel,hsd:who=0,begin return(getherostat(hsd:who,12,currentstat)) end script, gainherostat, hsd:who, hsd:stat, hsd:change, hsd:resetcurrent=false, begin variable(hsd:oldcur, hsd:oldmax, hsd:newcur, hsd:newmax, hsd:newbase, hsd:cap) if (hsd:resetcurrent == false) then ( hsd:oldcur := getherostat(hsd:who, hsd:stat, currentstat) hsd:oldmax := getherostat(hsd:who, hsd:stat, maximumstat) ) hsd:newbase := getherostat(hsd:who, hsd:stat, basestat) + hsd:change setherostat(hsd:who, hsd:stat, hsd:newbase, basestat) hsd:newmax := getherostat(hsd:who, hsd:stat, maximumstat) if (hsd:resetcurrent || hsd:oldmax <= 0) then ( # Set current to new max hsd:newcur := hsd:newmax ) else ( # Increase current proportional to change in max # Have to be careful about integer overflow. Each stat can be any int32 #hsd:newcur := hsd:oldcur * hsd:newmax / hsd:oldmax hsd:newcur := multdiv(hsd:oldcur, hsd:newmax, hsd:oldmax) ) # Enforce stat caps on current. No need to do this for base/max, as base isn't # capped, and max is autocapped when base is modified. hsd:cap := get hero stat cap(hsd:stat) if (hsd:cap && hsd:newcur > hsd:cap) then (hsd:newcur := hsd:cap) setherostat(hsd:who, hsd:stat, hsd:newcur, currentstat) return(hsd:newmax) end script,autosave,begin if (lastsaveslot==0) then(return(savemenu)) else(saveinslot(lastsaveslot),return(lastsaveslot)) end script,stringtoglobals,hsd:stringID,hsd:start,hsd:length,begin variable(hsd:temp,hsd:padding) if (hsd:stringID>=0,and,hsd:stringID<=maximum string id) then( if (hsd:length>=1) then( if (hsd:length+hsd:start>maximum global id) then(hsd:length:=maximum global id--hsd:start) hsd:padding:=hsd:length--stringlength(hsd:stringID) hsd:length:=stringlength(hsd:stringID) for (hsd:temp,1,hsd:length) do( writeglobal(hsd:start,asciifromstring(hsd:stringID,hsd:temp)) hsd:start+=1 ) for (hsd:temp,hsd:start,hsd:start+hsd:padding--1) do( writeglobal(hsd:temp,256) ) ) ) end script,globalstostring,hsd:stringID,hsd:start,hsd:length,begin variable(hsd:temp) variable(hsd:temp2) if (hsd:stringID>=0,and,hsd:stringID<=maximum string id) then( clearstring(hsd:stringID) if (hsd:length>=1) then( if (hsd:length+hsd:start>maximum global id) then(hsd:length:=maximum global id--hsd:start) for (hsd:temp,1,hsd:length) do( hsd:temp2:=readglobal(hsd:start+(hsd:temp--1)) if (hsd:temp2>=0,and,hsd:temp2<=255) then(appendascii(hsd:stringID,hsd:temp2)) ) ) ) end script,showstringat,hsd:stringID,hsd:x=0,hsd:y=0,begin setstringbit(hsd:stringID,0,1) positionstring(hsd:stringID,hsd:x,hsd:y) end script,centerstringat,hsd:stringID,hsd:x=-654321,hsd:y=-654321,begin if(hsd:x == -654321) then(hsd:x := get screen width / 2) if(hsd:y == -654321) then(hsd:y := get screen height / 2) setstringbit(hsd:stringID,0,1) positionstring(hsd:stringID,hsd:x--(stringlength(hsd:stringID)*4),hsd:y) end script,hidestring,hsd:stringID,begin setstringbit(hsd:stringID,0,0) end script,stringstyle,hsd:stringID,hsd:style=0,begin setstringbit(hsd:stringID,1,hsd:style) end script,stringisvisible,hsd:stringID,begin return(getstringbit(hsd:stringID,0)) end # Internal functions, do not use # To get around the 100 string limitation... script, hsd:save string, hsd:id, begin variable (hsd:sl) hsd:sl := create text set slice visible(hsd:sl, false) set slice text(hsd:sl, hsd:id) clear string(hsd:id) return (hsd:sl) end script, hsd:restore string, hsd:id, hsd:saved, begin get slice text(hsd:id, hsd:saved) free slice(hsd:saved) end # Improvement (but which requires enableinputtext) # script, last ascii, begin # variable (hsd:saved) # hsd:saved := hsd:savestring(0) # get input text(0) # if (string length(0)) then ( # return (ascii from string(0, 1)) # ) # hsd:restore string(0, hsd:saved) # end script, last ascii, begin variable(hsd:code, hsd:shift) hsd:shift := keyispressed(key:shift) if(keyval(30) >> 1) then (hsd:code := 65) #A... if(keyval(48) >> 1) then (hsd:code := 66) if(keyval(46) >> 1) then (hsd:code := 67) if(keyval(32) >> 1) then (hsd:code := 68) if(keyval(18) >> 1) then (hsd:code := 69) if(keyval(33) >> 1) then (hsd:code := 70) if(keyval(34) >> 1) then (hsd:code := 71) if(keyval(35) >> 1) then (hsd:code := 72) if(keyval(23) >> 1) then (hsd:code := 73) if(keyval(36) >> 1) then (hsd:code := 74) if(keyval(37) >> 1) then (hsd:code := 75) if(keyval(38) >> 1) then (hsd:code := 76) if(keyval(50) >> 1) then (hsd:code := 77) if(keyval(49) >> 1) then (hsd:code := 78) if(keyval(24) >> 1) then (hsd:code := 79) if(keyval(25) >> 1) then (hsd:code := 80) if(keyval(16) >> 1) then (hsd:code := 81) if(keyval(19) >> 1) then (hsd:code := 82) if(keyval(31) >> 1) then (hsd:code := 83) if(keyval(20) >> 1) then (hsd:code := 84) if(keyval(22) >> 1) then (hsd:code := 85) if(keyval(47) >> 1) then (hsd:code := 86) if(keyval(17) >> 1) then (hsd:code := 87) if(keyval(45) >> 1) then (hsd:code := 88) if(keyval(21) >> 1) then (hsd:code := 89) if(keyval(44) >> 1) then (hsd:code := 90)#...Z if(keyval(2) >> 1) then (if(hsd:shift) then (hsd:code :=33) else (hsd:code :=49)) # 1... if(keyval(3) >> 1) then (if(hsd:shift) then (hsd:code :=64) else (hsd:code :=50)) if(keyval(4) >> 1) then (if(hsd:shift) then (hsd:code :=35) else (hsd:code :=51)) if(keyval(5) >> 1) then (if(hsd:shift) then (hsd:code :=36) else (hsd:code :=52)) if(keyval(6) >> 1) then (if(hsd:shift) then (hsd:code :=37) else (hsd:code :=53)) if(keyval(7) >> 1) then (if(hsd:shift) then (hsd:code :=94) else (hsd:code :=54)) if(keyval(8) >> 1) then (if(hsd:shift) then (hsd:code :=38) else (hsd:code :=55)) if(keyval(9) >> 1) then (if(hsd:shift) then (hsd:code :=42) else (hsd:code :=56)) if(keyval(10) >> 1) then (if(hsd:shift) then (hsd:code :=40) else (hsd:code :=57)) if(keyval(11) >> 1) then (if(hsd:shift) then (hsd:code :=41) else (hsd:code :=48)) # ...0 if(keyval(41) >> 1) then (if(hsd:shift) then (hsd:code :=126) else (hsd:code :=96)) # ` ~ if(keyval(12) >> 1) then (if(hsd:shift) then (hsd:code :=95) else (hsd:code :=45)) # - _ if(keyval(13) >> 1) then (if(hsd:shift) then (hsd:code := 43) else (hsd:code := 61)) # = + if(keyval(26) >> 1) then (if(hsd:shift) then (hsd:code := 123) else (hsd:code := 91)) # [ { if(keyval(27) >> 1) then (if(hsd:shift) then (hsd:code := 125) else (hsd:code := 93)) # ] } if(keyval(39) >> 1) then (if(hsd:shift) then (hsd:code := 58) else (hsd:code := 59)) # ; : if(keyval(40) >> 1) then (if(hsd:shift) then (hsd:code := 34) else (hsd:code := 39)) # ' " if(keyval(51) >> 1) then (if(hsd:shift) then (hsd:code := 60) else (hsd:code := 44)) # , < if(keyval(52) >> 1) then (if(hsd:shift) then (hsd:code := 62) else (hsd:code := 46)) # . > if(keyval(53) >> 1) then (if(hsd:shift) then (hsd:code := 63) else (hsd:code := 47)) # / ? if(keyval(43) >> 1) then (if(hsd:shift) then (hsd:code := 124) else (hsd:code := 92)) # \ | if(keyval(102) >> 1) then (hsd:code := 47) # Num / if(keyval(55) >> 1) then (hsd:code := 42) # Num * if(keyval(71) >> 1) then (hsd:code := 55) # Num 7 if(keyval(72) >> 1) then (hsd:code := 56) # Num 8 if(keyval(73) >> 1) then (hsd:code := 57) # Num 9 if(keyval(74) >> 1) then (hsd:code := 45) # Num - if(keyval(75) >> 1) then (hsd:code := 52) # Num 4 if(keyval(76) >> 1) then (hsd:code := 53) # Num 5 if(keyval(77) >> 1) then (hsd:code := 54) # Num 6 if(keyval(78) >> 1) then (hsd:code := 43) # Num + if(keyval(79) >> 1) then (hsd:code := 49) # Num 1 if(keyval(80) >> 1) then (hsd:code := 50) # Num 2 if(keyval(81) >> 1) then (hsd:code := 51) # Num 3 if(keyval(82) >> 1) then (hsd:code := 48) # Num 0 if(keyval(83) >> 1) then (hsd:code := 46) # Num . if(keyval(57) >> 1) then (hsd:code := 32) #Space if(hsd:code <= 90 && hsd:code >= 65) then, begin if(hsd:shift == false) then (hsd:code += 32) end return (hsd:code) end script, input string, hsd:str, hsd:max len=-1, hsd:useexist=0, hsd:center=1, hsd:positionx=-654321, hsd:positiony=-654321, begin variable(hsd:done, hsd:key, hsd:show, hsd:tmp str, hsd:saved, hsd:enable input) hsd:enable input := input text enabled enable input text (true) if(hsd:useexist) else(clear string(hsd:str)) trim string(hsd:str,1,hsd:maxlen) hsd:show:=(string is visible(hsd:str) == false) if(hsd:max len < 0) then (hsd:max len := get screen width / 8) if(hsd:positiony <> -654321 || hsd:show) then( if(hsd:positionx == -654321) then(hsd:positionx := get screen width / 2) if(hsd:positiony == -654321) then(hsd:positiony := get screen height / 2 + 10) if(hsd:center) then( center string at(hsd:str,hsd:positionx,hsd:positiony) )else( show string at(hsd:str,hsd:positionx,hsd:positiony) ) )else( hsd:positionx := string x(hsd:str) hsd:positiony := string y(hsd:str) ) hsd:tmp str := hsd:str,xor,1 # A string ID different to hsd:str hsd:saved := hsd:save string(hsd:tmp str) while(not(hsd:done)) do, begin if(hsd:center) then(center string at(hsd:str,hsd:positionx,hsd:positiony)) wait if(keyval(key:Enter)>1 || keyval(key:Numpad Enter)>1) then(hsd:done:=true, return(true)) else( if(keyval(key:Backspace)>1) then(delete char(hsd:str,string length(hsd:str))) get input text(hsd:tmp str) concatenate strings(hsd:str, hsd:tmp str) trim string(hsd:str, 1, hsd:max len) while(key is pressed(key:Esc)) do, begin # Wait for the player to let go of Esc before finishing hsd:done:=true return(false) if(player is suspended) then(wait) # Esc will be ignored else(suspendplayer, wait, resumeplayer) # Ignore the Esc, don't bring up the menu end ) end enable input text (hsd:enable input) hsd:restore string(hsd:tmp str,hsd:saved) if(hsd:show) then(hide string(hsd:str)) end script,currentdisplaytile,hsd:tile,hsd:layernumber=0,begin if(hsd:tile>=160) then( return(animationstarttile(hsd:tile,hsd:layernumber)+gettileanimationoffset((hsd:tile--160)/48,hsd:layernumber)) ) else(return(hsd:tile)) end script, wait for sound, hsd:soundid, begin while(sound is playing(hsd:soundid)) do(wait(1)) end #-------------------------------------------------------------------------- #read/write enemy wrappers #getenemyname and setenemyname used to be scripts here script,getenemystat,hsd:enemyID,hsd:stat,begin return(readenemydata(hsd:enemyID,hsd:stat+62)) end script,setenemystat,hsd:enemyID,hsd:stat,hsd:value,begin writeenemydata(hsd:enemyID,hsd:stat+62,hsd:value) end script,resetenemystat,hsd:enemyID,hsd:stat,begin resetenemydata(hsd:enemyID,hsd:stat+62) end #get/set enemy appearance are now simply wrappers. too much confusion to remove them now script,getenemyappearance,hsd:enemyID,hsd:appearance,begin return(readenemydata(hsd:enemyID,hsd:appearance)) end script,setenemyappearance,hsd:enemyID,hsd:appearance,hsd:value,begin writeenemydata(hsd:enemyID,hsd:appearance,hsd:value) end #-------------------------------------------------------------------------- # read/write general wrappers script,set victory music,hsd:song,begin write general(3,hsd:song+1) end script,get victory music,begin return(read general(3)--1) end script,get death script,begin return(decode trigger(read general(42))) end script,get load script,begin return(decode trigger(read general(57))) end script,set load script,hsd:ID=0,begin write general(57,hsd:ID) end script,hsd:pref bit index,hsd:bitnum, begin if (hsd:bitnum >= 48) then ( return(222 + (hsd:bitnum--48)/16) # genBits3 ) else if (hsd:bitnum >= 16) then ( return(177 + (hsd:bitnum--16)/16) # genBits2 ) else ( return(101) # genBits ) end # See https://rpg.hamsterrepublic.com/ohrrpgce/GEN#General_bitsets for bitnum script,read preference bit,hsd:bitnum,begin variable(hsd:index) hsd:index := hsd:pref bit index(hsd:bitnum) hsd:bitnum := hsd:bitnum,mod,16 return((read general(hsd:index),and,2^hsd:bitnum)<>0) end script,write preference bit,hsd:bitnum,hsd:value=1,begin variable(hsd:index) hsd:index := hsd:pref bit index(hsd:bitnum) hsd:bitnum := hsd:bitnum,mod,16 if(hsd:value) then (hsd:value := 2^hsd:bitnum) write general(hsd:index, (read general(hsd:index),and,(-1--2^hsd:bitnum))+hsd:value) end script,set battle wait mode,hsd:bit=1,begin write preference bit(0, hsd:bit) end script,set caterpillar mode,hsd:bit=1,begin write preference bit(1, hsd:bit) end #@obsolete(set HP level up restore) script,set no HP level up restore,hsd:bit=1,begin write preference bit(2, hsd:bit) end #@obsolete(set MP level up restore) script,set no MP level up restore,hsd:bit=1,begin write preference bit(3, hsd:bit) end #@obsolete(set inn revive mode) script,set inn no revive mode,hsd:bit=1,begin write preference bit(4, hsd:bit) end script,set HP level up restore,hsd:bit=1,begin write preference bit(2, not(hsd:bit)) end script,set MP level up restore,hsd:bit=1,begin write preference bit(3, not(hsd:bit)) end script,set inn revive mode,hsd:bit=1,begin write preference bit(4, not(hsd:bit)) end script,set full hero swap mode,hsd:bit=1,begin write preference bit(5, hsd:bit) end #@obsolete(show battle ready meter) script,hide battle ready meter,hsd:bit=1,begin write preference bit(6, hsd:bit) end #@obsolete(show battle health meter) script,hide battle health meter,hsd:bit=1,begin write preference bit(7, hsd:bit) end script,show battle ready meter,hsd:bit=1,begin write preference bit(6, not(hsd:bit)) end script,show battle health meter,hsd:bit=1,begin write preference bit(7, not(hsd:bit)) end script,set debug keys disable,hsd:bit=1,begin write preference bit(8, hsd:bit) end script,set dead heroes gain experience,hsd:bit=1,begin write preference bit(19, hsd:bit) end script, set turn based battle mode,begin write general(192, 1) end script, get turn based battle mode,begin exit returning(read general(192) == 1) end script, set active time battle mode,begin write general(192, 0) end script, get active time battle mode,begin exit returning(read general(192) == 0) end script,set active battle pause for animations,hsd:bit=1,begin write preference bit(23, hsd:bit) end script,set capped hero stat,hsd:who,hsd:stat,hsd:value,hsd:stat type=current stat,begin variable(hsd:cap) if (hsd:stat type <> base stat) then ( hsd:cap := get hero stat cap(hsd:stat) if(hsd:cap>>0, and, hsd:cap<> 600) then(write general(85, 0)) else(write general(85, (hsd:newsize + 2) / 3 * 3 -- 1)) end script, extended scancodes enabled, begin return(read preference bit(24)) end script, get level cap, begin return(readgeneral(87)) end script, set level cap, hsd:cap, begin if(hsd:cap >= 0 && hsd:cap <= readgeneral(191)) then(writegeneral(87, hsd:cap)) end #-------------------------------------------------------------------------- # read/write gmap wrappers script,get map tileset,begin return(read gmap(0)) end script, get ambient music, begin return (read gmap(1) -- 1) end script, set ambient music, hsd:song=-1, begin write gmap(1,hsd:song + 1) if (hsd:song >= 0) then (play song (hsd:song)) else (if (hsd:song == -1) then (stop song)) end script,allow minimap,hsd:setting=1,begin write gmap(2,hsd:setting) end script,allow save anywhere,hsd:setting=1,begin write gmap(3,hsd:setting) end script,cancel map name display,begin write gmap(4,0) end script,set map edge mode,mode=0,hsd:tile=0,begin write gmap(5,mode) write gmap(6,hsd:tile) end script,get map edge mode,begin return(read gmap(5)) end script,set harm tile damage,hsd:damage=0,begin write gmap(9,hsd:damage) end script,set harm tile flash,hsd:colour=0,begin write gmap(10,hsd:colour) end script,get footoffset,begin return(read gmap(11)) end script,set footoffset,hsd:offset=0,begin write gmap(11,hsd:offset) end script,get instead of battle script,begin return (decode trigger(read gmap(13))) end script,set instead of battle script,hsd:ID=0,begin write gmap(13,hsd:ID) end script,get each step script,begin return (decode trigger(read gmap(14))) end script,set each step script,hsd:ID=0,begin write gmap(14,hsd:ID) end script,get on keypress script,begin return (decode trigger(read gmap(15))) end script,set on keypress script,hsd:ID=0,begin write gmap(15,hsd:ID) end script,draw npcs above heroes,hsd:setting=1,begin write gmap(16,hsd:setting) end script,get current map autorun script, begin return (read gmap(7)) end script,get current map autorun script argument, begin return (read gmap(8)) end #-------------------------------------------------------------------------- # read/write pass block wrappers script, read wall bit, hsd:x, hsd:y, hsd:bit, begin return ((read pass block(hsd:x, hsd:y), and, hsd:bit) <> 0) end script, write wall bit, hsd:x, hsd:y, hsd:bit, hsd:new value = true, begin variable (hsd:val) hsd:val := read pass block (hsd:x, hsd:y), and, (-1 -- hsd:bit) if (hsd:new value) then (hsd:val += hsd:bit) write pass block (hsd:x, hsd:y, hsd:val) end #-------------------------------------------------------------------------- # new wrappers/re-inventing of the wheel commands script, days of play, begin return(read general(51)) end script, hours of play, begin return(read general(52)) end script, minutes of play, begin return(read general(53)) end script, seconds of play, begin return(read general(54)) end script,set days of play,hsd:d, begin if(hsd:d >= 0) then (write general(51,hsd:d)) end script,set hours of play,hsd:h, begin if(hsd:h >= 0, and, hsd:h << 24) then (write general(52,hsd:h)) end script,set minutes of play,hsd:m, begin if(hsd:m >= 0, and, hsd:m << 60) then (write general(53,hsd:m)) end script,set seconds of play,hsd:s, begin if(hsd:s >= 0, and, hsd:s << 60) then (write general(54,hsd:s)) end #-------------------------------------------------------------------------- # menu wrappers script, first menu item, hsd:menuhandle, begin exit returning(menu item by slot(hsd:menuhandle, 0)) end script, last menu item, hsd:menuhandle, hsd:visible only=true, begin variable(hsd:idx) if (hsd:visible only) then ( hsd:idx := visible menu item count(hsd:menuhandle) -- 1 ) else ( hsd:idx := menu item count(hsd:menuhandle) -- 1 ) if (hsd:idx >= 0) then ( exit returning(menu item by slot(hsd:menuhandle, hsd:idx, false)) ) end script, wait for menu, hsd:menuhandle, begin while(menu is open(hsd:menuhandle)) do(wait(1)) end #-------------------------------------------------------------------------- # menu data wrappers script, get menu boxstyle, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 12)) end script, set menu boxstyle, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 12, hsd:n) end script, get menu textcolor, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 13)) end script, set menu textcolor, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 13, hsd:n) end script, get menu disabled textcolor, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 28)) end script, set menu disabled textcolor, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 28, hsd:n) end script, get menu max rows, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 14)) end script, set menu max rows, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 14, hsd:n) end script, get menu offset x, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 16)) end script, set menu offset x, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 16, hsd:n) end script, get menu offset y, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 17)) end script, set menu offset y, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 17, hsd:n) end script, get menu anchor x, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 18)) end script, set menu anchor x, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 18, hsd:n) end script, get menu anchor y, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 19)) end script, set menu anchor y, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 19, hsd:n) end script, get menu text align, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 20)) end script, set menu text align, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 20, hsd:n) end script, get menu min chars, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 21)) end script, set menu min chars, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 21, hsd:n) end script, get menu max chars, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 22)) end script, set menu max chars, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 22, hsd:n) end script, get menu border, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 23)) end script, set menu border, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 23, hsd:n) end script, get menu on close script, hsd:menuhandle, begin exit returning(decode trigger(read menu int(hsd:menuhandle, 24))) end script, set menu on close script, hsd:menuhandle, hsd:n=0, begin write menu int(hsd:menuhandle, 24, hsd:n) end script, get menu cancel button menu, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 25) -- 1) end script, set menu cancel button menu, hsd:menuhandle, hsd:n=-1, begin write menu int(hsd:menuhandle, 25, hsd:n + 1) end script, get menu item spacing, hsd:menuhandle, begin exit returning(read menu int(hsd:menuhandle, 27) -- 1) end script, set menu item spacing, hsd:menuhandle, hsd:n=-1, begin write menu int(hsd:menuhandle, 27, hsd:n + 1) end script, get menu bit, hsd:handle, hsd:bit, begin variable(hsd:n) hsd:n := read menu int(hsd:handle, 15) if(hsd:n,and,2^hsd:bit) then(exit returning(true)) exit returning(false) end script, set menu bit, hsd:handle, hsd:bit, hsd:value=1, begin variable(hsd:n) hsd:n := read menu int(hsd:handle, 15) if(hsd:value) then(hsd:n := hsd:n, or, 2^hsd:bit) else(hsd:n := hsd:n, and, (-1, xor, 2^hsd:bit)) write menu int(hsd:handle, 15, hsd:n) end #-------------------------------------------------------------------------- # menu item data wrappers script, set menu item, hsd:handle, hsd:type=0, hsd:subtype=0, hsd:tag1=0, hsd:tag2=0, hsd:stag=0, hsd:togtag=0, begin write menu item int(hsd:handle, 22, hsd:type) write menu item int(hsd:handle, 23, hsd:subtype) write menu item int(hsd:handle, 24, hsd:tag1) write menu item int(hsd:handle, 25, hsd:tag2) write menu item int(hsd:handle, 26, hsd:stag) write menu item int(hsd:handle, 27, hsd:togtag) end script, set menu item type, hsd:handle, hsd:n=0, begin write menu item int(hsd:handle, 22, hsd:n) end script, get menu item type, hsd:handle, begin exit returning(read menu item int(hsd:handle, 22)) end script, set menu item subtype, hsd:handle, hsd:n=0, begin write menu item int(hsd:handle, 23, hsd:n) end script, get menu item subtype, hsd:handle, begin exit returning(read menu item int(hsd:handle, 23)) end script, set menu item tag, hsd:handle, hsd:n=0, hsd:whichtag=1, begin if(hsd:whichtag == 1) then(write menu item int(hsd:handle, 24, hsd:n)) if(hsd:whichtag == 2) then(write menu item int(hsd:handle, 25, hsd:n)) end script, get menu item tag, hsd:handle, hsd:whichtag=1, begin if(hsd:whichtag == 1) then(exit returning(read menu item int(hsd:handle, 24))) if(hsd:whichtag == 2) then(exit returning(read menu item int(hsd:handle, 25))) end script, set menu item settag, hsd:handle, hsd:n=0, begin write menu item int(hsd:handle, 26, hsd:n) end script, get menu item settag, hsd:handle, begin exit returning(read menu item int(hsd:handle, 26)) end script, set menu item togtag, hsd:handle, hsd:n=0, begin write menu item int(hsd:handle, 27, hsd:n) end script, get menu item togtag, hsd:handle, begin exit returning(read menu item int(hsd:handle, 27)) end script, get menu item bit, hsd:handle, hsd:bit, begin variable(hsd:n) hsd:n := read menu item int(hsd:handle, 28) if(hsd:n,and,2^hsd:bit) then(exit returning(true)) exit returning(false) end script, set menu item bit, hsd:handle, hsd:bit, hsd:value=1, begin variable(hsd:n) hsd:n := read menu item int(hsd:handle, 28) if(hsd:value) then(hsd:n := hsd:n, or, 2^hsd:bit) else(hsd:n := hsd:n, and, (-1, xor, 2^hsd:bit)) write menu item int(hsd:handle, 28, hsd:n) end script, set menu item color, hsd:handle, hsd:n=0, begin write menu item int(hsd:handle, 32, hsd:n) end script, get menu item color, hsd:handle, begin exit returning(read menu item int(hsd:handle, 32)) end script, set menu item disabled color, hsd:handle, hsd:n=0, begin write menu item int(hsd:handle, 33, hsd:n) end script, get menu item disabled color, hsd:handle, begin exit returning(read menu item int(hsd:handle, 33)) end #-------------------------------------------------------------------------- # slice commands script, get npc sprite, hsd:npc, begin variable (hsd:sl, hsd:tmp) hsd:sl := get npc slice(hsd:npc) # If the NPC is tag-disabled it has no slice and we return 0; not an error. if (hsd:sl) then (return (lookup slice(sl:walkabout sprite component, hsd:sl))) end script, get hero sprite, hsd:rank, begin variable (hsd:sl) hsd:sl := get hero slice(hsd:rank) # If the caterpillar rank is empty we return 0; not an error. if (hsd:sl) then (return (lookup slice(sl:walkabout sprite component, hsd:sl))) end script, get hero sprite by slot, hsd:who, begin variable (hsd:sl) hsd:sl := get hero slice by slot(hsd:who) # If the slot is empty we return 0; not an error. if (hsd:sl) then (return (lookup slice(sl:walkabout sprite component, hsd:sl))) end script, load sprite, hsd:type, hsd:number, hsd:pal = -1, begin switch (hsd:type) do ( case(spritetype:hero) return(load hero sprite (hsd:number, hsd:pal)) case(spritetype:smallenemy) return(load small enemy sprite (hsd:number, hsd:pal)) case(spritetype:mediumenemy) return(load medium enemy sprite (hsd:number, hsd:pal)) case(spritetype:largeenemy) return(load large enemy sprite (hsd:number, hsd:pal)) case(spritetype:walkabout) return(load walkabout sprite (hsd:number, hsd:pal)) case(spritetype:weapon) return(load weapon sprite (hsd:number, hsd:pal)) case(spritetype:attack) return(load attack sprite (hsd:number, hsd:pal)) case(spritetype:border) return(load border sprite (hsd:number, hsd:pal)) case(spritetype:portrait) return(load portrait sprite (hsd:number, hsd:pal)) case(spritetype:backdrop) return(load backdrop sprite (hsd:number)) else ( variable(hsd:tmp) hsd:tmp := hsd:save string(99) script error(string sprintf(99, $99="load sprite(%d,%d,%d): invalid type %d", hsd:type, hsd:number, hsd:pal, hsd:type), true) hsd:restore string(99, hsd:tmp) ) ) end script, create sprite, hsd:type, hsd:number, hsd:pal = -1, begin return(load sprite(hsd:type, hsd:number, hsd:pal)) end script, replace sprite, hsd:sl, hsd:type, hsd:number, hsd:pal = -1, begin switch (hsd:type) do ( case(spritetype:hero) replace hero sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:smallenemy) replace small enemy sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:mediumenemy) replace medium enemy sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:largeenemy) replace large enemy sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:walkabout) replace walkabout sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:weapon) replace weapon sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:attack) replace attack sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:border) replace border sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:portrait) replace portrait sprite (hsd:sl, hsd:number, hsd:pal) case(spritetype:backdrop) replace backdrop sprite (hsd:sl, hsd:number) else ( variable(hsd:tmp) hsd:tmp := hsd:save string(99) script error(string sprintf(99, $99="replace sprite(%d,%d,%d): invalid type %d", hsd:type, hsd:number, hsd:pal, hsd:type), true) hsd:restore string(99, hsd:tmp) ) ) end script, load enemy sprite, hsd:size, hsd:number, hsd:pal = -1, begin if(hsd:size == EnemySize:small) then(return(load small enemy sprite(hsd:number, hsd:pal))) if(hsd:size == EnemySize:medium) then(return(load medium enemy sprite(hsd:number, hsd:pal))) if(hsd:size == EnemySize:large) then(return(load large enemy sprite(hsd:number, hsd:pal))) end script, replace enemy sprite, hsd:ID, hsd:size, hsd:number, hsd:pal = -1, begin if(hsd:size == EnemySize:small) then(return(replace small enemy sprite(hsd:ID, hsd:number, hsd:pal))) if(hsd:size == EnemySize:medium) then(return(replace medium enemy sprite(hsd:ID, hsd:number, hsd:pal))) if(hsd:size == EnemySize:large) then(return(replace large enemy sprite(hsd:ID, hsd:number, hsd:pal))) end #### first child/next sibling wrappers script, first child of type, hsd:parent, hsd:type, begin variable(hsd:sl) hsd:sl := first child(hsd:parent) if(hsd:sl==0) then(exit returning(hsd:sl)) if(slice type(hsd:sl) == hsd:type) then(exit returning(hsd:sl)) exit returning(next sibling of type(hsd:sl, hsd:type)) end script, next sibling of type, hsd:sl, hsd:type, begin hsd:sl := next sibling(hsd:sl) while(hsd:sl) do ( if(slice type(hsd:sl) == hsd:type) then(exit returning(hsd:sl)) hsd:sl := next sibling(hsd:sl) ) exit returning(hsd:sl) end script, first container child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:container)) end script, next container sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:container)) end script, first rect child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:rect)) end script, next rect sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:rect)) end script, first sprite child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:sprite)) end script, next sprite sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:sprite)) end script, first text child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:text)) end script, next text sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:text)) end script, first ellipse child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:ellipse)) end script, next ellipse sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:ellipse)) end script, first grid child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:grid)) end script, next grid sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:grid)) end script, first scroll child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:scroll)) end script, next scroll sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:scroll)) end script, first select child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:select)) end script, next select sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:select)) end script, first panel child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:panel)) end script, next panel sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:panel)) end script, first line child, hsd:parent, begin return(first child of type(hsd:parent, slicetype:line)) end script, next line sibling, hsd:sib, begin return(next sibling of type(hsd:sib, slicetype:line)) end #### More slice commands script, get selected child, hsd:parent, begin return(slice child(hsd:parent, get select slice index(hsd:parent))) end script, set selected child, hsd:parent, hsd:child, begin if (parent slice(hsd:child) <> hsd:parent) then ( variable(hsd:tmp) hsd:tmp := hsd:save string(99) script error($99="set selected slice: 2nd slice must be a child of the 1st", true) hsd:restore string(99, hsd:tmp) ) else ( set select slice index(hsd:parent, slice child index(hsd:child)) ) end script, free slice children, hsd:parent, begin variable(hsd:sl, hsd:next) hsd:sl := first child(hsd:parent) while(hsd:sl) do( hsd:next := next sibling(hsd:sl) free slice(hsd:sl) hsd:sl := hsd:next ) end script, realign slice, hsd:sl, hsd:halign, hsd:valign, hsd:hanchor=-1, hsd:vanchor=-1, begin set horiz align(hsd:sl, hsd:halign) set vert align(hsd:sl, hsd:valign) if(hsd:hanchor <> -1) then(set horiz anchor(hsd:sl, hsd:hanchor)) if(hsd:vanchor <> -1) then(set vert anchor(hsd:sl, hsd:vanchor)) end script, gently realign slice, hsd:sl, hsd:halign, hsd:valign, hsd:hanchor=-1, hsd:vanchor=-1, begin variable(hsd:oldx, hsd:oldy) hsd:oldx := slice screen x(hsd:sl) hsd:oldy := slice screen y(hsd:sl) realign slice(hsd:sl, hsd:halign, hsd:valign, hsd:hanchor, hsd:vanchor) set slice screen x(hsd:sl, hsd:oldx) set slice screen y(hsd:sl, hsd:oldy) end script, center slice, hsd:sl, begin realign slice(hsd:sl, 1, 1, 1, 1) end script, set slice screen x, hsd:sl, hsd:newx, begin variable(hsd:oldx, hsd:diff) hsd:oldx := slice screen x(hsd:sl) hsd:diff := hsd:newx -- hsd:oldx set slice x(hsd:sl, slice x(hsd:sl) + hsd:diff) end script, set slice screen y, hsd:sl, hsd:newy, begin variable(hsd:oldy, hsd:diff) hsd:oldy := slice screen y(hsd:sl) hsd:diff := hsd:newy -- hsd:oldy set slice y(hsd:sl, slice y(hsd:sl) + hsd:diff) end script, set slice size, hsd:sl, hsd:width, hsd:height, begin set slice width(hsd:sl, hsd:width) set slice height(hsd:sl, hsd:height) end script, put slice screen, hsd:sl, hsd:newx, hsd:newy, begin put slice(hsd:sl, slice x(hsd:sl) + hsd:newx -- slice screen x(hsd:sl), slice y(hsd:sl) + hsd:newy -- slice screen y(hsd:sl)) end script, move slice to screen pos, hsd:sl, hsd:newx, hsd:newy, hsd:ticks, begin variable(hsd:offsetx, hsd:offsety) hsd:offsetx := slice screen x(hsd:sl) -- slice x(hsd:sl) hsd:offsety := slice screen y(hsd:sl) -- slice y(hsd:sl) move slice to(hsd:sl, hsd:newx -- hsd:offsetx, hsd:newy -- hsd:offsety, hsd:ticks) end script, set padding, hsd:sl, hsd:newpadding, begin set left padding (hsd:sl, hsd:newpadding) set right padding (hsd:sl, hsd:newpadding) set top padding (hsd:sl, hsd:newpadding) set bottom padding(hsd:sl, hsd:newpadding) end script, reparent to npc, hsd:sl, hsd:npc, begin set parent(hsd:sl, lookup slice(sl:walkabout sprite component, get npc slice(hsd:npc))) end script, reparent to hero, hsd:sl, hsd:hero rank, begin set parent(hsd:sl, lookup slice(sl:walkabout sprite component, get hero slice(hsd:hero rank))) end script, gently reparent, hsd:sl, hsd:newparent, begin variable(hsd:oldx, hsd:oldy) hsd:oldx := slice screen x(hsd:sl) hsd:oldy := slice screen y(hsd:sl) set parent(hsd:sl, hsd:newparent) set slice screen x(hsd:sl, hsd:oldx) set slice screen y(hsd:sl, hsd:oldy) end script, lookup ancestor, hsd:code, hsd:sl, begin variable(hsd:par) hsd:par := slice parent(hsd:sl) while(hsd:par) do( if(get slice lookup(hsd:par) == hsd:code) then(exit(hsd:par)) hsd:par := slice parent(hsd:par) ) exit(0) end #-------------------------------------------------------------------------- # helper scripts script, dirX, dir, begin switch (dir) do ( #case (up, down) return (0) case (right) return (1) case (left) return (-1) ) end script, dirY, dir, begin switch (dir) do ( #case (left, right) return (0) case (down) return (1) case (up) return (-1) ) end #-------------------------------------------------------------------------- # script triggers define trigger,begin 0, script 1, plotscript end #-------------------------------------------------------------------------- # betweenable operators define operator,begin 20 ^ exponent 30,mod,modulus 30 / divide 30 * multiply 40 -- subtract 40 + add 50 == equal 50 <> notequal 50 << lessthan 50 >> greaterthan 50 < lessthan 50 > greaterthan 50 <= lessthanorequalto 50 >= greaterthanorequalto 60,xor,xor 60,and,and 60,or, or 65 && logand 70 || logor 70 ^^ logxor 80 := setvariable 80 += increment 80 -= decrement 80 $+ concatenatestrings 80 $= copystring end #-------------------------------------------------------------------------- # global constants define constant, begin 0,zero 1,one 2,two 3,three 4,four 5,five 6,six 7,seven 8,eight 9,nine 10,ten 0,false 1,true 0,off 1,on 0,north 1,east 2,south 3,west 0,up 2,down 3,left 1,right 0,me 0,none -1,autonumber 0,currentstat 1,maximumstat 2,basestat 0b1,northwall 0b10,eastwall 0b100,southwall 0b1000,westwall 0b10000,vehicleA 0b100000,vehicleB 0b1000000,harmtile 0b10000000,overheadtile # Special constants used only by 'move slice with wallchecking' # Each is euqal to the wall bits for two directions, shifted 24 bits left 0b0011 00000000 00000000 00000000,northeast corner 0b1001 00000000 00000000 00000000,northwest corner 0b0110 00000000 00000000 00000000,southeast corner 0b1100 00000000 00000000 00000000,southwest corner # Special zones 10000,zone:OneWayExit 0,inside battle 1,outside battle 2,hero portrait 0,NPCstat:picture 1,NPCstat:palette 2,NPCstat:movetype 0,NPCmovetype:standstill 1,NPCmovetype:wander 2,NPCmovetype:pace 3,NPCmovetype:rightturns 4,NPCmovetype:leftturns 5,NPCmovetype:randomturns 6,NPCmovetype:chaseyou 6,NPCmovetype:chaseyoumeandering 7,NPCmovetype:avoidyou 7,NPCmovetype:avoidyoumeandering 8,NPCmovetype:walkinplace 9,NPCmovetype:chaseyoudirect 10,NPCmovetype:avoidyoudirect 11,NPCmovetype:followwallsright 12,NPCmovetype:followwallsleft 13,NPCmovetype:followwallsrightstopsforothers 14,NPCmovetype:followwallsleftstopsforothers 15,NPCmovetype:chaseyoupathfinding 3,NPCstat:movespeed 4,NPCstat:displaytext 5,NPCstat:whenactivated 0,NPCwhenactivated:changedirection 1,NPCwhenactivated:faceplayer 2,NPCwhenactivated:donotfaceplayer 6,NPCstat:giveitem # Note: item num + 1 7,NPCstat:pushability 0,NPCpush:off 1,NPCpush:full 2,NPCpush:vertical 3,NPCpush:horizontal 4,NPCpush:uponly 5,NPCpush:rightonly 6,NPCpush:downonly 7,NPCpush:leftonly 8,NPCstat:activation 0,NPCactivation:use 1,NPCactivation:touch 2,NPCactivation:stepon 9,NPCstat:tag1 10,NPCstat:tag2 11,NPCstat:onetimeusetag 11,NPCstat:onetimeuseflag 12,NPCstat:script 13,NPCstat:scriptargument 14,NPCstat:vehicle 15,NPCstat:defaultmovementzone 16,NPCstat:defaultavoidancezone 17,NPCstat:ignorepassmap 18,NPCstat:pathfindingrule # Values for NPCstat:pathfindingrule 0,pathfinding:default 1,pathfinding:npcs obstruct 2,pathfinding:npcs ignored 0,color:red 1,color:green 2,color:blue 0,leftbutton 1,rightbutton 2,middlebutton -1,getcount 0,string:outline 1,string:flat # readenemydata constants 53,Enemy:Picture 54,Enemy:Palette 55,Enemy:PictureSize 0, EnemySize:small 1, EnemySize:medium 2, EnemySize:large 56,Enemy:Gold 57,Enemy:Experience 58,Enemy:Item 59,Enemy:ItemPercent 60,Enemy:RareItem 61,Enemy:RareItemPercent 17,Stealability -1, IsNotStealable 0, StealableOnce 1, StealableInfinity 18, StealableItem 19, StealableItemChance 20, StealableRareItem 21, StealableRareItemchance # end of readenemydata constants 0, Crop 1, Wrap 2, Defaulttile -1,party 0, extra 0 1, extra 1 2, extra 2 0b1,mapstate:mapsettings 0b10,mapstate:npclocations 0b100,mapstate:npcdefinitions 0b1000,mapstate:tilemap 0b10000,mapstate:passmap 0b100000,mapstate:zonemap #0b1000000,mapstate:foemap 0b110,mapstate:npcs 0b111000,mapstate:tiles 0b11111111,mapstate:all # Values for "draw NPCs above heroes" 0,layering:heroes over NPCs 1,layering:NPCS over heroes 2,layering:heroes and NPCs together 0,timer:stop #use in speed -1,timer:default #use in any -2,timer:gameover#use in trigger 0b1,timerflag:critical 0b10,timerflag:battle 0b100,timerflag:menu 0,menutype:label 0,menutype:caption 1,menutype:special 2,menutype:menu 3,menutype:textbox 4,menutype:script 0,menulabel:selectable 1,menulabel:disabled 2,menulabel:unselectable 2,menulabel:cant be selected 0,menuspecial:items 1,menuspecial:spells 2,menuspecial:status 3,menuspecial:equip 4,menuspecial:order 5,menuspecial:team 6,menuspecial:orderteam 7,menuspecial:map 8,menuspecial:save 9,menuspecial:load 10,menuspecial:quit 11,menuspecial:volume 12,menuspecial:mapalways 13,menuspecial:savealways 14,menuspecial:margins 15,menuspecial:purchases 16,menuspecial:windowed 17,menuspecial:fullscreen 18,menuspecial:musicvolume 19,menuspecial:soundvolume 0,menuitembit:hide when disabled #Renamed 0,menuitembit:hide if disabled 1,menuitembit:close menu when selected #Renamed 1,menuitembit:close menu when activated 2,menuitembit:skip close script 0,menubit:translucent box 1,menubit:never show scrollbar 2,menubit:allow gameplay 3,menubit:suspend player even if gameplay allowed 4,menubit:no box 5,menubit:no close 6,menubit:no controls 7,menubit:prevent main menu 8,menubit:advance text box when menu closes 9,menubit:highlight selection background 10,menubit:remember selection 11,menubit:clamp to screen bounds ### The align: constants are for menu alignment, NOT for slices! 0,align:center -1,align:left 1,align:right -1,align:top 1,align:bottom -1,tileset:default -1,song:silence -2,song:same as map -2,song:same as last map -1,any enemy 0,inv:max ### The edge: constants are for slice alignment, NOT for menus! 0,edge:left 1,edge:center 2,edge:right 0,edge:top 1,edge:middle 2,edge:bottom 1,slicetype:Special 2,slicetype:Container 3,slicetype:Rectangle 3,slicetype:Rect 4,slicetype:Sprite 5,slicetype:Text 6,slicetype:Map 7,slicetype:Grid 8,slicetype:Ellipse 9,slicetype:Scroll 10,slicetype:Select 11,slicetype:Panel 12,slicetype:Layout 13,slicetype:Line 0,spritetype:hero 1,spritetype:smallenemy 2,spritetype:mediumenemy 3,spritetype:largeenemy 4,spritetype:walkabout 5,spritetype:weapon 6,spritetype:attack 7,spritetype:border 8,spritetype:portrait 9,spritetype:backdrop 0,autosort:Off 1,autosort:Custom 2,autosort:Y 3,autosort:TopY 4,autosort:CenterY 5,autosort:BottomY -1,border:line -2,border:none -99,border:raw 0,trans:solid 1,trans:fuzzy 2,trans:hollow 3,trans:blend 0,blend:normal 1,blend:add 1,blend:additive 2,blend:multiply 0,hand:Attack A 1,hand:Attack B 0,dissolve:random scatter 1,dissolve:crossfade 2,dissolve:diagonal vanish 3,dissolve:sink into ground 4,dissolve:squash 5,dissolve:melt 6,dissolve:vaporise 6,dissolve:vaporize 6,dissolve:vapourise 7,dissolve:phase out 8,dissolve:squeeze 9,dissolve:shrink 10,dissolve:flicker 11,dissolve:shrink to center 12,dissolve:fade 13,dissolve:ghostly fade 14,dissolve:fade to white 15,dissolve:puff 16,dissolve:fade up 17,dissolve:blip -1,dissolvetime:default 50000,maximum global id 255,maximum string id -1, ui:Background # Background colour -2, ui:MenuItem # Normal menu item -3, ui:DisabledItem # Disabled menu item -4, ui:SelectedItem # Selection, alternates 3 & 4 -5, ui:SelectedItem2 # Selection flash color -6, ui:SelectedDisabled # Selected disabled item -7, ui:SelectedDisabled2 # Selected disabled item flash color -8, ui:HighlightA # Background to selected menu item -9, ui:HighlightB # Background used in equip menu -10, ui:TimeBar # Hero's time bar -11, ui:TimeBarFull # Time bar flash when full -12, ui:HealthBar # Hero's health bar -13, ui:HealthBarFull # Health bar flash when full -14, ui:Text # Default text colour -15, ui:TextOutline # Text outline colour -16, ui:Description # Spell description -17, ui:Money # Status menu money display -18, ui:Shadow # Vehicle shadow -19, ui:SpecialItem # Special menu item -20, ui:SelectedSpecial # Selected Special item -21, ui:SelectedSpecial2 # Selected Special item flash color -22, ui:Items:Swap -23, ui:Items:SwapDisabled -24, ui:Items:SwapSpecial -25, ui:Items:Item -26, ui:Items:Disabled -27, ui:Items:Special -28, ui:Items:Selected -29, ui:Items:Selected2 -30, ui:Items:SelectedDisabled -31, ui:Items:SelectedDisabled2 -32, ui:Items:SelectedSpecial -33, ui:Items:SelectedSpecial2 -34, ui:Items:Highlight -35, ui:Items:Highlight2 -36, ui:Items:SwapHighlight -37, ui:Items:SwapHighlight2 -38, ui:MouseHoverItem # A menu item over which the mouse is hovering -39, ui:Damage # Default damage digit color -40, ui:Heal -41, ui:Absorb -42, ui:Poison -43, ui:Regen -44, ui:FadeOutNewGame -45, ui:FadeOutLoadGame -46, ui:FadeOutDeath -47, ui:FadeOutQuit -48, ui:FadeOutDoor -49, ui:FadeOutInn -50, ui:FadeOutEnterBattle -51, ui:FadeOutWonBattle -52, ui:FadeOutExitBattle -53, ui:MPBar # Hero's MP bar -54, ui:MPBarFlash # MP bar flash colour (when higher than max) 0,pool:local 1,pool:global end # define constant, begin -100000, sl:root -100001, sl:textbox text -100002, sl:textbox portrait -100003, sl:textbox choice0 -100004, sl:textbox choice1 -100016, sl:textbox box -100017, sl:textbox portrait box -100018, sl:textbox choice box -100019, sl:textbox root -100005, sl:script layer -100005, sl:sprite layer -100006, sl:textbox layer -100007, sl:string layer -100021, sl:reserve -100008, sl:maproot -100009, sl:obsolete overhead -100020, sl:map overlay -100010, sl:walkabout layer -100011, sl:hero layer -100012, sl:npc layer -100013, sl:walkabout sprite -100013, sl:walkabout sprite component -100014, sl:walkabout shadow -100014, sl:walkabout shadow component -100015, sl:backdrop -101000, sl:map layer0 -101001, sl:map layer1 -101002, sl:map layer2 -101003, sl:map layer3 -101004, sl:map layer4 -101005, sl:map layer5 -101006, sl:map layer6 -101007, sl:map layer7 -101008, sl:map layer8 -101009, sl:map layer9 -101010, sl:map layer10 -101011, sl:map layer11 -101012, sl:map layer12 -101013, sl:map layer13 -101014, sl:map layer14 -101015, sl:map layer15 -102100, sl:pathfind dest display end # SCANCODE.HSI# This include file defines key: and joy: constants for use with commands like #"keypress", "key is pressed" and "wait for key", and also axis: constants for # "joystick axis". # You don't need to include this file, it's done automatically. define constant,begin # These *key constants can be used with any keypress commands. -1,anykey -2,upkey -3,downkey -4,leftkey -5,rightkey -6,usekey -7,menukey -8,fleekey -8,runkey -9,cancelkey 01,key:Esc 02,key:1 02,key:Exclamation 03,key:2 03,key:At Sign 04,key:3 04,key:Hash 05,key:4 05,key:Dollar Sign 06,key:5 06,key:Percent 07,key:6 07,key:Circumflex 08,key:7 08,key:Ampersand 09,key:8 09,key:Asterix 09,key:Asterisk 10,key:9 10,key:Left Parenthesis 11,key:0 11,key:Right Parenthesis 12,key:Minus 12,key:Underscore 13,key:Equals 13,key:Plus 14,key:Backspace 15,key:Tab 16,key:Q 17,key:W 18,key:E 19,key:R 20,key:T 21,key:Y 22,key:U 23,key:I 24,key:O 25,key:P 26,key:Left Bracket 26,key:Left Brace 27,key:Right Bracket 27,key:Right Brace 28,key:Enter 29,key:Ctrl 30,key:A 31,key:S 32,key:D 33,key:F 34,key:G 35,key:H 36,key:J 37,key:K 38,key:L 39,key:Semicolon 39,key:Colon 40,key:Quote 40,key:Doublequote 40,key:Apostrophe 41,key:Backquote 41,key:Tilde 42,key:Left Shift 43,key:Backslash 43,key:Pipe 44,key:Z 45,key:X 46,key:C 47,key:V 48,key:B 49,key:N 50,key:M 51,key:Comma 51,key:Left Caret 52,key:Period 52,key:Right Caret 53,key:Slash 53,key:Question Mark 54,key:Right Shift 55,key:Numpad Asterix 55,key:Numpad Asterisk 56,key:Alt 57,key:Space 58,key:Capslock 59,key:F1 60,key:F2 61,key:F3 62,key:F4 63,key:F5 64,key:F6 65,key:F7 66,key:F8 67,key:F9 68,key:F10 69,key:Numlock # On Macs this is the Clear numpad key instead 70,key:Scroll Lock 71,key:Home 72,key:Up 73,key:Page Up 74,key:Numpad Minus 75,key:Left 77,key:Right 78,key:Numpad Plus 79,key:End 80,key:Down 81,key:Page Down 82,key:Insert 83,key:Delete 87,key:F11 88,key:F12 91,key:Left Win Logo 91,key:Left Command #Macintosh 91,key:Left Meta 92,key:Right Win Logo 92,key:Right Command #Macintosh 92,key:Right Meta 93,key:Context 94,key:F13 95,key:F14 96,key:F15 97,key:Shift 98,key:Left Alt 99,key:Right Alt 100,key:Left Ctrl 101,key:Right Ctrl 102,key:Numpad Slash # previously key:Slash 103,key:Numpad Enter # previously key:Enter 104,key:Numpad 7 # previously key:Home 105,key:Numpad 8 # previously key:Up 106,key:Numpad 9 # previously key:Page Up 108,key:Numpad 4 # previously key:Left 109,key:Numpad 5 110,key:Numpad 6 # previously key:Right 112,key:Numpad 1 # previously key:End 113,key:Numpad 2 # previously key:Down 114,key:Numpad 3 # previously key:Page Down 115,key:Numpad 0 # previously key:Insert 116,key:Numpad Period # previously key:Delete 117,key:Print Screen 118,key:Pause # previously key:Numlock 119,key:Filtered Alt # Same as key:Alt, but try to filter out keypresses which are part of window manager combinations 120,key:Any Enter # either key:Enter or key:Numpad Enter 121,key:Meta # either key:Left Meta or key:Right Meta 121,key:Win Logo 121,key:Command # Keys >= 128 are scancodes for other devices (mouse, joystick) 128,joy:A # B button on a SNES controller! 128,joy:Cross # PS 129,joy:B # A button on a SNES controller! 129,joy:Circle # PS 130,joy:X # Y button on a SNES controller! 130,joy:Square # PS 131,joy:Y # X button on a SNES controller! 131,joy:Triangle # PS 132,joy:Left Stick # When pressed as a button 133,joy:Right Stick # Center-left button: Select (NES, SNES, PS1-3), Back (Xbox), Share (PS4), View (Xbox) 134,joy:Select 134,joy:Back # Center button: PS button (PS3), Xbox guide button 135,joy:Logo 135,joy:Guide # Center-right button: Start (NES, SNES, Genesis, N64, Saturn, PS1-3, Xbox), Options (PS4), Menu (XBox) 136,joy:Start 137,joy:L1 # Left shoulder 138,joy:R1 # Right shoulder 139,joy:L2 # Left trigger. Also axis:L2 140,joy:R2 # Right trigger. Also axis:R2 #141-143 unassigned # Dpad, and also translates axis:X/Y (left thumbstick on a gamepad) to button presses # (unless "Map joystick (left) stick to dpad" is disabled) 144,joy:Left 145,joy:Right 146,joy:Up 147,joy:Down # Translation of right stick (axis:RightX/Y) to button presses 148,joy:RStick Left 149,joy:RStick Right 150,joy:RStick Up 151,joy:RStick Down # Obsolete aliases 144,joy:x left 145,joy:x right 146,joy:y up 147,joy:y down 128,joy:button 1 129,joy:button 2 130,joy:button 3 131,joy:button 4 132,joy:button 5 133,joy:button 6 134,joy:button 7 135,joy:button 8 136,joy:button 9 137,joy:button 10 138,joy:button 11 139,joy:button 12 140,joy:button 13 141,joy:button 14 142,joy:button 15 143,joy:button 16 144,joy:button 17 145,joy:button 18 146,joy:button 19 147,joy:button 20 148,joy:button 21 149,joy:button 22 150,joy:button 23 151,joy:button 24 152,joy:button 25 153,joy:button 26 154,joy:button 27 155,joy:button 28 156,joy:button 29 157,joy:button 30 158,joy:button 31 159,joy:button 32 # 160-163 reserved # These are only returned by waitforkey(anykey)! You can't use them elsewhere! # Don't confuse these with "left button", etc, which are used for "mouse click", etc. #180,mouse:left #181,mouse:right #182,mouse:middle end define constant, begin # Joystick axes 0, x axis # Old style alias 1, y axis # The X,Y axes are the left thumbstick on a gamepad 0, axis:X # Also mapped to joy:Left, joy:Right 1, axis:Y # Also mapped to joy:Up, joy:Down 2, axis:RightX # Also mapped to joy:RStickLeft, joy:RStickRight 3, axis:RightY # Also mapped to joy:RStickUp, joy:RStickDown 4, axis:L2 # Also mapped to joy:L2 button 5, axis:R2 # Also mapped to joy:R2 button end AUTOTEST.HSI # HamsterSpeak constant definitions for autotest.rpgdir define constant, begin 2,tag:box chain test 3,tag:menu tag test 4,tag:req for atk use tag 5,tag:atk use test tag 6,tag:atk use test no req 7,tag:door req tag 8,tag:textbox 14 happened 9,tag:textbox 15 happened 10,tag:Victory 11,tag:Freki level 0 12,tag:Freki level teens 13,tag:boat tag 1,song:tinglazedandnoncommutative 0,hero:UNUSED 1,hero:Helga 2,hero:Olaf 3,hero:Frumpy 4,hero:Styrge 5,hero:Kitt 6,hero:Bram 7,hero:UNUSED 2 8,hero:UNUSED 3 9,hero:UNUSED 4 10,hero:UNUSED 5 11,hero:UNUSED 6 12,hero:UNUSED 7 13,hero:UNUSED 8 14,hero:UNUSED 9 15,hero:UNUSED 10 16,hero:UNUSED 11 17,hero:UNUSED 12 18,hero:UNUSED 13 19,hero:UNUSED 14 20,hero:UNUSED 15 21,hero:UNUSED 16 22,hero:UNUSED 17 23,hero:UNUSED 18 24,hero:UNUSED 19 25,hero:UNUSED 20 26,hero:UNUSED 21 27,hero:UNUSED 22 28,hero:UNUSED 23 29,hero:UNUSED 24 30,hero:UNUSED 25 31,hero:UNUSED 26 32,hero:UNUSED 27 33,hero:UNUSED 28 34,hero:UNUSED 29 35,hero:UNUSED 30 36,hero:UNUSED 31 37,hero:UNUSED 32 38,hero:UNUSED 33 39,hero:UNUSED 34 40,hero:UNUSED 35 41,hero:UNUSED 36 42,hero:UNUSED 37 43,hero:UNUSED 38 44,hero:UNUSED 39 45,hero:UNUSED 40 46,hero:UNUSED 41 47,hero:UNUSED 42 48,hero:UNUSED 43 49,hero:UNUSED 44 50,hero:UNUSED 45 51,hero:UNUSED 46 52,hero:UNUSED 47 53,hero:UNUSED 48 54,hero:UNUSED 49 55,hero:UNUSED 50 56,hero:UNUSED 51 57,hero:UNUSED 52 58,hero:UNUSED 53 59,hero:UNUSED 54 60,hero:UNUSED 55 61,hero:UNUSED 56 62,hero:UNUSED 57 63,hero:UNUSED 58 64,hero:UNUSED 59 65,hero:Freki 66,hero:UNUSED 60 0,item:DefltWep 3,item:Boots 4,item:SteelSho 5,item:Bulky 6,item:Whatsit 7,item:Lump 0,stat:HP 1,stat:MP 2,stat:Atk 3,stat:Aim 4,stat:Def 5,stat:Dog 6,stat:Mag 7,stat:Wil 8,stat:Spd 9,stat:Ctr 10,stat:MP~ 11,stat:Hits 0,element:Fire 1,element:Ice 2,element:Lit 3,element:Earth 4,element:Other 5,element:Other 2 6,element:Other 3 7,element:Other 4 8,element:Type 1killer 9,element:Type 2killer 10,element:Type 3killer 11,element:Type 4killer 12,element:Type 5killer 13,element:Type 6killer 14,element:Type 7killer 15,element:Type 8killer 1,slot:Weapon 2,slot:Head 3,slot:Body 4,slot:Arms 5,slot:Legs 0,map:Test Town 1,map:Afterbattle script map 2,map:Insteadofbattle script map 3,map:InsteadAfter battle map 4,map:Door test map 5,map:Pathland 6,map:Vehicle Test Map 7,map:Pathland Door Annex 8,map:Only one local npc 9,map:Many local NPCs 10,map:obsolete map data DO NOT EDIT 11,map:map with an autorun 1,atk:SelfStab 2,atk:L10 Wolf 3,atk:Force Run 4,atk:Force Vict 5,atk:Force Exit 6,atk:BecomeMush 7,atk:AtkTagUse 8,atk:AtTagNoReq 9,atk:Suicide 10,atk:Ice Attack 11,atk:Self3End 1,shop:Boring Shop 2,shop:Empty Shop 2,menu:Menu from menu 3,menu:1st item unselectble 4,menu:Nothing selectable 0,enemy:Mushboom 1,enemy:Run Forcer 2,enemy:Victory Forcer 3,enemy:Exit Forcer 4,enemy:ZombBoom 5,enemy:AtkTagUseTester 6,enemy:AtkTagTestNoReq 7,enemy:Data read test 8,enemy:Ogreboom 9,enemy:IceAttacker 1,sli:Some lookup 2,sli:my root slice 3,sli:no extras 4,sli:lotsa extras 5,sli:default extras 6,sli:one extra end AUTOTEST.HSS######################################################################## # Many of the tests in this script might seem silly. That is okay. # # See interactivetest.hss for tests which require user input. # # Any time you are preparing to fix an engine bug, consider adding a # test that demonstrates the bug FIRST before you fix the bug. include, hstests.hss include, autotest.hsi include, "autotest-plotstr.hsi" # Save slots used: # 1 for save/load tests # 2 for save/load tests # 3 for export globals tests # 4 test expanding strings from save slots # 5 empty, for testing failure of expanding strings from empty save slots # 31 save slot: persistent # 400 used for testing higher number save slots ######################################################################## define constant(1, default wait) define constant(10, timer:checkpoint) define constant(30, timer:set args test) global variable(100, menu item script global) global variable(101, timer global) global variable(102, timer global will become) global variable(103, battle script sequence) global variable(104, menu close global) global variable(105, embedding global) global variable(106, export global 1) global variable(107, export global 2) global variable(108, expecting death) global variable(109, died) global variable(110, map autorun triggered) global variable(111, eachstep triggered) global variable(112, textbox script triggered) global variable(113, npc script triggered) global variable(114, testing script triggers) global variable(115, savegame map) global variable(116, savegame slice) global variable(117, savegame npc) global variable(118, called resetgame) global variable(119, hook loadgame) global variable(120, timer checkpoint interval) global variable(121, saveglobal) global variable(122, observed hero count) global variable(123, move hero count) global variable(124, timer expect arg 1) global variable(125, timer expect arg 2) global variable(126, autorun counter) global variable(50000, the global with the biggest id) # 200-500 used in hstests.hss # 1000-1063 used in zonetests define constant(1000, array:zones) # 5000-6000 used in hstests.hss #string 0 = error messages #string 1-9 = temporary misc #string 10 = error message arg #string 11 = asserts #string 95-99 = temp misc define constant(10, err arg string) define constant(11, assert expression string) # see notes at the top of this file for what save slots get used define constant(31, save slot: persistent) define constant(400, save slot: high) ######################################################################## # Set on starting map 0 plotscript, mapautorun, begin # Test that the map autorun script on the starting map happens before # the newgame script map autorun triggered += 1 end # TODO: What would be nice is to reset the game between each test suite, # making use of the ability to pass args to a new/load game script, # so that we don't have to worry about things interfering with each other plotscript, new game, arg1, arg2, arg3, begin trace($1="newgame script") tracevalue(arg1, arg2, arg3) suspend player seed random(4444) # This stuff is for "test reset game" import globals(save slot: persistent, @called resetgame, @called resetgame) if (called resetgame || arg1) then ( after resetgame(arg1, arg2, arg3) run tests 2 # continue tests ) else ( run tests 1 # start tests ) end plotscript, load game, slot, arg1, arg2, arg3, begin trace($1="loadgame script") tracevalue(slot, arg1, arg2, arg3, hook loadgame) suspend player seed random(4444) if (hook loadgame) then ( after loadgame(arg1, arg2, arg3) run tests 3 # continue tests ) else ( # This means we weren't expecting this script to be called crash ) end # testing starts here script, run tests 1, begin assert(map autorun triggered == 1) interpreter tests extra array tests global npc tests scheduling tests plotstr tests string load tests platform tests save slot tests slice tests master palette tests maptile tests wallchecking tests zone tests map state tests inventory tests hero tests death tests trigger tests door tests map autorun tests npc tests menu tests textbox tests shop tests script trigger tests attack tests enemy tests battle tests timer tests pathfinding tests vehicle tests obsolete map data tests run game tests resetgame tests # Resets the game crash end script, start checkpoint timer, interval, begin timer checkpoint interval := interval do start checkpoint interval end script, do start checkpoint interval , begin _checkpoint set timer(timer:checkpoint, 0, timer checkpoint interval, @do start checkpoint interval) end script, stop checkpoint timer, begin stop timer(timer:checkpoint) end # follows "resetgame tests" script, run tests 2, begin savegame tests # Saves and loads the game crash end # follows "savegame tests" script, run tests 3, begin # more tests here, potentially passed tests end script, passed tests, begin $0="TESTS SUCCEEDED" trace(0) gameover end ######################################################################## script, w, ticks=default wait, begin wait(ticks) _checkpoint end # Returns a string of the script call stack in given string id script, callstack, string, begin variable(depth, id) depth := 1 $ string = "" while (true) do ( id := getcallingscriptid(depth) if (id == 0) then (break) if (depth == 1) then ( getscriptname(string, id) ) else ( getscriptname(95, id) stringsprintf(string, $96="%s -> %s", 95, string) ) depth += 1 ) return(string) end script, crash, begin if(string length(10) >> 0) then( $0+"(" concatenate strings(0, err arg string) $0+")" ) show text box(1) $1="crash() called from " callstack(2) 1 $+ 2 trace(1) $1="in testsuite: " 1 $+ 0 trace(1) w(25) # script error(0) game over end script, assert failure, begin $1="ASSERT FAILURE:" trace(1) trace(assert expression string) crash end ######################################################################## # Test the interaction of different script fibres, including pausing, # waiting, and back-compat blocking. # This makes use of timers, but the real timer tests are elsewhere. # (Timer tests happen after these tests!) # Triggering scripts is also tested in "script trigger tests" and # a number of other tests for npcs, menus, battles, etc. script, scheduling tests, begin $0="scheduling tests" tick counter slice := create container set slice velocity x(tick counter slice, 1, 1000) blocking tests assert(check bug 430 enabled == false) variable (oldval) oldval := read general(178) # genBits2 write general(178, oldval, or, (2 ^ 1)) # Enable bug 430 assert(check bug 430 enabled == true) write general(178, oldval) free slice(tick counter slice) end script, ticknumber, begin return(slice x(tick counter slice)) end ######################################################################## script, blocker script, begin # assert(ticker 0 == expected ticker 0) ticker 1 += 1 wait ticker 1 += 1 end script, blocker script 2, begin assert(ticker 1 == expected ticker 1) ticker 2 += 1 wait ticker 2 += 1 assert(ticker 1 == expected ticker 1) end script, eachtick script, begin ticker 0 += 1 set timer(3, 0, 1, @eachtick script) end script, blocking tests, begin $0="blocking tests" variable (start tick) start tick := ticknumber ticker 0 := 0 ticker 1 := 0 # globals ticker 2 := 0 # Start an each-tick script on a timer that should not interfer with anything else # (since it has a higher timer ID) set timer(3, 0, 1, @eachtick script) wait(2) assert(ticknumber == start tick + 2) # Trigger another script and check that this one is blocked # (This is also a test for bug 430, because of eachtick script) expected ticker 0 := 0 set timer(1, 0, 1, @blocker script) assert(ticknumber == start tick + 2) # This script will continue running until the next tick assert(ticker 1 == 0) wait(1) assert(ticker 1 == 2) assert(ticknumber == start tick + 4) # Trigger two scripts to run at once; one blocks the other (test for bug 430) expected ticker 1 := 2 set timer(1, 0, 1, @blocker script) set timer(2, 0, 1, @blocker script 2) # Runs first assert(ticknumber == start tick + 4) wait assert(ticknumber == start tick + 7) # one tick wait each plus the wait above assert(ticker 1 == 4) assert(ticker 2 == 2) # Check eachtick ran every tick #trace value(ticknumber, start tick, ticker 0, ticker 1, ticker 2) assert(ticker 0 == ticknumber -- start tick) stop timer(3) end ######################################################################## script, bug 430 tester, begin variable (start tick) start tick := ticknumber wait # should be skipped if (ticknumber == start tick) then ( # was skipped ticker 1 += 1 ) end # blocking tests is completely broken if bug 430 is enabled, so here is a separate test, # Returns whether bug 430 is enabled script, check bug 430 enabled, begin $0="check bug 430 enabled" variable (start tick) start tick := ticknumber ticker 1 := 0 # globals ticker 2 := 0 # Trigger two scripts to run at once; one blocks the other (test for bug 430) expected ticker 1 := 0 set timer(1, 0, 1, @bug 430 tester) set timer(2, 0, 1, @blocker script 2) # Runs first wait assert(ticker 2 == 2) if(ticknumber == start tick + 2 && ticker 1 == 1) then ( # wait in blocker script 2 plus the wait above return (true) ) else if(ticknumber == start tick + 3 && ticker 1 == 0) then ( return (false) ) else ( # Other combinations should be impossible crash ) end ######################################################################## script, inventory tests, begin $0="Inventory tests" # This tests only the inventory and commands to manipulate it. # Far more item tests including some equipment/inventory stuff is in 'equipment tests' # Precondition: empty inventory assert(get inventory size == 600) variable(slot, lastslot) for (slot, 0, get inventory size -- 1) do ( assert(item in slot(slot) == -1) assert(item count in slot(slot) == 0) ) # Simple stuff get item(item:Boots, 3) assert(inventory(item:Boots) == 3) assert(item in slot(0) == item:Boots) assert(item count in slot(0) == 3) get item(item:Boots, 99) assert(inventory(item:Boots) == 102) delete item(item:Boots) assert(inventory(item:Boots) == 101) delete item(item:Boots, 101) assert(inventory(item:Boots) == 0) # test item slot commands assert(item in slot(0) == -1) assert(item count in slot(0) == 0) assert(item in slot(1) == -1) assert(item count in slot(1) == 0) set item in slot(1, item:Boots) # used on empty slot, adds one item assert(item in slot(1) == item:Boots) assert(item count in slot(1) == 1) assert(inventory(item:Boots) == 1) lastslot := get inventory size -- 1 set item in slot(lastslot, item:Boots) assert(item in slot(lastslot) == item:Boots) set item count in slot(lastslot, 99) assert(inventory(item:Boots) == 100) # check deleteitem deletes in right order delete item(item:Boots, 5) assert(inventory(item:Boots) == 95) assert(item count in slot(1) == 0) assert(item count in slot(lastslot) == 95) # transmog a stack of items set item in slot(lastslot, item:SteelSho) assert(item in slot(lastslot) == item:SteelSho) assert(item count in slot(lastslot) == 95) assert(inventory(item:SteelSho) == 95) assert(inventory(item:Boots) == 0) # test the two additional ways of deleting items set item in slot(lastslot, -1) assert(item count in slot(lastslot) == 0) set item in slot(2, item:Boots) set item count in slot(2, 0) assert(item in slot(2) == -1) # leave nothing for (slot, 0, get inventory size -- 1) do ( assert(item in slot(slot) == -1) ) # test max stack sizes assert(get item maximum stack size(item:Boots) == 99) assert(get item maximum stack size(item:Bulky) == 3) get item(item:Bulky, 6) assert(inventory(item:Bulky) == 6) assert(item count in slot(0) == 3) assert(item count in slot(1) == 3) set item in slot(2, item:Boots) set item count in slot(2, 40) # changing type should cause stacks to overflow if too large set item in slot(2, item:Bulky) assert(inventory(item:Bulky) == 46) assert(item count in slot(2) == 3) delete item(item:Bulky, 46) end ######################################################################## script, hero tests, begin hero party management tests # The party now contains heroes 0, 1, 2, 3 in that order hero appearance tests hero caterpillar tests suspend walkabouts tests hero exp and levels tests hero stat growth test hero stat tests equipment tests hero misc tests hero names embed tests # The party should continue to be 0, 1, 2, 3 end ## hero commands left to test ## spell lists #can learn spell (hero,attack) #forget spell (hero,attack) #knows spell (hero,attack) #read spell (hero,list,slot) #teach spell (hero,attack) #write spell (hero,list,slot,attack) ## Equipment #set default weapon (hero,item) ## Stats #get level MP (who, mp level slot, type) #set level MP (who, mp level slot, new value) ## Misc #hero base elemental resist as int (who, element) #hero total elemental resist as int (who, element) #set hero base elemental resist (who, element, percent) plotscript, add hero hook, slot, who, begin assert(hero by slot(slot) == who) observed hero count += 1 end plotscript, remove hero hook, slot, who, begin assert(hero by slot(slot) == -1) observed hero count -= 1 end plotscript, move hero hook, slot, old slot, loading, begin # This script only does something on three specific calls, see below, if (testing script triggers) then ( move hero count += 1 assert(loading == false) ) if (testing script triggers == 1) then ( # Swapping slots 2 and 3, both occupied assert(slot == 2 || slot == 3) assert(slot + old slot == 5) ) if (testing script triggers == 2) then ( # Swapping hero into an empty slot assert(slot == 20) assert(old slot >= 4) assert(hero by slot(slot) == hero:Kitt) assert(hero by slot(old slot) == -1) ) end script, hero party management tests, begin $0="hero party management tests" # Preconditions assert(room in active party == 3) variable(h0x, h0y, h0speed, h0d) h0x := hero x(0) h0y := hero y(0) h0speed := get hero speed(0) h0d := hero direction(0) assert(observed hero count == 1) add hero(hero:Helga) add hero(hero:Olaf) add hero(hero:Frumpy) assert(room in active party == 0) assert(observed hero count == 4) assert(hero by rank(0) == hero:Freki) assert(hero by rank(1) == hero:Helga) assert(hero by rank(2) == hero:Olaf) assert(hero by rank(3) == hero:Frumpy) # with a full party, hero by rank and hero by slot should return the same values assert(hero by rank(0) == hero by slot(0)) assert(hero by rank(1) == hero by slot(1)) assert(hero by rank(2) == hero by slot(2)) assert(hero by rank(3) == hero by slot(3)) # now delete the leader delete hero(hero:Freki) assert(observed hero count == 3) assert(room in active party == 1) assert(hero by rank(0) == 1) assert(hero by rank(1) == 2) assert(hero by rank(2) == 3) assert(hero by rank(3) == -1) assert(hero by slot(0) == -1) assert(hero by slot(1) == 1) assert(hero by slot(2) == 2) assert(hero by slot(3) == 3) # Test some commands which should work by rank, not party slot # (TODO: incomplete) assert(hero x(0) == h0x) assert(hero y(0) == h0y) assert(hero z(0) == 0) assert(get hero speed(0) == h0speed) assert(hero direction(0) == h0d) # add a different leader add hero(hero:Styrge) assert(hero by slot(0) == hero:Styrge) # test find hero assert(find hero(hero:Freki) == -1) assert(find hero(hero:Helga) == 1) assert(find hero(hero:Olaf) == 2) assert(find hero(hero:Frumpy) == 3) assert(find hero(hero:Styrge) == 0) # test rank in caterpillar assert(rank in caterpillar(hero:Freki) == -1) assert(rank in caterpillar(hero:Helga) == 1) assert(rank in caterpillar(hero:Olaf) == 2) assert(rank in caterpillar(hero:Frumpy) == 3) assert(rank in caterpillar(hero:Styrge) == 0) # Add a hero to the reserve add hero(hero:Kitt) assert(room in active party == 0) variable(slot) slot := find hero(hero:Kitt) assert(slot >= 4) assert(rank in caterpillar(hero:Kitt) == -1) assert(hero by slot(slot) == hero:Kitt) # this command needs to work on reserve slots assert(hero by rank(4) == -1) # this command should not work on reserve slots # names $1="Styrge" get hero name(2, 0) assert(string compare(1, 2)) $1="Helga" get hero name(2, 1) assert(string compare(1, 2)) $1="Olaf" get hero name(2, 2) assert(string compare(1, 2)) $1="Frumpy" get hero name(2, 3) assert(string compare(1, 2)) $1="Kitt" get hero name(2, find hero(hero:Kitt)) assert(string compare(1, 2)) $1="Kittzilla" set hero name(1, find hero(hero:Kitt)) get hero name(2, find hero(hero:Kitt)) assert(string compare(1, 2)) # Swapping swap out hero(hero:Helga) assert(hero by slot(1) == -1) assert(find hero(hero:Helga) >= 4) swap in hero(hero:Kitt) assert(hero by slot(1) == hero:Kitt) assert(find hero(hero:Kitt) >> 0 && find hero(hero:Kitt) <= 3) swap by position(0, 3) # swap Styrge and Frumpy assert(hero by slot(0) == hero:Frumpy) assert(hero by slot(3) == hero:Styrge) swap by position(3, find hero(hero:Helga)) # swap Styrge and Helga assert(hero by slot(3) == hero:Helga) assert(find hero(hero:Styrge) >= 4) swap by name(hero:Kitt, hero:Styrge) assert(hero by slot(1) == hero:Styrge) assert(find hero(hero:Kitt) >= 4) swap out hero(hero by slot(0)) # swap out frumpy assert(hero by slot(0) == -1) # restore numeric order add hero(hero:Freki) # Freki assert(hero by slot(0) == hero:Freki) swap by position(1, find hero(hero:Helga)) assert(hero by slot(1) == hero:Helga) swap by position(2, find hero(hero:Olaf)) assert(hero by slot(2) == hero:Olaf) swap by position(3, find hero(hero:Frumpy)) assert(hero by slot(3) == hero:Frumpy) # add another copy of Freki, should go to reserve add hero(hero:Freki) slot := find hero(hero:Freki) assert(slot == 0) delete hero by slot(slot) slot := find hero(hero:Freki) assert(slot >= 4) # add back leader Freki assert(hero by slot(0) == -1) add hero(hero:Freki) assert(hero by slot(0) == hero:Freki) # Delete the reserve Freki assert(slot >= 4) assert(hero by slot(slot) == hero:Freki) assert(delete hero by slot(slot) == 0) assert(hero by slot(slot) == -1) # original Freki should be untouched, and not in the reserve assert(find hero(hero:Freki) >= 0) assert(find hero(hero:Freki) <= 3) w # Test "move hero hook" testing script triggers := 1 # Tell the hook script to pay attention assert(move hero count == 0) # Swapping two occupied slots swap by position (2, 3) assert(move hero count == 2) testing script triggers := 2 # Swap occupied and empty swap by position(find hero(hero:Kitt), 20) assert(move hero count == 3) testing script triggers := false swap by position (2, 3) end script, hero appearance tests, begin # preconditions assert(hero by slot(3) == hero:Frumpy) # ensure we're using party slots, not hero ids or caterpillar position swap by position(2, 3) swap by position(1, 10) # 2 = hero:Frumpy assert(get hero picture(2, inside battle) == 8) assert(get hero picture(2, outside battle) == 9) assert(get hero picture(2, hero portrait) == 2) assert(get hero palette(2, inside battle) == -1) assert(get hero palette(2, outside battle) == -1) assert(get hero palette(2, hero portrait) == 2) set hero picture(2, 0, inside battle) set hero picture(2, 4, outside battle) set hero picture(2, 7, hero portrait) set hero palette(2, 37, inside battle) set hero palette(2, 1, outside battle) set hero palette(2, -1, hero portrait) show text box(17) # test portrait by party slot w(3) advance text box assert(get hero picture(2, inside battle) == 0) assert(get hero picture(2, outside battle) == 4) assert(get hero picture(2, hero portrait) == 7) assert(get hero palette(2, inside battle) == 37) assert(get hero palette(2, outside battle) == 1) assert(get hero palette(2, hero portrait) == -1) reset hero picture(2, inside battle) reset hero picture(2, outside battle) reset hero picture(2, hero portrait) reset hero palette(2, inside battle) reset hero palette(2, outside battle) reset hero palette(2, hero portrait) assert(get hero picture(2, inside battle) == 8) assert(get hero picture(2, outside battle) == 9) assert(get hero picture(2, hero portrait) == 2) assert(get hero palette(2, inside battle) == -1) assert(get hero palette(2, outside battle) == -1) assert(get hero palette(2, hero portrait) == 2) # Restore state swap by position(2, 3) swap by position(1, 10) end script, hero names embed tests, begin $0="hero names embed tests" variable(h0, h1, h2, h3) # remember the old party order h0 := hero by slot(0) h1 := hero by slot(1) h2 := hero by slot(2) h3 := hero by slot(3) swap by position(0, find hero(hero:Olaf)) swap out hero(hero by slot(1)) swap out hero(hero by slot(2)) swap out hero(hero by slot(3)) $1="Olaf,,," $2="Olaf,,," $3="Freki,Helga,Olaf,Frumpy,Styrge" hero names embed helper swap by position(2, find hero(hero:Olaf)) $1="Olaf,,," $2=",,Olaf," hero names embed helper swap by position(0, find hero(hero:Frumpy)) $1="Frumpy,Olaf,," $2="Frumpy,,Olaf," hero names embed helper swap by position(1, find hero(hero:Olaf)) swap by position(3, find hero(hero:Frumpy)) $1="Olaf,Frumpy,," $2=",Olaf,,Frumpy" hero names embed helper add hero(hero:Olaf) # slot 1 $4="Nolaf" set hero name(4, 1) $1="Olaf,Nolaf,Frumpy," $2="Olaf,Nolaf,,Frumpy" hero names embed helper swap by position(0, find hero(hero:Frumpy)) $1="Frumpy,Nolaf,Olaf," $2="Frumpy,Nolaf,,Olaf" $3="Freki,Helga,Nolaf,Frumpy,Styrge" hero names embed helper show no value, w advance textbox swap by position(0, 1) # Nolaf to front delete hero(hero:Olaf) # Test embedtext from save slots # Control test, no change to hero name save in slot(4), w expand string($1="${H1}", 4) show string(1), w assert(string compare(1, $2="Helga")) # Hero name by hero id # Helga should be in the reserve when this happens, but we don't care exactly which reserve slot variable(helgaslot) helgaslot := find hero(hero:Helga) assert(helgaslot > 3) # Change Helga's name set hero name($3="Hagar", helgaslot) save in slot(4), w expand string($1="${H1}", 4) show string(1), w assert(string compare(1, $2="Hagar")) # Restore hero name, check again set hero name($3="Helga", helgaslot) assert(string compare(get hero name(1, helgaslot), $2="Helga")) expand string($1="${H1}", 4) show string(1), w assert(string compare(1, $2="Hagar")) # Hero name by party slot # Put helga in slot 2 swap by position(find hero(hero:Helga), 2) assert(find hero(hero:Helga) == 2) # Rename her and resave set hero name($3="Humpty", 2) save in slot(4), w expand string($1="${P2}", 4) show string(1), w assert(string compare(1, $2="Humpty")) # Restore name, check again set hero name($3="Helga", 2) assert(string compare(get hero name(1, 2), $2="Helga")) expand string($1="${P2}", 4) show string(1), w assert(string compare(1, $2="Humpty")) # Hero name by caterpillar slot # Put helga in slot 3 swap by position(find hero(hero:Helga), 3) assert(find hero(hero:Helga) == 3) # Make slot 2 empty show string(get hero name(1, 2)), w swap out hero(hero:Olaf) assert(hero by slot(2) == -1) # Make sure slot 0 is empty assert(hero by slot(0) == -1) # Helga should be rank 1 (2nd) in the caterpillar assert(rank in caterpillar(hero:Helga) == 1) # Rename Helga and save set hero name($1="Hissy", 3) save in slot(4), w expand string($1="${C1}", 4) show string(1), w assert(string compare(1, $2="Hissy")) # Restore name, check again set hero name($3="Helga", 3) assert(string compare(get hero name(1, 3), $2="Helga")) expand string($1="${C1}", 4) show string(1), w assert(string compare(1, $2="Hissy")) show no value # Check strings being expanded from an empty slot # Make sure slot 5 is really empty delete save(5) assert(string compare($1="${H1}", expand string($2="${H1}", 5))) assert(string compare($1="${P0}", expand string($2="${P0}", 5))) assert(string compare($1="${C0}", expand string($2="${C0}", 5))) assert(string compare($1="${H1},${H2},${H3}", expand string($2="${H1},${H2},${H3}", 5))) # Although not hero related, lets throw some tests for ${V} and ${S} in here too. #saveglobal is global id 121 saveglobal := 54321 show string(expand string($1="Var=${V121}")), w assert(string compare(1, $2="Var=54321")) # Save the global to save slot 4, check it save in slot(4), w saveglobal := 1 show string(expand string($1="Var=${V121}", 4)), w assert(string compare(1, $2="Var=54321")) # Replace it with another value saveglobal := 100001 save in slot(4), w saveglobal := 1 show string(expand string($1="Var=${V121}", 4)), w assert(string compare(1, $2="Var=100001")) assert(saveglobal == 1) # Check empty slot 5 show string(expand string($1="Var=${V121}", 5)), w assert(string compare(1, $2="Var=${V121}")) # Test strings $255="A very fine mess" save in slot(4), w $255="Cleaned up" show string(expand string($2="${S255}", 4)), w assert(string compare(255, $1="Cleaned up")) assert(string compare(2, $1="A very fine mess")) # A different string $2="Is better than sloppy order" save in slot(4), w $2="" show string(expand string($3="${S2}", 4)), w assert(string compare(3, $1="Is better than sloppy order")) # An empty save slot (5) show string(expand string($3="${S2}", 5)), w assert(string compare(3, $1="${S2}")) # Test a string in a high-numbered save slot $3="Not Over 9000!!" save in slot(save slot: high) $3="Cleaned up" show string(expand string($2="String=${S3}", save slot: high)) assert(string compare(2, $1="String=Not Over 9000!!")) # restore old party order swap by position(0, find hero(h0)) swap by position(1, find hero(h1)) swap by position(2, find hero(h2)) swap by position(3, find hero(h3)) show box names advance textbox end script, hero names embed helper, begin show string(2) $4="${C0},${C1},${C2},${C3}" expand string(4) $5="${P0},${P1},${P2},${P3}" expand string(5) $6="${H65},${H1},${H2},${H3},${H4}" expand string(6) assert(string compare(1, 4)) assert(string compare(2, 5)) assert(string compare(3, 6)) show box names end script, show box names, begin show text box(9) w(10) show text box(10) w(10) show text box(11) w(10) end ## Party management #lock hero (who) #unlock hero (who) script, hero caterpillar tests, begin variable(i) $0="hero caterpillar tests" $err arg string="leader, cater=ON" do hero cater tests(me) suspend caterpillar for(i, 0, 3) do( $err arg string="hero " append number(err arg string, i) $err arg string=", cater=OFF" do hero cater tests(i) ) resume caterpillar $err arg string="" end script, do hero cater tests, who, begin variable(d) walk hero to x (who, 8), w wait for hero(who) assert(hero x(who) == 8) walk hero to y(who, 10), w wait for hero(who) assert(hero y(who) == 10) camera follows hero(who) walk hero to x(who, 9), w wait for hero(who) assert(hero x(who) == 9) walk hero to y(who, 8), w wait for hero(who) assert(hero y(who) == 8) camera follows hero(0) walk hero to x (who, 6), w wait for hero(who) assert(hero x(who) == 6) set hero position(who, 7, 7), w assert(hero x(who) == 7) assert(hero y(who) == 7) walk hero(who, south, 2) wait for hero(who), w assert(hero y(who) == 9) assert(hero direction(who) == south) assert(forward x(who) == 7) assert(forward y(who) == 10) walk hero(who, south, -1) # negative distance means walk backwards wait for hero(who), w assert(hero y(who) == 8) assert(hero direction(who) == south) walk hero(who, south, 1) wait for hero(who), w assert(hero y(who) == 9) assert(hero direction(who) == south) walk hero(who, west, 2) wait for hero(who), w assert(hero x(who) == 5) assert(hero direction(who) == west) assert(forward x(who) == 4) assert(forward y(who) == 9) walk hero(who, north, 1) wait for hero(who), w assert(hero y(who) == 8) assert(hero direction(who) == north) walk hero(who, east, 1) wait for hero(who), w assert(hero x(who) == 6) assert(hero direction(who) == east) # spin for(d, north, west) do( set hero direction(who, d), w assert(hero direction(who) == d) ) # moonwalk in a circle walk hero(who, south, 1) set hero direction(who, north) wait for hero(who), w assert(hero direction(who) == north) assert(hero x(who) == 6) assert(hero y(who) == 9) walk hero(who, west, 1) set hero direction(who, east) wait for hero(who), w assert(hero direction(who) == east) assert(hero x(who) == 5) assert(hero y(who) == 9) walk hero(who, north, 1) set hero direction(who, south) wait for hero(who), w assert(hero direction(who) == south) assert(hero x(who) == 5) assert(hero y(who) == 8) walk hero(who, east, 1) set hero direction(who, west) wait for hero(who), w assert(hero direction(who) == west) assert(hero x(who) == 6) assert(hero y(who) == 8) # moonwalk in a circle using negative distance walk hero(who, north, -1) wait for hero(who), w assert(hero direction(who) == north) assert(hero x(who) == 6) assert(hero y(who) == 9) walk hero(who, east, -1) wait for hero(who), w assert(hero direction(who) == east) assert(hero x(who) == 5) assert(hero y(who) == 9) walk hero(who, south, -1) wait for hero(who), w assert(hero direction(who) == south) assert(hero x(who) == 5) assert(hero y(who) == 8) walk hero(who, west, -1) wait for hero(who), w assert(hero direction(who) == west) assert(hero x(who) == 6) assert(hero y(who) == 8) # walk into wall walk hero(who, north, 3) # should only make it 2 tiles wait for hero(who) assert(hero Y(who) == 6) # check walls expect hero walls(who, true, false, false, false) walk hero(who, west, 1) wait for hero(who), w walk hero(who, north, 1) wait for hero(who), w expect hero walls(who, false, true, false, false) walk hero(who, north, 2) wait for hero(who), w walk hero(who, east, 1) wait for hero(who), w expect hero walls(who, false, false, true, false) walk hero(who, east, 5) wait for hero(who), w expect hero walls(who, true, true, false, false) # speed test time! set hero speed(who, 2) assert(get hero speed(who) == 2) walk hero(who, south, 1) w(9), assert(hero is walking(who)) w(1), assert(hero is walking(who) == false) set hero speed(who, 4) assert(get hero speed(who) == 4) walk hero(who, south, 1) w(4), assert(hero is walking(who)) w(1), assert(hero is walking(who) == false) set hero speed(who, 5) assert(get hero speed(who) == 5) walk hero(who, south, 1) w(3), assert(hero is walking(who)) w(1), assert(hero is walking(who) == false) set hero speed(who, 10) assert(get hero speed(who) == 10) walk hero(who, south, 1) w(1), assert(hero is walking(who)) w(1), assert(hero is walking(who) == false) set hero speed(who, 20) assert(get hero speed(who) == 20) walk hero(who, south, 1) w(1), assert(hero is walking(who) == false) walk hero(who, west, 1), w walk hero(who, north, 2), w(2) assert(hero x(who) == 10) assert(hero y(who) == 6) set hero speed(who) assert(get hero speed(who) == 4) walk hero(who, west, 3) wait for hero(who) #FIXME: should probably test misaligned walking too # frame variable(fr) for(fr, 1, 8) do( set hero frame(who, (fr ,mod, 2)) assert(hero frame(who) == (fr ,mod, 2)) w(fr) ) #pixel pos variable(px, py) px := hero pixel x(who) assert(px == 140) py := hero pixel y(who) assert(py == 120) variable(ix, iy) for(iy, 0, 5) do( for(ix, 0, 5) do( put hero(who, 105 + ix, 105 + iy) assert(hero pixel x(who) == 105 + ix) assert(hero pixel y(who) == 105 + iy) w ) ) # Test one-wall walls set hero position(who, 5, 9) walk hero(who, south, 1) # normal walk onto a tile with aone-way wall wait for hero(who) assert(hero y(who) == 10) walk hero(who, east, 1) # walk off, where there is no wall wait for hero(who) assert(hero x(who) == 6) walk hero(who, west, 2) # walking between tiles with one-way walls in other directions wait for hero(who) assert(hero x(who) == 4) walk hero(who, west, 1) # attempt to walk through a normal wall while on a oneway wall wait for hero(who) assert(hero x(who) == 4) walk hero(who, north, 1) # walk through one-way wall (allowed) wait for hero(who) assert(hero y(who) == 9) walk hero(who, south, 1) # try to walk disallowed direction wait for hero(who) assert(hero y(who) == 9) walk hero(who, east, 1) wait for hero(who) walk hero(who, south, 2) # walk through one-way wall wait for hero(who) assert(hero y(who) == 11) walk hero(who, north, 1) # try to walk disallowed direction wait for hero(who) assert(hero y(who) == 11) put hero(who, px, py), w end script, suspend walkabouts tests, begin $0="suspend walkabouts tests" # There's an awful lot of things that could be tested, including NPC and hero movement. # Mostly just test heroes. trace(0) trace value (herox, heroy) # Check initial conditions assert(get hero speed(me) == 4) assert(hero is walking(me) == false) variable (initial x) initial x := hero x(me) walk hero(me, left, 1) wait(1) variable (px) px := hero pixel x(me) suspend walkabouts assert(walkabouts are suspended) # Check movement paused wait(2) assert(px == hero pixel x(me)) assert(hero is walking(me)) resume walkabouts assert(walkabouts are suspended == false) # Check moving wait(1) assert(px <> hero pixel x(me)) # Cancel move walk hero(me, left, 0) wait(1) assert(hero is walking(me) == false) suspend walkabouts # Can still move the hero while suspended assert(hero x(me) <> initial x) set hero position(me, initial x, hero y(me)) assert(hero x(me) == initial x) wait(1) # Walk commands don't take effect while suspended assert(hero direction(me) == left) walk hero(me, right, 1) assert(hero direction(me) == right) # walkhero changes the direction directly wait(1) assert(hero pixel x(me) == initial x * 20) # But do once resumed resume walkabouts wait(1) assert(hero pixel x(me) <> initial x * 20) # Cleanup set hero position(me, initial x, hero y(me)) walk hero(me, left, 0) end script, expect hero walls, who, wn, we, ws, ww, begin assert(check hero wall(who, north) == wn) assert(check hero wall(who, east) == we) assert(check hero wall(who, south) == ws) assert(check hero wall(who, west) == ww) end ## caterpillar #suspend hero walls #resume hero walls #set hero frame (who, frame) #set hero speed (who, speed) #set hero z (who, z) script, hero exp and levels tests, begin variable(i) $0="hero exp and levels tests" # check default level curve assert(experience to level(1) == 30) assert(experience to level(2) == 71) assert(experience to level(3) == 125) assert(experience to level(4) == 195) assert(experience to level(5) == 284) assert(experience to level(6) == 396) assert(experience to level(7) == 535) assert(experience to level(8) == 707) assert(experience to level(9) == 918) assert(experience to level(10) == 1176) assert(experience to level(11) == 1491) assert(experience to level(12) == 1874) assert(experience to level(13) == 2339) assert(experience to level(14) == 2902) assert(experience to level(15) == 3583) assert(experience to level(99) == 50183838) # check Freki's level curve (should be same as default) variable(freki slot) freki slot := find hero(hero:freki) assert(freki slot >= 0) assert(experience to level(1, freki slot) == 30) assert(experience to level(2, freki slot) == 71) assert(experience to level(3, freki slot) == 125) assert(experience to level(4, freki slot) == 195) assert(experience to level(5, freki slot) == 284) assert(experience to level(6, freki slot) == 396) assert(experience to level(7, freki slot) == 535) assert(experience to level(8, freki slot) == 707) assert(experience to level(9, freki slot) == 918) assert(experience to level(10, freki slot) == 1176) assert(experience to level(11, freki slot) == 1491) assert(experience to level(12, freki slot) == 1874) assert(experience to level(13, freki slot) == 2339) assert(experience to level(14, freki slot) == 2902) assert(experience to level(15, freki slot) == 3583) assert(experience to level(99, freki slot) == 50183838) # check Bram's level curve (should faster than default) add hero(hero:Bram) variable(bram slot) bram slot := find hero(hero:Bram) assert(bram slot >= 0) assert(experience to level(1, bram slot) == 30) assert(experience to level(2, bram slot) == 70) assert(experience to level(3, bram slot) == 121) assert(experience to level(4, bram slot) == 185) assert(experience to level(5, bram slot) == 264) assert(experience to level(6, bram slot) == 360) assert(experience to level(7, bram slot) == 475) assert(experience to level(8, bram slot) == 612) assert(experience to level(9, bram slot) == 775) assert(experience to level(10, bram slot) == 967) assert(experience to level(11, bram slot) == 1193) assert(experience to level(12, bram slot) == 1458) assert(experience to level(13, bram slot) == 1768) assert(experience to level(14, bram slot) == 2130) assert(experience to level(15, bram slot) == 2551) assert(experience to level(99, bram slot) == 36587434) delete hero(hero:Bram) assert(get hero level(0) == 0) # level setting for(i, 1, 99) do( set hero level(0, i) assert(get hero level(0) == i) assert(total experience(0) == experience to level(i)) ) # level-based spell learning/forgetting set hero level(0, 9) assert(knows spell (0, 2) == false) # Freki should not have L.10 Wolf at level 9 set hero level(0, 10) assert(knows spell (0, 2) == true) # Freki should learn L.10 Wolf at level 10 set hero level(0, 0, false) assert(get hero level(0) == 0) assert(hero levelled(0) == -10) assert(get hero stat(0, 12, 1) == -10) # Undocumented use of stat 12 assert(knows spell (0, 2) == true) # Freki should not forget L.10 Wolf because of how we deleveled update level up learning(0, true) assert(knows spell (0, 2) == false) # Now Freki should forget L.10 Wolf. # experience assert(experience to next level(0) == 30) give experience(0, 5) assert(hero levelled(0) == 0) assert(experience to next level(0) == 25) give experience(0, 25) assert(get hero level(0) == 1) assert(hero levelled(0) == 1) assert(experience to next level(0) == 41) give experience(0, -1) # de-level should not work with this command, but experience will go down assert(get hero level(0) == 1) assert(hero levelled(0) == 0) assert(experience to next level(0) == 42) give experience(0, 42) assert(get hero level(0) == 2) assert(hero levelled(0) == 1) set hero level(0, 9) give experience(0, experience to next level(0)) assert(get hero level(0) == 10) assert(hero levelled(0) == 1) assert(spells learned(0, get count) == 1) assert(spells learned(0, 0) == 2) assert(spells learnt(0, 0) == 1) #deprecated, but why not test it? give experience(0, 1) # should not cause levelling assert(hero levelled == 0) assert(spells learned(0, get count) == 0) # split experience set hero level(0, 0, true) give experience(party, 30) assert(hero levelled(0) == 0) assert(total experience(0) == 8) assert(total experience(1) == 8) assert(total experience(2) == 8) assert(total experience(3) == 8) give experience(party, 88) assert(get hero level(0) == 1) assert(get hero level(1) == 1) assert(get hero level(2) == 1) assert(get hero level(3) == 1) assert(total experience(find hero(hero:Kitt)) == 0) # outside of the party # experience for dead heroes set hero level(0, 0, true) set hero level(1, 0, true) set hero level(2, 0, true) set hero level(3, 0, true) set hero stat(2, 0, 0) # kill Olaf set dead heroes gain experience (false) give experience(party, 120) assert(total experience(0) == 40) assert(total experience(1) == 40) assert(total experience(2) == 0) assert(total experience(3) == 40) set hero level(0, 0, true) set hero level(1, 0, true) set hero level(2, 0, true) set hero level(3, 0, true) set dead heroes gain experience (true) give experience(party, 120) assert(total experience(0) == 30) assert(total experience(1) == 30) assert(total experience(2) == 30) assert(total experience(3) == 30) set hero level(0, 0, true) set hero level(1, 0, true) set hero level(2, 0, true) set hero level(3, 0, true) set hero stat(2, 0, get hero stat(2, 0, maximum stat)) # revive Olaf # level caps set hero level(0, 1) assert(get level cap == 99) set level cap(2) assert(get level cap == 2) give experience(0, 41) assert(get hero level(0) == 2) assert(total experience(0) == 71) assert(experience to next level(0) == 54) # being at the level cap does not alter the exp to next level give experience(0, 10000000) assert(hero levelled(0) == 0) assert(get hero level(0) == 2) set level cap(99) # Hero level range check tags assert(hero by slot(0) == hero:Freki) set hero level(0, 0, true), w assert(check tag(tag: freki level 0) == true) assert(check tag(tag: freki level teens) == false) set hero level(0, 12, true), w assert(check tag(tag: freki level 0) == false) assert(check tag(tag: freki level teens) == false) set hero level(0, 13, true), w assert(check tag(tag: freki level 0) == false) assert(check tag(tag: freki level teens) == true) set hero level(0, 19, true), w assert(check tag(tag: freki level 0) == false) assert(check tag(tag: freki level teens) == true) set hero level(0, 20, true), w assert(check tag(tag: freki level 0) == false) assert(check tag(tag: freki level teens) == false) # Undocumented stat 12 stuff assert(hero levelled(0) == 1) # Precondition assert(get hero level(0) == 20) # Precondition assert(get hero stat(0, 12, 1) == 1) # == hero levelled assert(get hero stat(0, 12, 0) == 20) # == getherolevel variable(temp) temp := get hero stat(0, 0, maximum stat) set hero stat(0, 12, 42, 0) # Set hero level = 42 (but don't change stats) assert(get hero level(0) == 42) assert(get hero stat(0, 12, 0) == 42) assert(get hero stat(0, 0, maximum stat) == temp) # Doesn't change stats assert(hero levelled(0) == 1) # Doesn't change "hero levelled" set hero stat(0, 12, 3, 1) # Set "hero levelled" = 3 assert(hero levelled(0) == 3) set hero stat(0, 12, 20, 0) # Reset # reset set hero level(0, 0, true) set hero level(1, 0, true) set hero level(2, 0, true) set hero level(3, 0, true) end script, hero stat growth test, begin $0="hero stat growth test" show string(0), w # This tests the crappy default stat growth curve, which we will hopefully replace someday set hero level(0 ,0) assert(get hero stat(0, 0, maximum stat) == 10) set hero level(0 ,1) assert(get hero stat(0, 0, maximum stat) == 13) set hero level(0 ,2) assert(get hero stat(0, 0, maximum stat) == 16) # set hero level(0 ,3) # assert(get hero stat(0, 0, maximum stat) == 19) # set hero level(0 ,4) # assert(get hero stat(0, 0, maximum stat) == 23) # set hero level(0 ,5) # assert(get hero stat(0, 0, maximum stat) == 26) # set hero level(0 ,6) # assert(get hero stat(0, 0, maximum stat) == 30) # set hero level(0 ,7) # assert(get hero stat(0, 0, maximum stat) == 34) # set hero level(0 ,8) # assert(get hero stat(0, 0, maximum stat) == 38) # set hero level(0 ,9) # assert(get hero stat(0, 0, maximum stat) == 42) set hero level(0 ,10) assert(get hero stat(0, 0, maximum stat) == 46) assert(get level mp(0, 0) == 5) assert(get level mp(0, 1) == 3) assert(get level mp(0, 2) == 2) assert(get level mp(0, 3) == 1) assert(get level mp(0, 4) == 0) assert(get level mp(0, 5) == 0) assert(get level mp(0, 6) == 0) assert(get level mp(0, 7) == 0) # set hero level(0 ,11) # assert(get hero stat(0, 0, maximum stat) == 50) # set hero level(0 ,12) # assert(get hero stat(0, 0, maximum stat) == 55) # set hero level(0 ,13) # assert(get hero stat(0, 0, maximum stat) == 60) # set hero level(0 ,14) # assert(get hero stat(0, 0, maximum stat) == 64) # set hero level(0 ,15) # assert(get hero stat(0, 0, maximum stat) == 69) # set hero level(0 ,16) # assert(get hero stat(0, 0, maximum stat) == 75) # set hero level(0 ,17) # assert(get hero stat(0, 0, maximum stat) == 80) # set hero level(0 ,18) # assert(get hero stat(0, 0, maximum stat) == 85) # set hero level(0 ,19) # assert(get hero stat(0, 0, maximum stat) == 91) set hero level(0 ,20) assert(get hero stat(0, 0, maximum stat) == 96) # set hero level(0 ,21) # assert(get hero stat(0, 0, maximum stat) == 102) # set hero level(0 ,22) # assert(get hero stat(0, 0, maximum stat) == 108) # set hero level(0 ,23) # assert(get hero stat(0, 0, maximum stat) == 114) # set hero level(0 ,24) # assert(get hero stat(0, 0, maximum stat) == 121) # set hero level(0 ,25) # assert(get hero stat(0, 0, maximum stat) == 127) # set hero level(0 ,26) # assert(get hero stat(0, 0, maximum stat) == 134) # set hero level(0 ,27) # assert(get hero stat(0, 0, maximum stat) == 140) # set hero level(0 ,28) # assert(get hero stat(0, 0, maximum stat) == 147) # set hero level(0 ,29) # assert(get hero stat(0, 0, maximum stat) == 154) set hero level(0 ,30) assert(get hero stat(0, 0, maximum stat) == 161) # set hero level(0 ,31) # assert(get hero stat(0, 0, maximum stat) == 168) # set hero level(0 ,32) # assert(get hero stat(0, 0, maximum stat) == 176) # set hero level(0 ,33) # assert(get hero stat(0, 0, maximum stat) == 183) # set hero level(0 ,34) # assert(get hero stat(0, 0, maximum stat) == 191) # set hero level(0 ,35) # assert(get hero stat(0, 0, maximum stat) == 199) # set hero level(0 ,36) # assert(get hero stat(0, 0, maximum stat) == 207) # set hero level(0 ,37) # assert(get hero stat(0, 0, maximum stat) == 215) # set hero level(0 ,38) # assert(get hero stat(0, 0, maximum stat) == 223) # set hero level(0 ,39) # assert(get hero stat(0, 0, maximum stat) == 232) set hero level(0 ,40) assert(get hero stat(0, 0, maximum stat) == 240) # set hero level(0 ,41) # assert(get hero stat(0, 0, maximum stat) == 249) # set hero level(0 ,42) # assert(get hero stat(0, 0, maximum stat) == 258) # set hero level(0 ,43) # assert(get hero stat(0, 0, maximum stat) == 267) # set hero level(0 ,44) # assert(get hero stat(0, 0, maximum stat) == 276) # set hero level(0 ,45) # assert(get hero stat(0, 0, maximum stat) == 285) # set hero level(0 ,46) # assert(get hero stat(0, 0, maximum stat) == 295) # set hero level(0 ,47) # assert(get hero stat(0, 0, maximum stat) == 304) # set hero level(0 ,48) # assert(get hero stat(0, 0, maximum stat) == 314) # set hero level(0 ,49) # assert(get hero stat(0, 0, maximum stat) == 324) set hero level(0 ,50) assert(get hero stat(0, 0, maximum stat) == 334) # set hero level(0 ,51) # assert(get hero stat(0, 0, maximum stat) == 344) # set hero level(0 ,52) # assert(get hero stat(0, 0, maximum stat) == 354) # set hero level(0 ,53) # assert(get hero stat(0, 0, maximum stat) == 365) # set hero level(0 ,54) # assert(get hero stat(0, 0, maximum stat) == 375) # set hero level(0 ,55) # assert(get hero stat(0, 0, maximum stat) == 386) # set hero level(0 ,56) # assert(get hero stat(0, 0, maximum stat) == 397) # set hero level(0 ,57) # assert(get hero stat(0, 0, maximum stat) == 408) # set hero level(0 ,58) # assert(get hero stat(0, 0, maximum stat) == 419) # set hero level(0 ,59) # assert(get hero stat(0, 0, maximum stat) == 430) set hero level(0 ,60) assert(get hero stat(0, 0, maximum stat) == 442) # set hero level(0 ,61) # assert(get hero stat(0, 0, maximum stat) == 453) # set hero level(0 ,62) # assert(get hero stat(0, 0, maximum stat) == 465) # set hero level(0 ,63) # assert(get hero stat(0, 0, maximum stat) == 477) # set hero level(0 ,64) # assert(get hero stat(0, 0, maximum stat) == 489) # set hero level(0 ,65) # assert(get hero stat(0, 0, maximum stat) == 501) # set hero level(0 ,66) # assert(get hero stat(0, 0, maximum stat) == 513) # set hero level(0 ,67) # assert(get hero stat(0, 0, maximum stat) == 526) # set hero level(0 ,68) # assert(get hero stat(0, 0, maximum stat) == 538) # set hero level(0 ,69) # assert(get hero stat(0, 0, maximum stat) == 551) set hero level(0 ,70) assert(get hero stat(0, 0, maximum stat) == 564) # set hero level(0 ,71) # assert(get hero stat(0, 0, maximum stat) == 577) # set hero level(0 ,72) # assert(get hero stat(0, 0, maximum stat) == 590) # set hero level(0 ,73) # assert(get hero stat(0, 0, maximum stat) == 604) # set hero level(0 ,74) # assert(get hero stat(0, 0, maximum stat) == 617) # set hero level(0 ,75) # assert(get hero stat(0, 0, maximum stat) == 631) # set hero level(0 ,76) # assert(get hero stat(0, 0, maximum stat) == 644) # set hero level(0 ,77) # assert(get hero stat(0, 0, maximum stat) == 658) # set hero level(0 ,78) # assert(get hero stat(0, 0, maximum stat) == 672) # set hero level(0 ,79) # assert(get hero stat(0, 0, maximum stat) == 686) set hero level(0 ,80) assert(get hero stat(0, 0, maximum stat) == 701) # set hero level(0 ,81) # assert(get hero stat(0, 0, maximum stat) == 715) # set hero level(0 ,82) # assert(get hero stat(0, 0, maximum stat) == 730) # set hero level(0 ,83) # assert(get hero stat(0, 0, maximum stat) == 745) # set hero level(0 ,84) # assert(get hero stat(0, 0, maximum stat) == 759) # set hero level(0 ,85) # assert(get hero stat(0, 0, maximum stat) == 774) # set hero level(0 ,86) # assert(get hero stat(0, 0, maximum stat) == 790) # set hero level(0 ,87) # assert(get hero stat(0, 0, maximum stat) == 805) # set hero level(0 ,88) # assert(get hero stat(0, 0, maximum stat) == 820) # set hero level(0 ,89) # assert(get hero stat(0, 0, maximum stat) == 836) set hero level(0 ,90) assert(get hero stat(0, 0, maximum stat) == 852) # set hero level(0 ,91) # assert(get hero stat(0, 0, maximum stat) == 868) # set hero level(0 ,92) # assert(get hero stat(0, 0, maximum stat) == 884) # set hero level(0 ,93) # assert(get hero stat(0, 0, maximum stat) == 900) # set hero level(0 ,94) # assert(get hero stat(0, 0, maximum stat) == 916) # set hero level(0 ,95) # assert(get hero stat(0, 0, maximum stat) == 933) # set hero level(0 ,96) # assert(get hero stat(0, 0, maximum stat) == 949) # set hero level(0 ,97) # assert(get hero stat(0, 0, maximum stat) == 966) set hero level(0 ,98) assert(get hero stat(0, 0, maximum stat) == 983) set hero level(0 ,99) assert(get hero stat(0, 0, maximum stat) == 1000) set hero level(0, 0, true) show no value, w end script, restore hp and mp, begin variable(i) for (i, 0, 40) do ( if (hero by slot(i) <> -1) then ( set hero stat(i, stat:hp, get hero stat(i, stat:hp, maximum stat), current stat) set hero stat(i, stat:mp, get hero stat(i, stat:mp, maximum stat), current stat) ) ) end script, hero stat tests, begin $0="hero stat tests" # test hero stat commands, stat capping, equip stat bonuses, current vs. max quirks, negative stats, level mp # check initial condition assert(hero by slot(1) == hero:Helga) assert(get hero level(1) == 0) assert(get hero stat(1, stat:hp, current stat) == 10) assert(get hero stat(1, stat:mp, current stat) == 20) assert(get hero stat(1, stat:atk, current stat) == 10) assert(get hero stat(1, stat:spd, current stat) == 30) assert(get hero stat(1, stat:hp, base stat) == 10) assert(get hero stat(1, stat:mp, base stat) == 20) assert(get hero stat(1, stat:atk, base stat) == 9) # default weapon has +1 atk assert(get hero stat(1, stat:spd, base stat) == 30) # test stat caps assert(get hero stat cap(stat:hp) == 0) assert(get hero stat cap(stat:mp) == 0) assert(get hero stat cap(stat:atk) == 100) #in-editor assert(get hero stat cap(stat:spd) == 0) # set capped hero stat set capped hero stat(1, stat:atk, 110, current stat) assert(get hero stat(1, stat:atk, current stat) == 100) assert(get hero stat(1, stat:atk, base stat) == 9) set capped hero stat(1, stat:atk, 120, maximum stat) assert(get hero stat(1, stat:atk, maximum stat) == 100) assert(get hero stat(1, stat:atk, base stat) == 99) set capped hero stat(1, stat:hp, 999999, current stat) assert(get hero stat(1, stat:hp, current stat) == 999999) set hero stat(1, stat:hp, 10, current stat) #back to original # set hero stat should not be affected by caps set hero stat(1, stat:atk, 110, current stat) assert(get hero stat(1, stat:atk, current stat) == 110) # modify caps set hero stat cap(stat:hp, 5) set hero stat cap(stat:mp, 12) assert(get hero stat cap(stat:hp) == 5) assert(get hero stat(1, stat:hp, current stat) == 5) assert(get hero stat(1, stat:hp, maximum stat) == 5) assert(get hero stat(1, stat:hp, base stat) == 10) assert(get hero stat(1, stat:mp, current stat) == 12) assert(get hero stat(1, stat:mp, maximum stat) == 12) assert(get hero stat(1, stat:mp, base stat) == 20) # set base stat set hero stat(1, stat:atk, 20, base stat) assert(get hero stat(1, stat:atk, maximum stat) == 21) #+1 from weapon set hero stat(1, stat:atk, 200, base stat) assert(get hero stat(1, stat:atk, base stat) == 200) assert(get hero stat(1, stat:atk, maximum stat) == 100) #capped set hero stat(1, stat:atk, 10, current stat) #back to original set hero stat(1, stat:atk, 10, maximum stat) #original max stat but not base stat! assert(get hero stat(1, stat:atk, base stat) == 110) set hero stat(1, stat:atk, 9, base stat) #back to original max and base assert(get hero stat(1, stat:atk, maximum stat) == 10) set hero stat cap(stat:atk, 0) set hero stat cap(stat:spd, 10) assert(get hero stat cap(stat:atk) == 0) assert(get hero stat cap(stat:spd) == 10) assert(get hero stat(1, stat:atk, current stat) == 10) assert(get hero stat(1, stat:atk, maximum stat) == 10) assert(get hero stat(1, stat:spd, current stat) == 10) assert(get hero stat(1, stat:spd, maximum stat) == 10) set hero stat cap(stat:hp, 0) set hero stat cap(stat:mp, 0) set hero stat cap(stat:spd, 0) # gain hero stat assert(gain hero stat(1, stat:atk, 3) == 13) #return new maximum assert(get hero stat(1, stat:atk, base stat) == 12) assert(get hero stat(1, stat:atk, maximum stat) == 13) assert(get hero stat(1, stat:atk, current stat) == 13) # Only max and current should respect caps set hero stat cap(stat:atk, 11) assert(gain hero stat(1, stat:atk, 4) == 11) #return new maximum assert(get hero stat(1, stat:atk, base stat) == 16) assert(get hero stat(1, stat:atk, maximum stat) == 11) assert(get hero stat(1, stat:atk, current stat) == 11) gain hero stat(1, stat:atk, -7) #back to original set hero stat cap(stat:atk, 0) # Test proportional increase assert(get hero stat(1, stat:hp, current stat) == 5) # HP: 5/10 assert(gain hero stat(1, stat:hp, 6) == 16) assert(get hero stat(1, stat:hp, current stat) == 8) # HP: 8/16 assert(get hero stat(1, stat:hp, maximum stat) == 16) assert(gain hero stat(1, stat:hp, -7) == 9) # Test reset-to-max assert(gain hero stat(1, stat:hp, 1, true) == 10) assert(get hero stat(1, stat:hp, current stat) == 10) # HP: 10/10 assert(get hero stat(1, stat:hp, maximum stat) == 10) # test original stats restored assert(get hero stat(1, stat:hp, maximum stat) == 10) assert(get hero stat(1, stat:hp, base stat) == 10) assert(get hero stat(1, stat:mp, maximum stat) == 20) assert(get hero stat(1, stat:mp, base stat) == 20) assert(get hero stat(1, stat:atk, current stat) == 10) assert(get hero stat(1, stat:atk, maximum stat) == 10) assert(get hero stat(1, stat:atk, base stat) == 9) assert(get hero stat(1, stat:spd, current stat) == 30) assert(get hero stat(1, stat:spd, maximum stat) == 30) assert(get hero stat(1, stat:spd, base stat) == 30) # but not current values for hp, mp assert(get hero stat(1, stat:hp, current stat) == 10) assert(get hero stat(1, stat:mp, current stat) == 12) # Simple test of hero level mp # The hero is level 0. Other levels are tested in "hero stat growth test" assert(get level mp(1, 0, current stat) == 1) assert(get level mp(1, 0, maximum stat) == 1) variable(level) for(level, 1, 7) do ( assert(get level mp(1, level, current stat) == 0) assert(get level mp(1, level, maximum stat) == 0) ) set level mp(1, 7, 99) assert(get level mp(1, 7) == 99) set level mp(1, 7, 0) # Check for valid level MP spell lists assert(hero uses level mp(find hero(hero:Frumpy)) == true) # has valid Level MP spell list assert(hero uses level mp(find hero(hero:Olaf)) == false) # has Level MP spell list, but it is not in the battle menu assert(hero uses level mp(find hero(hero:Freki)) == false) # has other spell list, but not level mp based assert(hero uses level mp(find hero(hero:Helga)) == false) # Has no spell lists # test heal party assert(get hero stat(1, stat:hp, current stat) == 10) # Precondition assert(read preference bit(4) == false) # Precondition: "Inns don't revive dead heroes" off set level mp(1, 0, 0) heal party assert(get hero stat(1, stat:mp, current stat) == 20) assert(get level mp(1, 0, current stat) == 1) set hero stat(1, stat:hp, 0, current stat) heal party(false) # Don't revive heroes assert(get hero stat(1, stat:hp, current stat) == 0) heal party(true) # Revive heroes assert(get hero stat(1, stat:hp, current stat) == 10) set hero stat(1, stat:hp, 0, current stat) heal party # Default: Revive heroes, because of the above pref bit assert(get hero stat(1, stat:hp, current stat) == 10) end script, equipment tests, begin $0="equipment tests" # This is a continuation of 'hero stat tests', see that for preconditions # additional precondition: empty inventory, as well as: assert(find hero(hero:Freki) == 0) assert(find hero(hero:Helga) == 1) # test equipment commands get item(item:Boots) assert(inventory(item:Boots) == 1) assert(equip where(1, item:Boots) == slot:legs) # equippable by all heroes assert(check equipment(1, slot:legs) == -1) assert(check equipment(1, slot:weapon) == item:DefltWep) # default weapon (not properly tested) assert(get default weapon(1) == item:DefltWep) force equip(1, slot:legs, item:Boots) # stat bonuses: spd+2 hp+3 assert(check equipment(1, slot:legs) == item:Boots) assert(inventory(item:Boots) == 0) # test stat bonuses assert(get hero stat(1, stat:hp, current stat) == 10) assert(get hero stat(1, stat:hp, maximum stat) == 13) # only affects max values of hp, mp assert(get hero stat(1, stat:hp, base stat) == 10) assert(get hero stat(1, stat:spd, current stat) == 32) assert(get hero stat(1, stat:spd, maximum stat) == 32) # resets current value to max for other stats assert(get hero stat(1, stat:spd, base stat) == 30) assert(inventory(item:SteelSho) == 0) assert(equip where(0, item:SteelSho) == slot:legs) #equippable only by Freki assert(equip where(1, item:SteelSho) == false) # Note that force equip can be used to equip an item not in the inventory, # in that case you get a free copy. # Force equip also allows equipping in wrong slot force equip(1, slot:weapon, item:SteelSho) # stat bonuses: atk+4 (default weapon has atk+1) assert(check equipment(1, slot:weapon) == item:SteelSho) assert(check equipment(1, slot:legs) == item:Boots) assert(inventory(item:DefltWep) == 0) # shouldn't gain a default weapon assert(get hero stat(1, stat:atk, current stat) == 13) assert(get hero stat(1, stat:atk, maximum stat) == 13) # test unequipping unequip(1, slot:legs) assert(inventory(item:Boots) == 1) assert(check equipment(1, slot:legs) == -1) set hero stat(1, stat:hp, 29, current stat) # check effects of unequipping... even on stats set hero stat(1, stat:spd, 29, current stat) # which the equipment doesn't have bonuses on unequip(1, slot:weapon) assert(inventory(item:SteelSho) == 1) assert(check equipment(1, slot:weapon) == item:DefltWep) assert(get hero stat(1, stat:hp, current stat) == 10) # current values of hp,mp should be capped to max assert(get hero stat(1, stat:hp, maximum stat) == 10) assert(get hero stat(1, stat:spd, current stat) == 30) assert(get hero stat(1, stat:spd, maximum stat) == 30) # resets current value to max for other stats # TODO: test equip elemental resists # test for Bug 743 - Unequipping items with stat bonuses that exceed stat limits is broken assert(get hero stat(1, stat:hp, current stat) == 10) # preconditions (max same) assert(get hero stat(1, stat:spd, current stat) == 30) set hero stat cap(stat:hp, 5) set hero stat cap(stat:spd, 5) force equip(1, slot:legs, item:Boots) assert(get hero stat(1, stat:hp, current stat) == 5) # cap hp, mp to the cap assert(get hero stat(1, stat:hp, maximum stat) == 5) assert(get hero stat(1, stat:spd, current stat) == 5) # resets current value to max for other stats assert(get hero stat(1, stat:spd, maximum stat) == 5) unequip(1, slot:legs) assert(get hero stat(1, stat:hp, current stat) == 5) assert(get hero stat(1, stat:hp, maximum stat) == 5) assert(get hero stat(1, stat:spd, current stat) == 5) assert(get hero stat(1, stat:spd, maximum stat) == 5) set hero stat cap(stat:hp, 0) set hero stat cap(stat:spd, 0) assert(get hero stat(1, stat:hp, current stat) == 5) # only affects max values of hp, mp assert(get hero stat(1, stat:hp, maximum stat) == 10) assert(get hero stat(1, stat:spd, current stat) == 30) # resets current value to max for other stats assert(get hero stat(1, stat:spd, maximum stat) == 30) # ...fix that up restore hp and mp assert(get hero stat(1, stat:hp, current stat) == 10) # cleanup delete item(item:SteelSho) delete item(item:Boots) end script, hero misc tests, begin $0="hero misc tests" show string(0), w variable(n) assert(hero by slot(0) == hero:Freki) assert(get hero hand x(0, hand:attack A) == 22) assert(get hero hand y(0, hand:attack A) == 11) assert(get hero hand x(0, hand:attack B) == 2) assert(get hero hand y(0, hand:attack B) == 17) set hero hand x(0, hand:attack A, 50) set hero hand y(0, hand:attack A, -25) set hero hand x(0, hand:attack B, -10) set hero hand y(0, hand:attack B, 1) assert(get hero hand x(0, hand:attack A) == 50) assert(get hero hand y(0, hand:attack A) == -25) assert(get hero hand x(0, hand:attack B) == -10) assert(get hero hand y(0, hand:attack B) == 1) set hero hand x(0, hand:attack A, get default hero hand x(0, hand:attack A)) set hero hand y(0, hand:attack A, get default hero hand y(0, hand:attack A)) set hero hand x(0, hand:attack B, get default hero hand x(0, hand:attack B)) set hero hand y(0, hand:attack B, get default hero hand y(0, hand:attack B)) assert(get hero hand x(0, hand:attack A) == 22) assert(get hero hand y(0, hand:attack A) == 11) assert(get hero hand x(0, hand:attack B) == 2) assert(get hero hand y(0, hand:attack B) == 17) end ######################################################################## script, npc tests, begin npc reference tests npc movement tests(1) npc movement tests(NPC reference(1)) npc id tests npc extra tests npc tag and onetime tests use npc script tests npc slice tests alter npc tests end script, npc movement tests, n, begin $0="npc movement tests" $err arg string="n=", append number(err arg string, n) show string(0) # assert starting pos assert(npc X(n) == 3) assert(npc Y(n) == 5) # walk in a circle, testing speed set npc speed(n, 4) walk npc(n, south, 1), w wait for npc(n),w assert(npc Y(n) == 6) set NPC speed(n, 5) walk npc(n, east, 1), w wait for npc(n),w assert(npc X(n) == 4) set NPC speed(n, 10) walk npc(n, north, 1), w wait for npc(n),w assert(npc Y(n) == 5) set NPC speed(n, 2) walk npc(n, west, 1), w wait for npc(n),w assert(npc X(n) == 3) set npc speed(n, 4) # Walk backwards walk npc(n, east, -1) wait for npc(n), w assert(npc X(n) == 2) assert(npc direction(n) == east) walk npc(n, south, -1) wait for npc(n), w assert(npc Y(n) == 4) assert(npc direction(n) == south) set npc position(n, 3, 5) show no value $err arg string="" end script, npc reference tests, begin variable(n) assert(npc copy count(1) == 1) assert(npc copy count(2) == 0) assert(npc copy count(4) == 3) n := npc reference(1) assert(n < 0) assert(get npc id(n) == 1) assert(npc copy number(n) == 0) n := NPC reference(4, 1) assert(get npc id(n) == 4) assert(npc copy number(n) == 1) assert(npc x(n) == 2) assert(npc y(n) == 13) n := NPC reference(4, 3) assert(n == 0) # Doesn't exist # Passing an ID should return the ID, copy 0 assert(get npc id(1) == 1) assert(npc copy number(1) == 0) assert(get npc id(2) == -1) # Doesn't exist assert(npc copy number(2) == -1) # Doesn't exist assert(get npc id(3) == 3) assert(npc copy number(3) == 0) # Invalid IDs or references assert(get npc id(9000) == -1) assert(get npc id(-9000) == -1) assert(npc copy number(9000) == -1) assert(npc copy number(-9000) == -1) assert(npc copy count(9000) == 0) assert(npc copy count(-9000) == 0) end script, npc id tests, begin variable(n) n := NPC reference(1) set npc direction(n, south), w assert(get npc id(n) == 1) change npc id(n, 2), w(4) assert(get npc id(n) == 2) change npc id(n, 1), w end script, npc extra tests, begin $0="npc extra tests" variable(npc) npc := npc reference(4) assert(extra length(npc) == 3) assert(npc extra(npc, 0) == 0) assert(npc extra(npc, 2) == 0) set npc extra(npc, -1, 999) assert(npc extra(npc, 2) == 999) assert(get extra(npc, 2) == 999) append extra(npc, 1000) assert(get extra(npc, 3) == 1000) end script, npc tag and onetime tests, begin $0="npc onetime tests" variable(hx, hy, n) # Moving the hero in this script is a little silly, # but ensures that the onetime NPCs are on-screen # ...which they probably would have been anyway hx := hero x(me) hy := hero y(me) walk hero to y(me, 12) wait for hero(me), w walk hero to x(me, 4) wait for hero(me), w assert(check onetime(3) == false) assert(check onetime(4) == false) use npc(3), w assert(check onetime(3) == true) assert(check onetime(4) == false) use npc(4), w assert(check onetime(3) == true) assert(check onetime(4) == true) w n := npc reference(4) assert(n == false) set onetime(4, false), w n := npc reference(4) assert(n <> false) assert(check tag(10000) == false) w n := npc reference(5) assert(n <> false) set tag(10000, true) w n := npc reference(5) assert(n == false) assert(check tag(10000) == true) walk hero to x(me, hx) wait for hero(me), w walk hero to y(me, hy) wait for hero(me), w end plotscript, another npc script, begin assert(ticknumber == 2) npc script triggered := 1 end script, use npc script tests, begin $0="use npc script tests" # Tests the implicit wait behaviour of usenpc tick counter slice := create container set slice velocity x(tick counter slice, 1, 1000) assert(ticknumber == 0) create npc(8) # Does nothing use npc(8) assert(ticknumber == 1) delete npc(8) # Both this script and anothernpcscript should wait create npc(7) # Calls anothernpcscript npc script triggered := 0 use npc(7) assert(npc script triggered == 1) assert(ticknumber == 2) delete npc(7) free slice(tick counter slice) end script, npc slice tests, begin $0="npc slice tests" # Test positioning of NPC slices. # Note that there's lots of tests for npc slices elsewhere too, # in particular sprite slice spritesets are tested in "global npc tests". variable(n1, sl1) n1 := create npc(9, 10, 8, west) # Check that walkabout slice positions are set immediately sl1 := get npc slice(n1) assert(slice x(sl1) == 10 * 20 && slice y(sl1) == 8 * 20) set NPC position(n1, 3, 4) assert(slice x(sl1) == 3 * 20 && slice y(sl1) == 4 * 20) put NPC(n1, 31, 41) assert(slice x(sl1) == 31 && slice y(sl1) == 41) delete npc(n1) end script, alter npc tests, begin $0="alter npc tests" assert(current map == 0) w # make a pair of NPCs to use in these tests variable(n1, n2) n1 := create npc(9, 5, 5, west),w n2 := create npc(9, 11, 5, east),w # First do picture and palette changes on the first instance # and verify the changes on the second instance assert(get npc sprite id(n2) == 13) assert(get npc sprite palette(n2) == -1) alter npc(n1, NPCStat:picture, 12),w assert(get npc sprite id(n2) == 12) alter npc(n1, NPCStat:palette, 5),w assert(get npc sprite palette(n2) == 5) alter npc(n1, NPCStat:picture, 13),w alter npc(n1, NPCStat:palette, -1),w # Test move speed variable(ox, oy) assert(read npc(n1, NPCStat:move speed) == 0) alter npc(n1, NPCStat:move speed, 1), w ox := npc pixel x(n2) oy := npc pixel y(n2) walk npc(n2, east, 1) w(10) assert(npc pixel x(n2) == ox + 10) w(10) assert(npc pixel x(n2) == ox + 20) alter npc(n1, NPCStat:move speed, 2),w walk npc(n2, south, 1) w(1) assert(npc pixel y(n2) == oy + 2) wait for npc(n2) assert(npc pixel y(n2) == oy + 20) alter npc(n1, NPCStat:move speed, 4),w walk npc(n2, west, 1) w(1) assert(npc pixel x(n2) == ox + 16) wait for npc(n2) alter npc(n1, NPCStat:move speed, 5),w walk npc(n2, north, 1) w(1) assert(npc pixel y(n2) == oy + 15) wait for npc(n2) # Has gone in a complete circle assert(npc pixel x(n2) == ox) assert(npc pixel y(n2) == oy) # How about diagonal next? alter npc(n1, NPCStat:move speed, 10),w walk npc(n2, right, 1) walk npc(n2, down, 1) w(1) assert(npc pixel x(n2) == ox + 10) assert(npc pixel y(n2) == oy + 10) w(1) assert(npc pixel x(n2) == ox + 20) assert(npc pixel y(n2) == oy + 20) alter npc(n1, NPCStat:move speed, 20) walk npc(n2, left, 1) walk npc(n2, up, 1) w(1) assert(npc pixel x(n2) == ox + 0) assert(npc pixel y(n2) == oy + 0) alter npc(n1, NPCStat:move speed, 0) # Now test textbox display assert(read npc(n1, NPCStat:display text) == 0) alter npc(n1, NPCStat:display text, 18),w assert(current text box == -1) use npc(n2), w assert(current text box == 18) advance text box, w assert(current text box == -1) # Test touch and step-on activation # We will use a text box for this test alter npc(n1, NPCStat:display text, 18),w assert(current text box == -1) assert(read npc(n1, NPCstat:activation) == NPCactivation:use) # Move the hero adjacent to the npc walk hero to x(me, npc x(n2)),w wait for hero(me),w assert(hero x(me) == npc x(n2)) assert(hero y(me) == npc y(n2) + 1) assert(current text box == -1) # Try to walking into the npc, nothing should happen walk hero(me, north, 1), w wait for hero(me),w assert(hero y(me) == npc y(n2) + 1) assert(current text box == -1) # Make the NPC touch-activated alter npc(n1, NPCstat:activation, NPCactivation:touch), w # Nothing should happen yet assert(current text box == -1) # Walk the hero into the NPC walk hero(me, north, 1), w wait for hero(me), w assert(current text box == 18) advance text box assert(current text box == -1) # Walk the hero next to the NPC (does nothing because the NPC isn't moving) walk hero(me, right, 1), w wait for hero(me), w assert(current text box == -1) walk hero(me, left, 1), w wait for hero(me), w assert(current text box == -1) # Now move the npc. Even when moving away into a tile one space diagonal, activation should happen alter npc(n1, NPCStat:move speed, 5) walk npc(n2, right, 1), w wait for npc(n2), w assert(current text box == 18) advance text box assert(current text box == -1) # Move one tile further. This should not activate walk npc(n2, right, 1), w wait for npc(n2), w assert(current text box == -1) # Walk back one tile, into the diagonal space. Will activate walk npc(n2, left, 1), w wait for npc(n2), w assert(current text box == 18) advance text box, w assert(current text box == -1) # Walk back one more space, into the adjacent tile, will activate again walk npc(n2, left, 1), w wait for npc(n2), w assert(current text box == 18) advance text box, w assert(current text box == -1) # Now try step-on activation alter npc(n1, NPCstat:activation, NPCactivation:stepon),w walk hero(me, north, 1), w assert(current text box == -1) wait for hero(me), w assert(current text box == 18) advance text box, w assert(current text box == -1) # Move the heroes around walk hero(me, north, 1), w wait for hero(me),w assert(current text box == -1) walk hero(me, right, 1), w wait for hero(me),w walk hero(me, down, 2), w wait for hero(me),w walk hero(me, left, 1), w wait for hero(me),w assert(hero x(me) == npc x(n2)) assert(hero y(me) == npc y(n2) + 1) # Move the step-on npc under the hero (for better or for worse, this does not activate) assert(current text box == -1) walk npc(n2, down, 1), w assert(current text box == -1) wait for npc(n2), w assert(current text box == -1) # Walk the npc back and reset its activation walk npc(n2, up, 1), w wait for npc(n2), w assert(current text box == -1) alter npc(n1, NPCstat:activation, NPCactivation:use), w assert(read npc(n1, NPCstat:activation) == NPCactivation:use) alter npc(n1, NPCstat:display text, 0) #_cancel runfast #wait for key #_runfast # Test getting items assert(read npc(n1, NPCstat:give item) == 0) alter npc(n1, NPCstat:give item, item:Whatsit + 1), w assert(read npc(n1, NPCstat:give item) == item:Whatsit + 1) # There should not be any Whatsits in your inventory yet assert(inventory(item:Whatsit) == 0) # Now get one use npc(n2),w assert(inventory(item:Whatsit) == 1) # Get a few more use npc(n2),w use npc(n2),w use npc(n2),w assert(inventory(item:Whatsit) == 4) # Now clear the get item alter npc(n1, NPCstat:give item, 0), w # This should not give the item use npc(n2),w assert(inventory(item:Whatsit) == 4) ### still needs tests: # NPCstat:move type # NPCstat:when activated # NPCstat:pushability # NPCstat:script # NPCstat:script argument # NPCstat:vehicle # NPCstat:default movement zone # NPCstat:default avoidance zone # NPCstat:ignore passmap while (npc copy count(9) > 0) do( delete npc(9),w ) end script, get npc sprite id, ref, begin variable(sl, spr) sl := get npc slice(ref) spr := lookup slice(sl:walkabout sprite component, sl) assert(get sprite type(spr) == spritetype:walkabout) exit returning(get sprite set number(spr)) end script, get npc sprite palette, ref, begin variable(sl, spr) sl := get npc slice(ref) spr := lookup slice(sl:walkabout sprite component, sl) assert(get sprite type(spr) == spritetype:walkabout) exit returning(get sprite palette(spr)) end ######################################################################## script, death tests, begin $0="death tests" # See also "test harm tile death" below assert (get death script == 0) set death script(@on death script) assert (get death script == @on death script) assert(died == 0) expecting death := false # Setting hero stats to 0 should NOT trigger death variable (i) for (i, 0, 3) do ( set hero stat(i, stat:hp, 0) ) wait assert(died == 0) # Death by oob attack set hero stat(0, stat:hp, 10) # Only hero 0 alive expecting death := true map cure(atk:suicide, 0) assert(get hero stat(0, stat:hp) == 0) # Death script should not be triggered until next tick assert(died == 0) wait(1) assert(died == 1) # Re-trigger even if already dead map cure(atk:suicide, 0) assert(died == 1) wait(1) assert(died == 2) # Death shouldn't be triggered if one hero has 0 max hp variable(old maxhp) oldmaxhp := get hero stat(1, stat:hp, maximum stat) set hero stat(1, stat:hp, 0, maximum stat) map cure(atk:suicide, 0) wait(1) assert(died == 2) set hero stat(1, stat:hp, old maxhp, maximum stat) # Death shouldn't be triggered if heroes are healed before the next tick map cure(atk:suicide, 0) set hero stat(0, stat:hp, 1) wait(1) assert(died == 2) #FIXME: test death by battle expecting death := false died := 0 restore hp and mp end script, on death script, begin $9="on death script" trace(9) if (expecting death) then ( died += 1 exit script ) crash end script, test harm tile death, start hp, begin # Called from "harm tile tests" expecting death := true set harm tile damage(100) walk hero(me, right, 1) wait for hero(me) # The step finishes, causing death, then it will be processed the same tick, spawning the script assert(died == 1) assert hurt pattern(7, start hp, start hp, start hp, start hp, start hp) expecting death := false died := 0 end script, global npc tests, begin $0="global npc tests" variable(oldmap, oldx, oldy) oldmap := current map oldx := hero x(me) oldy := hero y(me) teleport to map(8, 3, 3) w(1) variable(n1, n2) n2 := create npc(0, 10, 8, south, pool:global) n1 := create npc(0, 9, 8, south, pool:local) w(1) # Global NPC 0 and local NPC 0 will have different sprites assert(get sprite set number(get npc sprite(n1)) == 11) # sheep assert(get sprite set number(get npc sprite(n2)) == 15) # chewie # By ref works on both set npc direction(n1, left) set npc direction(n2, left) w(1) assert(npc direction(n1) == left) assert(npc direction(n2) == left) # by ID does the local ID set npc direction(0, right) w(1) assert(npc direction(n1) == right) assert(npc direction(n2) == left) teleport to map(9, 3, 2) w(1) n1 := npc reference(2) assert(n1 <> 0) assert(npc x(n1) == 4) assert(npc y(n1) == 3) assert(get sprite set number(get npc sprite(n1)) == 13) w(1) n1 := global npc reference(2) assert(n1 == global npc(2)) # test alias assert(n1 <> 0) assert(npc x(n1) == 11) assert(npc y(n1) == 3) assert(get sprite set number(get npc sprite(n1)) == 17) w(1) n1 := global npc reference(2, 2) assert(n1 <> 0) assert(npc x(n1) == 11) assert(npc y(n1) == 5) assert(get sprite set number(get npc sprite(n1)) == 17) w(1) n2 := create npc(2, 11, 6, left, pool:global) assert(npc copy count(2) == 3) assert(npc copy count(2, pool:global) == 4) w(1) # Change NPC ID and pool change npc id(n2, 1) # should still be global assert(get sprite set number(get npc sprite(n2)) == 16) # triangle w(1) # become local change npc id(n2, 0, pool:local) assert(get sprite set number(get npc sprite(n2)) == 13) # pup w(1) # back to a global again change npc id(n2, 0, pool:global) assert(get sprite set number(get npc sprite(n2)) == 15) # chewie w(1) # Test change npc id with ID numbers # Change the first local 2 into 3 change npc id(2, 3) assert(npc y(2) == 4) w(1) # change the first global 2 into 1 change npc id(2, 1, pool:global) assert(get sprite set number(get npc sprite(global npc reference(1))) == 16) # chewie w(1) # many NPC commands will only refer to local NPCs by ID, you need a refernce to worj with globals # No NPC should move, because local ID 1 does not exist, even though global ID 1 exists walk npc(1, left, 1) wait for npc(1) # Global NPC id 1 will not have moved assert(get npc id(npc at spot(11, 3)) == 1) w(1) # Test read npc assert(read npc(2, npcstat:picture, pool:local) == 13) # pup n1 := npc reference(2) assert(read npc(n1, npcstat:picture) == 13) # pup w(1) assert(read npc(2, npcstat:picture, pool:global) == 17) # snake n1 := global npc reference(2) assert(read npc(n1, npcstat:picture) == 17) # snake w(1) n2 := create global npc(0, 7, 5) assert(n2 < 0) assert(get sprite set number(get npc sprite(n2)) == 15) # chewie walk npc(n2, south, 1) wait for npc(n2) assert(npc y(n2) == 6) w(1) # Test alter NPC assert(read npc(0, npcstat:movespeed, pool:global) == 4) alter npc(0, npcstat:movespeed, 10, pool:global) assert(read npc(0, npcstat:movespeed, pool:global) == 10) w(1) # Alterations made to global NPC persist between map changes teleport to map(8, 3, 3) w(1) assert(npc copy count(0, pool:global) == 0) assert(read npc(0, npcstat:movespeed, pool:global) == 10) n1 := create global npc(0, 4, 4, south) assert(read npc(0, npcstat:movespeed, pool:global) == 10) walk npc(n1, south,1) wait for npc(n1) w(1) # And a local npc with the same ID is unaffected n2 := create npc(0, 5, 4, left) assert(read npc(0, npcstat:movespeed, pool:local) == 4) assert(read npc(n2, npcstat:movespeed) == 4) w(1) # change it into a global npc assert(get npc pool(n2) == pool:local) change npc id(n2, 0, pool:global) assert(get npc pool(n2) == pool:global) assert(read npc(n2, npcstat:movespeed) == 10) w(1) teleport to map(oldmap, oldx, oldy) end ######################################################################## script, trigger tests, begin harm tile tests end script, assert hurt pattern, test no, start hp, h0, h1, h2, h3, begin # h# is the amount of damage by which hero # in the walkabout party should be hurt # h# is ignored if # > number of heroes in walkabout party $0="assert hurt pattern, test no. " append number(0, test no) subscript, consider rank, rank, harm amount, begin if (hero by rank(rank) == -1) then (exit script) # This will break if there are duplicate heroes, a well known flaw variable(slot) slot := find hero(hero by rank(rank)) tracevalue(rank, slot, get hero stat(slot, stat:hp), start hp -- harm amount) assert(get hero stat(slot, stat:hp) == start hp -- harm amount) set hero stat(slot, stat:hp, start hp) end consider rank(0, h0) consider rank(1, h1) consider rank(2, h2) consider rank(3, h3) end script, harm tile tests, begin $0="harm tile tests" # Test harmtile damage walk hero to x(me, 7) walk hero to y(me, 6) wait for hero(me) variable(start hp) start hp := get hero stat(0, stat:hp, current stat) write map block(6, 6, 140, 1) write pass block(6, 6, harmtile) subscript, test damage patterns, begin set caterpillar mode(on) # Turn off "Harm tiles harm non-caterpillar party" (actually the current setting in the .rpg) write general(177, read general(177), and, (-1, xor, 2^12)) # hero is now at tile 7,6, caterpillar is enabled and not suspended, and all heroes have 'start hp' hp # Test damage to individual heroes, caterpillar enabled # also testing crossing over harmtile without stopping walk hero(me, left, 1) wait for hero(me), _checkpoint # check for flash assert hurt pattern(0, start hp, true, false, false, false) walk hero(me, left, 2) wait for hero(me), _checkpoint assert hurt pattern(1, start hp, false, true, true, false) # Test damage to individual heroes, caterpillar suspended suspend caterpillar walk hero(1, right, 1) # step onto harm tile walk hero(2, down, 1) # step off harm tile walk hero(3, left, 1) # step onto harm tile wait for hero(2) assert hurt pattern(2, start hp, false, true, false, true) # Test damage to whole party, caterpillar disabled # (Leader walks back and forth over the tile) set caterpillar mode(off) walk hero(me, right, 3) # two tiles onto harm, then one off wait for hero(me) # "Harm tiles harm non-caterpillar party" is off assert hurt pattern(3, start hp, true, false, false, false) # Turn on "Harm tiles harm non-caterpillar party" write general(177, read general(177), or, 2^12) walk hero(me, left, 2) wait for hero(me) assert hurt pattern(4, start hp, true, true, true, true) # Check this makes no difference resume caterpillar walk hero(me, right, 2) wait for hero(me) assert hurt pattern(5, start hp, true, true, true, true) end # Test with four heroes in the party trace($99="First harmtile test run") test damage patterns # Move hero back to 7,6 set hero position(me, 11, 6) walk hero to x(me, 7) wait for hero(me) # Test party and walkabout slots not matching trace($99="Second harmtile test run") swap by position(0, 20) # remove leader test damage patterns # Test damage value set harm tile damage(2) walk hero(me, left, 2) wait for hero(me) assert hurt pattern(6, start hp, 2, 2, 2, 2) # Test death test harm tile death(start hp) # Cleanup write map block(6, 6, 0, 1) write pass block(6, 6, 0) swap by position(0, 20) # return leader set caterpillar mode(on) set harm tile damage(1) # restore # Caterpiller on and resumed, all heroes have 'start hp' hp end ######################################################################## script, menu tests, begin $0="menu tests" variable(i, m, mi, main, m1) m := create menu, w if(get menu id(m) <> -1) then($0="get menu id should have reported -1 for script-generated menu", crash) mi := add menu item(m), w $1="Puppies" set menu item caption(mi, 1), w mi := add menu item(m), w $1="Kittens" set menu item caption(mi, 1), w mi := add menu item(m), w $1="Walruses" set menu item caption(mi, 1), w mi := add menu item(m), w $1="Octopus" set menu item caption(mi, 1), w mi := add menu item(m), w $1="Plip" set menu item caption(mi, 1), w main := open menu, w bring menu forward(bottom menu), w for(i, align:left, align:right) do( set menu anchor x(m, i), w if(get menu anchor x(m) <> i) then($0="menu anchor x", crash) set menu anchor y(m, i), w if(get menu anchor y(m) <> i) then($0="menu anchor y", crash) ) $1="Puppies" mi := find menu item caption(m, 1) if(mi == 0) then($0="failed to find first menu item by caption", crash) get menu item caption(mi, 2) if(not(string compare(1, 2))) then($0="found menu item that was not puppies", crash) $1="Walruses" mi := find menu item caption(m, 1) get menu item caption(mi, 2) if(not(string compare(1, 2))) then($0="found menu item that was not walruses", crash) mi := find menu item caption(m, 1, mi) #search for Walruses starting after Walruses if(mi <> 0) then($0="find menu item walrus should have failed", crash) mi := add menu item(m) $1="Kittens" set menu item caption(mi, 1), w variable(kitten1, kitten2, walruses) #search for Kitten from top $1="Kittens" kitten1 := find menu item caption(m, 1) #search for Kitten starting after Walruses $2="Walruses" walruses := find menu item caption(m, 2) kitten2 := find menu item caption(m, 1, walruses) if(kitten1 == 0) then($0="failed to find first kitten", crash) if(kitten2 == 0) then($0="failed to find second kitten", crash) get menu item caption(kitten1, 2) if(not(string compare(1, 2))) then($0="found menu item that was not kitten(1)", crash) get menu item caption(kitten2, 2) if(not(string compare(1, 2))) then($0="found menu item that was not kitten(2)", crash) if(kitten1 == kitten2) then($0="found the same kitten twice", crash) mi := add menu item(m), w delete menu item(mi), w $1="Kittens" mi := find menu item caption(m, 1) delete menu item(mi), w mi := first menu item(m) delete menu item(mi), w if(find menu ID(1) <> 0) then($0="found unopened menu", crash) open menu(1),w m1 := find menu ID(1) if(get menu ID(m1) <> 1) then($0="get menu ID mismatch vs find menu", crash) if(m1 == 0) then($0="failed to find opened menu", crash) close menu(m1),w for(i, -3, 12) do( set menu border(main, i), w ) if(get menu border(main) <> 12) then($0="readback of menu border thickness failed", crash) for(i, 0, 10) do( set menu boxstyle(main, i) ) if(get menu boxstyle(main) <> 10) then($0="readback of menu boxstyle failed", crash) for(i, 0, 15) do( set menu max chars(main, i), w if(get menu max chars(main) <> i) then($0="readback of menu max chars failed", crash) ) set menu max chars(main, 0), w for(i, 10, 30) do( set menu min chars(main, i), w if(get menu min chars(main) <> i) then($0="readback of menu min chars failed", crash) ) set menu min chars(main, 0), w for(i, -50, 50, 10) do( set menu offset x(main, i), w if(get menu offset x(main) <> i) then($0="readback of menu offset x failed", crash) set menu offset y(main, i), w if(get menu offset y(main) <> i) then($0="readback of menu offset y failed", crash) ) set menu offset x(main, 0) set menu offset y(main, 0) for(i, align:left, align:right) do( set menu anchor x(main, i), w if(get menu anchor x(main) <> i) then($0="readback of menu anchor x failed", crash) set menu anchor y(main, i), w if(get menu anchor y(main) <> i) then($0="readback of menu anchor y failed", crash) ) set menu anchor x(main, 0), w set menu anchor y(main, 0), w for(i, align:left, align:right) do( set menu text align(main, i), w if(get menu text align(main) <> i) then($0="readback of menu text align failed", crash) ) set menu text align(main, 0), w set menu bit(main, 0, true), w #Transparent box if(get menu bit(main, 0) <> true) then($0="failed to set menu bit", crash) set menu bit(main, 0, false), w #Opaque box if(get menu bit(main, 0) <> false) then($0="failed to unset menu bit", crash) variable(save rows) save rows := get menu max rows(main) set menu max rows(main, 3), w set menu bit(main, 1, true), w #never show scrollbar set menu bit(main, 1, false), w #show scrollbar set menu max rows(main, save rows) set menu bit(main, 4, true), w #no box set menu bit(main, 4, false), w #show box set menu bit(main, 8, true), w #Advance text box when menu closes show text box(6), w if(not(menu is open(main))) then($0="why isn't the main menu open?", crash) close menu(top menu), w close menu(main), w if(current text box <> -1) then($0="menu bit failed to close textbox", crash) if(menu is open(main)) then($0="why is the main menu still open?", crash) variable(antelope, buffalo, catbus, duiker) m := create menu, w antelope := add menu item(m), $0="Antelope", set menu item caption(antelope, 0), w buffalo := add menu item(m), $0="Buffalo", set menu item caption(buffalo, 0), w catbus := add menu item(m), $0="Catbus", set menu item caption(catbus, 0), w duiker := add menu item(m), $0="Duiker", set menu item caption(duiker, 0), w # Test disabled, hidden, and unselectable items set menu item bit(catbus, menuitembit:hide when disabled, true), w assert(get menu item bit(catbus, menuitembit:hide when disabled) == true) # Disable and hide now set menu item type(catbus, menutype:label) set menu item subtype(catbus, menulabel:disabled) # (menu item disabled/visible/selectable should reflect changes immediately without needing a wait) assert(menu item disabled(catbus) == true) assert(menu item visible(catbus) == false) assert(menu item selectable(catbus) == false) w # Don't hide set menu item bit(catbus, menuitembit:hide when disabled, false) assert(menu item disabled(catbus) == true) assert(menu item visible(catbus) == true) assert(menu item selectable(catbus) == true) w # Un-selectable set menu item subtype(catbus, menulabel:unselectable) assert(menu item disabled(catbus) == false) assert(menu item visible(catbus) == true) assert(menu item selectable(catbus) == false) w # Re-enable set menu item subtype(catbus, menulabel:selectable) assert(menu item disabled(catbus) == false) assert(menu item visible(catbus) == true) assert(menu item selectable(catbus) == true) w # Test unselectable menu items are unselectable # (Note: you can select hidden items! Keeping for backcompat?) select menu item(catbus), w assert(selected menu item(m) == catbus) set menu item subtype(catbus, menulabel:unselectable) w # Requires a wait to take effect assert(selected menu item(m) == duiker) # The next selectable item assert(select menu item(antelope) == true) assert(select menu item(catbus) == false) # Unselectable, fails assert(selected menu item(m) == antelope) set menu item subtype(catbus, menulabel:selectable) select menu item(catbus) assert(selected menu item(m) == catbus) set menu item settag(catbus, 3) if(get menu item settag(catbus) <> 3) then($0="menu item settag readback failed", crash) if(check tag(3)) then($0="tag 3 shouldn't be on yet (menu)", crash) use menu item(catbus), w if(not(check tag(3))) then($0="tag 3 shouldn't be on now (menu)", crash) set menu item settag(catbus, 0) set menu item togtag(catbus, 3) use menu item(catbus), w if(check tag(3)) then($0="tag 3 should be toggled off (menu)", crash) use menu item(catbus), w if(check tag(3)==OFF) then($0="tag 3 should be toggled on (menu)", crash) use menu item(catbus), w if(check tag(3)) then($0="tag 3 should be toggled off again (menu)", crash) set menu item togtag(catbus, 0) for(i, 1, 2) do( set menu item tag(catbus, -3, i), w if(get menu item tag(catbus, i) <> -3) then($0="menu item tag readback failed", crash) set tag(3, ON), w set menu item tag(catbus, 3, i), w set tag(3, OFF), w set menu item tag(catbus, 0, i), w ) $0="menu item tag req", show string(0) for(i, 1, 2) do( set tag(3, OFF) if(get menu item tag(catbus, i) <> 0) then($0="menu item tag req should be zero:", append number(0, i), crash) set menu item tag(catbus, 3, i), w if(get menu item tag(catbus, i) <> 3) then($0="menu item tag req readback fail:", append number(0, i), crash) set tag(3, ON), w set menu item tag(catbus, -3, i), w set tag(3, OFF), w set menu item tag(catbus, 0, i), w ) show no value # menu item extra data assert(extra length(buffalo) == 3) for(i, 0, 2) do( assert(get menu item extra(buffalo, i) == 0) set menu item extra(buffalo, i, i*10) assert(get menu item extra(buffalo, i) == i*10) assert(get extra(buffalo, i) == i*10) set extra(buffalo, i, 20) assert(get menu item extra(buffalo) == 20) ) resize extra(buffalo, 0) assert(extra length(buffalo) == 0) append extra(buffalo, 42) assert(extra length(buffalo) == 1) assert(get menu item extra(buffalo, -1) == 42) # Check negative indices set menu item type(catbus, menutype: special) $0="" # use default caption set menu item caption(catbus, 0), w for (i, 0, 13) do( set menu item subtype(catbus, i), w ) $0="Catbus, not Save" set menu item caption(catbus, 0), w $0="" set menu item caption(catbus, 0), w set menu item type(catbus, menutype:menu), w for(i, 0, 2) do( set menu item subtype(catbus, i), w if(get menu item subtype(catbus) <> i) then($0="menu item subtype readback failed", crash) ) $0="Catbus" set menu item caption(catbus, 0), w # open another menu set menu item type(catbus, menutype:menu) set menu item subtype(catbus, 2) use menu item(catbus), w if(get menu id(top menu) <> 2) then($0="Failed to open a menu from a menu", crash) close menu(top menu), w # open a text box set menu item type(catbus, menutype:textbox) set menu item subtype(catbus, 7) use menu item(catbus), w if(current textbox <> 7) then($0="Failed to open a text box from a menu", crash) advance text box, w if(get menu item type(catbus) <> menutype:textbox) then($0="menu item type readback failed", crash) set menu item type(catbus, menutype:label) # run a script from a menu set menu item type(catbus, menutype:script) set menu item subtype(catbus, @on menu item use) use menu item(catbus), w if(menu item script global <> 99) then($0="Failed to run a script from a menu", crash) variable(oldcol) oldcol := get menu textcolor(m) for(i, 0, 10) do( set menu textcolor(m, i * 13), w if(get menu textcolor(m) <> i * 13) then($0="menu textcolor readback failed", crash) ) set menu textcolor(m, oldcol) # iterate all menu items variable(count) count := 0 mi := first menu item(m) while(mi) do( count += 1 mi := next menu item(mi) ) if(count <> 4) then($0="iterated wrong number of menu items (all)") # now hide catbus set menu item bit(catbus, menu item bit:hide when disabled, true) set menu item tag(catbus, 3) set tag(3, OFF) # iterate all except hidden count := 0 mi := first menu item(m) while(mi) do( count += 1 mi := next menu item(mi, true) ) if(count <> 3) then($0="iterated wrong number of menu items (vis only)") # iterate all including hidden count := 0 mi := first menu item(m) while(mi) do( count += 1 mi := next menu item(mi, false) ) if(count <> 4) then($0="iterated wrong number of menu items (vis only)") # close when selected set menu item bit(antelope, 1, true) use menu item(antelope), w if(top menu == m) then($0="Even Toed Ungulate menu failed to close", crash) menu close global := 0 m := create menu, w mi := add menu item(m) $1="close me" set menu item caption(mi, 1), w set menu item bit(mi, menu item bit:close menu when selected, true) set menu on close script(m, @on close menu test) if(get menu on close script(m) <> @on close menu test) then($0="menu close script readback failed", crash) use menu item(mi), w if(menu close global <> 99) then($0="menu close script didn't run", crash) # Test background highlight w(2) m := create menu, w mi := add menu item(m), w set menu item caption(mi, $1="Lorem"), w mi := add menu item(m), w set menu item caption(mi, $1="Ipsum"), w mi := add menu item(m), w set menu item caption(mi, $1="Dolor"), w mi := add menu item(m), w set menu item caption(mi, $1="Sit"), w mi := add menu item(m), w set menu item caption(mi, $1="Amet"), w assert(get menu bit(m, menubit:highlight selection background) == false) set menu bit(m, menubit:highlight selection background), w assert(get menu bit(m, menubit:highlight selection background) == true) mi := first menu item(m) while(mi) do( mi := next menu item(mi, true) if(mi) then(select menu item(mi)) w(2) ) w close menu(m),w # Test closing a textbox by closing the menu m := create menu, w mi := add menu item(m), w set menu item caption(mi, $1="Twas brillig"), w mi := add menu item(m), w set menu item caption(mi, $1="And the slithy toaves..."), w assert(get menu bit(m, menubit:advance text box when menu closes) == false) show text box(2),w # first, closing the menu should not close the textbox by default close menu(m),w assert(current text box == 2) advance text box, w assert(current text box == -1) # Now do it again... m := create menu, w mi := add menu item(m), w set menu item caption(mi, $1="Did gyre and gimbal"), w mi := add menu item(m), w set menu item caption(mi, $1="In the wabe..."), w assert(get menu bit(m, menubit:advance text box when menu closes) == false) set menu bit(m, menubit:advance text box when menu closes), w assert(get menu bit(m, menubit:advance text box when menu closes) == true) show text box(2),w # This time, closing the menu should close the textbox too close menu(m),w assert(current text box ==-1) # Test edgecases for menus without selectable menu item. # Open a menu where the first item is unselectable: m := open menu(3) assert(menu item slot(selected menu item(m)) == 1) w close menu(m) # Empty menu m := create menu() assert(selected menu item == 0) close menu(m) # Open a menu with no selectable items m := open menu(4) assert(selected menu item == 0) w close menu(m) menu scroll tests end script, on menu item use, begin menu item script global := 99 end script, on close menu test, begin menu close global := 99 end script, scroll through menu, menu, numitems, begin variable (i, j, mi) # test scrolling for (i, 1, 3, 2) do ( set menu max rows(menu, i) # forwards mi := first menu item(menu) while (mi) do ( select menu item(mi), w mi := next menu item(mi) ) # backwards mi := menu item by slot(menu, numitems -- 1) while (mi) do ( select menu item(mi), w mi := previous menu item(mi) ) # randomly for (j, 0, 4) do ( select menu item(menu item by slot(menu, random(0, numitems -- 1))), w ) ) set menu max rows(menu, 0) end script, menu scroll tests, begin $0="menu scroll tests" variable (main, mi, next, i, numitems, numvisitems) main := open menu, w set menu bit(main, 1, false), w #show scrollbar allow minimap(true), w #make sure there are no hidden items allow save anywhere(true), w # test menu item iteration mi := first menu item(main) while (mi) do ( get menuitemcaption(mi, err arg string) #trace(err arg string) appendnumber(err arg string, numitems) assert (menu item slot(mi) == numitems) assert (menu item by slot(main, numitems, true) == mi) assert (menu item by slot(main, numitems, false) == mi) assert (menu item true slot(mi) == numitems) assert (menu item by true slot(main, numitems) == mi) next := next menu item(mi, false) if (next) then ( assert (mi == previous menu item(next)) ) set menu item extra(mi, 0, numitems) numitems += 1 mi := next ) assert(numitems == 9) $err arg string="" # menu item iteration edge cases assert (previous menu item(first menu item(main)) == 0) assert (next menu item(menu item by slot(main, numitems -- 1)) == 0) assert (menu item by slot(main, numitems, true) == 0) assert (menu item by slot(main, numitems, false) == 0) assert (menu item by slot(main, -1) == 0) assert (menu item by true slot(main, -1) == 0) assert (menu item by true slot(main, numitems) == 0) # test "select menu item" mi := first menu item(main) while (mi) do ( select menu item(mi), w assert (selected menu item(main) == mi) mi := next menu item(mi) ) # test scrolling scroll through menu(main, numitems) # check hidden items sorted to end: # 1. hide three items set tag(3, OFF) variable(hidden1, hidden2, hidden3) hidden3 := menu item by slot(main, 4) set menu item bit(hidden3, menu item bit: hide when disabled, true) set menu item tag(hidden3, 3, 1) hidden1 := menu item by slot(main, 0) set menu item bit(hidden1, menu item bit: hide when disabled, true) set menu item tag(hidden1, 3, 1) hidden2 := menu item by slot(main, 3) set menu item bit(hidden2, menu item bit: hide when disabled, true) set menu item tag(hidden2, 3, 1) w # 2. add new item mi := add menu item(main) set menu item extra(mi, 0, numitems) numitems += 1 $1="a new item!" set menu item caption(mi, 1), w assert (numitems == menu item count(main)) numvisitems := numitems -- 3 assert (numvisitems == visible menu item count(main)) # 3. check visible items in correct order variable (temp, extra, mi2) temp := -1 for (i, 0, num items -- 3 -- 1) do ( mi := menu item by slot(main, i, true) mi2 := menu item by slot(main, i, false) assert (mi == mi2) extra := get menu item extra(mi2, 0) if (extra <= temp) then ($0="menu items not in increasing order", crash) temp := extra ) # 4. check hidden items at end in correct order if (menu item by slot(main, numitems -- 3, true) <> 0) then ($0="menuitembyslot returned hidden item", crash) if (menu item by slot(main, numitems -- 3, false) <> hidden1) then ($0="hidden items out of order", crash) if (menu item by slot(main, numitems -- 2, false) <> hidden2) then ($0="hidden items out of order", crash) if (menu item by slot(main, numitems -- 1, false) <> hidden3) then ($0="hidden items out of order", crash) assert (menu item by slot(main, numitems, false) == 0) # 5. check "true order" hasn't changed for (i, 0, num items -- 1) do ( mi := menu item by true slot(main, i) assert (menu item true slot(mi) == i) assert (get menu item extra(mi, 0) == i) ) # 6. test "last menu item" assert (last menu item(main) == menu item by slot(main, numvisitems -- 1)) assert (last menu item(main, false) == menu item by slot(main, numitems -- 1, false)) assert (next menu item(last menu item(main)) == 0) # Don't return first invisible item assert (next menu item(last menu item(main), false) <> 0) # Do return first invisible item # test scrolling again scroll through menu(main, numitems -- 3) # check unhidden menu items sorted back correctly set tag(3, ON), w for (i, 0, numitems -- 1) do ( mi := menu item by slot(main, i, false) assert (mi == menu item by slot(main, i, true)) assert (get menu item extra(mi, 0) == i) ) close menu(main) end #next menu(menu handle) #open menu (ID, allow duplicate) #parent menu(menu item handle) #previous menu(menu handle) #swap menu items(handle1, handle2) #wait for menu (menu handle) ######################################################################## script, textbox tests, begin $0="textbox tests" show text box(2), w advance text box, w show text box(3), w advance text box, w if(current textbox <> 4) then(crash) advance text box, w show text box(3), w advance text box, w if(current textbox <> 5) then(crash) advance text box, w if(current textbox <> -1) then(crash) w show text box(12), w, advance text box, w show text box(13), w, advance text box, w variable (oldval) oldval := read general(178) # genBits2 assert((oldval, and, 2^2) == 2^2) # "showtextbox happens immediately" is on # check showtextbox isn't delayed show text box(14) assert(checktag(tag:textbox 14 happened) == true) # no wait required before advance advance textbox wait assert(current textbox == -1) settag(tag:textbox 14 happened, false) # check both showtextboxes work show text box(14) show text box(15) assert(checktag(tag:textbox 14 happened) == true) assert(checktag(tag:textbox 15 happened) == true) advance textbox settag(tag:textbox 14 happened, false) settag(tag:textbox 15 happened, false) write general(178, oldval -- 2^2) # "showtextbox happens immediately" OFF # Check currenttextbox still updates immediately show text box(2) assert(current textbox == 2) # wait required before advance wait advance text box assert(current textbox == -1) # check showtextbox is delayed show text box(14) assert(checktag(tag:textbox 14 happened) == false) wait assert(checktag(tag:textbox 14 happened) == true) advance textbox settag(tag:textbox 14 happened, false) # check only last showtextbox works show text box(14) show text box(15) wait assert(checktag(tag:textbox 14 happened) == false) assert(checktag(tag:textbox 15 happened) == true) advance textbox write general(178, oldval) end ######################################################################## script, shop tests, begin # Ain't much here yet... $0="shop tests" assert(is shop buy menu empty(shop:Boring Shop) == false) assert(is shop hire menu empty(shop:Boring Shop) == false) assert(is shop buy menu empty(shop:Empty Shop) == true) assert(is shop hire menu empty(shop:Empty Shop) == true) w end ######################################################################## script, battle tests, begin # there are some other battle tests in with the timer tests $0="battle tests" set battle countdown (182) assert(get battle countdown == 182) show value(random(1, 999999999)), w force random battle(1) show value(random(1, 999999999)), w # this should remain deterministic after battle show no value, w # attack forces run set tag(tag:Victory, true) assert(fight formation(1) == false), w # sets victory tag assert(check tag(tag:Victory) == false) # attack forces victory assert(fight formation(2) == true), w assert(check tag(tag:Victory) == true) # attack forces exit assert(fight formation(3) == false), w # test tag check: battle should not trigger force random battle(2) assert(last formation <> 4) w(5) fight formation(5) w(5) # Test attacks setting tags. set tag(4, false) set tag(5, false) fight formation(6) w(5) # The first time should NOT set tag 5 because tag 4 was not set assert(not(check tag(5))), w set tag(4, true) fight formation(6) w(5) # The second time SHOULD set tag 5 because tag 4 WAS set assert(check tag(5)), w set tag(6, false) fight formation(7) w(5) # The third one should always turn the tag on because the tag check is 0. assert(check tag(6)), w test battle formation modification test hero counterattacks end # Formation set should be 1-2 script, force random battle, formation set = 1, begin variable(s, x, y, d) if (formation set == 0) then (formation set := 1) # If run with runscriptbyid # save hero state s := get hero speed(me) x := hero x(me) y := hero y(me) d := hero direction(me) # get the hero ready for forcing the battle set hero speed(0, 20) # Formations 1-3 are at x = 14-16 set hero position(0, 13 + formation set, 9), w # force the battle walk hero(0, north, 1), w # restore hero state set hero speed(me, s) set hero position(me, x, y) set hero direction(me, d) w # Countdown should be in range 40-160 (test this here so we see multiple battles assert(get battle countdown >= 40 && get battle countdown <= 160) end script, force non random battle, begin w fight formation(0) w(2) end plotscript, after battle, begin $0="After battle script:" battle script sequence += 1 append number(0, battle script sequence) trace(0) show string at(0, 0, 0) w hide string(0) end plotscript, instead of battle, form, begin $0="Instead of battle script(" append number(0, form) $0+")" trace(0) w fight formation(form) $0=" finish instead of battle" trace(0) end script, test battle formation modification, begin # Test formation editing commands # use reward gold to keep track of how many enemies are present in each formation variable(orig gold, gold) orig gold := party money gold := party money fight formation(8), w assert(party money == gold + 1) # Add an enemy to the formation add enemy to formation (8, 8, 100, 90, 1) assert(formation slot enemy(8, 1) == 8) assert(formation slot x(8, 1) == 100) assert(formation slot y(8, 1) == 90) gold := party money fight formation(8), w assert(party money == gold + 2) # Fill the empty slots in the formation variable(i) for(i, 2, 7) do( add enemy to formation (8, 8, 100, 90 + i * 20, 1) ) gold := party money fight formation(8), w assert(party money == gold + 8) # remove several enemies, including the original enemy in slot 0 delete enemy from formation (8, 0) delete enemy from formation (8, 1) delete enemy from formation (8, 2) delete enemy from formation (8, 3) w assert(formation slot enemy(8, 0) == -1) assert(formation slot enemy(8, 1) == -1) assert(formation slot enemy(8, 2) == -1) assert(formation slot enemy(8, 3) == -1) gold := party money fight formation(8), w assert(party money == gold + 4) # Test finding an enemy w # an enemy that will not be found assert(find enemy in formation (8, 1, 0) == -1) assert(find enemy in formation (8, 1, get count) == 0) # an enemy that is actually present assert(find enemy in formation (8, 8, 0) == 4) assert(find enemy in formation (8, 8, 3) == 7) assert(find enemy in formation (8, 8, get count) == 4) # Test background changing assert(get formation background(8) == 1) set formation background(8, 0) assert(get formation background(8) == 0) # Test writing song id number show value(get formation song(8)) assert(get formation song(8) == song:silence) set formation song(8, song:same as map) assert(get formation song(8) == song:same as map) set formation song(8, song:tin glazed and noncommutative) assert(get formation song(8) == song:tin glazed and noncommutative) # actually run the battle. We can't test the visuals, but -autosnap will see it fight formation(8), w # Test resetting the formation to default reset formation(8), w assert(get formation background(8) == 1) assert(get formation song(8) == song:silence) assert(find enemy in formation (8, 8, 0) == 0) assert(find enemy in formation (8, 8, get count) == 1) assert(formation slot enemy(8, 0) == 8) assert(formation slot x(8, 0) == 131) assert(formation slot y(8, 0) == 169) show string(string sprintf(2, $1="%dx%d", formation slot x(8, 0), formation slot y(8, 0))), w fight formation(8), w # Test modifying and resetting individual formation slots # Assert original values assert(formation slot enemy(9, 0) == 0) assert(formation slot x(9, 0) == 18) assert(formation slot y(9, 0) == 201) assert(formation slot enemy(9, 1) == -1) assert(formation slot x(9, 1) == 0) assert(formation slot y(9, 1) == 0) # Make changes delete enemy from formation(9, 0) add enemy to formation(9, 8, 50, 190, 1) assert(formation slot enemy(9, 0) == -1) # deleted enemies do not have their x,y deleted, but width/height are no longer included assert(formation slot x(9, 0) == 1) assert(formation slot y(9, 0) == 167) assert(formation slot enemy(9, 1) == 8) assert(formation slot x(9, 1) == 50) assert(formation slot y(9, 1) == 190) fight formation(9) # Reset single slots reset formation slot(9, 0) assert(formation slot enemy(9, 0) == 0) assert(formation slot x(9, 0) == 18) assert(formation slot y(9, 0) == 201) assert(formation slot enemy(9, 1) == 8) assert(formation slot x(9, 1) == 50) assert(formation slot y(9, 1) == 190) reset formation slot(9, 1) assert(formation slot enemy(9, 0) == 0) assert(formation slot x(9, 0) == 18) assert(formation slot y(9, 0) == 201) assert(formation slot enemy(9, 1) == -1) assert(formation slot x(9, 1) == 0) assert(formation slot y(9, 1) == 0) # restore original money set money(orig gold) show no value end script, test hero counterattacks, begin assert(hero by slot(0) == hero:Freki) assert(get hero stat(0, stat:HP, current stat) == 10), w fight formation(10), w # Freki's HP should be 4 points lower, -1 for the ice attack, and -3 for her self-counterattack assert(get hero stat(0, stat:HP, current stat) == 6), w # Heal up set hero stat(0, stat:HP, 10, current stat), w end ######################################################################## script, attack tests, begin $0="attack tests" # Reading attack name $1="SelfStab" read attack name(2, atk:SelfStab) assert(string compare(1,2)) $2="" read attack name(2, 0 + 1) assert(string compare(1,2)) $2="" get attack name(2, 0 -- 1) assert(string compare(1,2)) # Reading attack caption $1="Attack self" get attack caption(2, 0 + 1) assert(string compare(1,2)) assert(get attack extra(atk:SelfStab, 0) == 42) assert(get attack extra(atk:SelfStab, 2) == 99) assert(get attack extra(atk:ForceRun) == 0) assert(get attack extra(10 + 1, 2) == 1) # Currently the last attack end ######################################################################## script, enemy tests, begin $0="enemy tests" assert(enemy elemental resist as int(enemy:Data Read Test, 2) == 0) assert(enemy elemental resist as int(enemy:Data Read Test, 15) == -5) # Name get enemy name(enemy:Data Read Test, 1) $2 = "Data read test" assert(string compare(1, 2)) $2 = "Data read test2" set enemy name(enemy:Data Read Test, 2) get enemy name(enemy:Data Read Test, 1) assert(string compare(1, 2)) reset enemy name(enemy:Data Read Test) get enemy name(enemy:Data Read Test, 1) $2 = "Data read test" assert(string compare(1, 2)) # Length limit is currently 16, so check at least first 16 chars saved $2 = "SeenGoldDuckUponHigh" set enemy name(enemy:Data Read Test, 2) get enemy name(enemy:Data Read Test, 1) trim string(1, 1, 16) trim string(2, 1, 16) assert(string compare(1, 2)) # Stats assert(get enemy stat(enemy:Data Read Test, stat:HP) == 13) set enemy stat(enemy:Data Read Test, stat:Hits, 6) assert(get enemy stat(enemy:Data Read Test, stat:Hits) == 6) reset enemy stat(enemy:Data Read Test, stat:Hits) assert(get enemy stat(enemy:Data Read Test, stat:HP) == 13) # Other set enemy appearance(enemy:Data Read Test, Enemy:PictureSize, EnemySize:large) assert(get enemy appearance(enemy:Data Read Test, Enemy:PictureSize) == EnemySize:large) assert(get enemy appearance(enemy:Data Read Test, Enemy:Palette) == -1) assert(read enemy data(enemy:Data Read Test, Enemy:Item) == 1) write enemy data(enemy:Data Read Test, Enemy:RareItem, 2) assert(read enemy data(enemy:Data Read Test, Enemy:RareItem) == 2) assert(read enemy data(enemy:Data Read Test, Enemy:ItemPercent) == 50) write enemy data(enemy:Data Read Test, Enemy:ItemPercent, 24) assert(read enemy data(enemy:Data Read Test, Enemy:ItemPercent) == 24) reset enemy data(enemy:Data Read Test, Enemy:ItemPercent) assert(read enemy data(enemy:Data Read Test, Enemy:ItemPercent) == 50) end ######################################################################## script, timer tests, begin variable(i) allocate timers(32) set timer(31, 10, 1, @timer test 1, 1) show string at(1, 10, 10) w, w, w, w if(read timer(31) <> 6) then($0="read timer failed", crash) w(6), w timer global := 100 set timer(31, 0, 1, @looping timer test, 1) w(11) # Test "set timer args" timer global := 0 set timer(timer:set args test, 0, 1, @timer args test) set timer args(timer:set args test, -999, 100) timer expect arg 1 := -999 timer expect arg 2 := 100 wait assert(timer global == 1) # Args should be preserved when run again set timer(timer:set args test, 0) wait assert(timer global == 2) # Changing the trigger to different script wipes the args set timer(timer:set args test, 0, 1, @timer args test 2) timer expect arg 1 := timer:set args test # Default args timer expect arg 2 := 0 wait assert(timer global == 12) # Passing no args set timer args(timer:set args test) set timer(timer:set args test, 0) timer expect arg 1 := 0 timer expect arg 2 := 0 wait assert(timer global == 22) # Throw an error if no script triggered # set timer(timer:set args test, 0, 1, 0) # set timer args(timer:set args test, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) $err arg string="random" test timer and battle interactions(@force random battle) $err arg string="fight formation" test timer and battle interactions(@force non random battle) $err arg string="" $0="timer interactions with after battle", trace(0) teleport to map(1, 10, 8), w # after battle battle script sequence := 0 test timer and battle interactions(@force random battle) if(battle script sequence <> 3) then($0="(ab) afterbattle should have happened 3 times", crash) $0="timer interactions with instead of battle", trace(0) teleport to map(2, 10, 8), w # instead of battle battle script sequence := 0 test timer and battle interactions(@force random battle) if(battle script sequence <> 0) then($0="(ib) afterbattle should have happened 0 times", crash) $0="timer interactions with after battle + instead of battle", trace(0) teleport to map(3, 10, 8), w # after battle + instead of battle battle script sequence := 0 test timer and battle interactions(@force random battle) if(battle script sequence <> 3) then($0="(ab+ib) afterbattle should have happened 3 times", crash) teleport to map(0, 10, 8), w hide string(1) end script, test timer and battle interactions, trigger battle, begin #regular timer timer global := 0 timer global will become := 1000 set timer(31, 10, 1, @battle timer test, -1, 0) run script by id(trigger battle) if(read timer(31) <= 0) then($0="timer should still be running", crash) if(timer global <> 0) then($0="timer global should still be zero", crash) w(10) if(read timer(31) >> 0) then($0="timer should be done by now", crash) if(timer global <> timer global will become) then($0="timer global didn't change", crash) #timerflag:battle timer global := 0 timer global will become := 2000 set timer(31, 10, 1, @battle timer test, 1, timerflag:battle) run script by id(trigger battle) if(read timer(31) >> 0) then($0="(bat) timer should be done by now", crash) if(timer global <> timer global will become) then($0="(bat) timer global didn't change", crash) #timerflag:battle ,or, timerflag:critical timer global := 0 timer global will become := 3000 set timer(31, 10, 1, @battle timer test, 1, (timerflag:battle,or,timerflag:critical)) set timer(30, 20, 1, @battle timer test, 0, (timerflag:battle)) run script by id(trigger battle) if(read timer(31) >> 0) then($0="(bat+crit) timer should be done by now", crash) if(timer global <> timer global will become) then($0="(bat+crit) timer global didn't change", crash) timer global will become := 4000 if(read timer(30) <= 0) then($0="(bat+crit) second timer should still be running", crash) w(12) if(read timer(30) >> 0) then($0="(bat+crit) second timer should be done by now", crash) if(timer global <> timer global will become) then($0="(bat+crit) timer global didn't change on second timer", crash) timer global := 0 w end script, timer test 1, begin show value(12345) w end script, looping timer test, begin if(timer global <= 0) then(timer global := 0, exit script) set timer(31, 0, 1, @looping timer test, 1) timer global -= 10 show value(timer global) _checkpoint end script, timer args test, arg1, arg2, arg3 = 42, begin assert(arg1 == timer expect arg 1) assert(arg2 == timer expect arg 2) #assert(arg3 == 42) # arg3 defaults to 0 instead of 42 due to an engine bug assert(arg3 == 0) timer global += 1 end script, timer args test 2, arg1, arg2, begin assert(arg1 == timer expect arg 1) assert(arg2 == timer expect arg 2) timer global += 10 end script, battle timer test, begin timer global := timer global will become $0="battle timer test:" append number(0, timer global) trace(0) show string(0), w end ######################################################################## script, pathfinding tests, begin $0="Pathfinding tests" variable(oldx, oldy, oldmap) oldx := herox(me) oldy := heroy(me) oldmap := current map teleport to map(map:Pathland, 8, 7) start checkpoint timer(4) variable(ref) ref := create NPC(0, 17, 3) pathfind npc to(ref, hero x(me), hero y(me), 1) wait for npc(ref) assert(dist from leader(ref) == 1) pathfind npc to(ref, 8, 3) wait for npc(ref) assert(npc x(ref) == 8) assert(npc y(ref) == 3) # With pacing NPCs in the way create npc(1, 8, 10, right) create npc(1, 8, 11, right) create npc(1, 8, 12, right) create npc(1, 8, 13, right) camera follows npc(ref) pathfind npc to(ref, 10, 16) wait for npc(ref) assert(npc x(ref) == 10) assert(npc y(ref) == 16) # To an unreachable zone destination pathfind npc to(ref, 15, 5, 2) wait for npc(ref) assert(dist from pos(ref, 15, 5) == 2) # Cancelling a walk pathfind npc to(ref, 14, 9) wait for npc(ref) assert(is at pos(ref, 14, 9)) pathfind npc to(ref, 17, 11) wait(10) cancel npc walk(ref) assert(is at pos(ref, 15, 8)) # also test cancelling a regular walk npc walk npc(ref, left, 4) wait(10) cancel npc walk(ref) assert(is at pos(ref, 13, 8)) # cancel a walk mid-step walk npc(ref, right, 3) wait(1) cancel npc walk(ref) assert(npc is walking(ref) == true) # this doesn't become false until the current step finishes wait for npc(ref) assert(npc is walking(ref) == false) assert(is at pos(ref, 14, 8)) # Test obstructed wait with no timeout create npc(2, 9, 8) pathfind npc to(ref, 9, 7) wait(7 * 5) # wait the time it takes to walk 7 steps (will get stuck after 6 steps) assert(is at pos(ref, 10, 8)) walk npc(2, south, 1) wait for npc(ref) assert(is at pos(ref, 9, 7)) # Test npc following npc walk npc(ref, south, 1) wait for npc(1) assert(is at pos(ref, 9, 7)) pathfind npc to(ref, 16, 18) wait(10) npc chases npc(2, ref, false, 10) wait for npc(ref) assert(is at pos(ref, 16, 18)) wait for npc(2) assert(dist from pos(2, 16, 18) == 1) # Test that npc is walking supports pathfinding pathfind npc to(2, 13, 16) variable(i) # The whole path (4 tiles at 4 ticks each) should return true for(i, 1, 4 * 4) do( w assert(npc is walking(2)) ) # And then when the path finishes, return false w assert(npc is walking(2) == false) # Test NPC giving up an unreachable path after stillticks pathfind npc to(2, 14, 14, 12) # the first two steps should go fine w(4) w(4) assert(is at pos(2, 14, 15)) assert(npc is walking(2)) # wait 12 more ticks, should not have moved w(12) assert(is at pos(2, 14, 15)) assert(npc is walking(2)) # wait 1 more tick, and the npc should have given up walking w(1) assert(npc is walking(2)==false) # now add some barrier npcs variable(n0, n1, n2, n3) n0 := create npc(3, 15, 15, left) n1 := create npc(3, 14, 16, up) n2 := create npc(3, 13, 15, right) set npc speed(3, 10) # make the npc walk, make one of the barrier npcs move at the last moment pathfind npc to(2, 17, 15, 7) # try for 7 ticks # should fail for 6 ticks for(i, 1, 6) do( w(1) assert(npc is walking(2)) assert(is at pos(2, 14, 15)) assert(npc pixel x(2) == 14 * 20) ) # abruptly remove a barrier npc destroy npc(n0) w(1) # NPC 2 should start walking assert(npc is walking(2)==true) assert(npc pixel x(2) == 14 * 20 + 5) wait for npc(2) assert(is at pos(2, 17, 15)) # clean up the other barrier npcs destroy npc(n1) destroy npc(n2) # Now test some hero pathfinding camera follows hero subscript, hero tile, rank, x, y, begin exit returning(hero x(rank) == x && hero y(rank) == y) end #show string(string sprintf(1, $2="x=%d y=%d", hero x(me), hero y(me))) assert(hero tile(me, 8, 7)) pathfind hero to(me, 13, 5) wait(5) assert(hero tile(me, 9, 7)) wait for hero(me) # should reach dest assert(hero tile(me, 13, 5)) # caterpillar should follow assert(hero tile(1, 12, 5)) assert(hero tile(2, 12, 6)) assert(hero tile(3, 11, 6)) # now path each hero individually suspend caterpillar pathfind hero to(0, 8, 7) pathfind hero to(1, 9, 7) pathfind hero to(2, 8, 8) pathfind hero to(3, 9, 8) wait for hero(0) wait for hero(1) wait for hero(2) wait for hero(3) assert(hero tile(0, 8, 7)) assert(hero tile(1, 9, 7)) assert(hero tile(2, 8, 8)) assert(hero tile(3, 9, 8)) # Test hero-on-hero collision (or lack thereof) pathfind hero to(0, 12, 7) pathfind hero to(1, 11, 7) wait for hero(0) wait for hero(1) # Hero 1 should walk right through hero 0 pathfind hero to(1, 13, 7) wait(5) assert(hero tile(1, hero x(0), hero y(0))) wait(5) # should still be walking for one more tick assert(hero is walking(1)) wait(1) # okay, should be done now assert(hero is walking(1)==false) # now lets test hero-on-npc collisions # get hero 1 out of the way walk hero(1, right, 1) # create some NPC barriers n0 := create npc(3, 12, 6, down) n1 := create npc(3, 13, 7, left) n2 := create npc(3, 12, 8, up) n3 := create npc(3, 11, 7, right) w(1) # Hero pathing should fail pathfind hero to(0, 12, 10) wait(1) # the hero is still trying to walk assert(hero is walking(0)) # the hero has not moved assert(hero tile(0, 12, 7)) cancel hero walk(0) assert(hero is walking(0) == false) # now move one NPC out of the way set npc speed(3, 10) pathfind npc to(n0, 14, 6) wait(2) # Now the hero can move pathfind hero to(0, 12, 10) wait(5) assert(hero is walking(0)) assert(hero tile(0, 12, 6)) wait for hero(0) # move the npcs over to block hero 1 pathfind npc to(n2, 15, 7) pathfind npc to(n3, 14, 8) # npc 1 is blocked, but non-leader heroes # are currently allowed to pass through npcs pathfind hero to(1, 16, 7) wait(1) assert(hero is walking(1) == true) wait for hero(1) assert(hero tile(1, 16, 7)) # send an NPC running, and have the hero chase it pathfind npc to(n1, 5, 5) hero chases npc(0, n1, true) wait for npc(n1) # hero should still be catching up assert(hero is walking(0)) wait for hero(0) assert(hero is walking(0) == false) # now path the hero somewhere it can't reach, it should get close pathfind hero to(0, 8, 5) wait(5) assert(hero is walking(0)) wait(5) assert(hero tile(0, 7, 4)) w # send the hero on a long path, but cancel after a step and a half pathfind hero to(0, 8, 12) w(7) cancel hero walk(0) # hero should still finish the current step assert(hero is walking(0)), w assert(hero is walking(0)), w wait for hero(0) assert(hero is walking(0) == false) assert(hero tile(0, 6, 5)) # now to test stop-after-stillticks # put hero hero back in the NPC cage set hero speed(me, 10) pathfind hero to(0, 14, 7) wait(2) # move the npc back to block pathfind npc to(n1, 13, 7) wait for hero(0) wait for npc(n1) # The hero should try to walk for 10 ticks and give up pathfind hero to(0, 13, 8, 10) for(i, 1, 10) do( show value(i) w(1) assert(hero is walking(0)) assert(hero tile(0, 14, 7)) ) w(1) # the hero should have given up by now assert(hero is walking(0) == false) assert(hero tile(0, 14, 7)) # Now more tests of hero chasing npc hero chases npc(0, n1) w(2) # should not have moved yet, but trying to move assert(hero tile(0, 14, 7)) assert(hero is walking(0)) pathfind npc to(n1, 12, 7) wait for npc(n1) #the hero is slower, so they should still be walking assert(hero tile(0, 13, 7)) assert(hero is walking(0)) # the hero does not give up w(10) assert(hero tile(0, 13, 7)) assert(hero is walking(0)) # make the NPC move again walk npc(n1, south, 1) wait(5) assert(hero tile(0, 12, 7)) assert(hero is walking(0)) # cancel chase cancel hero walk(0) assert(hero is walking(0)==false) # move the npc again pathfind npc to(n1, 10, 8) wait for npc(n1) assert(is at pos(n1, 10, 8)) # make the hero chase the npc, but stop when reached hero chases npc(0, n1, true) wait for hero(0) assert(hero tile(0, 11, 8)) assert(hero is walking(0)==false) # make the npc move again, hero will not follow walk npc(n1, south, 1) wait for npc(n1) assert(hero tile(0, 11, 8)) assert(hero is walking(0)==false) # get rid of the barrier npcs w destroy npc(n0) destroy npc(n1) destroy npc(n2) destroy npc(n3) w # Now test doors and teleporting when pathfinding resume caterpillar set hero speed(0, 4) pathfind hero to(0, 15, 5) wait for hero(0) assert(hero tile(0, 15, 5)) # path the hero into the door pathfind hero to(0, 17, 5) for(i, 1, 9) do( w assert(current map == 5) ) # In one more tick, we should be through the door w assert(current map == 7) assert(hero is walking(0)==false) assert(hero tile(0, 3, 4)) # walk through a door that leads to the current map pathfind hero to(0, 8, 2) wait for hero(0) assert(hero tile(0, 8, 2)) # ready start to go through the door pathfind hero to(0, 14, 2) assert(hero pixel x(0) == 8 * 20) assert(hero pixel y(0) == 2 * 20) w(4) # almost through the door assert(hero pixel x(0) == 8 * 20 + 16) assert(hero pixel y(0) == 2 * 20) w(1) # through the door, should keep walking since the dest is still on this map assert(hero pixel x(0) == 9 * 20) assert(hero pixel y(0) == 6 * 20) wait for hero(0) assert(hero tile(0, 14, 2)) assert(hero tile(1, 13, 2)) assert(hero tile(2, 13, 3)) assert(hero tile(3, 12, 3)) # now test teleporting while pathing pathfind hero to(0, 14, 8) #wait for one step w(5) assert(hero tile(0, 14, 3)) teleport to map(5, 4, 4) assert(hero is walking(0)==false) assert(hero tile(0, 4, 4)) # Test again, but partway through a step # go back to the other map teleport to map(7, 14, 2) w pathfind hero to(0, 14, 8) #wait for a fraction of a step w(2) assert(hero pixel y(0) == 2 * 20 + 8) # now teleport mid-step teleport to map(5, 4, 4) wait for hero(0) assert(hero pixel x(0) == 4 * 20) # Uh oh! the hero is misaligned with the grid # (which sucks, but is sort of expected, and is consistent with teleporting while doing a "walk hero") assert(hero pixel y(0) == 4 * 20 + 3 * 4) w # fix alignment put hero(0, 4 * 20, 5 * 20) w # Do it again with "walk hero" instead of "pathfind hero to" # go back to the other map teleport to map(7, 14, 2) w walk hero(0, south, 1) #wait for a fraction of a step w(2) assert(hero pixel y(0) == 2 * 20 + 8) # now teleport mid-step teleport to map(5, 4, 4) wait for hero(0) assert(hero pixel x(0) == 4 * 20) # Yep, hero is misaligned again, just like with "pathfind hero to" assert(hero pixel y(0) == 4 * 20 + 3 * 4) w # fix alignment again put hero(0, 4 * 20, 5 * 20) w # test that "wait for all" respects pathfinding suspend caterpillar pathfind hero to(2, 4, 3) pathfind hero to(3, 4, 2) n0 := create npc(3, 5, 2) n1 := create npc(3, 5, 4) set npc speed(3, 10) w pathfind hero to(0, 2, 6) pathfind hero to(1, 1, 6) pathfind hero to(2, 2, 7) pathfind hero to(3, 1, 7) pathfind npc to(n0, 7, 8) pathfind npc to(n1, 8, 8) wait for all assert(hero tile(0, 2, 6)) assert(hero tile(1, 1, 6)) assert(hero tile(2, 2, 7)) assert(hero tile(3, 1, 7)) assert(is at pos(n0, 7, 8)) assert(is at pos(n1, 8, 8)) # now a path the hero should finish first pathfind hero to(0, 2, 5) pathfind npc to(n1, 4, 4) wait for all assert(hero tile(0, 2, 5)) assert(is at pos(n1, 4, 4)) # now a path the npc should finish first pathfind hero to(0, 8, 8) pathfind npc to(n1, 5, 4) wait for all assert(hero tile(0, 8, 8)) assert(is at pos(n1, 5, 4)) resume caterpillar # clean up stop checkpoint timer show no value # Pathfinding to extra data set hero position(me, 12, 6) # Hero pos doesn't matter, just moving the camera variable(sl, result) sl := create map overlay container result := pathfind into extra as hero(sl, 13, 6, 14, 3) assert(result==true) visualize path from extra(sl) assert(get extra(sl, 0) == 13) assert(get extra(sl, 1) == 6) assert(get extra(sl, extra length(sl)--2) == 14) assert(get extra(sl, extra length(sl)--1) == 3) assert(extra length(sl) == 5 * 2) w # With maxsearch, give up at a range of 2 result := pathfind into extra as hero(sl, 13, 6, 14, 3, 2) assert(result==false) visualize path from extra(sl) assert(extra length(sl) == 2 * 2) w # To an unreachable spot result := pathfind into extra as hero(sl, 13, 6, 19, 0) assert(result==false) visualize path from extra(sl) w # Ignore the first step result := pathfind into extra as hero(sl, 13, 6, 14, 3, 0, false, true) assert(result==true) visualize path from extra(sl) assert(get extra(sl, extra length(sl)--2) == 14) assert(get extra(sl, extra length(sl)--1) == 3) assert(extra length(sl) == 4 * 2) w # Append a second path to the first result := pathfind into extra as hero(sl, 13, 6, 14, 3, 0, false, false) assert(result==true) result := pathfind into extra as hero(sl, 14, 3, 15, 2, 0, true, true) assert(result==true) visualize path from extra(sl) assert(extra length(sl) == 7 * 2) w # Append a first path while preserving default 3 extra values free slice(sl) sl := create map overlay container result := pathfind into extra as hero(sl, 13, 6, 14, 3, 0, true, false) assert(extra length(sl) == 3 + 5*2) assert(get extra(sl, 0) == 0) assert(get extra(sl, 1) == 0) assert(get extra(sl, 2) == 0) assert(get extra(sl, 3) == 13) assert(get extra(sl, 4) == 6) visualize path from extra(sl, 3) w # Test NPC pathing (current NPC positions don't matter really) n0 := create npc(0, 10, 6) # Cannot walk across grass n1 := create npc(1, 10, 8) # Can walk across grass # Across the grass result := pathfind into extra as npc(sl, n1, 12, 5, 14, 3) assert(result == true) assert(extra length(sl) == 5 * 2) assert(get extra(sl, 0) == 12) assert(get extra(sl, 1) == 5) assert(get extra(sl, 8) == 14) assert(get extra(sl, 9) == 3) visualize path from extra(sl) w # Around the grass result := pathfind into extra as npc(sl, n0, 12, 5, 14, 3) assert(result == true) assert(extra length(sl) == 9 * 2) assert(get extra(sl, 0) == 12) assert(get extra(sl, 1) == 5) assert(get extra(sl, extra length(sl)--2) == 14) assert(get extra(sl, extra length(sl)--1) == 3) visualize path from extra(sl) w # around the grass and the hero set hero position(me, 11, 3) result := pathfind into extra as npc(sl, n0, 12, 5, 14, 3) assert(extra length(sl) == 11 * 2) visualize path from extra(sl) w # Can't reach the middle of the grass result := pathfind into extra as npc(sl, n0, 12, 5, 13, 4) assert(result == false) assert(extra length(sl) == 1 * 2) visualize path from extra(sl) w # Zero-length path (start excluded) result := pathfind into extra as npc(sl, n0, 12, 5, 13, 4, 0, false, true) assert(result == false) assert(extra length(sl) == 0 * 2) visualize path from extra(sl) w # Append 3 waypoints (full circle) pathfind into extra as npc(sl, n0, 12, 5, 14, 3, 0, false, true) pathfind into extra as npc(sl, n0, 14, 3, 15, 7, 0, true, true) pathfind into extra as npc(sl, n0, 15, 7, 12, 5, 0, true, true) assert(extra length(sl) == 24 * 2) visualize path from extra(sl) w # Cleanup free slice(sl) teleport to map(oldmap, oldx, oldy) end script, create map overlay container, begin variable(sl) sl := create container(0, 0) set parent(sl, lookup slice(sl:map overlay)) fill parent(sl, true) exit(sl) end script, visualize path from extra, sl, offset=0, begin free slice children(sl) variable(i, x, y, box) for(i, 0, ((extra length(sl) -- offset) / 2) -- 1) do( x := get extra(sl, offset + i * 2) y := get extra(sl, offset + i * 2 + 1) box := create rect(18, 18) set parent(box, sl) set rect bgcol(box, 1) set rect opacity(box, 25) set slice x(box, x * 20 + 1) set slice y(box, y * 20 + 1) ) end script, is at pos, ref, x, y, begin exit returning(npc x (ref) == x && npc y (ref) == y) end script, dist from leader, ref, begin exit returning(dist from pos(ref, hero x(me), hero y(me))) end script, dist from pos, ref, x, y, begin variable(dx, dy) dx := abs(npc x(ref) -- x) dy := abs(npc y(ref) -- y) exit returning(dx + dy) end ######################################################################## script, vehicle tests, begin $0="Vehicle tests" variable(oldx, oldy, oldmap) oldx := herox(me) oldy := heroy(me) oldmap := current map teleport to map(map:Vehicle Test Map, 4, 4) w assert(current vehicle id == -1) assert(current vehicle npc == false) # First test mount with usenpc. Does not need to be adjacent, but does check mount passability rules assert(check tag(tag:boat tag) == false) assert(hero x(me) == 4) assert(hero y(me) == 4) w # This should fail to mount because we are not on a "B" tile use npc(1) assert(current vehicle npc == false) w(20) assert(check tag(tag:boat tag) == false) assert(hero x(me) == 4) assert(hero y(me) == 4) walk hero(me, left, 2) wait for hero(me), w assert(hero x(me) == 2) assert(hero y(me) == 4) # This should work because although we are not adjacent, we are standing on a B tile use npc(1) assert(current vehicle npc == NPC reference(1)) assert(current vehicle id == 0) w(20) assert(check tag(tag:boat tag) == true) assert(hero x(me) == 2) assert(hero y(me) == 2) # Now move the hero, and the vehicle npc should move also walk hero(me, left, 2) wait for hero(me), w walk hero(me, up, 2) wait for hero(me), w assert(hero x(me) == 0) assert(hero y(me) == 0) assert(npc x(1) == 0) assert(npc y(1) == 0) # Moving the NPC while it is being used as a vehicle should not move it # (although the sprite will be shifted slightly as it tries to move) walk npc(1, right, 5) wait for npc(1), w assert(npc x(1) == 0) assert(npc y(1) == 0) # Move back to the shore walk hero(me, right, 3) wait for hero(me), w walk hero(me, down, 2) wait for hero(me), w show string(string sprintf(1, $2="x=%d y=%d", hero x(me), hero y(me))) assert(hero x(me) == 3) assert(hero y(me) == 1) set hero direction(me, right), w # Dismount into the ocean. should not step forward assert(current vehicle npc) dismount vehicle assert(not(current vehicle npc)) w(20) assert(hero x(me) == 3) assert(hero y(me) == 1) assert(check tag(tag:boat tag) == false) # Mounting from here should fail use npc(1) assert(not(current vehicle npc)) w(20) assert(hero x(me) == 3) assert(hero y(me) == 1) assert(check tag(tag:boat tag) == false) # Force mounting, which ignores checking the tile we are standing on force mount vehicle(1) assert(current vehicle npc) w(20) assert(hero x(me) == 3) assert(hero y(me) == 1) assert(check tag(tag:boat tag) == true) walk hero(me, right, 1) wait for hero(me), w assert(hero x(me) == 4) assert(hero y(me) == 1) assert(npc x(1) == 4) assert(npc y(1) == 1) # Dismount, does not step ahead (which sucks, and was a mistake, but is rather too old to fix cleanly) dismount vehicle, w(20) assert(not(current vehicle npc)) assert(check tag(tag:boat tag) == false) assert(hero x(me) == 4) assert(hero y(me) == 1) assert(npc x(1) == 4) assert(npc y(1) == 1) w set hero position(me, 4, 2) variable(n) n := create global npc(3, 2, 5) hero chases npc(me, n, true, 10) wait for hero(me) set hero direction(me, left) use npc(n) w(20) walk hero(me, right, 5) w wait for hero(me) gracefully dismount vehicle w(20) walk hero(me, right, 1) w wait for hero(me) walk hero(me, south, 4) w teleport to map(oldmap, oldx, oldy) end ######################################################################## script, door tests, begin $0="Door tests" # preconditions assert(herox(me) == 6) assert(heroy(me) == 6) # querying doors assert(get door x(0) == 8) assert(get door y(0) == 5) assert(door at spot(8, 5) == 0) assert(door at spot(0, 0) == -1) # lots of doors at 0,0 with exists=NO assert(door at spot(1, 1) == 1) # door 1 has no enabled doorlinks assert(get door destination id(0) == 1) assert(get door destination map(0) == 4) assert(door exists(0)) assert(get door destination id(1) == -1) assert(get door destination map(1) == -1) assert(door exists(1)) assert(door exists(10) == false) # using doors walk hero to x(0, 8) wait for hero walk hero to y(0, 5) wait for hero assert(current map == map:door test map) assert(hero x(0) == 4) assert(hero y(0) == 4) walk hero(0, south, 1) wait for hero use door(1) # shouldn't work, disabled by tag assert(hero x(0) == 4) # not triggered walk hero(0, north, 1) wait for hero assert(hero x(0) == 4) # not triggered set tag(tag:door req tag, on) wait assert(hero x(0) == 4) # not triggered by enabling a door underneath you suspend doors walk hero(0, south, 1) wait for hero walk hero(0, north, 1) wait for hero assert(hero x(0) == 4) # not triggered resume doors wait assert(hero x(0) == 4) # door underneath hero not triggered walk hero(0, south, 1) wait for hero walk hero(0, north, 1) wait for hero assert(hero x(0) == 11) # triggered assert(hero y(0) == 4) show string($99="screen should be faded out") use door(0) # door underneath hero _checkpoint assert(current map == map:test town) show string($99="screen should not be faded out") use door(4, false) _checkpoint show no value assert(hero x(0) == 2) assert(hero y(0) == 6) walk hero to x(0, 6) wait for hero # querying doors on other maps assert(current map == map:test town) assert(door exists(0, map:Door test map)) assert(not(door exists(2, map:Door test map))) assert(get door x(0, map:Door test map) == 11) assert(get door y(0, map:Door test map) == 4) assert(check tag(7) == on) assert(get door destination id(0, map:Door test map) == 0) assert(get door destination map(0, map:Door test map) == map:Test Town) assert(get door destination id(1, map:Door test map) == 0) assert(get door destination map(1, map:Door test map) == map:Door test map) set tag(7, off) assert(get door destination id(1, map:Door test map) == -1) assert(get door destination map(1, map:Door test map) == -1) set tag(7, on) assert(get door destination id(2, map:Door test map) == -1) assert(get door destination map(2, map:Door test map) == -1) end ######################################################################## # Not defined as a plotscript on purpose script, each-step script, x, y, dir, begin $0="each-step script", trace assert(x == hero x) assert(y == hero y) assert(dir == hero direction) # First to run assert(npc script triggered == 0) assert(map autorun triggered == 0) eachstep triggered += 1 end plotscript, npc triggered script, arg, npc, begin $0="npc triggered script", trace assert(arg == -1) assert(npc == npc reference(6)) # Second to run assert(eachstep triggered == 1) assert(map autorun triggered == 0) npc script triggered += 1 # Should happen immediately (also tested in textbox tests) # and trigger two scripts advance textbox # Fifth to run assert(current textbox == -1) assert(textbox script triggered == 1) assert(map autorun triggered == 1) npc script triggered += 1 end plotscript, textbox advance script, begin $0="textbox advance script", trace assert(current map == 4) assert(hero direction == left) # These should be the correct position on the new map assert(hero x == 11) assert(hero y == 4) # Third to run assert(current textbox == -1) assert(npc script triggered == 1) assert(eachstep triggered == 1) assert(map autorun triggered == 0) textbox script triggered += 1 end # Set on map 4 plotscript, map 4 autorun, arg, begin if (testing script triggers == false) then (exit script) $0="map 4 autorun", trace assert(arg == 42) assert(current map == 4) # Fourth to run assert(textbox script triggered == 1) map autorun triggered += 1 # also set in "map autorun" end script, concurrent script trigger tests, begin $0="concurrent script trigger tests" # Test multiple triggers happening the same tick, and that they all happen in the right order. # This tests both scripts triggered inside and outside the interpreter # Take a step, triggering each-step script and stepping on an NPC, which runs a script, # and opens a textbox, which is advanced, running a script and activating a door which # goes to a map with an autorun script # Preconditions assert(current map == 0) set hero position(0, 6, 6) npc script triggered := 0 map autorun triggered := 0 set eachstep script (@each-step script) testing script triggers := true tick counter slice := create container set slice velocity x(tick counter slice, 1, 1000) assert(ticknumber == 0) assert(get hero speed(me) == 4) create npc(6, hero x -- 1, hero y) walk hero(me, left, 1) wait for hero #Events happen in this order, and scripts should run in reverse #order of triggering: # (step completes) # (npc triggered, opens textbox) # npc script triggered # each step triggered # (interpreter entered) # (npc script calls advancetextbox) # (textbox loaded) # (preparemap called) # autorun triggered # after textbox script triggered # (this script resumes, waitfornpc finishing) #So scripts run in order (all in the same tick): # | each step # | npc # | | autorun # | | textbox # | npc finishes # this script # Sixth to run assert(npc script triggered == 2) assert(textbox script triggered == 1) assert(map autorun triggered == 1) assert(ticknumber == 5) # reset testing script triggers := false free slice(tick counter slice) teleport to map (0, 6, 6) assert(current map == 0) # Incremented by the other map autorun script assert(map autorun triggered == 2) end ######################################################################## script, another eachstep script, begin eachstep triggered += 1 wait for hero end script, yet another eachstep script, begin eachstep triggered += 1 subscript, waiting, begin wait for hero end waiting end script, script double trigger tests, begin $0="script trigger tests" # precondition assert(hero x == 6 && hero y == 6) # Test double triggering of scripts set eachstep script(@another eachstep script) variable (oldval) oldval := read general(101) # genBits assert((oldval, and, 2^10) == 0) # "permit double triggering scripts" is off eachstep triggered := 0 walk hero(me, left, 3) wait for hero # eachstep should only trigger once assert(eachstep triggered == 1) write general(101, oldval + 2^10) # turn on "permit double triggering scripts" eachstep triggered := 0 walk hero(me, right, 3) wait for hero assert(eachstep triggered == 3) set eachstep script(@yet another eachstep script) eachstep triggered := 0 walk hero(me, left, 3) wait for hero assert(eachstep triggered == 3) write general(101, oldval) # turn off "permit double triggering scripts" eachstep triggered := 0 walk hero(me, right, 3) wait for hero # eachstep should should trigger three times because the "waiting" # subscript foils the double trigger check assert(eachstep triggered == 3) set eachstep script(0) assert(hero x == 6 && hero y == 6) end script, script trigger tests, begin concurrent script trigger tests script double trigger tests end ######################################################################## script, slice tests, begin $0="Slice tests" # Highly unfinished! slice extra tests slice collection tests slice tree tests slice search tests slice collision tests slice correspondence tests slice blending tests slice sort tests slice clone tests slice handle tests rect slice tests text slice tests panel slice tests ellipse slice tests end ######################################################################## script, slice handle tests, begin $0="Slice handle tests" # slice is valid variable (sl) assert(slice is valid(0) == false) sl := create container assert(slice is valid(sl)) free slice(sl) assert(slice is valid(sl) == false) assert(slice is valid(sprite layer)) assert(slice is valid(-1) == false) assert(slice is valid(4242) == false) # Check that slice handles aren't reused quickly # (The actual minimum number of frees before a handle is reused # is currently 256*4000 = 1,024,000) variable(i, sl2) sl := create container free slice(sl) for (i, 0, 5100) do ( sl2 := create container assert(sl2 <> sl) free slice(sl2) ) end ######################################################################## script, rect slice tests, begin $0="Rect Slice tests" variable (sl) # Test rect transparency sl := create rect(100, 100), w assert(slice is rect(sl)) assert(slice type(sl) == slicetype:rect) assert(get rect trans(sl) == trans:solid) assert(get rect fuzziness(sl) == 100) set rect trans(sl, trans:hollow), w assert(get rect trans(sl) == trans:hollow) assert(get rect fuzziness(sl) == 0) set rect fuzziness(sl, 25), w assert(get rect trans(sl) == trans:fuzzy) assert(get rect fuzziness(sl) == 25) assert(get rect opacity(sl) == 25) # It's an alias set rect fuzziness(sl, 0), w assert(get rect trans(sl) == trans:hollow) assert(get rect fuzziness(sl) == 0) set rect fuzziness(sl, 100), w assert(get rect trans(sl) == trans:solid) assert(get rect fuzziness(sl) == 100) set rect opacity(sl, 70), w assert(get rect trans(sl) == trans:blend) assert(get rect opacity(sl) == 70) assert(get rect fuzziness(sl) == 70) # Alias set rect trans(sl, trans:solid) assert(get rect opacity(sl) == 100) set rect trans(sl, trans:hollow) assert(get rect opacity(sl) == 0) set rect trans(sl, trans:fuzzy), w assert(get rect trans(sl) == trans:fuzzy) # Using setrecttrans preserves previous opacity to 70% assert(get rect fuzziness(sl) == 70) set rect trans(sl, trans:blend), w assert(get rect opacity(sl) == 70) assert(get rect fuzzy zoom(sl) == 1) # Default value set rect fuzzy zoom(sl, 1000) assert(get rect fuzzy zoom(sl) == 1000) assert(get rect stationary pattern(sl) == false) # Default value set rect stationary pattern(sl, true) assert(get rect stationary pattern(sl) == true) free slice(sl) # Test rect box border and raw box border sl := create rect(99, 99), w set slice x(sl, 10) set slice y(sl, 10) assert(get rect style(sl) == 0) assert(get rect border(sl) == 0) assert(get rect raw border(sl) == border:line) set rect raw border(sl, 0), w assert(get rect style(sl) == -1) assert(get rect border(sl) == border:raw) assert(get rect raw border(sl) == 0) set rect border(sl, border:none), w assert(get rect border(sl) == border:none) assert(get rect raw border(sl) == border:none) set rect border(sl, border:line), w assert(get rect border(sl) == border:line) assert(get rect raw border(sl) == border:line) set rect raw border(sl, 1), w assert(get rect border(sl) == border:raw) assert(get rect raw border(sl) == 1) set rect border(sl, 13), w assert(get rect border(sl) == 13) assert(get rect raw border(sl) == 1) set rect raw border(sl, border:none), w assert(get rect border(sl) == border:none) assert(get rect raw border(sl) == border:none) set rect raw border(sl, border:line), w assert(get rect border(sl) == border:line) assert(get rect raw border(sl) == border:line) free slice(sl) # Test rect style sl := create rect(120, 120, 14), w assert(get rect style(sl) == 14) # Testing that the style is as in the box style editor assert(get rect border(sl) == 14) assert(get rect raw border(sl) == 1) assert(get rect fg col(sl) == 252) assert(get rect bg col(sl) == 65) set rect fg col(sl, 42), w assert(get rect style(sl) == -1) set rect style(sl, 0), w assert(get rect style(sl) == 0) assert(get rect border(sl) == 0) assert(get rect raw border(sl) == border:line) assert(get rect fg col(sl) == 249) assert(get rect bg col(sl) == 33) free slice(sl) end ######################################################################## script, text slice tests, begin $0="Text Slice tests" # Check initial state as expected variable(sl) sl := create text assert(slice is text(sl)) assert(slice type(sl) == slicetype:text) get slice text(2, sl) assert(string length(2) == 0) assert(get wrap(sl) == false) assert(get outline(sl) == false) assert(get text color(sl) == 0) # which means uiText assert(get text bg(sl) == 0) $2="fee Fi\n \n foe" set slice text(sl, 2) get slice text(3, sl) assert(string compare(2, 3)) # Non-wrapping slices have fixed size tracevalue(slice width(sl),slice height(sl)) assert(slice width(sl) == 48) assert(slice height(sl) == 30) # 3 lines #set slice width(sl, 10) # throws an error #set slice height(sl, 10) # throws an error assert(slice width(sl) == 48) assert(slice height(sl) == 30) # 3 lines # Wrapping slices recompute height based on width set wrap(sl, true) assert(get wrap(sl) == true) assert(slice width(sl) == 48) # shouldn't have changed set slice width(sl, 35) set wrap(sl, true) # Modifying text slice data calls UpdateTextSlice (wait also would) assert(slice width(sl) == 35) assert(slice height(sl) == 40) set slice height(sl, 10) # Doesn't show an error but will be overridden when updated set wrap(sl, true) # Modifying text slice data calls UpdateTextSlice (wait also would) assert(slice height(sl) == 40) set wrap(sl, false) assert(slice width(sl) == 48) # Recomputes immediately # TODO: test recomputing of embed codes $2="" $3="" free slice(sl) end ######################################################################## script, panel slice tests, begin $0="Panel Slice tests" variable(sl) sl := create panel assert(slice is panel(sl)) assert(slice type(sl) == slicetype:panel) # Check initial state as expected assert(get panel primary index(sl) == 0) assert(get panel percent as int(sl) == 50) assert(get panel padding(sl) == 0) assert(get panel is vertical(sl) == false) assert(get panel pixels(sl) == 0) set panel primary index(sl, 1) assert(get panel primary index(sl) == 1) set panel percent(sl, 40) assert(get panel percent as int(sl) == 40) set panel padding(sl, 4) assert(get panel padding(sl) == 4) set panel pixels(sl, 5) assert(get panel pixels(sl) == 5) set panel is vertical(sl, true) assert(get panel is vertical(sl) == true) # TODO: check children are sized correctly free slice(sl) end ######################################################################## script, ellipse slice tests, begin $0="Ellipse Slice tests" variable(sl) sl := create ellipse(10, 10, 15, 0), w assert(slice is ellipse(sl)) assert(get ellipse border col(sl) == 15) set ellipse border col(sl, 14), w assert(get ellipse border col(sl) == 14) assert(get ellipse fill col(sl) == 0) set ellipse fill col(sl, 1), w assert(get ellipse fill col(sl) == 1) set slice x(sl, 20), w set slice y(sl, 20), w set slice width(sl, 30), w set slice height(sl, 30), w free slice(sl) end ######################################################################## script, slice clone tests, begin # Test cloneslice variable(sl, sl2, ch, ch2) sl := get npc slice(next npc reference) set slice extra(sl, extra 2, 42) sl2 := clone slice(sl) assert(next sibling(sl2) == sl) # Check that things got copied assert(slice screen x(sl) == slice screen x(sl2)) assert(slice screen y(sl) == slice screen y(sl2)) assert(get slice extra(sl2, extra 2) == 42) assert(child count(sl) == child count(sl2)) ch := first child(sl) ch2 := first child(sl2) assert(get slice lookup(ch) < 0) assert(get slice lookup(ch2) == 0) # special lookup codes removed free slice(sl2) sl := sprite layer assert(slice type(sl) == slicetype:special) sl2 := clone slice(sl) assert(slice is container(sl2)) # Special slices turn into containers assert(previous sibling(sl) == sl2) assert(child count(sl) == child count(sl2)) free slice(sl2) sl2 := clone slice(sl, false) # recurse == false assert(child count(sl2) == 0) # Didn't recurse free slice(sl2) # More detailed checks that extra arrays are copied sl := create container sl2 := clone slice(sl) # Copy a default NULL array assert(extra length(sl2) == 3) free slice(sl2) resize extra(sl, 0) # Copy a length 0 array sl2 := clone slice(sl) assert(extra length(sl2) == 0) free slice(sl2) resize extra(sl, 50000) set slice extra(sl, -1, 12345) sl2 := clone slice(sl) # Copy a large array assert(extra length(sl2) == 50000) assert(get slice extra(sl2, 49999) == 12345) # Check the array, not its pointer, is copied set slice extra(sl2, 49998, 16) assert(get slice extra(sl2, 49998) == 16) assert(get slice extra(sl, 49998) == 0) free slice(sl2) free slice(sl) end ######################################################################## # Example from plotdict script, remove extra, obj, value, begin variable (idx) while (true) do ( idx := find extra (obj, value) if (idx == -1) then (exit) # All deleted delete extra (obj, idx) # Normally we'd do "idx += 1" to look for the next occurrence of 'value' # after idx, but because we deleted it we don't need to. ) end ######################################################################## # The following sets of testcases for slice & generic extra data commands # were accidentally duplicated. Most also get tested in many other places. script, slice extra tests, begin variable(sl) sl := create line assert(extra length(sl) == 3) set slice extra(sl, 0, 100) set slice extra(sl, 2, 102) assert(get slice extra(sl, 2) == 102) assert(get slice extra(sl, -1) == 102) assert(get slice extra(sl, -3) == 100) assert(get extra(sl, 2) == 102) assert(get extra(sl, -1) == 102) assert(get extra(sl, -3) == 100) set extra(sl, 1, 4242) assert(get slice extra(sl, 1) == 4242) assert(get extra(sl, -2) == 4242) resize extra(sl, 1) assert(extra length(sl) == 1) assert(get slice extra(sl, -1) == 100) resize extra(sl, 3) assert(get slice extra(sl, -1) == 0) append extra(sl, 103) assert(extra length(sl) == 4) assert(get slice extra(sl, 3) == 103) resize extra(sl, 999999) set slice extra(sl, 999998, 998) assert(get slice extra(sl, -1) == 998) append extra(sl, 999) set slice extra(sl, 999999, 999) assert(get slice extra(sl, -1000000) == 100) free slice(sl) # Also, loading slice extra data is tested in "slice collection tests" # And clone extra data is tested in "slice clone tests" end script, extra array tests, begin $0="extra array tests" variable(xt) show string($1="Make a testing slice and use its extra data") xt := create container(0,0) show string($1="Test the 3 default elements") assert(extra length(xt)==3) assert(get extra(xt,0)==0) assert(get extra(xt,1)==0) assert(get extra(xt,2)==0) show string($1="Test setting data") set extra(xt, 0, 100) set extra(xt, 1, 101) set extra(xt, 2, 102) assert(get extra(xt,0)==100) assert(get extra(xt,1)==101) assert(get extra(xt,2)==102) show string($1="Test end-based indexing") assert(get extra(xt,-1)==102) assert(get extra(xt,-2)==101) assert(get extra(xt,-3)==100) show string($1="Test appending") assert(append extra(xt, 999)==4) assert(get extra(xt,3)==999) show string($1="Test resizing") resize extra(xt,6) assert(extra length(xt)==6) assert(get extra(xt,0)==100) assert(get extra(xt,3)==999) assert(get extra(xt,4)==0) assert(get extra(xt,5)==0) resize extra(xt,3) assert(extra length(xt)==3) assert(get extra(xt,-1)==102) resize extra(xt,0) assert(extra length(xt)==0) resize extra(xt,2) assert(get extra(xt,0)==0) assert(get extra(xt,1)==0) show string($1="Test extra insertion") set extra(xt,0,100) set extra(xt,1,200) assert(extra length(xt)==2) insert extra(xt,1,111) assert(extra length(xt)==3) assert(get extra(xt,0)==100) assert(get extra(xt,1)==111) assert(get extra(xt,2)==200) insert extra(xt,0,99) assert(get extra(xt,0)==99) assert(get extra(xt,1)==100) assert(get extra(xt,2)==111) assert(get extra(xt,3)==200) show string($1="Test extra insertion from negative index") insert extra(xt,-1,222) assert(get extra(xt,0)==99) assert(get extra(xt,1)==100) assert(get extra(xt,2)==111) assert(get extra(xt,3)==222) assert(get extra(xt,4)==200) append extra(xt,100) show string($1="Test find extra") assert(find extra(xt,1)==-1) assert(find extra(xt,111)==2) assert(find extra(xt,111,2)==2) assert(find extra(xt,111,3)==-1) assert(find extra(xt,100)==1) assert(find extra(xt,100,2)==5) assert(find extra(xt,100,-1)==5) assert(find extra(xt,100,-4)==5) assert(find extra(xt,100,-5)==1) assert(find extra(xt,100,-40)==1) assert(find extra(xt,100,99)==-1) show string($1="Test deletion") assert(delete extra(xt,3)==222) assert(delete extra(xt,1)==100) assert(delete extra(xt,-1)==100) assert(get extra(xt,0)==99) assert(get extra(xt,1)==111) assert(get extra(xt,2)==200) assert(extra length(xt)==3) show string($1="Test delete range") append extra(xt,333) append extra(xt,444) assert(extra length(xt)==5) assert(delete extra range(xt, 1, 4) == 111) assert(extra length(xt)==2) assert(get extra(xt,0)==99) assert(get extra(xt,1)==444) show string($1="Delete empty range (nothing happens)") delete extra range(xt, 1, 1) assert(extra length(xt)==2) assert(get extra(xt,0)==99) assert(get extra(xt,1)==444) delete extra range(xt, 0, 0) assert(extra length(xt)==2) delete extra range(xt, 2, 2) # [length, length) assert(extra length(xt)==2) delete extra range(xt, 3, 3) # out of bounds is OK assert(extra length(xt)==2) assert(get extra(xt,0)==99) assert(get extra(xt,1)==444) show string($1="Delete range from end") append extra(xt,555) append extra(xt,666) assert(extra length(xt)==4) assert(delete extra range(xt, -3, -1) == 444) assert(extra length(xt)==2) assert(get extra(xt,0)==99) assert(get extra(xt,1)==666) show string($1="Delete range up to end") assert(delete extra range(xt, 1, 2) == 666) assert(extra length(xt)==1) assert(get extra(xt,0)==99) show string($1="Test remove extra") append extra(xt, 100) append extra(xt, 99) remove extra(xt, 100) assert(extra length(xt)==2) assert(get extra(xt,0)==99) assert(get extra(xt,1)==99) remove extra(xt, 99) assert(extra length(xt)==0) show no value free slice(xt) end ######################################################################## # Tests loading slices from file. # A lot more could be added to this script, slice collection tests, begin $0="slice collection tests" variable(sl, sl2) # This is a slice collection with the root slice edited sl := load slice collection(0) w assert(sl) assert(parent slice(sl) == sprite layer) # default parent # Test "check parentage" assert(check parentage(sl, sprite layer) == true) assert(check parentage(sl, sl) == false) # Defined behaviour assert(check parentage(sprite layer, sl) == false) assert(check parentage(sl, lookup slice(sl:root)) == true) sl2 := create rect assert(check parentage(sl, sl2) == false) assert(check parentage(sl2, sl) == false) free slice(sl2) assert(slice is rect(sl) == true) assert(is filling parent(sl) == false) assert(slice x(sl) == -10) assert(slice y(sl) == -20) assert(slice width(sl) == 100) assert(slice height(sl) == 50) assert(get slice visible(sl) == true) assert(extra length(sl) == 3) assert(get slice extra(sl, 0) == 10) assert(get slice extra(sl, 1) == 20) assert(get slice extra(sl, 2) == 30) assert(get top padding(sl) == 1) assert(get right padding(sl) == 2) assert(get bottom padding(sl) == 3) assert(get left padding(sl) == 4) assert(get slice clipping(sl) == true) assert(get slice lookup(sl) == sli:my root slice) assert(get rect fuzziness(sl) == 48) assert(get rect fg col(sl) == 101) assert(get rect bg col(sl) == 71) assert(get rect style(sl) == -1) assert(get horiz align(sl) == edge:right) assert(get vert align(sl) == edge:middle) assert(get horiz anchor(sl) == edge:right) assert(get vert anchor(sl) == edge:top) assert(slice screen x(sl) == 310) # position of the anchor point assert(slice screen y(sl) == 80) sl2 := lookup slice(sli:some lookup) assert(sl2) assert(parent slice(sl2) == sl) assert(slice is sprite(sl2) == true) assert(get sprite type(sl2) == spritetype:walkabout) assert(get spriteset number(sl2) == 6) assert(get sprite palette(sl2) == 1) assert(get sprite frame(sl2) == 4) assert(get sprite trans(sl2) == false) assert(sprite is horiz flipped(sl2) == true) assert(sprite is vert flipped(sl2) == false) assert(sprite is dissolving(sl2) == false) assert(slice width(sl2) == 20) assert(slice height(sl2) == 20) assert(slice x(sl2) == 10) assert(slice y(sl2) == -4) assert(slice screen x(sl2) == 224) assert(slice screen y(sl2) == 77) sl2 := lookup slice(sli:no extras) assert(extra length(sl2) == 0) sl2 := lookup slice(sli:default extras) assert(extra length(sl2) == 3) assert(get slice extra(sl2, 0) == 0) assert(get slice extra(sl2, 1) == 0) assert(get slice extra(sl2, 2) == 0) sl2 := lookup slice(sli:one extra) # Check the length is saved although no non-default values assert(extra length(sl2) == 1) assert(get slice extra(sl2, 0) == 0) sl2 := lookup slice(sli:lotsa extras) assert(extra length(sl2) == 10000) # This tests the encoding of runs of identical values as "repeat" nodes # A "repeat" before any "int" defaults to 0 assert(get slice extra(sl2, 0) == 0) assert(get slice extra(sl2, 2) == 0) assert(get slice extra(sl2, 3) == -98) assert(get slice extra(sl2, 4) == -98) assert(get slice extra(sl2, 5) == -98) assert(get slice extra(sl2, 6) == 0) assert(get slice extra(sl2, 9997) == 0) # A run which goes to the end of the array is a special case assert(get slice extra(sl2, 9998) == -99) assert(get slice extra(sl2, 9999) == -99) free slice(sl) # A simpler collection sl := load slice collection(1) assert(sl) assert(get slice visible(sl) == false) # edited assert(is filling parent(sl) == true) # the default free slice(sl) # Test loading slice extra from obsolete file format sl := load slice collection(1300) assert(extra length(sl) == 3) assert(get slice extra(sl, 0) == 0) assert(get slice extra(sl, 1) == 0) assert(get slice extra(sl, 2) == 0) sl2 := first child(sl) assert(extra length(sl) == 3) assert(get slice extra(sl2, 0) == 10) assert(get slice extra(sl2, 1) == 20) assert(get slice extra(sl2, 2) == 30) free slice(sl) # Loading a missing collection in range 0-32767 returns 0 without error sl := load slice collection(32700) assert(sl == 0) end ######################################################################## script, slice search tests, begin $0="Slice search tests" variable(sl, sl1, sl11, sl111, sl1111, sl1112, sl2) # Build a tree. X1 is the first child of X, X2 is the second child sl1 := create container sl11 := create container, set parent(sl11, sl1) sl111 := create container, set parent(sl111, sl11) set slice lookup(sl111, 14) sl1111 := create container, set parent(sl1111, sl111) sl1112 := create container, set parent(sl1112, sl111) set slice lookup(sl1112, 14) sl2 := create container set slice lookup(sl2, 14) # next slice in tree sl := 0 sl := next slice in tree(sl, sl1), assert(sl == sl1) sl := next slice in tree(sl, sl1), assert(sl == sl11) assert(next slice in tree(sl, sl1, false) == 0) # sl11 has no sibling sl := next slice in tree(sl, sl1), assert(sl == sl111) sl := next slice in tree(sl, sl1), assert(sl == sl1111) assert(next slice in tree(sl, sl1, false) == sl1112) sl := next slice in tree(sl, sl1), assert(sl == sl1112) assert(next slice in tree(sl, sl1, false) == 0) sl := next slice in tree(sl, sl1), assert(sl == 0) # Iterate whole tree sl := next slice in tree(sl1112), assert(sl == sl2) # Starting at the root slice sl := next slice in tree(0, 0), assert(sl == lookup slice(sl:root)) sl := next slice in tree(sl, 0, false), assert(sl == 0) # lookup next slice assert(lookup next slice(sl:walkabout sprite component) == lookup slice(sl:walkabout sprite component)) sl := 0 assert(lookup slice(14, sl1) == sl111) sl := lookup next slice(14, sl, sl1), assert(sl == sl111) sl := lookup next slice(14, sl, sl1), assert(sl == sl1112) sl := lookup next slice(14, sl, sl1), assert(sl == 0) sl := lookup next slice(14, sl1112), assert(sl == sl2) sl := lookup next slice(14, sl1111, sl1), assert(sl == sl1112) # Starting from a slice without lookup 14 sl := 0 while (true) do ( sl := lookup next slice(sl:walkabout sprite component, sl) if (sl == 0) then (break) assert(get sprite type(sl) == spritetype:walkabout) ) free slice(sl1) free slice(sl2) end ######################################################################## # Unfinished tests of findcollidingslice and sliceatpixel script, slice collision tests, begin $0="Slice collision tests" variable(parent, sl1, sl2, sl3, sl4, sl5, temp) parent := create select # f put slice (parent, 100, 200) sl1 := create container(0, 0) set parent(sl1, parent) assert(slice at pixel(parent, 0, 0) == 0) # can't be hit assert(slice at pixel(parent, 0, 0, get count) == 0) sl2 := create container(10, 10) set parent(sl2, parent) sl3 := create container(1, 1) set parent(sl3, parent) put slice(sl3, 4, 5) sl4 := create container(1, 1) set parent(sl4, sl3) wait(1) # update select visibility ### Testing slice at pixel # Unfinished: no testing of slices with negative width/height. # Only sl1 should be visible... assert(get slice visible(sl1) == true) assert(get slice visible(sl2) == false) assert(get slice visible(sl3) == false) assert(get slice visible(sl4) == true) assert(slice at pixel(parent, 100, 200) == sl2) # topleft corner assert(slice at pixel(parent, 105, 205) == sl2) # inside assert(slice at pixel(parent, 100, 210) == 0) # on the edge of sl2 assert(slice at pixel(parent, 110, 200) == 0) # on the edge of sl2 assert(slice at pixel(parent, 100, 200, get count) == 1) # sliceatpixel and findcollidingslice must return slices from bottommost to topmost assert(slice at pixel(parent, 104, 205, get count) == 3) assert(slice at pixel(parent, 104, 205, 0) == sl2) assert(slice at pixel(parent, 104, 205, 1) == sl3) assert(slice at pixel(parent, 104, 205, 2) == sl4) assert(slice at pixel(parent, 104, 205, 3) == 0) # now without descending: assert(slice at pixel(parent, 104, 205, get count, false) == 2) assert(slice at pixel(parent, 104, 205, 0, false) == sl2) assert(slice at pixel(parent, 104, 205, 1, false) == sl3) assert(slice at pixel(parent, 104, 205, 2, false) == 0) # test visibleonly assert(slice at pixel(parent, 104, 205, get count, true, true) == 0) # visibility of the 'parent' slice doesn't affect anything (sl3 is not visible) assert(slice at pixel(sl3, 104, 205, get count, true, true) == 1) # change visible slice to sl3 set select slice index(parent, 2) wait(1) # update select visibility assert(get slice visible(sl3) == true) # now sl3 and sl4 should be hit assert(slice at pixel(parent, 104, 205, get count, true, true) == 2) assert(slice at pixel(parent, 104, 205, 0, true, true) == sl3) assert(slice at pixel(parent, 104, 205, 1, true, true) == sl4) # ##Testing find colliding slice # Unfinished: don't yet check all the cases of an AABB collision test. # (Easier to test manually with collisiontest.rpg) # Also, no testing of slices with negative width/height. sl5 := load walkabout sprite(0) assert(slice height(sl5) == 20) put slice(sl5, 100, 190) # sliceatpixel and findcollidingslice must return slices from bottommost to topmost #tracevalue(parent, sl1, sl2, sl3, sl4, sl5) assert(find colliding slice(parent, sl5, get count) == 3) # Don't find sl1 which is zero size (FIXME: which I think probably isn't correct, since "slice contains" would say yes) #assert(find colliding slice(parent, sl5, 0) == sl1) assert(find colliding slice(parent, sl5, 0) == sl2) assert(find colliding slice(parent, sl5, 1) == sl3) assert(find colliding slice(parent, sl5, 2) == sl4) assert(find colliding slice(parent, sl5, 3) == 0) # Test non-overlap of adjacent slices set parent(sl5, parent) put slice(sl5, 0, 5 -- 20) # positioned so sl3 on bottom edge # Create another couple slices adjacent to sl5 on the top and left temp := create container(1, 1) set parent(temp, parent) put slice(temp, -1, 0) # 1 left of sl5 temp := create container(1, 1) set parent(temp, parent) put slice(temp, 0, 5 -- 20 -- 1) # 1 up from sl5 assert(find colliding slice(parent, sl5, 0) == sl2) # doesn't find sl1, zero size assert(find colliding slice(parent, sl5, 1) == 0) # should not find sl3, nor sl5, nor the temp slices # Now overlap by one put slice(sl5, 0, 5 -- 20 + 1) # now sl3 overlaps assert(find colliding slice(parent, sl5, 0) == sl2) # doesn't find sl1, zero size assert(find colliding slice(parent, sl5, 1) == sl3) assert(find colliding slice(parent, sl5, 2) == sl4) assert(find colliding slice(parent, sl5, 3) == 0) # should not find sl5 # try using a 0x0 slice to search for overlaps - should find nothing. # (FIXME: This is probably not correct; as an infinitesimal point it overlaps sl2 and sl5. assert(find colliding slice(parent, sl1, 0) == 0) # Test no descending # Don't find sl1 which is zero size (FIXME: which I think probably isn't correct, since "slice contains" would say yes) assert(find colliding slice(parent, sl5, 0, false) == sl2) assert(find colliding slice(parent, sl5, 1, false) == sl3) assert(find colliding slice(parent, sl5, 2, false) == 0) # shouldn't find sl4 assert(find colliding slice(parent, sl5, get count, false) == 2) # Test visible only (only sl3 is visible) assert(find colliding slice(parent, sl5, get count, true, true) == 2) assert(find colliding slice(parent, sl5, 0, true, true) == sl3) assert(find colliding slice(parent, sl5, 1, true, true) == sl4) assert(find colliding slice(parent, sl5, 2, true, true) == 0) # Do two 0x0 slices at the same point overlap? (they shouldn't) free slice children(parent) temp := create container(0, 0) set parent(temp, parent) temp := create container(0, 0) set parent(temp, parent) assert(find colliding slice(parent, temp, get count) == 0) free slice(parent) end ######################################################################## # Return index of a child of the root slice. script, root child index, lookup code, begin variable(sl) clear string(err arg string) append number(err arg string, lookup code) sl := lookup slice(lookup code) assert(sl) assert(parent slice(sl) == lookup slice(sl:root)) return(slice child indeX(sl)) end # Unfinished, only inspects children of root. # But see also "slice correspondence tests" for NPC & hero slices script, slice tree tests, begin $0="Slice tree tests" assert(sprite layer == lookup slice(sl:script layer)) # Ensure the major slice layers appear in a fixed order. # Probably OK for new slices to get added between these (anyone making assumptions about the n-th # child here may be too much pain to support) variable (scr, map, textbox, backdrop, strings) map := root child index(sl:map root) backdrop := root child index(sl:backdrop) scr := root child index(sl:script layer) textbox := root child index(sl:textbox layer) strings := root child index(sl:string layer) assert(map < backdrop) assert(backdrop < scr) assert(scr < textbox) assert(textbox < strings) end ######################################################################## # This tests commands for converting between slices and hero/npc references script, slice correspondence tests, begin #### Test NPC slices variable(npc, sl, sl2, walkabout layer) walkabout layer := lookup slice(sl:npc layer) npc := next npc reference while (npc) do ( sl := get npc slice(npc) assert(sl) assert(npc reference from slice(sl) == npc) # Should be the top-level walkabout container assert(slice parent(sl) == walkabout layer) assert(slice x(sl) == npc pixel x(npc)) assert(slice y(sl) == npc pixel y(npc)) sl2 := lookup slice(sl:walkabout sprite component, sl) assert(sl2) assert(sl2 == get npc sprite(npc)) assert(npc reference from slice(sl2) == 0) npc := next npc reference(npc) ) sl := get hero slice(0) assert(sl && npc reference from slice(sl) == 0) #### Test hero slices # Preconditions assert(hero by slot(0) == hero:Freki) assert(hero by slot(1) == -1) assert(hero by slot(2) == -1) assert(hero by slot(3) == -1) sl := get hero slice(0) assert(sl) assert(slice parent(sl) == lookup slice(sl:hero layer)) assert(slice x(sl) == hero pixel x(0)) assert(slice y(sl) == hero pixel y(0)) assert(sl == get hero slice by slot(0)) assert(hero rank from slice(sl) == 0) assert(hero slot from slice(sl) == 0) sl2 := lookup slice(sl:walkabout sprite component, sl) assert(sl2) assert(sl2 == get hero sprite(0)) # Defaults to -1 assert(hero rank from slice(get npc slice(next npc reference)) == -1) assert(hero slot from slice(get npc slice(next npc reference)) == -1) # Check it returns rank, not party slot swap by position(0, 1) sl := get hero slice(0) assert(sl) assert(hero rank from slice(sl) == 0) assert(hero slot from slice(sl) == 1) # Compare with 'by slot' assert(get hero slice by slot(0) == 0) assert(get hero slice by slot(1) == sl) # Test rank > 0 add hero(hero:Bram) sl := get hero slice(1) assert(sl) assert(get hero slice by slot(1) == sl) assert(hero rank from slice(sl) == 1) assert(hero slot from slice(sl) == 1) # Hero slices belonging to non-existent heroes shouldn't exist, but before # gorgonzola they did exist. (Already tested "get hero slice by slot") assert(get hero slice(2) == 0) # Restore delete hero(hero:Bram) swap by position(0, 1) end ######################################################################## script, slice blending tests, begin variable(sl, collection) sl := load hero sprite(0, 1) assert(get blending enabled(sl) == false) assert(get opacity(sl) == 100) assert(get blend mode(sl) == blend:normal) # Test opacity set opacity(sl, 50), w assert(get opacity(sl) == 50) assert(get blending enabled(sl) == true) # And blend mode set blend mode(sl, blend:multiply), w assert(get blend mode(sl) == blend:multiply) set blending enabled(sl, false), w assert(get blending enabled(sl) == false) assert(get opacity(sl) == 100) assert(get blend mode(sl) == blend:normal) # Check blending settings preserved when blending is disabled set blending enabled(sl, true), w assert(get opacity(sl) == 50) assert(get blend mode(sl) == blend:multiply) free slice(sl) sl := create container # Allowed on non-blendable slices assert(get blending enabled(sl) == false) assert(get opacity(sl) == 100) assert(get blend mode(sl) == blend:normal) free slice(sl) # Check Map slice blending sl := lookup slice(sl:map layer 1) set opacity(sl, 30), w assert(get opacity(sl) == 30) set opacity(sl, 100) # Check blending settings loaded from file correctly collection := load slice collection(2) sl := first sprite child(collection) assert(get opacity(sl) == 45) assert(get blend mode(sl) == blend:add) free slice(collection) end ######################################################################## script, slice sort tests, begin # Very incomplete variable(parent, ch1, ch2, ch3, ch4) parent := create container(100,100) ch1 := create container(10,10) set parent(ch1, parent) ch2 := create container(10,10) set parent(ch2, parent) ch3 := create container(10,20) set parent(ch3, parent) ch4 := create container(10,100) set parent(ch4, parent) #### get/set child autosort # Preconditions assert(current map == 0) assert(read gmap(16) == 0) # Map 0 is set to heroes over NPCs. assert(get child autosort(lookup slice(sl:walkabout layer)) == autosort:off) write gmap(16, 2) # Layering: NPCs and heroes together assert(read gmap(16) == 2) # This might actually change in future when more sophisticated layering is implemented assert(get child autosort(lookup slice(sl:walkabout layer)) == autosort:Y) write gmap(16, 0) # Reset to heroes over NPCs set child autosort(parent, autosort:bottomY) assert(get child autosort(parent) == autosort:bottomY) # Test bottomY sorting set slice edge y(ch1, edge:bottom, 100) assert(slice y(ch1) == 100 -- 10) set vert anchor(ch2, edge:middle) set slice edge y(ch2, edge:bottom, 50) assert(slice y(ch2) == 50 -- 10/2) set vert anchor(ch3, edge:bottom) set slice edge y(ch3, edge:bottom, 80) assert(slice y(ch3) == 80) set vert anchor(ch4, edge:middle) set vert align(ch4, edge:bottom) set slice edge y(ch4, edge:bottom, 50) wait(1) assert(slice child(parent, 0) == ch2) assert(slice child(parent, 1) == ch4) assert(slice child(parent, 2) == ch3) assert(slice child(parent, 3) == ch1) free slice(parent) end ######################################################################## define constant(1, zone:center) define constant(2, zone:wholegrass) define constant(3, zone:rightedge) define constant(4, zone:leftedge) define constant(5, zone:everything) define constant(6, zone:topedge) define constant(7, zone:bottomedge) # Equivalent to readzone, but checks it agrees with zoneatspot script, check zone, id, x, y, begin variable(i, what) for (i, 0, zone at spot(x, y, getcount) -- 1) do ( what := zone at spot(x, y, i) assert(what > 0) if (what == id) then ( assert(read zone(id, x, y) == true) exit returning (true) ) ) assert(read zone(id, x, y) == false) return(false) end script, zone tests, begin $0="zone tests" # Could do with more tests of the internal complexities of ZoneMap # Read some existing tiles (green plot of grass) assert(zone at spot(17, 15, getcount) == 3) assert(check zone(1, 17, 15) == 1) assert(check zone(2, 17, 15) == 1) assert(check zone(3, 17, 15) == 0) assert(check zone(5, 17, 15) == 1) assert(zone at spot(16, 16, getcount) == 4) assert(check zone(1, 16, 16) == 0) assert(check zone(2, 16, 16) == 1) assert(check zone(3, 16, 16) == 0) assert(check zone(4, 16, 16) == 1) assert(check zone(5, 16, 16) == 1) assert(check zone(7, 16, 16) == 1) # zone number of tiles assert(zone number of tiles(1) == 1) assert(zone number of tiles(2) == 9) assert(zone number of tiles(5) == 800) assert(zone number of tiles(8) == 0) assert(zone number of tiles(9988) == 0) # Zone name get zone name (95, zone:leftedge) $96="left edge" assert(string compare(95, 96)) # Test zone handles (except extra data) variable (zone5) zone5 := get zone(5) assert(zone5 && zone5 <> 5) clearstring(95) get zone name (95, get zone(zone:leftedge)) assert(string compare(95, 96)) assert(read zone(zone5, 16, 16) == 1) write zone(zone5, 16, 16, 0) assert(read zone(5, 16, 16) == 0) write zone(5, 16, 16, 1) assert(zone number of tiles(zone5) == 800) # Zone extra #assert(get zone(zone 5) == zone 5) # Meant to be idempotent assert(get zone extra(5, 0) == 10) assert(get zone extra(5, 1) == -2147483648) assert(get zone extra(5, 2) == 2147483647) assert(get zone extra(5, -1) == 2147483647) assert(get extra(zone5, -1) == 2147483647) set extra(zone5, -2, 32) assert(get zone extra(5, 1) == 32) assert(extra length(zone5) == 3) # A zone with zero length extra variable (zone10) zone10 := get zone(10) assert(extra length(zone10) == 0) append extra(zone10, 2) assert(extra length(zone10) == 1) assert(get extra(zone10, -1) == 2) # A zone with more extra assert(extra length(get zone(11)) == 13) assert(get zone extra(11, 12) == 999) # A nonexistent zone get zone name (95, 9000) assert(string length(95) == 0) assert(get zone extra(9000, 0) == 0) assert(get zone extra(9000, 1) == 0) set zone extra (9000, 2, 32) assert(get zone extra(9000, 2) == 32) # Erasing a zone shouldn't affect others on the same tile write zone(1, 17, 15, 0) assert(check zone(1, 17, 15) == 0) assert(check zone(2, 17, 15) == 1) assert(check zone(5, 17, 15) == 1) assert(zone at spot(17, 15, getcount) == 2) write zone(1, 17, 15, 1) assert(check zone(1, 17, 15) == 1) # Write a zone that doesn't exist at all yet write zone(1003, 16, 14, 1) assert(check zone(1003, 16, 14) == 1) variable(idx, idx2, count) # Already 3 zones here; place 15 zones on one tile (the max) count := 3 for (idx, 1001, 1012) do ( write zone(idx, 17, 15, 1) assert(check zone(idx, 17, 15) == 1) count += 1 assert(zone at spot(17, 15, getcount) == count) ) # Remove them again in FIFO order for (idx, 1001, 1012) do ( write zone(idx, 17, 15, 0) assert(check zone(idx, 17, 15) == 0) count -= 1 assert(zone at spot(17, 15, getcount) == count) for (idx2, idx + 1, 1012) do ( assert(check zone(idx2, 17, 15) == 1) ) ) # Check other zones within the same 4x4 block are undisturbed assert(zone at spot(16, 14, getcount) == 5) assert(check zone(1, 16, 14) == 0) assert(check zone(2, 16, 14) == 1) assert(check zone(3, 16, 14) == 0) assert(check zone(4, 16, 14) == 1) assert(check zone(5, 16, 14) == 1) assert(check zone(6, 16, 14) == 1) assert(check zone(1003, 16, 14) == 1) zones randomized test end script, zones randomized test, begin # Do a randomised test of writing and reading zones in a 8x8 area # (four 4x4 blocks) at top-left corner of the map). # The idea is that the zonemap code has a lot of edge cases as a result of # implementation details which are a huge pain to write tests for, and those # tests wouldn't be worth much if the implementation changes. # Unfortunately these tests still aren't worth much; changing the various magic # constants results in them not hitting the edge cases anyway! :( # We check which zones we expect to see in 64 globals which act as bitvectors, # the i-th bit set if that tile should be in zone i. show value(1) wait # Returns true or false. id >= 1 subscript, readarray, id, x, y, begin return((read global(array:zones + x + y * 8) / 2^(id--1)), and, 1) end # id >= 1 subscript, writearray, id, x, y, value, begin variable(bits) bits := read global(array:zones + x + y * 8) bits := bits, and, (-1 -- 2^(id--1)) if (value) then (bits += 2^(id--1)) write global(array:zones + x + y * 8, bits) end # Num zones at tile subscript, array count zones, x, y, begin return(bitcount(read global(array:zones + x + y * 8))) end # Check the whole area is as it should be subscript, test area, begin variable(x, y, id) for (x, 0, 7) do ( for (y, 0, 7) do ( for (id, 1, 31) do ( assert(readarray(id, x, y) == read zone(id, x, y)) ) assert(zone at spot(x, y, getcount) == array count zones(x, y)) ) ) end # Initial state variable(x,y) for (x, 0, 7) do ( for (y, 0, 7) do (writearray(zone:everything, x, y, 1)) ) #test area # Stick to 15 zones in the whole area, so no overflow occurs variable(it, id, newvalue) for (it, 0, 300) do ( show value(it) x := random(0,4) y := random(0,5) id := random(1,15) newvalue := random(0,1000) 0 assert(readarray(id, x, y) == readzone(id, x, y)) writezone(id, x, y, newvalue) writearray(id, x, y, newvalue) if (it, mod, 5 == 0) then (test area) ) show value(2) wait # Now start using more zones, so that overcrowding occurs # But don't use more than 15 per tile for (it, 0, 5000) do ( show value(10000+it) x := random(0,7) y := random(0,3) id := random(1,31) newvalue := random(0,2) > 0 if (newvalue == 1 && array count zones(x, y) == 15) then (continue) assert(readarray(id, x, y) == readzone(id, x, y)) writezone(id, x, y, newvalue) writearray(id, x, y, newvalue) if (it, mod, 200 == 0) then (test area) ) shownovalue wait end ######################################################################## script, master palette tests, begin $0="master palette tests" # Test reading master palette assert(get color(0) == RGB(255, 0, 255)) assert(get color(6) == RGB(155, 83, 3)) assert(extract color(get color(19), color:red) == 37) assert(extract color(get color(19), color:green) == 139) assert(extract color(get color(19), color:blue) == 255) # Test searching master palette assert(find color(255, 0, 255) == 0) assert(find color(0, 0, 0, 255) == 255) assert(find color(0, 0, 0, 256) == 0) assert(find color(255, 0, 255, 1) == 185) assert(find color(255, 0, 255, 185) == 185) assert(find color(255, 0, 255, 186) == 200) assert(find color(180, 180, 0) == 103) assert(find color(512, 100, -512) == 168) # Test get/set ui color assert(get ui color(ui:background) == 240) assert(get ui color(0) == 0) assert(get ui color(255) == 255) assert(get ui color(ui:MPBarFlash) == 37) # Currently last UI col open menu(0) set ui color(ui:menu item, 99) assert(get ui color(ui:menu item) == 99) w close menu(top menu) set ui color(ui:menu item, ui:background) assert(get ui color(ui:menu item) == 240) set ui color(ui:menu item, 250) # Reset # Test "get ui color" autotoggling variable(c1, c2, tog1, tog2, ) c1 := get ui color(ui:selected item) c2 := get ui color(ui:selected item 2) assert(c1 == 14) assert(c2 == 15) tog1 := get ui color(ui:selected item 2, true) wait(1) assert(get ui color(ui:selected item 2) == c2) tog2 := get ui color(ui:selected item 2, true) # Currently it changes every tick assert((tog1 == c1 && tog2 == c2) || (tog1 == c2 && tog2 == c1)) # Test box styles assert(get box style color(14) == 65) assert(get box style edge color(14) == 252) assert(get box style border(14) == 1) assert(get box style color(0) == 33) # Lots of other color commands could be tested end ######################################################################## script, maptile tests, begin $0="maptile tests" # Test some tilemap, passmap, foemap commands # (Zones are tested separately in 'zone tests', and wallchecking # in 'wallchecking tests' and 'do hero cater tests') # Read some tiles on the left edge of the house (of map 0) assert(read map block(6, 5, 0) == 112) assert(read map block(6, 4, 0) == 96) assert(read map block(6, 4, 1) == 0) assert(read map block(6, 4, 2) == 58) assert(read pass block(6, 5) == westwall + southwall) # Oneway doors assert(read zone(zone:OneWayExit, 4, 10) == 1) assert(read pass block(4, 10) == southwall + northwall) assert(read pass block(5, 10) == southwall) # Write tilemap write map block(3, 2, 255, 1) assert(read map block(3, 2, 1) == 255) reset map state(mapstate:tilemap) assert(read map block(3, 2, 1) == 0) # Write passmap write pass block(3, 2, 255) assert(read pass block(3, 2) == 255) write pass block(3, 2, 0) # Read/write wall bit write pass block(3, 2, east wall + harm tile) assert(read wall bit(3, 2, east wall) == true) assert(read wall bit(3, 2, west wall) == false) write wall bit(3, 2, east wall, false) write wall bit(3, 2, vehicle a, true) assert(read pass block(3, 2) == vehicle a + harm tile) write pass block(3, 2, 0) # Read foemap assert(read foe map(14, 5) == 0) assert(read foe map(14, 6) == 1) assert(read foe map(-1, 0) == 0) # Test tile animations # An animated tile (water assert(read map block(3, 3, 0) == 192) # animation start tile (tile number, layer) assert(animation start tile (192, 0) == 144) # get tile animation offset (animation pattern, layer) # Second animation pattern isn't used, so this should be zero assert(get tile animation offset(1, 0) == 0) assert(currentdisplaytile(208) == 0) # first tile of the range assert(currentdisplaytile(192) >= 144 && currentdisplaytile(192) <= 147) assert(currentdisplaytile(192) == 144 + get tile animation offset(0, 0)) #set tile animation offset (animation pattern, offset, layer) not tested # These checks will have to change if any layers are added to map 0 or 1 variable(rem map, rem x, rem y) rem map := current map rem x := hero x(me) rem y := hero y(me) teleport to map(0, 0, 0) w assert(last layer id == 2) assert(layer id under walkabouts == 1) w teleport to map(1, 0, 0) w assert(last layer id == 1) assert(layer id under walkabouts == 0) w # go back to the map we were on before teleport to map(rem map, rem x, rem y) end ######################################################################## script, map state tests, begin $0="map state tests" # Preconditions assert(current map == 0) # These tests are quite incomplete: # No tests of NPC definition or map settings # No tests of saving/loading data when leaving/entering map # No tests that load/saving/deleting one state doesn't change the others # The RELOAD NPC instance file format is used only by map state, so it should be fully tested somewhere variable(mapstate:tilepass) mapstate:tilepass := mapstate:tilemap + mapstate:passmap # Test maptiles and walls, saving to a custom save state file assert(read map block(7, 2, 2) == 42) # Precondition assert(read pass block(7, 2) == northwall) # Precondition write map block(7, 2, 11, 2) write pass block(7, 2, eastwall) assert(read map block(7, 2, 2) == 11) assert(read pass block(7, 2) == eastwall) # "load map state" with a custom ID should do nothing if the file doesn't exist load map state(mapstate:tilepass, 1) assert(read map block(7, 2, 2) == 11) assert(read pass block(7, 2) == eastwall) # save/reset/load save map state(mapstate:tilepass, 1) reset map state(mapstate:tilepass) assert(read map block(7, 2, 2) == 42) assert(read pass block(7, 2) == northwall) load map state(mapstate:tilemap, 1) # Half-hearted test of loading tiles and walls separately assert(read map block(7, 2, 2) == 11) assert(read pass block(7, 2) == northwall) load map state(mapstate:passmap, 1) assert(read pass block(7, 2) == eastwall) write map block(7, 2, 12, 2) write pass block(7, 2, westwall) # delete state delete map state(mapstate:tilepass, 1) # "load map state" with a custom ID should again do nothing load map state(mapstate:tilepass, 1) assert(read map block(7, 2, 2) == 12) assert(read pass block(7, 2) == westwall) # "load map state" with no ID should default to resetting load map state(mapstate:tilepass) assert(read map block(7, 2, 2) == 42) assert(read pass block(7, 2) == northwall) # Test zones assert(read zone(6, 16, 14) == true) # Precondition assert(read zone(6, 15, 14) == false) # Precondition assert(get zone extra(5, 0) == 10) # Precondition write zone(6, 16, 14, false) write zone(6, 15, 14, true) set zone extra(5, 0, 11) write zone(765, 10, 20, true) # an unused zone assert(read zone(6, 16, 14) == false) assert(read zone(6, 15, 14) == true) assert(read zone(765, 10, 20) == true) # "load map state" with a custom ID should do nothing if the file doesn't exist load map state(mapstate:zonemap, 1) assert(read zone(6, 16, 14) == false) assert(read zone(6, 15, 14) == true) assert(read zone(765, 10, 20) == true) assert(get zone extra(5, 0) == 11) # save/reset/load save map state(mapstate:zonemap, 1) reset map state(mapstate:zonemap) assert(read zone(6, 16, 14) == true) assert(read zone(6, 15, 14) == false) assert(read zone(765, 10, 20) == false) assert(get zone extra(5, 0) == 10) load map state(mapstate:zonemap, 1) assert(read zone(6, 16, 14) == false) assert(read zone(6, 15, 14) == true) assert(read zone(765, 10, 20) == true) assert(get zone extra(5, 0) == 11) write zone(6, 16, 14, true) write zone(6, 15, 14, true) set zone extra(5, 0, 12) # delete state delete map state(mapstate:zonemap, 1) # "load map state" with a custom ID should again do nothing load map state(mapstate:zonemap, 1) assert(read zone(6, 16, 14) == true) assert(read zone(6, 15, 14) == true) assert(read zone(765, 10, 20) == true) assert(get zone extra(5, 0) == 12) # "load map state" with no ID should default to resetting load map state(mapstate:zonemap) assert(read zone(6, 16, 14) == true) assert(read zone(6, 15, 14) == false) assert(read zone(765, 10, 20) == false) assert(get zone extra(5, 0) == 10) # Test NPC instances variable(npc, newnpc) npc := npc reference(4, 2) assert(npc x(npc) == 3 && npc y(npc) == 13) # Precondition assert(npc copy count(7) == 0) # Precondition set npc position(npc, 5, 6) newnpc := create NPC(7, 1, 2) assert(npc copy count(7) == 1) # "load map state" with a custom ID should do nothing if the file doesn't exist load map state(mapstate:npcs, 1) assert(npc x(npc) == 5 && npc y(npc) == 6) assert(npc x(newnpc) == 1 && npc y(newnpc) == 2) # save/load/reset save map state(mapstate:npcs, 1) # Check deleted NPCs are restored, with same npcref delete NPC(npc) assert(get NPC id(npc) == -1) # Check the npcref is invalid reset map state(mapstate:npcs) # NPC references should stay valid if it's the same NPC assert(npc x(npc) == 3 && npc y(npc) == 13) # Check created NPCs are deleted assert(npc copy count(7) == 0) assert(get NPC id(newnpc) == -1) load map state(mapstate:npcs, 1) assert(npc x(npc) == 5 && npc y(npc) == 6) # Check created NPCs are loaded assert(npc copy count(7) == 1) assert(npc x(newnpc) == 1 && npc y(newnpc) == 2) # delete state delete map state(mapstate:npcs, 1) # "load map state" with a custom ID should again do nothing load map state(mapstate:npcs, 1) assert(npc x(npc) == 5 && npc y(npc) == 6) assert(npc x(newnpc) == 1 && npc y(newnpc) == 2) # "load map state" with no ID should default to resetting load map state(mapstate:npcs) assert(npc x(npc) == 3 && npc y(npc) == 13) assert(get NPC id(newnpc) == -1) end ######################################################################## script, obsolete map data tests, begin $0="obsolete map data tests" variable(rem map, rem x, rem y) rem map := current map rem x := hero x(me) rem y := hero y(me) teleport to map(map: Obsolete map data DO NOT EDIT, 0, 0) # This map should not be opened in Custom, so that the map lumps aren't loaded and re-saved. # Copied from zone tests # Other zone data commands get zone name (95, 5) $96="extra data test" assert(string compare(95, 96)) assert(extra length(get zone(5)) == 3) assert(get zone extra(5, 0) == 10) assert(get zone extra(5, 1) == -2147483648) assert(get zone extra(5, 2) == 2147483647) # A nonexistent zone get zone name (95, 9000) assert(string length(95) == 0) assert(extra length(get zone(9000)) == 3) assert(get zone extra(9000, 0) == 0) assert(get zone extra(9000, 1) == 0) assert(get zone extra(9000, 2) == 0) teleport to map(rem map, rem x, rem y) end ######################################################################## script, wallchecking tests, begin $0="wallchecking tests" # This tests moveslicewithwallchecking and checkwallcollisionx/y commands. # This follows previous tests of basic hero movement ("do hero cater tests") # which check hero movement obeys walls. variable(tilex, tiley) tilex := 6 tiley := 15 # The tile at tilex,tiley is called the center tile # hitbox size variable(hitboxw, hitboxh) variable(hitbox) hitbox := create container set parent(hitbox, lookupslice(sl:map layer 0)) subscript, set hitbox size, wide, high, begin hitboxw := wide hitboxh := high set slice size(hitbox, wide, high) end subscript, testcollide, testnum, x, y, xgo, ygo, expectedx, expectedy, expectedret = -1, begin #show value(testnum) #tracevalue(testnum, x, y, xgo, ygo, expectedx, expectedy) variable(resultx, resulty, ret) # if (false) then ( # resultx := check wall collision x(x, y, hitboxw, hitboxh, xgo, ygo) # resulty := check wall collision y(x, y, hitboxw, hitboxh, xgo, ygo) # ) else ( putslice(hitbox, x, y) ret := moveslicewithwallchecking(hitbox, xgo, ygo) resultx := slicex(hitbox) -- x resulty := slicey(hitbox) -- y # ) #tracevalue(resultx, resulty) if (expectedret <> -1) then ( #trace(string sprintf(98, $99="ret: %b wanted %b", ret, expectedret)) assert(ret == expectedret) ) assert(resultx == expectedx) assert(resulty == expectedy) end # Test 45 degree and near-45 degree collisions with one of the 4 corners of the center tile # cornerx and cornery are 0 or 1 for left/up or right/bottom, # and also possibly the far corner if there are no walls at the first one. subscript, test corner, cornerx, cornery, cornermask, begin #tracevalue(cornerx, cornery) # The four walls of the center tile variable(wall up, wall left, wall right, wall down) wall left := (readpassblock(tilex, tiley), and, westwall) || (readpassblock(tilex--1, tiley), and, eastwall) wall right := (readpassblock(tilex, tiley), and, eastwall) || (readpassblock(tilex+1, tiley), and, westwall) wall up := (readpassblock(tilex, tiley ), and, northwall) || (readpassblock(tilex, tiley--1), and, southwall) wall down := (readpassblock(tilex, tiley ), and, southwall) || (readpassblock(tilex, tiley+1 ), and, northwall) # whether there is a wall on the vertical or horizontal side of # the center tile adjacent to the corner variable(vside, hside, far vside, far hside) if (cornerx == 0) then ( vside := wall left far vside := wall right ) else ( vside := wall right far vside := wall left ) if (cornery == 0) then ( hside := wall up far hside := wall down ) else ( hside := wall down far hside := wall up ) # position in pixels of the corner variable(x, y) x := (tilex + cornerx) * 20 y := (tiley + cornery) * 20 # Convert to position of (top-left of) collider when at the corner if (cornerx == 0) then (x -= hitboxw) if (cornery == 0) then (y -= hitboxh) # Distance moved by collider before reaching corner variable(strikedist) strikedist := 22 # should be >= 2 # 1 or -1, the sign of xgo/ygo of the collider variable(xgodir, ygodir) if (cornerx == 0) then (xgodir := 1) else (xgodir := -1) if (cornery == 0) then (ygodir := 1) else (ygodir := -1) # xgo/ygo are 10 pixels beyond the corner variable(xgo, ygo) xgo := xgodir * 2 * strikedist #(10 + strikedist) ygo := ygodir * 2 * strikedist #(10 + strikedist) # start position of collider (top-left), in pixels variable(startx, starty) startx := x -- xgodir * strikedist starty := y -- ygodir * strikedist if (vside || hside) then ( # Hit the corner at 45 degree testcollide(1, startx, starty, xgo, ygo, xgodir * strikedist, ygodir * strikedist, cornermask) # Move parallel to the corner, so we miss it by 1 pixel, but still at 45 degree testcollide(2, startx + xgodir, starty, xgo, ygo, xgodir * strikedist, ygodir * strikedist) testcollide(3, startx, starty + ygodir, xgo, ygo, xgodir * strikedist, ygodir * strikedist) # Try angles slightly above and below 45 degree but which still hit the corner at the same time testcollide(4, startx+1, starty, xgo -- 2, ygo, xgodir * strikedist -- 1, ygodir * strikedist, cornermask) testcollide(5, startx, starty+1, xgo, ygo -- 2, xgodir * strikedist, ygodir * strikedist -- 1, cornermask) testcollide(6, startx--1, starty, xgo + 2, ygo, xgodir * strikedist + 1, ygodir * strikedist, cornermask) testcollide(7, startx, starty--1, xgo, ygo + 2, xgodir * strikedist, ygodir * strikedist + 1, cornermask) # Hit the corner in one axis a fraction of a pixel before the other testcollide(8, startx+1, starty, xgo -- 1, ygo, xgodir * strikedist -- 1, ygodir * strikedist, cornermask) testcollide(9, startx--1, starty, xgo + 1, ygo, xgodir * strikedist + 1, ygodir * strikedist, cornermask) testcollide(10, startx, starty -- 1, xgo, ygo + 1, xgodir * strikedist, ygodir * strikedist + 1, cornermask) testcollide(11, startx, starty + 1, xgo, ygo -- 1, xgodir * strikedist, ygodir * strikedist -- 1, cornermask) ) else if (strikedist > 20 && (far vside || farhside)) then ( # Pass through the corner, but hit a wall on the opposite side variable(expectx, expecty, expect ret) expectx := xgodir * (strikedist+20) expecty := ygodir * (strikedist+20) # Hit the inside corner at 45 degree if (far vside) then ( if (cornerx == 0) then (expectret += eastwall) else (expectret += westwall) ) if (far hside) then ( if (cornery == 0) then (expectret += southwall) else (expectret += northwall) ) testcollide(20, startx, starty, xgo, ygo, expectx, expecty, expectret) # Hit the inside corner in one axis a fraction of a pixel before the other testcollide(21, startx + 1, starty, xgo -- 1, ygo, expectx -- 1, expecty) testcollide(22, startx -- 1, starty, xgo + 1, ygo, expectx + 1, expecty) testcollide(23, startx, starty + 1, xgo, ygo -- 1, expectx, expecty -- 1) testcollide(24, startx, starty -- 1, xgo, ygo + 1, expectx, expecty + 1) ) else ( # Hit no walls testcollide(30, startx, starty, xgo, ygo, xgo, ygo, 0) ) end # Some simple manually written test configurations # The tile at tilex,tiley has walls on all sides variable(x,y) x := tilex*20 y := tiley*20 set hitbox size(10, 10) testcollide(100, x--20, y--5, 20, 0, 10, 0, eastwall) # hit wall from west testcollide(101, x+40, y--5, -40, 0, -20, 0, westwall) # ...east testcollide(102, x--5, y--15, 0, 20, 0, 5, southwall) # ...north testcollide(103, x--5, y+35, 0, -20, 0, -15, northwall) # ...south # Diagonal movement that hits the corner in one axis a fraction of a pixel # before the other axis variable(hitx, hity) # position of the the corner to hit hitx := tilex*20 + 20 hity := tiley*20 + 20 testcollide(110, hitx + 2, hity + 3, -5, -6, -2, -3, northwest corner) testcollide(111, hitx + 3, hity + 2, -6, -5, -3, -2, northwest corner) hitx := tilex*20 -- hitboxw testcollide(112, hitx -- 3, hity + 2, 6, -5, 3, -2, northeast corner) testcollide(113, hitx -- 2, hity + 3, 5, -6, 2, -3, northeast corner) hity := tiley*20 -- hitboxh testcollide(114, hitx -- 3, hity -- 2, 6, 5, 3, 2, southeast corner) testcollide(115, hitx -- 2, hity -- 3, 5, 6, 2, 3, southeast corner) # Test collision with the ends and center of a large hitbox (only x axis) set hitbox size(1, 58) variable(dx) # the sign of xgo (whether hit from left or right) variable(expected) # expected return value (wall mask) for(dx, 1, -1, -2) do ( x := tilex*20 if (dx == 1) then (x -= 10 + hitboxw) else (x += 10 + 20) if (dx == 1) then (expected := eastwall) else (expected := westwall) testcollide(104, x, y--19,dx*30, 9, dx*10, 3, expected) # hitting with the center of the hitbox testcollide(105, x, y+9, dx*30, 30, dx*10, 10, expected) # just hit the corner w/ the top by 1 pixel testcollide(106, x, y+10, dx*30, 30, dx*30, 30, 0) # just miss testcollide(107, x, y--47,dx*30, -30, dx*10, -10, expected) # just hit the corner w/ the bottom by 1 pixel testcollide(108, x, y--58,dx*30, -30, dx*30, -30, 0) # just miss ) # Test hitting diagonal hits of corners of various wall configurations walls. # We test multiple hitbox sizes, but we're not actually doing a serious test of that for (hitboxw, 10, 30, 10) do ( for (hitboxh, 10, 30, 10) do ( set hitbox size(hitboxw, hitboxh) variable(tt, walls) tt := microseconds # Try all possible walls on the center tile for (walls, 15, 0, -1) do ( #tracevalue(hitboxw, hitboxh, walls, 1) write pass block(tilex, tiley, walls) testcorner(0,0, southeast corner) testcorner(0,1, northeast corner) testcorner(1,0, southwest corner) testcorner(1,1, northwest corner) ) # Test walls in the same places, but on the adjacent 4 tiles instead for (walls, 15, 0, -1) do ( #tracevalue(hitboxw, hitboxh, walls, 2) write pass block(tilex+1, tiley, walls,and,westwall) write pass block(tilex, tiley+1, walls,and,northwall) write pass block(tilex--1, tiley, walls,and,eastwall) write pass block(tilex, tiley--1, walls,and,southwall) testcorner(0,0, southeast corner) testcorner(0,1, northeast corner) testcorner(1,0, southwest corner) testcorner(1,1, northwest corner) ) ) ) tracevalue(microseconds--tt) show no value free slice(hitbox) end ######################################################################## script, platform tests, begin $0="platform tests" # Blackbox, but we test reading from autotest_config.ini assert(read environment(1, $2="nonexistent") == 0) assert(string equal(1, $3="")) # Test case insensitivity assert(read environment(1, $2="Has_Value_42") == 42) assert(string equal(1, $3="42")) # Blackbox only. These don't do or return anything. assert(xbox request account picker == 0) assert(ps5 start story == 0) assert(ps5 end story == 0) # Steam or blackbox. # achievements.rpgdir can be used to test this actually works, here we just # test it throws no error. set rich presence($1="status") set rich presence($1="status", $2="substitution") end ######################################################################## script, save slot tests, begin $0="save slot tests" # This includes tests for commands which operate on save slots, # but doesn't test load saves itself; that's in "savegame tests" delete save(1) assert(save slot used(1) == false) # import/export globals export global 1 := -123456789 export globals(1, @export global 1, @export global 1) export global 1 := -2 assert(import globals(1, @export global 1) == -123456789) assert(export global 1 == -2) import globals(1, @export global 1, @export global 2) assert(export global 1 == -123456789) assert(export global 2 == 0) export global 2 := -100 export globals(1, @export global 2, @export global 2) save in slot(2) export global 1 := 0 export global 2 := 0 export globals(1, @export global 1, @export global 2) export global 1 := 100 export global 2 := 100 import globals(1, @export global 1, @export global 2) assert(export global 1 == 0) assert(export global 2 == 0) # high global id numbers # (Export this to slot 3 so I can inspect autotest.saves/2.rsav) the global with the biggest id := 123 assert(the global with the biggest id == 123) assert(@the global with the biggest id == 50000) export globals(3, @the global with the biggest id, @the global with the biggest id) write global(@the global with the biggest id, 321) assert(import globals(3, @the global with the biggest id) == 123) assert(the global with the biggest id == 321) # exporting globals should not cause a slot to appear as used assert(save slot used(1) == false) assert(save slot used(2) == true) # testing saveinslot earlier import globals(2, @export global 1, @export global 2) assert(export global 1 == -123456789) assert(export global 2 == -100) # different form export global 1 := -3 assert(import globals(2, @export global 1, @export global 1) == 0) assert(export global 1 == -123456789) # loading from nonexistent save... must zero out the globals without throwing an error import globals(28, @export global 1, @export global 2) assert(export global 1 == 0) assert(export global 2 == 0) # Check interaction between deletesave and importglobals # Originally, deletesave was documented as preserving stored global variables, so they could # still be read with importglobals. Since switching to RSAV in Zenzizenzic (2011), deletesave # now deletes the globals too! # Using rpgbatch, it seems no games are affected by the change (see svn commit message) export global 1 := 100 export global 2 := 100 export globals(1, @export global 1, @export global 2) delete save(1) # Slot 1 only had global variables delete save(2) # Slot 2 had a full save assert(save slot used(1) == false) assert(save slot used(2) == false) export global 1 := -1 export global 2 := -2 import globals(1, @export global 1, @export global 2) # Pre-Zenzizenzic behaviour #assert(export global 1 == -123456789) #assert(export global 2 == -100) # New behaviour assert(export global 1 == 0) assert(export global 2 == 0) import globals(2, @export global 1, @export global 2) # Pre-Zenzizenzic behaviour #assert(export global 1 == -123456789) #assert(export global 2 == -100) # New behaviour assert(export global 1 == 0) assert(export global 2 == 0) end ######################################################################## script, string load tests, begin $0="string load tests" # attack string tests in "attack tests" # Stat names assert(get stat name(1, stat:hp) == true) assert(string compare(1, $2="HP")) get stat name(1, stat:hits) # Last stat assert(string compare(1, $2="Hits")) get stat name(1, 15) # Last register assert(string compare(1, $2="mute register")) assert(get stat name(1, 16) == false) # Out of bounds assert(string compare(1, $2="")) embedding global := -1234 $3=" " # Test the obsolete stringfromtextbox: 4th arg ignored stringfromtextbox(1, 8, 2) $2="." assert(string compare(1, 2)) stringfromtextbox(1, 8, 3) $2="" assert(string compare(1, 2)) stringfromtextbox(1, 8, 4) $2="##" assert(string compare(1, 2)) stringfromtextbox(1, 8, 5, false) $2=",-1234. , " assert(string compare(1, 2)) stringfromtextbox(1, 8, 5, true) assert(string compare(1, 2)) # textbox line textboxline(1, 8, 2) $2="." assert(string compare(1, 2)) textboxline(1, 8, 3) $2="" assert(string compare(1, 2)) textboxline(1, 8, 4) $2=" ## " assert(string compare(1, 2)) textboxline(1, 8, 4, true, false) assert(string compare(1, 2)) textboxline(1, 8, 4, true, true) $2="##" assert(string compare(1, 2)) textboxline(1, 8, 5, false) $2=" ,${V105}. ,${S3} " assert(string compare(1, 2)) textboxline(1, 8, 5, true) $2=" ,-1234. , " assert(string compare(1, 2)) textboxline(1, 8, 5, true, true) $2=",-1234. , " assert(string compare(1, 2)) # textbox text $2=" This box is for testing textboxline\n and stringfromtextbox\n.\n\n ## \n ,-1234. , " textboxtext(1, 8, true, false) assert(string compare(1, 2)) # get scancode name tests $1="Left Bracket" get scancode name(2, key:leftbracket) assert(string compare(1,2)) $1="[" get scancode name(2, key:leftbracket, false) assert(string compare(1,2)) $1="Flee" # Previously "Run" get scancode name(2, flee key) # AKA run key assert(string compare(1,2)) $1="Menu" get scancode name(2, menu key) assert(string compare(1,2)) $1="Cancel" get scancode name(2, cancel key) assert(string compare(1,2)) $1="None" get scancode name(2, 0) assert(string compare(1,2)) $1="Space" get scancode name(2, key:space, false) assert(string compare(1,2)) $1="Left Shift" get scancode name(2, key:left shift, false) assert(string compare(1,2)) $1="Gamepad B" get scancode name(2, joy:B, false) tracevalue(joy:B) trace(2) assert(string compare(1,2)) $1="Gamepad Up" get scancode name(2, joy:up, false) assert(string compare(1,2)) $1="Gamepad Button 16" get scancode name(2, joy:button16, false) assert(string compare(1,2)) # get slice lookup name tests $1="" get slice lookup name(2, 0, true) assert(string compare(1,2)) get slice lookup name(2, 0, false) assert(string compare(1,2)) $1="map layer0" get slice lookup name(2, sl:maplayer0) assert(string compare(1,2)) $1="Some lookup" get slice lookup name(2, sli:Some lookup) assert(string compare(1,2)) $1="Lookup-40" get slice lookup name(2, -40) assert(string compare(1,2)) $1="" get slice lookup name(2, -40, false) assert(string compare(1,2)) end ######################################################################## script, savegame tests, begin $0="saving/loading tests 1" trace(0) # Partially split into savegame tests 2 # Preconditions assert(current map == 0) delete save(1) assert(save slot used(1) == false) savegame map := current map savegame slice := create rect(15, 20) put slice(savegame slice, 40, 40) savegame npc := createnpc(0, 5, 5) # Saving of string state # There are no commands to return the current colour and style # of a string (and I don't see any need to add them), so that can only be # tested by screenshot. $5 = "This is a green string" show string at(5, 100, 100) string color(5, 72) # Should default to 'string:outline' style $6 = "This is flat yellow-on-purple" show string at(6, 100, 110) string style(6, string:flat) string color(6, 14, 194) # yellow, purple $7="This should be plain style" show string at(7, 100, 120) w hook loadgame := 1 save in slot(1) hook loadgame := 0 assert(save slot used(1) == true) # Change state a bit to check it's actually reset and loaded hide string(5) $5 = "" $6 = "Now it's plain" string color(6) $7 = "Now it's yellow-on-purple" string style(7, string:flat) string color(7, 14, 194) # yellow, purple show string at(8, 0, 0) teleport to map(1) savegame map := -1 free slice(savegame slice) w load from slot(1) # continues from "after loadgame" $0="Loadgame didn't happen!" crash end script, after loadgame, arg1, arg2, arg3, begin if (hook loadgame == 1) then ( assert(arg1 == 0) assert(arg2 == 0) assert(arg3 == 0) savegame tests 2 crash ) else ( assert(arg1 == 30) assert(arg2 == -100) assert(arg3 == 0) hook loadgame := 0 ) end # This is called from the loadgame plotscript script, savegame tests 2, begin $0="saving/loading tests 2" trace(0) # Check globals, map number, slices loaded (game is set to save slices) assert(savegame map == current map) assert(slicewidth(savegame slice) == 15) # Check NPCs were NOT saved assert(get npc id(savegame npc) == -1) # doesn't exist # Check strings were loaded assert(string is visible(5)) assert(string is visible(6)) assert(string is visible(8) == false) $8 = "This is a green string" assert(string compare(5, 8)) assert(string x(6) == 100) assert(string y(6) == 110) # Can't test colour, style w # Clean up hide string(5) hide string(6) hide string(7) free slice(savegame slice) # Now try passing args to the loadgame script hook loadgame := 2 save in slot(1) hook loadgame := 0 load from slot(1, 30, -100) # continues from "after loadgame" $0="Loadgame didn't happen!" crash end ######################################################################## script, reset game tests, begin $0="reset game tests" trace(0) # Test with no args called resetgame := true export globals(save slot: persistent, @called resetgame, @called resetgame) reset game $0="resetgame didn't happen!" crash end # Called with default args plotscript, after resetgame, arg1, arg2, arg3, begin $0="reset game tests" trace(0) called resetgame := false export globals(save slot: persistent, @called resetgame, @called resetgame) if (arg1 == 0) then ( # after resetting with no args assert(arg2 == 0) assert(arg3 == 0) reset game(10, 20) $0="resetgame didn't happen!" crash ) else ( # after resetting with args assert(arg1 == 10) assert(arg2 == 20) assert(arg3 == 0) # exit the script and continue to next tests ) end ######################################################################## script, map autorun tests, begin $0="map autorun tests" autorun counter := 0 variable(last map, last x, last y) last map := current map last x := hero x(me) last y := hero y(me) w teleport to map(map:map with an autorun, 1, 1) assert(autorun counter == 1) # teleporting to a map you are already on does still run the autorun teleport to map(map:map with an autorun, 2, 2) assert(autorun counter == 2) # force a re-run of the autorun run script by id(get current map autorun script, get current map autorun script argument) assert(autorun counter == 3) w teleport to map(last map, last x, last y) end plotscript, simple autorun, arg, begin assert(arg == 444) autorun counter += 1 end ######################################################################## # rungame is not actually tested! script, run game tests, begin $0="run game tests" assert(check game exists($1="") == false) assert(check game exists($1="test.rpg")) assert(check game exists($1="foo.rpg") == false) #assert(check game exists($1="test.rpgdir")) assert(check game exists($1="autotest.rpgdir")) assert(check game exists($1="autotest.hss") == false) assert(check game exists($1="../testgame") == false) assert(check game exists($1="../testgame/autotest.rpgdir")) assert(check game exists($1="..\\testgame/Autotest.rpgdir")) assert(check game exists($1="../testgame\\autotest.rpgdir")) assert(check game exists($1="autotest.rpg") == false) #assert(check game exists($1="./testgame\\test.rpgDIR")) # Also check .rpg if given .rpgdir (not implemented) assert(check game exists($1=".//..\\TESTGAME\\autotest.RPGdir")) #assert(check game exists($1="../vikings/vikings.rpg")) # Also check .rpgdir if given .rpg (not implemented) # Should trailing slashes be allowed? #assert(check game exists($1="../vikings/vikings.rpgdir/") == false) #assert(check game exists($1="..\\vikings\\vikings.rpgdir\\") == false) end ######################################################################## #### COMMANDS THAT STILL NEED TESTS #### (Actually, this list is out of date) #### (Note: interactive commands should be in interactivetest.hss, and #### fundamental HS tests are in hstests.hss) #allow minimap (setting) #allow save anywhere (setting) #append ascii (ID, char) #ascii from string (ID, position) #autosave #camera follows hero (who) #camera follows NPC (who) #camera pixel X #camera pixel Y #cancel map name display #center slice (handle) #change tileset (tileset, layer) #check NPC wall (who, direction) #check parentage (handle, parent handle) #clamp slice (handle1, handle2) #clone sprite (handle) #concatenate strings (dest, source) #copy string (dest, source) #create container (width, height) #create ellipse (width, height, border color, fill color) #create grid (width, height, rows, columns) #create NPC (ID,X,Y,direction) #days of play #delete char (ID, position) #delete save (slot) #destroy NPC (reference) #dismount vehicle #draw NPCs above heroes (setting) #expand string(ID) #extended scancodes enabled #extract color(color, component) #fade screen in #fade screen out (red,green,blue) #fill parent (handle, true_or_false) #first child(handle) #first container child(handle) #first rect child(handle) #first sprite child(handle) #focus camera (x,y,speed) #for(counter,start,finish,step) do(commands) #formation probability (formation set, formation) #formation set frequency (formation set) #free slice children (handle) #free sprite (handle) #game over #get ambient music #get color(index) #get damage cap #get each step script #get ellipse border col (handle) #get ellipse fill col (handle) #get foot offset #get global string (ID, global) #get grid columns (handle) #get grid rows (handle) #get instead of battle script #get item name (ID, item) #get load script #get map edge mode #get map name (ID, map) #get map tileset #get money (amount) #get NPC ignores walls (who) #get NPC moves (who) #get NPC obstructs (who) #get NPC usable (who) #get on keypress script #get outline(handle) #get slice velocity x (handle) #get slice velocity y (handle) #get song name (ID, song) #get sort order (handle) #get text bg(handle) #get text color(handle) #get victory music #get wrap(handle) #globals to string(ID, starting global, length) #greyscale palette (first, last) #grid is shown (handle) #hide battle health meter (state) #hide battle ready meter (state) #horiz flip sprite (handle, flip) #hours of play #is filling parent (handle) #last child(handle) #last formation #last save slot #layer tileset (layer) #leader #load attack sprite (num, palette) #load backdrop sprite (num) #load border sprite (num, palette) #load hero sprite (num, palette) #load large enemy sprite (num, palette) #load medium enemy sprite (num, palette) #load palette (palette number) #load portrait sprite (num, palette) #load small enemy sprite (num, palette) #load tileset (tileset, layer) #load walkabout sprite (num, palette) #load weapon sprite (num, palette) #lose money (amount) #map cure (attack, target, attacker) #map height (map) #map width (map) #milliseconds #minutes of play #move slice above (handle, above what handle) #move slice below (handle, below what handle) #move slice by (handle, relative x, relative y, ticks) #move slice to (handle, x, y, ticks) #next container sibling(handle) #next rect sibling(handle) #next sibling(handle) #next sprite sibling(handle) #NPC at pixel (x, y, number) #NPC at spot (x, y, number) #NPC direction (who) #NPC frame (who) #number from string (ID, default) #order menu #outside battle cure #overhead tile #pan camera (direction,distance,pixelstep) #party money #pay money (amount) #place sprite #previous sibling(handle) #put camera (x,y) #put npc (who,x,y) #put slice (handle, X, Y) #put slice screen (handle, x, y) #put sprite (handle, x, y) #random formation (formation set) #read color (index, element) #realign slice (handle, horiz align, vert align, horiz anchor, vert anchor) #replace attack sprite (handle, num, palette) #replace backdrop sprite (handle, num) #replace border sprite (handle, num, palette) #replace char (ID, position, char) #replace hero sprite (handle, num, palette) #replace large enemy sprite (handle, num, palette) #replace medium enemy sprite (handle, num, palette) #replace portrait sprite (handle, num, palette) #replace small enemy sprite (handle, num, palette) #replace walkabout sprite (handle, num, palette) #replace weapon sprite (handle, num, palette) #reset palette #resume map music #resume NPCs #resume NPC walls #resume obstruction #resume overlay #resume random enemies #resume random enemys #resume timers #RGB(red, green, blue) #run game #run script by ID (id, argument1, argument2, argument3...) #save menu (reallysave) #search string (ID1, ID2, start) #seconds of play #seed random (new seed) #set battle wait mode (state) #set bottom padding (handle, pixels) #set color(index, value) #set damage cap (cap) #set days of play (days) #set debug keys disable (state) #set each step script (id) #set ellipse border col (handle, color) #set ellipse fill col (handle, color) #set foot offset (offset) #set grid columns (handle, columns) #set grid rows (handle, rows) #set harm tile damage (amount) #set harm tile flash (color) #set horiz align (handle, edge) #set horiz anchor (handle, edge) #set hours of play (hours) #set inn no revive mode (state) #set instead of battle script (id) #set inventory size (new size) #set left padding (handle, pixels) #set load script (id) #set map edge mode (mode, default tile) #set minutes of play (min) #set money (amount) #set no HP level up restore (state) #set no MP level up restore (state) #set NPC direction (who, direction) #set NPC frame (who, frame) #set NPC ignores walls (who, value) #set NPC moves (who, value) #set NPC obstructs (who, value) #set NPC speed (who, speed) #set NPC usable (who, value) #set on keypress script (id) #set outline(handle, outline) #set padding (handle, pixels) #set parent (handle, parent handle) #set rect bgcol (handle, color) #set rect fgcol (handle, color) #set right padding (handle, pixels) #set seconds of play (sec) #set slice clipping (handle, clip) #set slice edge x (handle, edge, value) #set slice height (handle, height) #set slice lookup (handle, code) #set slice screen x (handle, x) #set slice screen y (handle, y) #set slice velocity (handle, horiz pixels per tick, vert pixels per tick, ticks) #set slice velocity x (handle, pixels per tick, ticks) #set slice velocity y (handle, pixels per tick, ticks) #set slice visible (handle, vis) #set slice width (handle, width) #set slice x (handle, X) #set slice y (handle, Y) #set sort order (handle, order) #set sprite frame (handle, num) #set sprite palette (handle, num) #set sprite trans (handle, drawtransparent) #set sprite visible #set tag (tag,value) #set text bg(handle, color) #set text color(handle, color) #set tile animation offset (animation pattern, offset, layer) #set timer (id, count, speed, trigger, string, flags) #set top padding (handle, pixels) #set vert align (handle, edge) #set vert anchor (handle, edge) #set wrap(handle, wrap) #show backdrop (number) #show grid (handle, shown) #show map #show no value #show value (number) #slice collide (handle1, handle2) #slice collide point (handle, x, y) #slice contains (handle1, handle2) #slice edge x (handle, edge) #slice edge y (handle, edge) #slice is ellipse (handle) #slice is grid (handle) #slice is moving (handle) #slice is valid (id) #slice to back (handle) #slice to front (handle) #sort children (handle, wipe) #sprite frame count (handle) #sqrt (number) #stop slice (handle) #stop timer (id) #string to globals (ID, starting global, length) #suspend catapillar #suspend map music #suspend NPCs #suspend NPC walls #suspend obstruction #suspend overlay #suspend random enemies #suspend random enemys #suspend timers #system day #system hour #system minute #system month #system second #system year #tweak palette (red, green, blue, first, last) #update palette #use item (item) #use item in slot(slot) #vert flip sprite (handle, flip) #wait for all #wait for camera #wait for NPC (who) #wait for slice (handle) #walk NPC (who, direction, distance) #walk NPC to X (who, X) #walk NPC to Y (who, Y) #write color (index, element, value) #Y sort children (handle) HSTESTS.HSSe######################################################################## # This file contains testcases for the script interpreter and HSpeak. # It can compiled either as part of autotest.hss (run by autotest.rpg) # or independently, but compiling hstests_standalone.hss. # # These tests are very incomplete! # include a file with UTF-16 encoding include, "utf16 encoding test.hss" include, mixed line endings.hss ######################################################################## # Only use globals between 200-300 and 5000-6000 here. Others are used # in autotest.hss. global variable(200, ticker 0) global variable(201, ticker 1) global variable(202, ticker 2) global variable(203, expected ticker 0) global variable(204, expected ticker 1) global variable(205, tick counter slice) global variable(206, a global) global variable(207, another global) global variable(5000, global 5000) #Array of 20 globals starting at 5000 ######################################################################## script, interpreter tests, begin encoding tests lexer tests string tests math tests parser tests flow tests subscript tests random tests end ######################################################################## script, elseif A, x, begin if(x == 0) then( return(1) ) elseif(x == 1) then( return(2) ) else( return(3) ) end script, elseif B, x, begin if(x == 0) elseif(x == 1) then( return(2) ) end script, elseif C, x, begin if(x == 0) elseif(x == 1) else( return(3) ) end script, elseif tests, begin $0="elseif tests" assert(elseif A(0) == 1) assert(elseif A(1) == 2) assert(elseif A(2) == 3) assert(elseif B(0) == 0) assert(elseif B(1) == 2) assert(elseif B(2) == 0) assert(elseif C(0) == 0) assert(elseif C(1) == 0) assert(elseif C(2) == 3) end ######################################################################## script, switch A, x, begin return(1) switch (x) do( case(5) do() case(zero) case(2) return(100) return(101) case(7) return(-1) while(1) do(continue(2)) return(-1) case(1) return(102) case(3, 4, 2) return(103) break return(104) case(6, else) return(99) ) end script, switch B, x, begin return(1) switch(x) do( case(5) do() case(10) continue case(7) do(continue) case(2) do( return(100) break return(101) ) case(1) return(102) case((2+1), 2*2, zero) if(x) then(return(103)) else(return(104)) case(9) continue case(8) continue else(return(99)) ) end script, switch tests, begin $0="switch tests" assert(switch A(0) == 101) assert(switch A(1) == 102) assert(switch A(2) == 101) assert(switch A(3) == 103) assert(switch A(4) == 103) assert(switch A(5) == 1) assert(switch A(6) == 99) assert(switch A(7) == 102) assert(switch A(8) == 99) assert(switch B(0) == 104) assert(switch B(1) == 102) assert(switch B(2) == 100) assert(switch B(3) == 103) assert(switch B(4) == 103) assert(switch B(5) == 1) assert(switch B(6) == 99) assert(switch B(7) == 100) assert(switch B(8) == 99) assert(switch B(9) == 99) assert(switch B(10) == 100) end ######################################################################## script, bad break, begin break(1) end script, bad continue, begin continue(1) end # HSpeak used to allow orphaned then/else blocks, which act like do(), # except for the purpose of break/continue. # This can't actually be compiled without commenting out the # '{then/else} should follow an if' checks in normalize_flow_control script, orphaned blocks, begin # variable(dummytrue, dummyfalse, happened) # dummytrue := true # if(dummytrue) then (assert(true), happened += 1) # else (assert(false)) # else (happened += 10) # assert(happened == 11) # if(dummyfalse) then (assert(false)) # else (happened += 100) # else (happened += 1000) # then(happened += 10000) # assert(happened == 11111) end script, exit tests, begin subscript, return 0, begin exit() end subscript, return 1, begin exit(1) end subscript, return 2, begin return(2) exit end assert(return 0 == 0) assert(return 1 == 1) assert(return 2 == 2) end # This script does quite a bit more testing of continue than break. script, continue break tests, begin variable(ctr1, ctr2, ctr3, ctr4) subscript, simple continue test, begin variable(i) for (i, 1, 4) do ( continue ctr1 += 1 ) ctr2 := i end simple continue test assert(ctr1 == 0) assert(ctr2 == 5) ctr1 := 0 ctr2 := 0 subscript, simple break test, begin variable(i) for (i, 1, 4) do ( ctr1 += 1 break ctr1 += 1 ) ctr2 := i end simple break test assert(ctr1 == 1) assert(ctr2 == 1) ctr1 := 0 ctr2 := 0 subscript, conditional continue test, begin variable(i) for (i, 1, 4) do ( if (i == 3) then (continue (1)) ctr1 += i ) ctr2 := i end conditional continue test assert(ctr1 == 7) assert(ctr2 == 5) ctr1 := 0 ctr2 := 0 # Check only the topmost loop is exited subscript, basic nesting continue test, begin variable(i, j) for (i, 1, 3) do ( for (j, 2, 4) do ( ctr1 += 1 if (j > i) then (continue) ctr2 += 1 ) ctr3 += 10 ) end basic nesting continue test assert(ctr1 == 9) assert(ctr2 == 3) assert(ctr3 == 30) ctr1 := 0 ctr2 := 0 ctr3 := 0 subscript, continue 2 test, begin variable(i, j) for (i, 1, 4) do ( for (j, 1, 4) do ( if (j > i) then (continue (2)) ctr1 += 1 ) ctr2 += 1 ) end continue 2 test assert(ctr1 == 10) assert(ctr2 == 1) ctr1 := 0 ctr2 := 0 subscript, continue while test, begin variable(i, j) i := 10 while (i -= 1) do ( ctr1 += 1 if (i > 4) then (continue (1)) ctr2 += i ) end continue while test assert(ctr1 == 9) assert(ctr2 == 10) ctr1 := 0 ctr2 := 0 subscript, break while test, begin variable(i, j) i := 4 while (i -= 1) do ( ctr1 += 1 if (i == 1) then (break (1)) ctr2 += i ) end break while test assert(ctr1 == 3) assert(ctr2 == 5) ctr1 := 0 ctr2 := 0 subscript, while for continue 2 test, begin variable(i, j) i := 5 while (i) do ( i -= 1 ctr1 += 1 for (j, 0, 3) do ( ctr2 += 1 continue (2) ctr3 += 1 ) ctr4 += 1 ) end while for continue 2 test assert(ctr1 == 5) assert(ctr2 == 5) assert(ctr3 == 0) assert(ctr4 == 0) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 subscript, nested while for continue test 2, begin variable(i, j) i := 10 while (i) do ( ctr1 += 1 for (j, -2, 0) do ( ctr2 += 1 if (j) then (i -= 1) else (continue (2)) ctr3 += 1 continue ) ctr4 += 1 ) end nested while for continue test 2 assert(ctr1 == 5) assert(ctr2 == 15) assert(ctr3 == 10) assert(ctr4 == 0) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 subscript, continue break do test, begin variable(i) i := 0 ctr1 += 1 do ( i += 1 ctr2 += i if (i == 3) then (break) continue ctr3 += 1 ) ctr4 += 1 end continue break do test assert(ctr1 == 1) assert(ctr2 == 6) assert(ctr3 == 0) assert(ctr4 == 1) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 subscript, continue break nested do test, begin variable(i, j) i := 0 do ( i += 1 ctr1 += i j := 0 do ( j += 1 ctr2 += j if (i == 1) then (continue (2)) if (i == 3) then (break (2)) if (j < 2) then (continue) ctr3 += 1 ) ctr4 += 1 continue ) end continue break nested do test assert(ctr1 == 6) assert(ctr2 == 5) assert(ctr3 == 1) assert(ctr4 == 1) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 # continue(0) is illegal, but if you ignore it it does nothing subscript, continue 0 test, begin do ( ctr1 += 1 continue(0) ctr2 += 1 break ) end write general(205, 0) # genCurrentDebugMode, hide errors (release mode) continue 0 test write general(205, 1) # show errors (debug mode) assert(ctr1 == 1) assert(ctr2 == 1) ctr1 := 0 ctr2 := 0 # break(0) is illegal, but if you ignore it it does nothing subscript, break 0 test, begin do ( ctr1 += 10 break(0) ctr2 += 10 break ) end write general(205, 0) # genCurrentDebugMode, hide errors (release mode) break 0 test write general(205, 1) # show errors (debug mode) assert(ctr1 == 10) assert(ctr2 == 10) ctr1 := 0 ctr2 := 0 # Regular continue/break inside switch is tested in switch tests subscript, for switch continue 2 test, begin variable(i, j) for (i, 0, 3) do ( ctr1 += i switch (i) do ( case (1) do ( ctr2 += 1 continue ctr2 += 1 ) case (3) do ( ctr1 += 10 continue (2) ) case (else) do ( ctr3 += 1 continue ctr3 += 1 ) ) ctr4 += 1 ) ctr4 += 10 end for switch continue 2 test assert(ctr1 == 26) assert(ctr2 == 1) assert(ctr3 == 2) assert(ctr4 == 12) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 subscript, for switch break 2 test, begin variable(i, j) for (i, 0, 3) do ( ctr1 += i switch (i) do ( case (1) do ( ctr2 += 1 break ctr2 += 1 ) case (3) do ( ctr1 += 10 break (2) ) case (else) do ( ctr3 += 1 break ctr3 += 1 ) ) ctr4 += 1 ) ctr4 += 10 end for switch break 2 test assert(ctr1 == 16) assert(ctr2 == 1) assert(ctr3 == 2) assert(ctr4 == 13) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 subscript, variable continue test, begin variable(i, j) for (i, 1, 2) do ( ctr1 += 1 for (j, 1, 5) do ( ctr2 += 1 continue (j) ctr3 += 1 ) ctr4 += 1 ) end variable continue test assert(ctr1 == 2) assert(ctr2 == 4) assert(ctr3 == 0) assert(ctr4 == 0) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 subscript, variable break test, begin variable(i, j) for (i, 1, 3) do ( ctr1 += 1 for (j, 1, 5) do ( ctr2 += 1 break (i) ctr3 += 1 ) ctr4 += 1 ) end variable break test assert(ctr1 == 2) assert(ctr2 == 2) assert(ctr3 == 0) assert(ctr4 == 1) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 subscript, variable continue test 2, begin variable(i, j, k, n) n := -1 for (i, 1, 2) do ( for (j, 1, 2) do ( n += 1 # n==0: ctr1 += 2, ctr2 += 2, ctr3 += 1 # n==1: ctr1 += 2, ctr3 += 1 # after n==1: ctr4 += 1 # n==2, n==3: ctr1 += 1 for (k, 1, 2) do ( ctr1 += 1 if (n) then (continue (n)) ctr2 += 1 ) ctr3 += 1 ) ctr4 += 1 ) end variable continue test 2 assert(ctr1 == 6) assert(ctr2 == 2) assert(ctr3 == 2) assert(ctr4 == 1) ctr1 := 0 ctr2 := 0 ctr3 := 0 ctr4 := 0 end ######################################################################## script, flow tests, begin variable(var1) # for loop creates some state which can be corrupted for (var1, 0, 6) do ( bad break # Causes an error #bad continue ) elseif tests switch tests continue break tests orphaned blocks exit tests end ######################################################################## # These are in addition to the tests in parser_tests.hss, which are only compiled, not executed. script, parser tests, begin variable (x) (((x := true))) (assert(x)) ($1="42") assert(string compare(1, $2="42")) end ######################################################################## plotscript, sǮޤ qE, begin return (42) end script, encoding tests, begin $0="encoding tests" variable (ber) ber := 12 for (ber, ber, ber + 4) do () assert(ber == 17) # Lowercase form in Latin-1, uppercase not variable (xve) ve := 0 assert( sǮޤ qE == 42) end ######################################################################## script, lexer tests, begin # Check number parsing # We don't actually care that any of this is done at runtime # instead of compile time; id is only avoid "always false" warnings subscript, id, x (return (x)) assert(1 000 == id(1000)) assert(- 1 000 == id(0 -- 1000)) # tab assert(0x0 == id(0)) assert(0x 000 == id(0)) assert(0x 100 == id(256)) assert(0XABc == id(2748)) assert(- 0x 100 == id(-256)) assert(0xffffffff == id(-1)) assert(0x80000000 == id(-2147483648)) assert(-0xabcedf0 == id(-180153840)) assert(-0xffffffff == id(1)) assert(0x 100 == id(256)) assert(0b1 == id(1)) assert(0b1001010110011010011011111110101 == id(1254963189)) assert(0b11001010110011010011011111110101 == id(-892520459)) assert(0o1777 == id(1023)) assert(-0o1777 == id(-1023)) end ######################################################################## script, string tests, begin # This tests only pure string manipulation stuff. # plotstring-specific stuff is tested in "plotstr tests", while loading strings # from the game is in "string load tests" # Still many untested including: searchstring, numberfromstring, globalstostring $0="String tests", trace(0) $1="" $2="" assert(string compare(1,2)) $1="a" $2="A" assert(string compare(1,2) == false) $1=" .~fooy" $2=" .~fooY" assert(string compare(1,2) == false) # Check HSpeak encodes Unicode correctly, replacing unrepresentable characters with '?' $1=" S" # tab, space, exclamation $2="0R" # characters above U+00FF $3="???" trace(3) assert(string compare(2, 3)) 3 $= 1 3 $+ 2 trace(3) trace value(string length(3)) assert(string length(3) == 11) assert(ascii from string(3, 1) == 9) assert(ascii from string(3, 2) == 32) assert(ascii from string(3, 3) == 161) assert(ascii from string(3, 4) == 233) assert(ascii from string(3, 10) == 63) assert(ascii from string(3, 11) == 241) assert($1="foo" == 1) assert($1+"bar" == 1) # higher IDs $95="a " $96="" appendascii(96, 97) $96+" " assert(string compare(95, 96)) # string sprintf string sprintf(1, $2=" test ") assert(string compare(1, 2)) $2="%%" $3="%" string sprintf(1, 2) assert(string compare(1, 3)) $2=" test %d " $3=" test -24 " string sprintf(1, 2, -24) assert(string compare(1, 3)) $2=" test %d%d%d%d%d" $3=" test 1-2-3-4-5" string sprintf(1, 2, 1, -2, -3, -4, -5) assert(string compare(1, 3)) $2="test (%s)" $3="test (test (%s))" string sprintf(1, 2, 2) assert(string compare(1, 3)) $2=" test%c " $3=" testA " string sprintf(1, 2, 65) assert(string compare(1, 3)) $2=" test %x %x " $3=" test 1abcdef ffffffff " string sprintf(1, 2, 28036591, -1) assert(string compare(1, 3)) # Tests UTF-16 encoding, but uses strings assert(that script in the other file == 91) # appendnumber subscript, check, begin string sprintf(10, $99="'%s' == '%s'", 2, 3) return(string compare(2, 3)) clearstring(2) end $2="existing " append number(2, 42) , $3="existing 42", assert(check()) append number(2, 0) , $3="0", assert(check()) append number(2, 65) , $3="65", assert(check()) append number(2, 2147483647) , $3="2147483647", assert(check()) append number(2, -2147483648) , $3="-2147483648", assert(check()) append number(2, -1, 2) , $3="-1", assert(check()) append number(2, 1234, 3) , $3="1234", assert(check()) append number(2, 65, 4) , $3=" 65", assert(check()) append number(2, 65, 4, true) , $3="0065", assert(check()) append number(2, -65, 4) , $3=" -65", assert(check()) append number(2, -65, 4, true) , $3="-065", assert(check()) append number(2, 65, -4) , $3="65 ", assert(check()) append number(2, 65, -4, true) , $3="65 ", assert(check()) append number(2, -65, -4) , $3="-65 ", assert(check()) append number(2, -65, -4) , $3="-65 ", assert(check()) # trim string $1 = " this silly \nexample \t \n" trim string(1) $2 = "this silly \nexample" assert(string equal(1, 2)) trim string(1, 3, 9) $2 = "is silly " assert(string equal(1, 2)) # Blanking out the string trim string(1, 10, 5) # Start just past end $2 = "" assert(string equal(1, 2)) $1 = "secret" trim string(1, 1, 0) assert(string equal(1, 2)) $1 = "Qux" # A start index = 0 is treated as 1... trim string(1, 0, 2) trace(1) $2 = "Qu" assert(string equal(1, 2)) # ...but start = -1 is equivalent to trimstring(id)! $2 = " a " trim string(2, -1, 2) $1 = "a" assert(string equal(1, 2)) # replace substring $1 = "This is an example of replace substring" assert(replace substring (1, $2="is", $3="iiss") == 2) # Note that although "example" contains "exampl", it isn't replaced again with "examplee" assert(string equal(1, $4="Thiiss iiss an example of replace substring")) $1 = "AAABaaAA" assert(replace substring (1, $2="AA", $3="CA", 2) == 2) # Do only 2 replacements # Again, Aaab becomes CAab but the new Aa isn't replaced, because part of it was a replacement assert(string equal(1, $4="CAABaaCA")) $1 = "AaabaAaa" assert(replace substring (1, $2="AA", $3="CA", -1, true) == 3) # Case insensitive assert(string equal(1, $4="CAabCACA")) end ######################################################################## # Very incomplete # This script tests basic operations work script, math tests, begin $0="math tests" # These tests have to be carefully written to not contain any constant # expressions that HSpeak will optimise out variable(n, m) assert(n == 0) n := 10 assert(n == 10) assert(n + 5 == 15) assert(n -- 15 == -5) assert(n * -1 == -10) assert(abs(-1*n) == 10) assert(abs(n) == 10) assert(sign(n) == 1) assert(sign(n--10) == 0) assert(sign(-1*n) == -1) n += 1 assert(n == 11) n -= 10 assert(n == 1) assert((m := 3) == 3) assert((m -= 6) == -3) # mod and divide n := -9 assert(n / 10 == 0) assert(n, mod, 10 == -9) assert(n / 9 == -1) assert(n, mod, 9 == 0) assert(n / 5 == -1) assert(n, mod, 5 == -4) assert(n / -9 == 1) assert(n, mod, -9 == 0) assert(n / -10 == 0) assert(n, mod, -10 == -9) # This brackets are mandatory, := is left-associative n := (m := 9) assert(m == 9) assert(n == 9) n += (m += 3) assert(m == 12) assert(n == 21) n -= (m -= 1) assert(m == 11) assert(n == 10) assert(another global == 0) another global := 10 assert(another global == 10) assert(read global(@another global) == 10) write global(@another global, 4) assert(another global == 4) larger math tests assert(multdiv(10, 20, 30) == 7) assert(multdiv(1, 499, 1000) == 0) assert(multdiv(1, 500, 1000) == 1) assert(multdiv(1, 501, 1000) == 1) assert(multdiv(-1, 500, 1000) == 0) assert(multdiv(1 000 000, 1 000 000, -1 000) == -1 000 000 000) assert(multdiv(1 000 000, 1 000 000, 1) == 2147483647) assert(multdiv(1 000 000, -1 000 000, 1) == -2147483648) end # Return number of bits in an integer. Does NOT work for negative numbers! # Adapted from the "Software Optimization Guide for AMD Athlon 64 and Opteron Processors" script, bitcount, v, begin v := v -- ((v / 2), and, 0x55555555) v := (v, and, 0x33333333) + ((v / 2^2), and, 0x33333333) return (((v + (v / 2^4), and, 0xF0F0F0F) * 0x1010101) / 2^24) end # This script tests that whole routines work correctly script, larger math tests, begin assert(bitcount(0) == 0) assert(bitcount(0x70000000) == 3) assert(bitcount(0x11111111) == 8) assert(bitcount(0x107030ff) == 1+3+2+4+4) end ######################################################################## script, subscript tests, begin $0="subscript tests" variable(var1, var2) assert(sscript 1 == 2) assert(var1 == 1) subscript, sscript 1, begin var1 := 1 return (2) end subscript, sscript 2, arg=42, begin variable(x) var1 := arg x := var1 + 1 var1 += x end sscript 2(2) assert(var1 == 5) sscript 2 assert(var1 == 85) subscript, sscript 3, begin subscript, ssscript 1, arg2, begin x += arg2 + 10 end variable(x) x := 1 ssscript 1 (100) var2 := x end sscript 3 assert(var2 == 111) # test maximum nesting depth (4) a global := -1 subscript, sscript 4, arg1, begin variable(v0,v1) v0 := 5 subscript, ssscript, arg2, begin variable(v2) subscript, sssscript, arg3, begin variable(v3) subscript, ssssscript, arg4, begin # returns arg4 * 10 + 5 assert(a global == -1) a global := -2 assert(arg4 == 1234) variable(v4) #trace value(v4, arg4, v0) v4 += arg4 * 5 + v0 for (v0, v0, 1, -1) do (v4 += arg4) # v4 += 5 * arg4 #tracevalue(v0, v4, arg4 * 10 + 5) assert(v4 == arg4 * 10 + 5) var1 := var2 return(v4) end assert(arg3 == 123) v1 := 1002 return(ssssscript(arg3 * 10 + 4)) end assert(arg2 == 12) return(sssscript(arg2 * 10 + 3)) end assert(read global(@a global) == -1) return (ssscript(arg1 * 10 + 2)) assert(v0 == 0) # 1 past end of for loop (so 1 - 1) assert(v1 == 1002) end assert(sscript4(1) == 12345) assert(var1 == 111) assert(a global == -2) # break stops at a script boundary variable(var3) subscript, break subscript, begin break(4) var3 := 1 end for (var1, 0, 6) do ( break subscript var2 += 1 ) assert(var1 == 7) assert(var2 == 111 + 7) assert(var3 == 0) # Test call patterns other than being called by parent... # Recursion subscript, fib, x, begin variable(ret) if (x <= 2) then (ret += 1) else ( x -= 1 ret += fib(x) x -= 1 ret += fib(x) ) return(ret) end assert(fib(10) == 55) # All 4 directions of call between a script and its subscript assert(inside-outside fib(10) == 55) # Calling a sibling subscript or a sibling of a parent subscript (another fibonacci) var1 := 0 # temporary subscript, sibling 1, n, begin variable(ret) subscript, niece, k, begin if (k <= 2) then ( ret += 1 ) elseif (k, mod, 2) then ( ret += sibling 1(k -- 1) k -= 1 ret += sibling 2(k -- 1) ) else ( ret += sibling 2(k -- 1) k -= 1 ret += sibling 1(k -- 1) ) end niece(n) return(ret) end subscript, sibling 2, n, begin if (n <= 2) then (var1 += 1) else ( variable(ret) ret += sibling 1(n -- 2) var1 += sibling 1(n -- 1) var1 += ret ) return(var1) var1 := 0 end assert(sibling1(10) == 55) subscript scope tests(1) end # Test that inner variables shadow outer ones script, subscript scope tests, arg, begin variable(v1) v1 := 42 subscript, sub1, arg, begin assert(arg == 2) variable(v1) assert(v1 == 0) v1 := 63 assert(v1 == 63) end assert(arg == 1) sub1(2) assert(arg == 1) assert(v1 == 42) subscript, sub2, arg, begin variable(v1) subscript, sub3, v1, begin v1 += 5 subscript, sub4, arg () assert(arg == 100) for(arg, 0, 32) do () end assert(v1 == 0) sub3(10) assert(v1 == 0) assert(arg == 33) end sub2(100) assert(v1 == 42) end # A very weird way to compute fibonacci numbers script, inside-outside fib, n, begin variable(x) subscript, inside fib, begin variable(y) if (n <= 2) then ( x += 1 ) else ( n -= 1 y += inside fib() #n -- 1) n += 1 x += inside-outside fib(n -- 2) + y ) end if (n <= 2) then (exit returning (1)) n -= 1 inside fib() n -= 1 x += inside-outside fib(n) return(x) end ######################################################################## script, random tests, begin variable(i, x, outliers) # Test random() range for (i, 1, 100) do ( x := random(-3, 10) assert(x >= -3 && x <= 10) x := random(20, 2) assert(x >= 2 && x <= 20) ) # Edge cases for (i, 1, 10) do ( assert(random(0, 0) == 0) # In fact hspeak optimises this to a constant assert(random(-1, -1) == -1) x := random(-2, -1) assert(x >= -2 && x <= -1) x := random(-1, -2) assert(x >= -2 && x <= -1) ) # A simple test that random() is uniform for (i, 1, 10) do ( write global(@global 5000 + i, 0) ) for (i, 1, 500) do ( x := random(1, 10) write global(@global 5000 + x, read global(@global 5000 + x) + 1) ) for (i, 1, 10) do ( x := read global(@global 5000 + i) # 99.995% chance of the value being in this interval assert(x >= 25 && x <= 78) # 99.1% chance of the value being outside this interval outliers += (x < 34 || x > 68) ) assert(outliers <= 2) # "random choice" variable(bin1, bin2, bin3) assert(random choice() == 0) for (i, 1, 100) do ( assert(random choice(-1) == -1) switch(random choice(100, -100, 0)) do ( case(100) bin1 += 1 case(-100) bin2 += 1 case(0) bin3 += 1 case(else) assert(false) ) ) # 99.995% chance of the values being in this interval assert(bin1 >= 16 && bin1 <= 53) assert(bin2 >= 16 && bin2 <= 53) assert(bin3 >= 16 && bin3 <= 53) end ######################################################################## UTF16 ENCODING TEST.HSS# Included from autotest.hss, for HSpeak tests # This file is encoded in UTF-16BE with DOS newlines and extra CR characters # (Which might not survive version control) script, that script in the other file, begin $1="&" assert(ascii from string(1, 1) == 231) assert(ascii from string(1, 2) == 236) assert(ascii from string(1, 3) == 248) assert(ascii from string(1, 4) == 63) #294 return (91) end MIXED LINE ENDINGS.HSSscript, _dummy1, i, begin subscript, foo, argy1, begin end _dummy1(230) end script, _dummy2, i, begin noop variable(x, asdasd) subscript, foo2, begin end end AUTOTEST-PLOTSTR.HSI{# These the autotest.rpg tests which include characters above U+00FF, # which are handled by hspeak, but cause problems with Hamster Whisper script, plotstr tests, begin # This tests only the display of plotstrings. # Pure string manipulation stuff is tested in "string tests" in hstests.hss, # and reading strings from game data in "string load tests" $0="plotstr tests" $1=" S" # tab, space, exclamation $2="0R" # characters above U+00FF 1 $+ 2 show string at(3, 0, 0) w hide string(3) assert(string is visible(0) == false) position string(0, 50, 50) assert(string is visible(0) == false) # There are no commands to return the current colour and style # of a string (and I don't see any need to add them), so that can only be # tested by screenshot. $5 = "This isn't empty" show string at(5, 110, 100) assert(string is visible(5)) assert(string x(5) == 110) assert(string y(5) == 100) # Should default to 'string:outline' style and uiText colour w string color(5, 72, 15) # green, white w # Test return to default colour string color(5) w position string(5, 10, 20) assert(string x(5) == 10) assert(string y(5) == 20) w center string at(5, 160, 0) assert(string x(5) == 160 -- 4 * 16) assert(string y(5) == 0) $6 = "This is flat yellow-on-purple" show string at(6, 100, 110) assert(string is visible(6) == true) string style(6, string:flat) string color(6, 14, 194) # yellow, purple w string color(6) $6 = "Now it's tranparent flat white" w show string(6) w show no value # Can't test colour, style # Test clear clear string(6) assert(string length(6) == 0) # Shouldn't affect visibility assert(string is visible(6) == true) $6 = "XYZ" # Test hide hide string(6) assert(string is visible(6) == false) w # Clean up hide string(5) clear string(5) clear string(6) w end SRCFILES.TXT"file=/home/james/src/ohrrpgce/plotscr.hsd lump=plotscr.hsd offset=1 length=110252 file=/home/james/src/ohrrpgce/scancode.hsi lump=scancode.hsi offset=110254 length=5629 file=/home/james/src/ohrrpgce/testgame/autotest.hsi lump=autotest.hsi offset=115884 length=3045 file=/home/james/src/ohrrpgce/testgame/autotest.hss lump=autotest.hss offset=118930 length=235794 file=/home/james/src/ohrrpgce/testgame/hstests.hss lump=hstests.hss offset=354725 length=26032 file=/home/james/src/ohrrpgce/testgame/utf16 encoding test.hss lump=utf16 encoding test.hss offset=380758 length=427 file=/home/james/src/ohrrpgce/testgame/mixed line endings.hss lump=mixed line endings.hss offset=381186 length=220 file=/home/james/src/ohrrpgce/testgame/autotest-plotstr.hsi lump=autotest-plotstr.hsi offset=381407 length=1915