12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644 |
- //===== Athena Doc ========================================
- //= eAthena Script Commands
- //===== Description =======================================
- //= A reference manual for the eAthena scripting language.
- //= Commands are sorted depending on their functionality.
- //===== Version ===========================================
- //= 3.25.20081220
- //=========================================================
- //= 1.0 - First release, filled will as much info as I could
- //= remember or figure out, most likely there are errors,
- //= and things I have missed out [Fredzilla]
- //= 1.1 - Added better discription for "getmapxy" (by Terminal Vertex & Z3R0)
- //= 1.2b- Added a description for getpartymember (by HappyDenn)
- //= (+few spelling mistakes corrected)
- //= 2.0 - +79kb extra stuff and numerous corrections by
- //= Maeki Rika.
- //= 2.1 - Small but important corrections, more proofreading.
- //= Some important discoveries in item functions, the
- //= secret of making VVS weapons with 'getitem2' and
- //= other news. (Rika again) +10kb :)
- //= 2.2 - added getItemInfo description [Lupus]
- //= 2.3 - added plenty of info for recent (and not so) script commands I added
- //= [Skotlex]
- //= 2.4 - Explained the upper parameter of jobchange. [Skotlex]
- //= 2.5 - Added pow, sqrt and distance. [Lance]
- //= 2.6 - Added setd and getd. [Lance]
- //= 2.7 - petstat command. [Lance]
- //= 2.7a- delitem2, countitems2 commands [Lupus]
- //= 2.7b- clone command [Skotlex]
- //= 2.7c- disguise / undisguise, query_sql commands [Lupus]
- //= 2.8 - Deleted a copy of the nude command. Added axtoi command (needing a
- //= clearer explanation of atoi.Gave a better explanation of OnLabels
- //= and modified monster explanation due that L_Label isn't working with
- //= monster.
- //= 2.9.20061230 - Updated getitem and guardian. [FlavioJS]
- //= 2.10.20070101 - added sleep,sleep2,awake and updated the variables section.
- //= [FlavioJS]
- //= 2.11.20070109 - removed the unused flag argument in guildskill, added an
- //= optional argument to setcart,setfalcon,setriding and other cleanups
- //= [FlavioJS]
- //= 2.12.20070201 - Added npcshopitem, npcshopadditem, npcshopdelitem and
- //= npcshopattach [Skotlex]
- //= 3.00.20070208
- //= - Explained Logical Bitwise Operators.
- //= Dj-Yhn contributed to AND (&) operator, rest by myself. [erKURITA]
- //= - Added a resume of allowed variable and arrays scopes. [erKURITA]
- //= - Re-organized the script commands, and grouped them depending
- //= on what they do. [erKURITA]
- //= - Added a packload of commands that were missing,
- //= and corrected some of the wrong ones [Dj-Yhn, erKURITA & Trancid]
- //= 3.01.20070209
- //= Updated 'cutin' (removed lies, removed outdated bmp list) [ultramage]
- //= Removed 'cutincard' since eA no longer implements it
- //= 3.02.20070209
- //= Corrected/updated info on Xor/setd/getd/callfunc/callsub/return and
- //= updated some examples to use "better" code. [FlavioJS]
- //= 3.03.20070216
- //= Expanded/clarified information on npc timers, added info about the
- //= new attach flag for script commands startnpctimer/ stopnpctimer/
- //= initnpctimer [Skotlex]
- //= 3.03.20070226
- //= Updated makeitem and how to include " in strings [Lupus]
- //= 3.03.20070228
- //= Added info on OnTimerQuit label to npctimer section. [Skotlex]
- //= 3.04.20070317
- //= Removed all .gat refferences from the examples [Lupus]
- //= 3.04.20070330
- //= Adjusted the 'itemskill' description due to recent change [ultramage]
- //= 3.04.20070409
- //= Fixed the incorrect order of parameters in 'makeitem' [ultramage]
- //= 3.05.20070423
- //= menu/select/prompt produce consistent results for grouped and empty
- //= options [FlavioJS]
- //= 3.05.20070819
- //= Removed the messy 'unitdeadsit' command reference [ultramage]
- //= 3.05.20070823
- //= Fixed typo in 'areamonster' description (missing argument) [ultramage]
- //= 3.06 20070909
- //= Added 'gethominfo' description [Skotlex]
- //= 3.06.20070910
- //= Added info about the new behavior of 'getexp' [ultramage]
- //= 3.07.20070915
- //= Fixed 'duplicate' missing the target 'name' parameter! [ultramage]
- //= 3.08.20071018
- //= Clarified how npc names work. [FlavioJS]
- //= 3.09.20071103
- //= Added script function 'strnpcinfo' [ultramage]
- //= 3.10.20071122
- //= Added setnpcdisplay. [FlavioJS]
- //= 3.10.20071211
- //= Added query_logsql. [Skotlex]
- //= 3.11.20071215
- //= Updated guardianinfo and get-/setcastledata [ultramage]
- //= 3.12.20071218
- //= Corrected various mistakes mentioned in bugreport:373 [ultramage]
- //= 3.12.20071227
- //= Corrected description of scope and npc variables. [FlavioJS]
- //= 3.13.20080104
- //= Updated 'setcell' desc to match latest code changes [ultramage]
- //= 3.14.20080211
- //= Updated 'input' (new arguments and return value). [FlavioJS]
- //= 3.15.20080227
- //= Updated 'checkweight' description slightly. [L0ne_W0lf]
- //= 3.16.20080229
- //= Updated 'Shop' NPC type description to include cashshop. [L0ne_W0lf]
- //= Woopth. Fixed spelling. ;P Should be a bit clearer now. [L0ne_W0lf]
- //= 3.17.20080312
- //= Corrected cashshop description. (#FREEPOINTS->#KAFRAPOINTS) [L0ne_W0lf]
- //= 3.18.20080327
- //= Added documentation for the 'checkcell' command [ultramage]
- //= 3.19.20080407
- //= Extended the behaviour of 'guardian'. [FlavioJS]
- //= 3.20.20080425
- //= Corrected 'getitem', 'getitem2' & 'delitem2' (charid instead of accountid) [Toms]
- //= Modified 'delitem' (added optional accountid parameter) [Toms]
- //= 3.21.20080612
- //= Script commands extended to support skill names: [FlavioJS]
- //= skill, addtoskill, guildskill, getskilllv, getgdskilllv, itemskill,
- //= petskillattack, petskillattack2, petskillsupport, skilleffect, npcskilleffect,
- //= unitskilluseid, unitskillusepos, bonus/bonus2/bonus3/bonus4/bonus5
- //= 3.22.20080622
- //= Extended 'set' to return the variable reference. [FlavioJS]
- //= 3.22.20080901
- //= Adjusted the 'getequipname' description to match src [ultramage]
- //= 3.23.20080909
- //= Added WoE SE related commands. [L0ne_W0lf]
- //= 3.24.20081111
- //= Changed the error behaviour of delitem/delitem2/Zeny. [FlavioJS]
- //= 3.25.20081220
- //= Extended the behaviour of duplicates (warps/shops/cashshops). [FlavioJS]
- //= 3.26.20090702
- //= Replaced 'bonusautoscript' by 'autobonus'. [Inkfish]
- //= 3.27.20090725
- //= Added Quest Log related commands. [Inkfish]
- //=========================================================
- This document is a reference manual for all the scripting commands and functions
- available in current eAthena SVN. It is not a simple tutorial. When people tell
- you to "Read The F***ing Manual", they mean this.
- The information was mostly acquired through looking up how things actually work
- in the source code of the server, which was written by many people over time,
- and lots of them don't speak English and never left any notes - or are otherwise
- not available for comments. As such, anything written in here might not be
- correct, it is only correct to the best of our knowledge, which is limited.
- This is not a place to teach you basic programming. This document will not teach
- you basic programming by itself. It's more of a reference for those who have at
- least a vague idea of what they want to do and want to know what tools they have
- available to do it. We've tried to keep it as simple as feasible, but if you
- don't understand it, getting a clear book on programming in general will help
- better than yelling around the forum for help.
- A little learning never caused anyone's head to explode.
- Structure
- ---------
- The commands and functions are listed in no particular order:
- *Name of the command and how to call it.
- Descriptive text
- Small example if possible. Will usually be incomplete, it's there just to
- give you an idea of how it works in practice.
- To find a specific command, use Ctrl+F, (or whatever keys call up a search
- function in whatever you're reading this with) put an * followed by the command
- name, and it should find the command description for you.
- If you find anything omitted, please respond. :)
- Syntax
- ------
- Throughout this document, wherever a command wants an argument, it is given in
- <angle brackets>. This doesn't mean you should type the angle brackets. :) If an
- argument of a command is optional, it is given in {curly brackets}. You've
- doubtlessly seen this convention somewhere, if you didn't, get used to it,
- that's how big boys do it. If a command can optionally take an unspecified
- number of arguments, you'll see a list like this:
- command <argument>{,<argument>...<argument>}
- This still means they will want to be separated by commas.
- Where a command wants a string, it will be given in "quotes", if it's a number,
- it will be given without them. Normally, you can put an expression, like a bunch
- of functions or operators returning a value, in (round brackets) instead of most
- numbers. Round brackets will not always be required, but they're often a good
- idea.
- Wherever you refer to a map name, it's always 'mapname' or 'mapname.gat'
- (Please, don't use .gat suffix anymore. It's useless.)
- Script loading structure
- ------------------------
- Scripts are loaded by the map server as referenced in the 'conf/map_athena.conf'
- configuration file, but in the default configuration, it doesn't load any script
- files itself. Instead, it loads the file 'npc/scripts_main.conf' which itself
- contains references to other files. The actual scripts are loaded from txt
- files, which are linked up like this:
- npc: <path to a filename>
- Any line like this, invoked, ultimately, by 'map_athena.conf' will load up the
- script contained in this file, which will make the script available. No file
- will get loaded twice, to prevent possible errors.
- Another configuration file option of relevance is:
- delnpc: <path to a filename>
- This will unload a specifiled script filename from memory, which, while
- seemingly useless, may sometimes be required.
- Whenever '//' is encountered in a line upon reading, everything beyond this on
- that line is considered to be a comment and is ignored. This works wherever you
- place it.
- Upon loading all the files, the server will execute all the top-level commands
- in them. No variables exist yet at this point, no commands can be called other
- than those given in this section. These commands set up the basic server script
- structure - create NPC objects, spawn monster objects, set map flags, etc. No
- code is actually executed at this point except them. The top-level commands the
- scripting are pretty confusing, since they aren't structured like you would
- expect commands, command name first, but rather, normally start with a map name.
- What's more confusing about the top-level commands is that most of them use a
- tab symbol to divide their arguments.
- To prevent problems and confusion, the tab symbols are written as '%TAB%'
- throughout this document, even though this makes the text a bit less readable.
- Using an invisible symbol to denote arguments is one of the bad things about
- this language, but we're stuck with it for now. :)
- Here is a list of valid top-level commands:
- ** Set a map flag:
- <map name>%TAB%mapflag%TAB%<flag>
- This will, upon loading, set a specified map flag on a map you like. These are
- normally in files inside 'conf/mapflag' and are loaded first, so by the time the
- server's up, all the maps have the flags they should have. Map flags determine
- the behavior of the map regarding various common problems, for a better
- explanation, see 'setmapflag'.
- ** Create a permanent monster spawn:
- <map name>,<x>,<y>,<xs>,<ys>%TAB%monster%TAB%<monster name>%TAB%<mob id>,<amount>,<delay1>,<delay2>,<event>
- Map name is the name of the map the monsters will spawn on. x,y are the
- coordinates where the mob should spawn. If xs and ys are non-zero, they
- specify the diameters of a spawn-rectangle area who's center is x,y.
- Putting zeros instead of these coordinates will spawn the monsters randomly.
- Note this is only the initial spawn zone, as mobs random-walk, they are free
- to move away from their specified spawn region.
- Monster name is the name the monsters will have on screen, and has no relation
- whatsoever to their names anywhere else. It's the mob id that counts, which
- identifies monster record in 'mob_db.txt' database of monsters. If the mob name
- is given as "--ja--", the 'japanese name' field from the monster database is
- used, (which, in eAthena, actually contains an english name) if it's "--en--",
- it's the 'english name' from the monster database (which contains an uppercase
- name used to summon the monster with a GM command).
- If you add 20000 to the monster ID, the monster will be spawned in a 'big
- version', (monster size class will increase) and if you add 10000, the 'tiny
- version' of the monster will be created. However, this method is deprecated
- and not recommended, as the values to add can change at a later time (20000
- and 10000 actually stand for 2*MAX_MOB_DB and MAX_MOB_DB respectively, which
- is defined on mob.h, and can change in the future as more mobs are created).
- The recommended way to change a mob's size is to use the event-field (see
- below).
- Amount is the amount of monsters that will be spawned when this command is
- executed, it is affected by spawn rates in 'battle_athena.conf'.
- Delay1 and delay2 are the monster respawn delays - the first one counts the time
- since a monster defined in this spawn was last respawned and the second one
- counts the time since the monster of this spawn was last killed. Whichever turns
- out to be higher will be used. If the resulting number is smaller than a random
- value between 5 and 10 seconds, this value will be used instead. (Which is
- normally the case if both delay values are zero.) The times are given in
- 1/1000ths of a second.
- You can specify a custom level to use for the mob different from the one of
- the database by adjoining the level after the name with a comma. eg:
- "Poring,50" for a name will spawn a monster with name Poring and level 50.
- Event is a script event to be executed when the mob is killed. The event must
- be in the form "NPCName::OnEventName" to execute, and the event name label
- should start with "On". As with all events, if the NPC is an on-touch npc, the
- player who triggers the script must be within 'trigger' range for the event to
- work.
- The Event field can be used alternatively to specify other mob properties. Use
- 2 to specify that the mob should be small, 4 for big monsters, and 8 for
- special ai mobs (which by default attack other monsters instead of players).
- You can add these, so using 10 will spawn small monsters that attack other
- mobs (if you specify both 2 and 4, the small version takes priority).
- ** Npc names
- /!\ WARNING: this applies to warps, npcs, duplicates and shops /!\
- Npc names are kinda special and are formatted this way:
- <Display name>{::<Unique name>}
- All npcs need to have a unique name that is used for identification purposes.
- When you have to identify a npc by it's name, you should use <Unique name>.
- If <Unique name> is not provided, use <Display name> instead.
- The client has a special feature when displaying names:
- if the display name contains a '#' character, it hides that part of the name.
- ex: if your npc is named 'Hunter#hunter1', it will be displayed as 'Hunter'
- <Display name> must be at most 24 characters in length.
- <Unique name> must be at most 24 characters in length.
- ** Define a warp point
- <from map name>,<fromX>,<fromY>,<facing>%TAB%warp%TAB%<warp name>%TAB%<spanx>,<spany>,<to map name>,<toX>,<toY>
- This will define a warp NPC that will warp a player between maps, and while most
- arguments of that are obvious, some deserve special mention.
- SpanX and SpanY will make the warp sensitive to a character who didn't step
- directly on it, but walked into a zone which is centered on the warp from
- coordinates and is SpanX in each direction across the X axis and SpanY in each
- direction across the Y axis.
- Warp NPC objects also have a name, because you can use it to refer to them later
- with 'enablenpc'/'disablenpc'
- Facing of a warp object is irrelevant, it is not used in the code and all
- current scripts have a zero in there.
- ** Define an NPC object.
- <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>}
- <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>}
- This will place an NPC object on a specified map at the specified location, and
- is a top-level command you will use the most in your custom scripting. The NPCs
- are triggered by clicking on them, and/or by walking in their trigger area, if
- defined, see that below.
- Facing is a direction the NPC sprite will face in. Not all NPC sprites have
- different images depending on the direction you look from, so for some facing
- will be meaningless. Facings are counted counterclockwise in increments of 45
- degrees, where 0 means facing towards the top of the map. (So to turn the sprite
- towards the bottom of the map, you use facing 4, and to make it look southeast
- it's facing 5.)
- Sprite id is the sprite number used to display this particular NPC. For a full
- list of sprite id numbers see http://kalen.s79.xrea.com/npc/npce.shtml You may
- also use a monster's ID number instead to display a monster sprite for this NPC.
- It is possible to use a job sprite as well, but you must first define it as a
- monster sprite in 'mob_avail.txt', a full description on how to do this is not
- in the scope of this manual.
- A '-1' sprite id will make the NPC invisible (and unclickable).
- A '111' sprite id will make an NPC which does not have a sprite, but is still
- clickable, which is useful if you want to make a clickable object of the 3D
- terrain.
- TriggerX and triggerY, if given, will define an area, centered on NPC and
- spanning triggerX cells in every direction across X and triggerY in every
- direction across Y. Walking into that area will trigger the NPC. If no
- 'OnTouch:' special label is present in the NPC code, the execution will start
- from the beginning of the script, otherwise, it will start from the 'OnTouch:'
- label.
- The code part is the script code that will execute whenever the NPC is
- triggered. It may contain commands and function calls, descriptions of which
- compose most of this document. It has to be in curly brackets, unlike elsewhere
- where we use curly brackets, these do NOT signify an optional parameter.
- ** Define a 'floating' NPC object.
- -%TAB%script%TAB%<NPC Name>%TAB%-1,{<code>}
- This will define an NPC object not triggerable by normal means. This would
- normally mean it's pointless since it can't do anything, but there are
- exceptions, mostly related to running scripts at specified time, which is what
- these floating NPC objects are for. More on that below.
- ** Define a shop/cashshop NPC.
- -%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}
- <map name>,<x>,<y>,<facing>%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}
- This will define a shop NPC, which, when triggered (which can only be done by
- clicking) will cause a shop window to come up. No code whatsoever runs in shop
- NPCs and you can't change the prices otherwise than by editing the script
- itself. (No variables even exist at this point of scripting, so don't even
- bother trying to use them.)
- The item id is the number of item in the 'item_db.txt' database. If Price is set
- to -1, the 'buy price' given in the item database will be used. Otherwise, the
- price you gave will be used for this item, which is how you create differing
- prices for items in different shops.
- Since trunk r12264 you can alternatively use "cashshop" in place of "shop"
- to use the Cash Shop interface, allowing you to buy items with special points
- (Currently stored as account vars in global_reg #CASHPOINTS and #KAFRAPOINTS.)
- This type of shop will not allow you to sell items at it, you may only
- purchase items here. The layout used to define sale items still count, and
- "<price>" refers to how many points will be spent purchasing the them.
- ** Define an warp/shop/cashshop/NPC duplicate.
- warp: <map name>,<x>,<y>,<facing>%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<spanx>,<spany>
- shop/cashshop/npc: -%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>
- shop/cashshop/npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>
- npc: -%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>
- npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>
- This will duplicate an warp/shop/cashshop/NPC referred to by 'label'.
- Warp duplicates inherit the target location.
- Shop/cashshop duplicates inherit the item list.
- NPC duplicates inherit the script code.
- The rest (name, location, facing, sprite ID, span/trigger area)
- is obtained from the definition of the duplicate (not inherited).
- ** Define a function object
- function%TAB%script%TAB%<function name>%TAB%{<code>}
- This will define a function object, callable with the 'callfunc' command (see
- below). This object will load on every map server separately, so you can get at
- it from anywhere. It's not possible to call the code in this object by
- anything other than the 'callfunc' script command.
- The code part is the script code that will execute whenever the function is
- called with 'callfunc'. It has to be in curly brackets, unlike elsewhere where
- we use curly brackets, these do NOT signify an optional parameter.
- Once an object is defined which has a 'code' field to it's definition, it
- contains script commands which can actually be triggered and executed.
- ~ RID? GID? ~
- What a RID is and why do you need to know
- -----------------------------------------
- Most scripting commands and functions will want to request data about a
- character, store variables referenced to that character, send stuff to the
- client connected to that specific character. Whenever a script is invoked by a
- character, it is passed a so-called RID - this is the character ID number of a
- character that caused the code to execute by clicking on it, walking into it's
- OnTouch zone, or otherwise.
- If you are only writing common NPCs, you don't need to bother with it. However,
- if you use functions, if you use timers, if you use clock-based script
- activation, you need to be aware of all cases when a script execution can be
- triggered without a RID attached. This will make a lot of commands and functions
- unusable, since they want data from a specific character, want to send stuff to
- a specific client, want to store variables specific to that character, and they
- would not know what character to work on if there's no RID.
- Unless you use 'attachrid' to explicitly attach a character to the script first.
- Whenever we say 'invoking character', we mean 'the character who's RID is
- attached to the running script. The script function "playerattached" can be
- used to check which is the currently attached player to the script (it will
- return 0 if the there is no player attached or the attached player no longer
- is logged on to the map-server).
- But what about GID?
- --- ---- ----- ----
- GID stands for the Game ID of something, this can either be the GID obtained
- through mobspawn (mob control commands) or the account ID of a character.
- Another way would be to right click on a mob,
- NPC or char as GM sprited char to view the GID.
- This is mostly used for the new version of skill and the mob control commmands
- implemented (but NEVER documented by Lance. Shame on you...).
- Item and pet scripts
- --------------------
- Each item in the item database has two special fields - EquipScript and
- UseScript. The first is script code run every time a character equips the item,
- with the RID of the equipping character. Every time they unequip an item, all
- temporary bonuses given by the script commands are cleared, and all the scripts
- are executed once again to rebuild them. This also happens in several other
- situations (like upon login) but the full list is currently unknown.
- UseScript is a piece of script code run whenever the item is used by a character
- by doubleclicking on it.
- Not all script commands work properly in the item scripts. Where commands and
- functions are known to be meant specifically for use in item scripts, they are
- described as such.
- Every pet in the pet database has a PetScript field, which determines pet
- behavior. It is invoked wherever a pet of the specified type is spawned.
- (hatched from an egg, or loaded from the char server when a character who had
- that pet following them connects) This may occur in some other situations as
- well. Don't expect anything other than commands definitely marked as usable in
- pet scripts to work in there reliably.
- Numbers
- -------
- Beside the common decimal numbers, which are nothing special whatsoever (though
- do not expect to use fractions, since ALL numbers are integer in this language),
- the script engine also handles hexadecimal numbers, which are otherwise
- identical. Writing a number like '0x<hex digits>' will make it recognised as a
- hexadecimal value. Notice that 0x10 is equal to 16. Also notice that if you try
- to 'mes 0x10' it will print '16'.
- This is not used much, but it pays to know about it.
- Variables
- ---------
- The meat of every programming language is variables - places where you store
- data.
- Variables are divided into and uniquely identified by the combination of:
- prefix - determines the scope and extent (or lifetime) of the variable
- name - an identifier consisting of '_' and alfanumeric characters
- postfix - determines the type of the variable: integer or string
- Scope can be:
- global - global to all servers
- local - local to the server
- account - attached to the account of the character identified by RID
- character - attached to the character identified by RID
- npc - attached to the NPC
- scope - attached to the scope of the instance
- Extent can be:
- permanent - They still exist when the server resets.
- temporary - They cease to exist when the server resets.
- Prefix: scope and extent
- nothing - A permanent variable attached to the character, the default
- variable type.
- "@" - A temporary variable attached to the character.
- SVN versions before 2094 revision and RC5 version will also treat
- 'l' as a temporary variable prefix, so beware of having variable
- names starting with 'l' if you want full backward compatibility.
- "$" - A global permanent variable.
- They are stored in "save\mapreg.txt" or database table `mapreg`,
- depending on server type.
- "$@" - A global temporary variable.
- This is important for scripts which are called with no RID
- attached, that is, not triggered by a specific character object.
- "." - A NPC variable.
- They exist in the NPC and dissapear when the server restarts or the
- npc is reloaded. Can be accessed from inside the NPC or by calling
- 'getvariableofnpc'.
- ".@" - A scope variable.
- They are unique to the instance and scope. Each instance has it's
- own scope that ends when the script ends. Calling a function with
- callsub/callfunc starts a new scope, returning from the function
- ends it. When a scope ends, it's variables are converted to values
- ('return .@var;' returns a value, not a reference).
- "#" - A permanent local account variable.
- They are stored with all the account data in "save\accreg.txt" in
- TXT versions and in the SQL versions in the 'global_reg_value'
- table using type 2.
- "##" - A permanent global account variable stored by the login server.
- They are stored in "save\account.txt" and in the SQL versions in the
- 'global_reg_value' table, using type 1. The only difference you will
- note from normal # variables is when you have multiple char-servers
- connected to the same login server. The # variables are unique to
- each char-server, while the ## variables are shared by all these
- char-servers.
- Postfix: integer or string
- nothing - integer variable, can store positive and negative numbers, but only
- whole numbers (so don't expect to do any fractional math)
- '$' - string variable, can store text
- Examples:
- name - permanent character integer variable
- name$ - permanent character string variable
- @name - temporary character integer variable
- @name$ - temporary character string variable
- $name - permanent global integer variable
- $name$ - permanent global string variable
- $@name - temporary global integer variable
- $@name$ - temporary global string variable
- .name - npc integer variable
- .name$ - npc string variable
- .@name - scope integer variable
- .@name$ - scope string variable
- #name - permanent local account integer variable
- #name$ - permanent local account string variable
- ##name - permanent global account integer variable
- ##name$ - permanent global account string variable
- If a variable was never set, it is considered to equal zero for integer
- variables or an empty string ("", nothing between the quotes) for string
- variables. Once you set it to that, the variable is as good as forgotten
- forever, and no trace remains of it even if it was stored with character or
- account data.
- Some variables are special, that is, they are already defined for you by the
- scripting engine. You can see the full list somewhere in 'db/const.txt', which
- is a file you should read, since it also allows you to replace lots of numbered
- arguments for many commands with easier to read text. The special variables most
- commonly used are all permanent character-based variables:
- StatusPoint - Amount of status points remaining.
- BaseLevel - Current base level
- SkillPoint - Amount of skill points remaining
- Class - Current job
- Upper - 1 if the character is an advanced job class.
- Zeny - Current amount of zeny
- Sex - Character's gender, 0 if female, 1 if male.
- Weight - The weight the character currently carries.
- MaxWeight - The maximum weight the character can carry.
- JobLevel - Character's job level
- BaseExp - The amount of base experience points the character has.
- Notice that it's zero (or close) if the character just got a level.
- JobExp - Same for job levels
- NextBaseExp - Amount of experience points needed to reach the next base level.
- NextJobExp - Same for job levels.
- Hp - Current amount of hit points.
- MaxHp - Maximum amount of hit points.
- Sp - Current spell points.
- MaxSp - Maximum amount of spell points.
- BaseJob - This is sneaky, apparently meant for baby class support.
- This will supposedly equal Job_Acolyte regardless of whether the
- character is an acolyte or a baby acolyte, for example.
- Karma - The character's karma. Karma system is not fully functional, but
- this doesn't mean this doesn't work at all. Not tested.
- Manner - The character's manner rating. Becomes negative if the player
- utters words forbidden through the use of 'manner.txt' client-side
- file.
- While these behave as variables, do not always expect to just set them - it is
- not certain whether this will work for all of them. Whenever there is a command
- or a function to set something, it's usually preferable to use that instead. The
- notable exception is Zeny, which you can and often will address directly -
- setting it will make the character own this number of zeny.
- If you try to set Zeny to a negative number, the script will be terminated with an error.
- Strings
- -------
- To include symbol '"' in a string you should use prefix '\"'
- Arrays
- ------
- Arrays (in eAthena at least) are essentially a set of variables going under the
- same name. You can tell between the specific variables of an array with an
- 'array index', a number of a variable in that array:
- <variable name>[<array index>]
- Variables stored in this way, inside an array, are also called 'array elements'.
- Arrays are specifically useful for storing a set of similar data (like several
- item IDs for example) and then looping through it. You can address any array
- variable as if it was a normal variable:
- set @arrayofnumbers[0],1;
- You can also do sneaky things like using a variable (or an expression, or even a
- value from an another array) to get at an array value:
- set @x,100;
- set @arrayofnumbers[@x],10;
-
- This will make @arrayofnumbers[100] equal to 10.
- Notice that index numbering always starts with 0. Arrays cannot hold more than
- 128 variables. (So the last one can't have a number higher than 127)
- And array indices probably can't be negative. Nobody tested what happens when
- you try to get a negatively numbered variable from an array, but it's not going
- to be pretty. :)
- Arrays can naturaly store strings:
- @menulines$[0] is the 0th element of the @menulines$ array of strings. Notice
- the '$', normally denoting a string variable, before the square brackets that
- denotes an array index.
- Resume of the allowed variable and array scopes
- ------ -- --- ------- -------- --- ----- ------
- +==========+======+=======+
- |VarType | Norm | Array |
- +==========+======+=======+
- |$Str$ | OK! | OK! |
- +----------+------+-------+
- |$@Str$ | OK! | OK! |
- +----------+------+-------+
- |@Str$ | OK! | OK! |
- +----------+------+-------+
- |#Str$ | OK! | FAIL! |
- +----------+------+-------+
- |Str$ | OK! | FAIL! |
- +----------+------+-------+
- |$Int | OK! | OK! |
- +----------+------+-------+
- |$@Int | OK! | OK! |
- +----------+------+-------+
- |@Int | OK! | OK! |
- +----------+------+-------+
- |#Int | OK! | FAIL! |
- +----------+------+-------+
- |Int | OK! | FAIL! |
- +----------+------+-------+
- |.Str$ | OK! | OK! |
- +----------+------+-------+
- |.Int | OK! | OK! |
- +----------+------+-------+
- |.@Str$ | OK! | OK! |
- +----------+------+-------+
- |.@Int | OK! | OK! |
- +----------+------+-------+
- Variable References
- -------------------
- //##TODO
- Operators
- ---------
- Operators are things you can do to variables and numbers. They are either the
- common mathematical operations or conditional operators
- + - will add two numbers. If you try to add two strings, the result will be a
- string glued together at the +. You can add a number to a string, and the
- result will be a string. No other math operators work with strings.
- - - will subtract two numbers.
- * - will multiply two numbers.
- / - will divide two numbers. Note that this is an integer division, i.e.
- 7/2 is not equal 3.5, it's equal 3.
- % - will give you the remainder of the division. 7%2 is equal to 1.
- There are also conditional operators. This has to do with the conditional
- command 'if' and they are meant to return either 1 if the condition is satisfied
- and 0 if it isn't. (That's what they call 'boolean' variables. 0 means 'False'.
- Anything except the zero is 'True' Odd as it is, -1 and -5 and anything below
- zero will also be True.)
- You can compare numbers to each other and you compare strings to each other, but
- you can not compare numbers to strings.
- == - Is true if both sides are equal. For strings, it means they are the same.
- >= - True if the first value is equal to, or greater than, the second value.
- <= - True if the first value is equal to, or less than, the second value
- > - True if the first value greater than the second value
- < - True if the first value is less than the second value
- != - True if the first value IS NOT equal to the second one
- Examples:
- 1==1 is True.
- 1<2 is True while 1>2 is False.
- @x>2 is True if @x is equal to 3. But it isn't true if @x is 2.
- Only '==' and '!=' have been tested for comparing strings. Since there's no way
- to code a seriously complex data structure in this language, trying to sort
- strings by alphabet would be pointless anyway.
- Comparisons can be stacked in the same condition:
- && - Is True if and only if BOTH sides are true.
- ('1==1 && 2==2' is true. '2==1 && 1==1' is false.)
- || - Is True if either side of this expression is True.
- 1==1 && 2==2 is True.
- 1==1 && 2==1 is False.
- 1==1 || 2==1 is True.
- Logical bitwise operators work only on numbers, and they are the following:
- << - Left shift.
- >> - Right shift.
- Left shift moves the binary 1(s) of a number n positions to the left,
- which is the same as multiplying by 2, n times.
- In the other hand, Right shift moves the binary 1(s) of a number n positions
- to the right, which is the same as dividing by 2, n times.
- Example:
- set b,2;
- set a, b << 3;
- mes a;
- set a, a >> 2;
- mes a;
- The first mes command would display 16, which is the same as 2 x (2 x 2 x 2) = 16.
- The second mes command would display 4, which is the same as 16 / 2 = 8. 8 / 2 = 4.
- & - And.
- | - Or.
- The bitwise operator AND (&) is used to test two values against eachother,
- and results in setting bits which are active in both arguments. This can
- be used for a few things, but in eAthena this operator is usually used to
- create bitmasks in scripts.
-
- The bitwise operator OR (|)sets to 1 a binary position if the binary position
- of one of the numbers is 1. This way a variable can hold several values we can check,
- known as bitmaks. A variable currently can hold up to 32 bitmasks (from position 0
- to position 1). This is a cheap(skate) and easy way to avoid using arrays to store several checks
- that a player can have.
-
- A bitmask basically is (ab)using the variables bits to set various options in
- one variable. With the current limit if variables it is possible to store 32
- different options in one variable (by using the bits on position 0 to 31).
- Example(s):
- - Basic example of the & operator, bit example:
- 10 & 2 = 2
- Why? :
- 10 = 2^1 + 2^3 (2 + 8), so in bits, it would be 1010
- 2 = 2^1 (2), so in bits (same size) it would be 0010
- The & (AND) operator sets bits which are active (1) in both arguments, so in the
- example 1010 & 0010, only the 2^1 bit is active (1) in both. Resulting in the bit
- 0010, which is 2.
- - Basic example of creating and using a bit mask:
- set @options,2|4|16; //(note: this is the same as 2+4+16, or 22)
- if (@options & 1) mes "Option 1 is activated";
- if (@options & 2) mes "Option 2 is activated";
- if (@options & 4) mes "Option 3 is activated";
- if (@options & 8) mes "Option 4 is activated";
- if (@options & 16) mes "Options 5 is activated";
- This would return the messages about option 2, 3 and 5 being shown (since we've set
- the 2,4 and 16 bit to 1).
- ^ - Xor.
- The bitwise operator XOR (eXclusive OR) sets a binary position to 0 if both
- numbers have the same value in the said position. On the other hand, it
- sets to 1 if they have different values in the said binary position.
- This is another way of setting and unsetting bits in bitmasks.
-
- Example:
- - First let's set the quests that are currently in progress:
- set inProgress,1|8|16; // quest 1,8 and 16 are in progress
- - After playing for a bit, the player starts another quest:
- if( inProgress&2 == 0 ){
- // this will set the bit for quest 2 (inProgress has that bit set to 0)
- set inProgress,inProgress^2;
- mes "Quest 2: find a newbie and be helpful to him for an hour.";
- close;
- }
- - After spending some time reading info on Xor's, the player finally completes quest 1:
- if( inProgress&1 && isComplete ){
- // this will unset the bit for quest 1 (inProgress has that bit set to 1)
- set inProgress,inProgress^1;
- mes "Quest 1 complete!! You unlocked the secrets of the Xor dinasty, use them wisely.";
- close;
- }
- Labels
- ------
- Within executable script code, some lines can be labels:
- <label name>:
- Labels are points of reference in your script, which can be used to route
- execution with 'goto', 'menu' and 'jump_zero' commands, invoked with 'doevent'
- and 'donpcevent' commands and are otherwise essential. A label's name may not be
- longer than 22 characters. (23rd is the ':'.) There is some confusion in the
- source about whether it's 22, 23 or 24 all over the place, so keeping labels
- under 22 characters could be wise. In addition to labels you name yourself,
- there are also some special labels which the script engine will start execution
- from if a special event happens:
- OnClock<hour><minute>:
- OnMinute<minute>:
- OnHour<hour>:
- On<weekday><hour><minute>:
- OnDay<month><day>:
- This will execute when the server clock hits the specified date or time. Hours
- and minutes are given in military time. ('0105' will mean 01:05 AM). Weekdays
- are Sun,Mon,Tue,Wed,Thu,Fri,Sat. Months are 01 to 12, days are 01 to 31.
- Remember the zero. :)
- OnInit:
- OnInterIfInit:
- OnInterIfInitOnce:
- OnInit will execute every time the scripts loading is complete, including when
- they are reloaded with @reloadscript command. OnInterIfInit will execute when
- the map server connects to a char server, OnInterIfInitOnce will only execute
- once and will not execute if the map server reconnects to the char server later.
- OnAgitStart:
- OnAgitEnd:
- OnAgitInit:
- OnAgitStart2:
- OnAgitEnd2:
- OnAgitInit2:
- OnAgitStart will run whenever the server shifts into WoE mode, whether it is
- done with @agitstart GM command or with 'AgitStart' script command. OnAgitEnd
- will do likewise for the end of WoE. OnAgitInit will run when castle data is
- loaded from the char-server by the map server.
- No RID will be attached while any of the abovementioned labels are triggered, so
- no character or account-based variables will be accessible, until you attach a
- RID with 'attachrid' (see below).
- The above also applies to, the last three laels, the only difference is that
- these labels are used exclusively for WoE SE, and are called independantly.
- OnTouch:
- This label will be executed if a trigger area is defined for the NPC object it's
- in. If it isn't present, the execution will start from the beginning of the NPC
- code. The RID of the triggering character object will be attached.
- OnPCLoginEvent:
- OnPCLogoutEvent:
- OnPCBaseLvUpEvent:
- OnPCJobLvUpEvent:
- It's pretty obvious when these four special labels will be invoked. For more
- information, see 'npc/sample/PCLoginEvent.txt'
- OnPCDieEvent:
- This special label triggers when a player dies. The variable 'killerrid' is
- set to the ID of the killer.
- OnPCKillEvent:
- This special label triggers when a player kills another player. The variable
- 'killedrid' is set to the ID of the player killed.
- OnNPCKillEvent:
- This special label triggers when a player kills a monster. The variable
- 'killedrid' is set to the Class of the monster killed.
- OnPCLoadMapEvent:
- This special label will trigger once a player steps in a map marked with the
- 'loadevent' mapflag and attach its RID. The fact that this label requires a
- mapflag for it to work is because, otherwise, it'd be server-wide and trigger
- everytime a player would change maps. Imagine the server load with 1,000 players
- (oh the pain...)
- Only the special labels which are not associated with any script command are
- listed here. There are other kinds of labels which may be triggered in a similar
- manner, but they are described with their associated commands.
- On<label name>:
- These special labels are used with Mob scripts mostly, and script commands
- that requires you to point/link a command to a mob or another npc, giving a label
- name to start from. The label name can be any of your liking, but must be
- Example:
- monster "prontera",123,42,"Poringz0rd",2341,23,"Master::OnThisMobDeath";
- amatsu,13,152,4 script Master 767,{
- mes "Hi there";
- close;
- OnThisMobDeath:
- announce "Hey, "+strcharinfo(0)+" just killed a Poringz0rd!",bc_blue|bc_all;
- end;
- }
- Each time you kill one, that announce will appear in blue to everyone.
- Scripting commands and functions
- --------------------------------
- The commands and functions are listed here in no particular order. There's a
- difference between commands and functions - commands leave no 'return value'
- which might be used in a conditional statement, as a command argument, or stored
- in a variable. Calling commands as if they were functions will sometimes work,
- but is not advised, as this can lead to some hard to track errors. Calling
- functions as if they were commands will mess up the stack, so 'return' command
- will not return correctly after this happens in a particular script.
- All commands must end with a ';'. Actually, you may expect to have multiple
- commands on one line if you properly terminate them with a ';', but it's better
- if you don't, since it is not certain just whether the scripting engine will
- behave nicely if you do.
- -------------------------
- From here on, we will have the commands sorted as follow:
- 1.- Basic commands.
- 2.- Information-retrieving commands.
- 3.- Checking commands.
- 4.- Player-related commands.
- 5.- Mob / NPC -related commands.
- 6.- Other commands.
- 7.- Instance Commands.
- =====================
- |1.- Basic commands.|
- =====================
- ---------------------------------------
- *mes "<string>";
- This command will displays a box on the screen for the invoking character, if no
- such box is displayed already, and will print the string specified into that
- box. There is normally no 'close' or 'next' button on this box, unless you
- create one with 'close' or 'next', and while it's open the player can't do much
- else, so it's important to create a button later. If the string is empty, it
- will show up as an empty line.
- mes "Text that will appear in the box";
- Inside the string you may put color codes, which will alter the color of the
- text printed after them. The color codes are all '^<R><G><B>' and contain three
- hexadecimal numbers representing colors as if they were HTML colors - ^FF0000 is
- bright red, ^00FF00 is bright green, ^0000FF is bright blue, ^000000 is black.
- ^FF00FF is a pure magenta, but it's also a color that is considered transparent
- whenever the client is drawing windows on screen, so printing text in that color
- will have kind of a weird effect. Once you've set a text's color to something,
- you have to set it back to black unless you want all the rest of the text be in
- that color:
- mes "This is ^FF0000 red ^000000 and this is ^00FF00 green, ^000000 so.";
-
- Notice that the text coloring is handled purely by the client. If you use non-
- english characters, the color codes might get screwed if they stick to letters
- with no intervening space. Separating them with spaces from the letters on
- either side solves the problem.
- ---------------------------------------
- *next;
- This command will create a 'next' button in the message window for the invoking
- character. If no window is currently on screen, it will be created. Used to
- segment NPC talking, this command is used A LOT. See 'mes'.
- mes "[Woman]";
- mes "This would appear on the page";
- next;
- // This is needed cause it is a new page and the top will now be blank
- mes "[Woman]";
- mes "This would appear on the 2nd page";
- ---------------------------------------
- *close;
- This command will create a 'close' button in the message window for the invoking
- character. If no window is currently on screen, it will be created. This is one
- of the ways to end a speech from an NPC. Once the button is clicked, the NPC
- script execution will end, and the message box will disappear.
- mes "[Woman]";
- mes "I am finished talking to you, click the close button";
- close;
- mes "This command will not run at all, cause the script has ended.";
- ---------------------------------------
- *close2;
- This command will create a 'close' button in the message window for the invoking
- character. If no window is currently on screen, it will be created. See 'close'.
- There is one important difference, though - even though the message box will
- have closed, the script execution will not stop, and commands after 'close2'
- will still run, meaning an 'end' has to be used to stop the script, unless you
- make it stop in some other manner.
- mes "[Woman]";
- mes "I will warp you now";
- close2;
- warp "place",50,50;
- end;
-
- Don't expect things to run smoothly if you don't make your scripts 'end'.
- ---------------------------------------
- *end;
- This command will stop the execution for this particular script. The two
- versions are prefectly equivalent. It is the normal way to end a script which
- does not use 'mes'.
- if (BaseLevel<=10) goto L_Lvl10;
- if (BaseLevel<=20) goto L_Lvl20;
- if (BaseLevel<=30) goto L_Lvl30;
- if (BaseLevel<=40) goto L_Lvl40;
- if (BaseLevel<=50) goto L_Lvl50;
- if (BaseLevel<=60) goto L_Lvl60;
- if (BaseLevel<=70) goto L_Lvl70;
- L_Lvl10:
- npctalk "Look at that you are still a n00b";
- end;
- L_Lvl20:
- npctalk "Look at that you are getting better, but still a n00b";
- end;
- L_Lvl30:
- npctalk "Look at that you are getting there, you are almost 2nd profession now right???";
- end;
- L_Lvl40:
- npctalk "Look at that you are almost 2nd profession";
- end;
- Without the use if 'end' it would travel through the labels until the end of the
- script. If you were lvl 10 or less, you would see all the speech lines, the use
- of 'end' stops this, and ends the script.
- ---------------------------------------
- *set <variable>,<expression>;
- This command will set a variable to the value that the expression results in.
- This is the only way to set a variable directly.
- This is the most basic script command and is used a lot whenever you try to do
- anything more advanced than just printing text into a messagebox.
- set @x,100;
-
- will make @x equal 100.
- set @x,1+5/8+9;
-
- will compute 1+5/8+9 (which is, surprisingly, 10 - remember, all numbers are
- integer in this language) and make @x equal it.
- Returns the variable reference (since trunk r12870).
- ---------------------------------------
- *setd "<variable name>",<value>;
- Works almost identical as set, just that the variable name is identified as a string,
- thus can be constructed dynamically.
- This command is equivalent to:
- set getd("variable name"),<value>;
- Example:
- set $var$, "Poring";
- setd "$var$", "Poporing";
- mes $var$; // Will return Poporing
- setd "$" + $var$ + "123$", "Poporing is cool";
- mes $Poporing123$; // Will return Poporing is cool.
- ---------------------------------------
- *getd("<variable name>")
- Returns a reference to a variable, the name can be constructed dynamically.
- Refer to setd for usage.
- Example:
- set getd("$varRefence"), 1;
- set @i, getd("$pikachu");
- ---------------------------------------
- *getvariableofnpc(<variable>,"<npc name>")
- Returns a reference to a NPC variable (. prefix) from the target NPC.
- This can only be used to get . variables.
- Example(s):
- //This will return the value of .var, note that this can't be used, since the value isn't catched.
- getvariableofnpc(.var,"TargetNPC");
-
- //This will set the .v variable to the value of the TargetNPC's .var variable.
- set .v,getvariableofnpc(.var,"TargetNPC");
-
- //This will set the .var variable of TargetNPC to 1.
- set getvariableofnpc(.var,"TargetNPC"),1;
- ---------------------------------------
- *goto <label>;
- This command will make the script jump to a label, usually used in conjunction
- with other command, such as "if", but often used on it's own.
- ...
- goto Label;
- mes "This will not be seen";
- Label:
- mes "This will be seen";
- Note by FlavioJS: goto's are "evil" and should be avoided if possible (ò_ó)
- ---------------------------------------
- *menu "<option_text>",<target_label>{,"<option_text>",<target_label>,...};
- This command will create a selectable menu for the invoking character. Only one
- menu can be on screen at the same time.
- Depending on what the player picks from the menu, the script execution will
- continue from the corresponding label. (it's string-label pairs, not label-
- string)
- Options can be grouped together, separated by the character ':'.
- menu "A:B",L_Wrong,"C",L_Right;
- It also sets a special temporary character variable @menu, which contains the
- number of option the player picked. (Numbering of options starts at 1.)
- This number is consistent with empty options and grouped options.
- menu "A::B",L_Wrong,"",L_Impossible,"C",L_Right;
- L_Wrong:
- // If they click "A" or "B" they will end up here
- // @menu == 1 if "A"
- // @menu == 2 will never happen because the option is empty
- // @menu == 3 if "B"
- L_Impossible:
- // Empty options are not displayed and therefore can't be selected
- // this label will never be reached from the menu command
- L_Right:
- // If they click "C" they will end up here
- // @menu == 5
- If a label is '-', the script execution will continue right after the menu
- command if that option is selected, this can be used to save you time, and
- optimize big scripts.
- menu "A::B:",-,"C",L_Right;
- // If they click "A" or "B" they will end up here
- // @menu == 1 if "A"
- // @menu == 3 if "B"
- L_Right:
- // If they click "C" they will end up here
- // @menu == 5
- Both these examples will perform the exact same task.
- If you give an empty string as a menu item, the item will not display. This
- can effectively be used to script dynamic menus by using empty string for
- entries that should be unavailable at that time.
- You can do it by using arrays, but watch carefully - this trick isn't high
- wizardry, but minor magic at least. You can't expect to easily duplicate it
- until you understand how it works.
- Create a temporary array of strings to contain your menu items, and populate it
- with the strings that should go into the menu at this execution, making sure not
- to leave any gaps. Normally, you do it with a loop and an extra counter, like
- this:
- setarray @possiblemenuitems$[0],<list of potential menu items>;
- set @j,0; // That's the menu lines counter.
-
- // We loop through the list of possible menu items.
- // @i is our loop counter.
- for( set @i,0; @i<getarraysize(@possiblemenuitems$) ; set @i,@i+1 )
- {
- // That 'condition' is whatever condition that determines whether
- // a menu item number @i actually goes into the menu or not.
-
- if (<condition>)
- {
- // We record the option into the list of options actually available.
-
- set @menulist$[@j],@possiblemenuitems$[@i];
-
- // We just copied the string, we do need it's number for later
- // though, so we record it as well.
-
- set @menureference[@j],@i;
-
- // Since we've just added a menu item into the list, we increment
- // the menu lines counter.
-
- set @j,@j+1;
- }
-
- // We go on to the next possible menu item.
- }
- This will create you an array @menulist$ which contains the text of all items
- that should actually go into the menu based on your condition, and an array
- @menureference, which contains their numbers in the list of possible menu items.
- (Remember, arrays start with 0.) There's less of them than the possible menu
- items you've defined, but the menu command can handle the empty lines - only if
- they are last in the list, and if it's made this way, they are. Now comes a
- dirty trick:
- // X is whatever the most menu items you expect to handle.
- menu @menulist$[0],-,@menulist$[1],-,....@menulist$[<X>],-;
- This calls up a menu of all your items. Since you didn't copy some of the
- possible menu items into the list, it's end is empty and so no menu items will
- show up past the end. But this menu call doesn't jump anywhere, it just
- continues execution right after the menu command. (And it's a good thing it
- doesn't, cause you can only explicitly define labels to jump to, and how do you
- know which ones to define if you don't know beforehand which options will end up
- where in your menu?)
- But how do you figure out which option the user picked? Enter the @menu.
- @menu contains the number of option that the user selected from the list,
- starting with 1 for the first option. You know now which option the user picked
- and which number in your real list of possible menu items it translated to:
- mes "You selected "+@possiblemenuitems$[@menureference[@menu-1]]+"!";
- @menu is the number of option the user picked.
- @menu-1 is the array index for the list of actually used menu items that we
- made.
- @menureference[@menu-1] is the number of the item in the array of possible menu
- items that we've saved just for this purpose.
- And @possiblemenuitems$[@menureference[@menu-1]] is the string that we used to
- display the menu line the user picked. (Yes, it's a handful, but it works.)
- You can set up a bunch of 'if (@menureference[@menu-1]==X) goto Y' statements to
- route your execution based on the line selected and still generate a different
- menu every time, which is handy when you want to, for example, make users select
- items in any specific order before proceeding, or make a randomly shuffled menu.
- Kafra code bundled with the standard distribution uses a similar array-based
- menu technique for teleport lists, but it's much simpler and doesn't use @menu,
- probably since that wasn't documented anywhere.
- See also 'select', which is probably better in this particular case. Instead of
- menu, you could use 'select' like this:
- set @dummy,select(@menulist$[0],@menulist$[1],....@menulist$[<X>]);
-
- For the purposes of the technique described above these two statements are
- perfectly equivalent.
- ---------------------------------------
- *select("<option>"{,"<option>",...})
- *prompt("<option>"{,"<option>",...})
- This function is a handy replacement for 'menu' for some specific cases where
- you don't want a complex label structure - like, for example, asking simple yes-
- no questions. It will return the number of menu option picked, starting with 1.
- Like 'menu', it will also set the variable @menu to contain the option the user
- picked.
- if (select("Yes:No")==1) mes "You said yes, I know.";
- And like 'menu', the selected option is consistent with grouped options
- and empty options.
- prompt works almost the same as select, except that when a character clicks
- the Cancel button, this function will return 255 instead.
- ---------------------------------------
- *input(<variable>{,<min>{,<max>}})
- This command will make an input box pop up on the client connected to the
- invoking character, to allow entering of a number or a string. This has many
- uses, one example would be a guessing game, also making use of the 'rand'
- function:
- mes "[Woman]";
- mes "Try and guess the number I am thinking of.";
- mes "The number will be between 1 and 10.";
- next;
- set @number, rand(1,10);
- input @guess;
- if(@guess==@number)
- {
- mes "[Woman]";
- mes "Well done that was the number I was thinking of";
- close;
- }
- else
- {
- mes "[Woman]";
- mes "Sorry, that wasn't the number I was thinking of.";
- close;
- }
- If you give the input command a string variable to put the input in, it will
- allow the player to enter text. Otherwise, only numbers will be allowed.
- mes "[Woman]";
- mes "Please say HELLO";
- next;
- input @var$;
- if(@var$=="HELLO")
- {
- mes "[Woman]";
- mes "Well done you typed it correctly";
- close;
- }
- else
- {
- mes "[Woman]";
- mes "Sorry you got it wrong";
- close;
- }
- Normally you may not input a negative number with this command.
- This is done to prevent exploits in badly written scripts, which would
- let people, for example, put negative amounts of zeny into a bank script and
- receive free zeny as a result.
- Since trunk r12192 the command has two optional arguments and a return value.
- The default value of 'min' and 'max' can be set with 'input_min_value' and
- 'input_max_value' in script_athena.conf.
- For numeric inputs the value is capped to the range [min,max]. Returns 1 if
- the value was higher than 'max', -1 if lower than 'min' and 0 otherwise.
- For string inputs it returns 1 if the string was longer than 'max', -1 is
- shorter than 'min' and 0 otherwise.
- ---------------------------------------
- *callfunc "<function>"{,<argument>,...<argument>};
- *callfunc("<function>"{,<argument>,...<argument>})
- This command lets you call up a function NPC. A function NPC can be called from
- any script on any map server. Using the 'return' command it will come back to
- the place that called it.
- place,50,50,6%TAB%script%TAB%Woman%TAB%115,{
- mes "[Woman]"
- mes "Lets see if you win";
- callfunc "funcNPC";
- mes "Well done you have won";
- close;
- }
- function%TAB%script%TAB%funcNPC%TAB%{
- set @win, rand(2);
- if(@win==0) return;
- mes "Sorry you lost";
- end;
- }
- You can pass arguments to your function - values telling it what exactly to do -
- which will be available there with getarg() (see 'getarg')
- Notice that returning is not mandatory, you can end execution right there.
- If you want to return a real value from inside your function NPC, it is better
- to write it in the function form, which will also work and will make the script
- generally cleaner:
- place,50,50,6%TAB%script%TAB%Man%TAB%115,{
- mes "[Man]"
- mes "Gimme a number!";
- next;
- input @number;
- if (callfunc("OddFunc",@number)) mes "It's Odd!";
- close;
- }
- function%TAB%script%TAB%OddFunc%TAB%{
- if (getarg(0)%2==0) return 0;// it's even
- return 1;// it's odd
- }
- ---------------------------------------
- *callsub <label>{,<argument>,...<argument>};
- *callsub(<label>{,<argument>,...<argument>})
- This command will go to a specified label within the current script (do NOT use
- quotes around it) coming in as if it were a 'callfunc' call, and pass it
- arguments given, if any, which can be recovered there with 'getarg'. When done
- there, you should use the 'return' command to go back to the point from where
- this label was called. This is used when there is a specific thing the script
- will do over and over, this lets you use the same bit of code as many times as
- you like, to save space and time, without creating extra NPC objects which are
- needed with 'callfunc'. A label is not callable in this manner from another
- script.
- Example 1: callsub for checking (if checks pass, return to script)
- callsub S_CheckFull, "guild_vs2",50;
- switch( rand(4) ) {
- case 0: warp "guild_vs2",9,50; end;
- case 1: warp "guild_vs2",49,90; end;
- case 2: warp "guild_vs2",90,50; end;
- case 3: warp "guild_vs2",49,9; end;
- }
- ...
- S_CheckFull:
- if (getmapusers(getarg(0)) >= getarg(1)) {
- mes "I'm sorry, this arena is full. Please try again later.";
- close;
- }
- return;
- Example 2: callsub used repeatedly, with different arguments
- // notice how the zeny check/delete is reused, instead of copy-pasting for every warp
- switch(select("Abyss Lake:Amatsu Dungeon:Anthell:Ayothaya Dungeon:Beacon Island, Pharos") {
- case 1: callsub S_DunWarp,"hu_fild05",192,207;
- case 2: callsub S_DunWarp,"ama_in02",119,181;
- case 3: callsub S_DunWarp,"moc_fild20",164,145;
- case 4: callsub S_DunWarp,"ayo_fild02",279,150;
- case 5: callsub S_DunWarp,"cmd_fild07",132,125;
- // etc
- }
- ...
- S_DunWarp:
- // getarg(0) = "mapname"
- // getarg(1) = x
- // getarg(2) = y
- if (Zeny >= 100) {
- set Zeny, Zeny-100;
- warp getarg(0),getarg(1),getarg(2);
- } else {
- mes "Dungeon warp costs 100 zeny.";
- }
- close;
- ---------------------------------------
- *getarg(<index>{,<default_value>})
- This function is used when you use the 'callsub' or 'callfunc' commands. In the
- call you can specify variables that will make that call different from another
- one. This function will return an argument the function or subroutine was
- called with, and is the normal way to get them.
- This is another thing that can let you use the same code more than once.
- Argument numbering starts with 0, i.e. the first argument you gave is number 0.
- If no such argument was given, a zero is returned.
- place,50,50,6%TAB%script%TAB%Woman1%TAB%115,{
- mes "[Woman]";
- mes "Lets see if you win";
- callfunc "funcNPC",2;
- mes "Well done you have won";
- ...
- place,52,50,6%TAB%script%TAB%Woman2%TAB%115,{
- mes "[Woman]";
- mes "Lets see if you win";
- callfunc "funcNPC",5;
- mes "Well done you have won";
- ...
- function%TAB%script%TAB%funcNPC%TAB%{
- set @win, rand(getarg(0));
- if(@win==0) return;
- mes "Sorry you lost";
- "woman1" NPC object calls the funcNPC. The argument it gives in this call is
- stated as 2, so when the random number is generated by the 'rand' function, it
- can only be 0 or 1. Whereas "woman2" gives 5 as the argument number 0 when
- calling the function, so the random number could be 0, 1, 2, 3 or 4, this makes
- "woman2" less likely to say the player won.
- You can pass multiple arguments in a function call:
- callfunc "funcNPC",5,4,3;
- getarg(0) would be 5, getarg(1) would be 4 and getarg(2) would be 3.
- Getarg has an optional argument since trunk r10773 and stable r10958.
- If the target argument exists, it is returned.
- Otherwise, if <default_value> is present it is returned instead,
- if not the script terminates immediately.
- in the previous example getarg(2,-1) would be 3 and getarg(3,-1) would be -1
- ---------------------------------------
- *return {<value>};
- When you use callsub or callfunc, this command allows you to go back to the
- calling script. You can optionally return with a value telling the calling
- program what exactly happened.
- callfunc "<your function>";// when nothing is returned
- set <variable>,callfunc("<your function>");// when a value is being returned
- ---------------------------------------
- *function <function name>;
- *<function name>;
- *function <function name> {
- <code>
- }
- (Skotlex stop being so selfish and give us all the commands T~T! J/k lol :P)
- This works like callfunc, but doesn't support arguments like callfunc. It's used for cleaner
- and fast script that doesn't require arguments for it to work. Also they must be inside a script.
- They're not separated scripts and they work more like labels.
- Note it looks like the normal declaration
- Usage:
- You first Declare the function with function <function name>;.
- Put the rest of your code. You can use then <function name>; to call the function. If it returns a value is unsure,
- test it if you want and give us some comments ;3
- And at least, but inside the script itself, put the function <function name> {<code>}.
- Example:
- prontera,154,189,4 script Item seller 767,{
- function SF_Selling;
- mes "I'll open this now if you have more than 50z and you are level 50 or bigger";
- next;
- if (Zeny > 50) && (BaseLevel > 50) {
- mes "Welcome";
- next;
- SF_Selling;
- close;
- } else
- set @needed,50-BaseLevel;
- mes "You either are Level "+BaseLevel+", thus you need "+@needed+" more levels";
- mes "to be able to use this npc; or you don't have enough zeny, so get some please";
- close;
- function SF_Selling {
- mes "Would you like to buy a phracon for 50z?";
- switch(select("Yes","No, thanks")) {
- case 1:
- mes "Ok, how many?";
- input @quantity;
- set @check,Zeny/50;
- if (@quantity > @check) {
- mes "Sorry but you can only have "+@check+" Phracons with "+Zeny;
- close;
- } else
- next;
- mes "here you have";
- set Zeny,Zeny-@quantity*50;
- getitem 1010,@quantity;
- close;
- case 2:
- mes "Good bye then";
- close;
- }
- }
- return;
- }
- ---------------------------------------
- *if (<condition>) <statement>;
- This is the basic conditional statement command, and just about the only one
- available in this scripting language.
- The condition can be any expression. All expressions resulting in a non-zero
- value will be considered True, including negative values. All expressions
- resulting in a zero are false.
- If the expression results in True, the statement will be executed. If it isn't
- true, nothing happens and we move on to the next line of the script.
- if (1) mes "This will always print.";
- if (0) mes "And this will never print.";
- if (5) mes "This will also always print.";
- if (-1) mes "Funny as it is, this will also print just fine.";
- For more information on conditional operators see the operators section above.
- Anything that is returned by a function can be used in a condition check without
- bothering to store it in a specific variable:
- if (strcharinfo(0)=="Daniel Jackson") mes "It is true, you are Daniel!";
- More examples of using the 'if' command in the real world:
- Example 1:
- set @var1,1;
- input @var2;
- if(@var1==@var2) goto L_Same;
- mes "Sorry that is wrong";
- close;
- L_Same:
- close;
- Example 2:
-
- set @var1,1;
- input @var2;
- if(@var1!=@var2) mes "Sorry that is wrong";
- close;
- (Notice examples 1 and 2 have the same effect.)
- Example 3:
- set @var1,@var1+1;
- mes "[Forgetfull Man]";
- if (@var==1) mes "This is the first time you have talked to me";
- if (@var==2) mes "This is the second time you have talked to me";
- if (@var==3) mes "This is the third time you have talked to me";
- if (@var==4) mes "This is the forth time you have talked to me, but I think I am getting amnesia, I have forgoten about you";
- if (@var==4) set @var,0;
- close;
- Example 4:
- mes "[Quest Person]";
- if(countitem(512)>=1) goto L_GiveApple;
- // The number 512 was found from item_db, it is the item number for the Apple.
- mes "Can you please bring me an apple?";
- close;
- L_GiveApple:
- mes "Oh an apple, I didnt want it, I just wanted to see one";
- close;
- Example 5:
- mes "[Person Checker]";
- if($name$!=null) goto L_Check;
- mes "Please tell me someones name";
- next;
- input $name$;
- set $name2$,strcharinfo(0);
- mes "[Person Checker]";
- mes "Thank you";
- L_Check:
- if($name$==strcharinfo(0) ) goto L_SameName;
- mes "[Person Checker]";
- mes "You are not the person that " +$name2$+ " mentioned";
- L_End:
- set $name$,null;
- set $name2$,null;
- close;
- L_SameName:
- mes "[Person Checker]";
- mes "You are the person that " +$name2$+ " just mentioned";
- mes "nice to meet you";
- goto L_End;
- See 'strcharinfo' for explanation of what this function does.
- Example 6: Using complex conditions.
- mes "[Multi Checker]";
- if( (@queststarted==1) && (countitem(512)>=5) ) goto L_MultiCheck;
- // Only if the quest has been started AND You have 5 apples will it goto "L_MultiCheck"
- mes "Please get me 5 apples";
- set @queststarted,1;
- close;
- L_MultiCheck:
- mes "[Multi Checker]";
- mes "Well done you have started the quest of got me 5 apples";
- mes "Thank you";
- set @queststarted,0;
- delitem 512,5;
- close;
- With the Advanced scripting engine, we got nested if's. That is:
- if (<condition>)
- dothis;
- else
- dothat;
-
- If the condition doesn't meet, it'll do the action following the else.
- We can also group several actions depending on a condition, the following way:
- if (<condition)
- {
- dothis1;
- dothis2;
- dothis3;
- } else {
- dothat1;
- dothat2;
- dothat3;
- dothat4;
- }
- Remember that if you plan to do several actions upon the condition being false, and
- you forget to use the curlies (the { } ), the second action will be executed regardless
- the output of the condition, unless of course, you stop the execution of the script if the
- condition is true (that is, in the first grouping using a return; , and end; or a close; )
- Also, you can have multiple conditions nested or chained, and don't worry about limits as to
- how many nested if you can have, there is no spoon ;)
- ...
- if (<condition 1>)
- dothis;
- else if (<condition 2>)
- {
- dotheother;
- do that;
- end;
- } else
- do this;
- ...
- ---------------------------------------
- *jump_zero (<condition>),<label>;
- This command works kinda like an 'if'+'goto' combination in one go. (See 'if').
- If the condition is false (equal to zero) this command will immediately jump to
- the specified label like in 'goto'.
- While 'if' is more generally useful, for some cases this could be an
- optimisation.
- ---------------------------------------
- *while (<condition>) <statement>;
- This is probably the simplest and most frequently used loop structure. The 'while'
- statement can be interpreted as "while <condition> is true, perform <statement>".
- It is a pretest loop, meaning the conditional expression is tested before any of the
- statements in the body of the loop are performed. If the condition evaluates to
- false, the statement(s) in the body of the loop is/are never executed. If the
- condition evaluates to true, the statement(s) are executed, then control transfers
- back to the conditional expression, which is reevaluated and the cycle continues.
- Multiple statements can be grouped with { }, curly braces, just like with the 'if' statement.
- Example 1:
- while (switch(select("Yes:No") == 2 ))
- mes "You picked no.";
- Example 2: multiple statements
- while (switch(select("Yes:No") == 2 )) {
- mes "Why did you pick no?";
- mes "You should pick yes instead!";
- }
- Example 3: counter-controlled loop
- set .@i, 1;
- while (.@i <= 5) {
- mes "This line will print 5 times.";
- set .@i, .@i +1;
- }
- Example 4: sentinel-controlled loop
- mes "Input 0 to stop";
- input .@num;
- while (.@num != 0) {
- mes "You entered " + .@num;
- input .@num;
- }
- close;
- ---------------------------------------
- *for (<variable initialization>; <condition>; <variable update>) <statement>;
- Another pretest looping structure is the 'for' statement. It is considered a
- specialized form of the 'while' statement, and is usually associated with counter-
- controlled loops. Here are the steps of the 'for' statement: the initialize
- statement is executed first and only once. The condition test is performed.
- When the condition evaluates to false, the rest of the for statement is skipped.
- When the condition evaluates to true, the body of the loop is executed, then the
- update statement is executed (this usually involves incrementing a variable).
- Then the condition is reevaluated and the cycle continues.
- Example 1:
- for( set .@i, 1; .@i <= 5; set .@i, .@i +1 )
- mes "This line will print 5 times.";
- Example 2:
- mes "This will print the numbers 1 - 5.";
- for( set .@i, 1; .@i <= 5; set .@i, .@i +1 )
- mes .@i;
- ---------------------------------------
- *do { <statement>; } while (<condition>);
- The 'do...while' is the only posttest loop structure available in this script
- language. With a posttest, the statements are executed once before the condition
- is tested. When the condition is true, the statement(s) are repeated. When the
- condition is false, control is transferred to the statement following the
- 'do...while' loop expression.
- Example 1: sentinel-controlled loop
- mes "This menu will keep appearing until you pick Cancel";
- do {
- set .@menu, select("One:Two:Three:Cancel");
- } while (.@menu != 4);
- Example 2: counter-controlled loop
- mes "This will countdown from 10 to 1.";
- set .@i, 10;
- do {
- mes .@i;
- set .@i, .@i - 1;
- } while (.@i > 0);
- ---------------------------------------
- *setarray <array name>[<first value>],<value>{,<value>...<value>};
- This command will allow you to quickly fill up an array in one go. Check the
- Kafra scripts in the distribution to see this used a lot.
- setarray @array[0], 100, 200, 300, 400, 500, 600;
- First value is the index of the first element of the array to alter. For
- example:
- setarray @array[0],200,200,200;
- setarray @array[1],300,150;
-
- will produce:
- @array[0]=200
- @array[1]=300
- @array[2]=150
- ---------------------------------------
- *cleararray <array name>[<first value to alter>],<value>,<number of values to set>;
- This command will change many array values at the same time to the same value.
- setarray @array[0], 100, 200, 300, 400, 500, 600;
- // This will make all 6 values 0
- cleararray @array[0],0,6;
- // This will make array element 0 change to 245
- cleararray @array[0],245,1;
- // This will make elements 1 and 2 change to 345
- cleararray @array[1],345,2;
- See 'setarray'.
- ---------------------------------------
- *copyarray <destination array>[<first value>],<source array>[<first value>],<amount of data to copy>;
- This command lets you quickly shuffle a lot of data between arrays, which is in
- some cases invaluable.
- setarray @array[0], 100, 200, 300, 400, 500, 600;
- // So we have made @array[]
- copyarray @array2[0],@array[2],2;
-
- // Now, @array2[0] will be equal to @array[2] (300) and
- // @array2[1] will be equal to @array[3].
- So using the examples above:
- @array[0] = 100
- @array[1] = 200
- @array[2] = 300
- @array[3] = 400
- @array[4] = 500
- @array[5] = 600
-
- New Array:
- @array2[0] = 300
- @array2[1] = 400
- @array2[2] = 0
- @array2[3] = 0
- Notice that @array[4] and @array[5] won't be copied to the second array, and it will return a
- 0.
- ---------------------------------------
- *deletearray <array name>[<first value>],<how much to delete>
- This command will delete a specified number of array elements totally from an
- array, shifting all the elements beyond this towards the beginning.
- // This will delete array element 0, and move all the other array elements
- // up one place.
- deletearray @array[0],1
- // This would delete array elements numbered 1, 2 and 3, leave element 0 in its
- // place, and move the other elements ups, so there are no gaps.
- deletearray @array[1],3
- IMPORTANT: deletarray is horribly broken since the earliest days of jAthena. It
- tends to merrily remove much more variables than it's told to remove, which
- makes it pretty much useless for anything other than removing an array from
- memory entirely. This would be very handy, if it always worked.
- ---------------------------------------
- ======================================
- |2.- Information-retrieving commands.|
- ======================================
- ---------------------------------------
- *strcharinfo(<type>)
- This function will return either the name, party name or guild name for the
- invoking character. Whatever it returns is determined by type.
- 0 - Character's name.
- 1 - The name of the party they're in if any.
- 2 - The name of the guild they're in if any.
-
- If a character is not a member of any party or guild, an empty string will be
- returned when requesting that information.
- ---------------------------------------
- *strnpcinfo(<type>)
- This function will return the various parts of the name of the calling npc.
- Whatever it returns is determined by type.
- 0 - The NPC's display name (visible#hidden)
- 1 - The visible part of the NPC's display name
- 2 - The hidden part of the NPC's display name
- 3 - The NPC's unique name (::name)
- ---------------------------------------
- *getarraysize(<array name>)
- This function returns the number of values that are contained inside the
- specified array. Notice that zeros and empty strings at the end of this array
- are not counted towards this number.
- For example:
- setarray @array[0], 100, 200, 300, 400, 500, 600;
- set @arraysize,getarraysize(@array);
- This will make @arraysize == 6. But if you try this:
- setarray @array[0], 100, 200, 300, 400, 500, 600, 0;
- set @arraysize,getarraysize(@array);
-
- @arraysize will still equal 6, even though you've set 7 values.
- ---------------------------------------
- *getelementofarray(<array name>,<index>)
- This function will return an array's element when given an index.
- // This will find the 2nd array value
- getelementofarray(@array,1)
- Pretty pointless now when we have
- @array[1]
- which has the same effect.
- ---------------------------------------
- *readparam(<parameter number>)
- This function will return the basic stats of an invoking character, referred to
- by the parameter number. Instead of a number, you can use a parameter name if it
- is defined in "db/const.txt".
- For reference, in there these things are defined:
- StatusPoint, BaseLevel, SkillPoint, Class, Upper, Zeny, Sex, Weight, MaxWeight,
- JobLevel, BaseExp, JobExp, NextBaseExp, NextJobExp, Hp, MaxHp, Sp, MaxSp,
- BaseJob, Karma, Manner, bVit, bDex, bAgi, bStr, bInt, bLuk
- All of these also behave as variables, but don't expect to be able to just 'set'
- all of them - some will not work for various internal reasons.
- // This would return how many status points you haven't spent yet
- readparam(9)
- Using this particular information as a function call is not required. Just
- putting
- StatusPoint
- will give you the same result, and some of these parameters work just like
- variables (i.e. you can 'set Zeny,100' to make the character have 100 zeny,
- destroying whatever zeny they had before, or 'set Zeny,Zeny+100' to give them
- 100 zeny)
- You can also use this command to get stat values:
- readparam(bVit)
- if(readparam(bVit)<=77) goto L_End;
- mes "Only people with over 77 Vit are reading this";
- L_End:
- close;
- ---------------------------------------
- *getcharid(<type>{,"<character name>"})
- This function will return a unique ID number of the invoking character, or, if a
- character name is specified, of that character.
- Type is the kind of associated ID number required:
- 0 - Character ID number.
- 1 - Party ID number.
- 2 - Guild ID number.
- 3 - Account ID number.
- For most purposes other than printing it, a number is better to have than a name
- (people do horrifying things to their character names).
- If the character is not in a party or not in a guild, the function will return 0
- if guild or party number is requested. If a name is specified and the character
- is not found, 0 is returned.
- If getcharid(0) returns a zero, the script got called not by a character and
- doesn't have an attached RID. Note that this will cause the map server to
- print "player not attached!" error messages, so it is preferred to use
- "playerattached" to check for the character attached to the script.
- if( getcharid(2) == 0 ) mes "Only members of a guild are allowed here!";
- ---------------------------------------
- *getchildid()
- *getmotherid()
- *getfatherid()
- These functions return the characters (child/mother/father) ID
- if (getmotherid()) mes "Oh... I know your mother's ID:"+getmotherid();
- ---------------------------------------
- *ispartneron()
- This function returns 1 if the invoking character's marriage partner is
- currently online and 0 if they are not or if the character has no partner.
- ---------------------------------------
- *getpartnerid()
- This function returns the character ID of the invoking character's marriage
- partner, if any. If the invoking character is not married, it will return 0,
- which is a quick way to see if they are married:
- if (getpartnerid()) mes "I'm not going to be your girlfriend!";
- if (getpartnerid()) mes "You're married already!";
- ---------------------------------------
- *getpartyname(<party id>)
- This function will return the name of a party that has the specified ID number.
- If there is no such party ID, "null" will be returned.
- Lets say the ID of a party was saved as a global variable:
- // This would return the name of the party from the ID stored in a variable
- mes "You're in the '"+getpartyname($@var)"' party, I know!";
- ---------------------------------------
- *getpartymember <party id>{,<type>};
- Thank you to HappyDenn for all this information.
- This command will find all members of a specified party and returns their names
- (or character id or account id depending on the value of "type") into an array
- of temporary global variables. There's actually quite a few commands like this
- which will fill a special variable with data upon execution and not do anything
- else.
- Upon executing this,
- $@partymembername$[] is a global temporary stringarray which contains all the
- names of these party members
- (only set when type is 0 or not specified)
- $@partymembercid[] is a global temporary number array which contains the
- character id of these party members.
- (only set when type is 1)
- $@partymemberaid[] is a global temporary number array which contains the
- account id of these party members.
- (only set when type is 2)
- $@partymembercount is the number of party members that were found.
- The party members will (apparently) be found regardless of whether they are
- online or offline. Note that the names come in no particular order.
- Be sure to use $@partymembercount to go through this array, and not
- 'getarraysize', because it is not cleared between runs of 'getpartymember'. If
- someone with 7 party members invokes this script, the array would have 7
- elements. But if another person calls up the NPC, and he has a party of 5, the
- server will not clear the array for you, overwriting the values instead. So in
- addition to returning the 5 member names, the 6th and 7th elements from the last
- call remain, and you will get 5+2 members, of which the last 2 don't belong to
- the new guy's party. $@partymembercount will always contain the correct number,
- (5) unlike 'getarraysize()' which will return 7 in this case.
- Example:
- // get the character's party ID
- getpartymember(getcharid(1));
- // immediately copy $@partymembercount value to a new variable, since
- // you don't know when 'getpartymember' will get called again for someone
- // else's party, overwriting your global array.
- set @partymembercount,$@partymembercount;
- // copy $@partymembername array to a new array
- copyarray @partymembername$[0],$@partymembername$[0],@partymembercount;
- //list the party members in NPC dialog
- set @count,0;
- L_DisplayMember:
- if(@count == @partymembercount) goto L_DisplayMemberEnd;
- mes (@count + 1) + ". ^0000FF" + @partymembername$[@count] + "^000000";
- set @count,@count+1;
- goto L_DisplayMember;
- L_DisplayMemberEnd:
- close;
- ---------------------------------------
- *getpartyleader(<party id>{,<type>});
- This function returns some information about the given party-id's leader.
- When type is ommitted, the default information retrieved is the leader's name.
- Possible types are:
- 1: Leader account id
- 2: Leader character id
- 3: Leader's class
- 4: Leader's current map name
- 5: Leader's current level as stored on the party structure (may not be
- current level if leader leveled up recently).
- If retrieval fails (leader not found or party does not exist), this function
- returns "null" instead of the character name, and -1 for the other types.
- ---------------------------------------
- *getlook(<type>)
- This function will return the number for the currentcharacter look value
- specified by type. See 'setlook' for valid look types.
- This can be used to make a certain script behave differently for characters
- dressed in black. :)
- ---------------------------------------
- *getsavepoint(<information type>)
- This function will return information about the invoking character's save point.
- You can use it to let a character swap between several recorded savepoints.
- Available information types are:
- 0 - Map name (a string)
- 1 - X coordinate
- 2 - Y coordinate
- ---------------------------------------
- \\
- 2,2 Item-related commands
- \\
- ---------------------------------------
- *getequipid(<equipment slot>)
- This function returns the item ID of the item equipped in the equipment slot
- specified on the invoking character. If nothing is equpped there, it returns -1.
- Valid equipment slots are:
- EQI_HEAD_TOP (1) - Upper head gear
- EQI_ARMOR (2) - Armor (Where you keep your Jackets and Robes)
- EQI_HAND_L (3) - What is in your Left hand.
- EQI_HAND_R (4) - What is in your Right hand.
- EQI_GARMENT (5) - The garment slot (Mufflers, Hoods, Manteaus)
- EQI_SHOES (6) - What foot gear the player has on.
- EQI_ACC_L (7) - Accessory 1.
- EQI_ACC_R (8) - Accessory 2.
- EQI_HEAD_MID (9) - Middle Headgear (masks and glasses)
- EQI_HEAD_LOW (10) - Lower Headgear (beards, some masks)
- Notice that a few items occupy several equipment slots, and if the character is
- wearing such an item, 'getequipid' will return it's ID number for either slot.
- Can be used to check if you have something equiped, or if you haven't got
- something equiped:
- if(getequipid(EQI_HEAD_TOP)==2234) goto L_WearingTiara;
- mes "Come back when you have a Tiara on";
- close;
- L_WearingTiara:
- mes "What a lovely Tiara you have on";
- close;
- You can also use it to make sure people don't pass a point before removing an
- item totally from them. Let's say you don't want people to wear Legion Plate
- armor, but also don't want them to equip if after the check, you would do this:
- if ((getequipid(EQI_ARMOR) == 2341) || (getequipid(EQI_ARMOR) == 2342) goto L_EquipedLegionPlate;
- // the || is used as an or argument, there is 2341 and 2342 cause there are
- // two different legion plate armors, one with a slot one without.
- if ((countitem(2341) > 0) || (countitem(2432) > 0) goto L_InventoryLegionPlate;
- mes "I will lets you pass";
- close2;
- warp "place",50,50;
- end;
- L_EquipedLegionPlate:
- mes "You are wearing some Legion Plate Armor, please drop that in your stash before continuing";
- close;
- L_InventoryLegionPlate:
- mes "You have some Legion Plate Armor in your inventory, please drop that in your stash before continuing";
- close;
- ---------------------------------------
- *getequipname(<equpment slot>)
- Returns the jname of the item equipped in the specified equipment slot on the
- invoking character, or an empty string if nothing is equipped in that position.
- Does the same thing as getitemname(getequipid()). Useful for an NPC to state
- what your are wearing, or maybe saving as a string variable.
- See 'getequipid' for a full list of valid equipment slots.
- if( getequipname(EQI_HEAD_TOP) != "" )
- mes "So you are wearing a "+getequipname(EQI_HEAD_TOP)+" on your head";
- else
- mes "You are not wearing any head gear";
- ---------------------------------------
- *getitemname(<item id>)
- Given the database ID number of an item, this function will return the text
- stored in the 'japanese name' field (which, in eAthena, stores an english name
- the players would normally see on screen.)
- ---------------------------------------
- *getbrokenid(<number>)
- This function will search the invoking character's inventory for any broken
- items, and will return their item ID numbers. Since the character may have
- several broken items, 1 given as an argument will return the first one found, 2
- will return the second one, etc. Will return 0 if no such item is found.
- // Let's see if they have anything broken:
- if (getbrokenid(1)==0) goto Skip;
- // They do, so let's print the name of the first broken item:
- mes "Oh, I see you have a broken "+getitemname(getbrokenid(1))+" here!";
- Skip:
- mes "You don't have anything broken, quit bothering me.";
- ---------------------------------------
- *getequipisequiped(<equipment slot>)
- This functions will return 1 if there is an equipment placed on the specified
- equipment slot and 0 otherwise. For a list of equipment slots
- see 'getequipid'. Function originally used by the refining NPCs:
- if (getequipisequiped(EQI_HEAD_TOP)) goto L_equipped;
- mes "[Refiner]";
- mes "Do you want me to refine your dumb head?";
- close;
- L_equipped:
- mes "[Refiner]";
- mes "That's a fine hat you are wearing there...";
- close;
- ---------------------------------------
- *getequipisenableref(<equipment slot>)
- Will return 1 if the item equipped on the invoking character in the specified
- equipment slot is refinable, and 0 if it isn't. For a list of equipment slots
- see 'getequipid'.
- if (getequipisenableref(EQI_HEAD_TOP)) goto L_Refine;
- mes "[Refiner]";
- mes "I can't refine this hat!...";
- close;
- L_Refine:
- mes "[Refiner]";
- mes "Ok I can refine this";
- close;
- ---------------------------------------
- *getequiprefinerycnt(<equipment slot>)
- Returns the current number of plusses for the item in the specified equipment
- slot. For a list of equipment slots see 'getequipid'.
- Can be used to check if you have reached a maximum refine value, default for
- this is +10:
- if(getequiprefinerycnt(EQI_HEAD_TOP) < 10) goto L_Refine_HeadGear;
- mes "Sorry, it's not possible to refine hats better than +10";
- close;
- L_Refine_HeadGear:
- mes "I will now upgrade your "+getequipname(EQI_HEAD_TOP);
- ---------------------------------------
- *getequipweaponlv(<equipment slot>)
- This function returns the weapon level for the weapon equipped in the specified
- equipment slot on the invoking character. For a list of equipment slots see
- 'getequipid'.
- Only EQI_HAND_L and EQI_HAND_R normally make sense, since only weapons
- have a weapon level. You can, however, probably, use this field for other
- equippable custom items as a flag or something.
- If no item is equipped in this slot, or if it doesn't have a weapon level
- according to the database, 0 will be returned.
- switch (getequipweaponlv(EQI_HAND_R)) {
- case 1: mes "You are holding a lvl 1 weapon"; break;
- case 2: mes "You are holding a lvl 2 weapon"; break;
- case 3: mes "You are holding a lvl 3 weapon"; break;
- case 4: mes "You are holding a lvl 4 weapon"; break;
- case 5: mes "You are holding a lvl 5 weapon, hm, must be a custom design"; break;
- default: mes "Seems you don't have a weapon on"; break;
- }
- Or for the left hand, cause it can hold a weapon or a shield:
- if(getequipid(EQI_HAND_R)==0) goto L_NothingEquiped;
- switch (getequipweaponlv(EQI_HAND_L)) {
- case 0: mes "You are holding a shield, so it doesnt have a level"; break;
- case 1: mes "You are holding a lvl 1 weapon"; break;
- case 2: mes "You are holding a lvl 2 weapon"; break;
- case 3: mes "You are holding a lvl 3 weapon"; break;
- case 4: mes "You are holding a lvl 4 weapon"; break;
- case 5: mes "You are holding a lvl 5 weapon, hm, must be a custom design"; break;
- }
- close;
- L_NothingEquiped:
- mes "Seems you have nothing equiped";
- close;
- ---------------------------------------
- *getequippercentrefinery(<equipment slot>)
- This function calculates and returns the percent value chance to successfully
- refine the item found in the specified equipment slot of the invoking character
- by +1. There is no actual formula, the sucess rate for a given weapon level of
- a certain refine level is found in the db/refine_db.txt file. For a list of
- equipment slots see 'getequipid'.
- These values can be displayed for the player to see, or used to calculate the
- random change of a refine succeeding or failing and then going through with it
- (which is what the official NPC refinery scripts use it for)
- // This will find a random number from 0 - 99 and if that is equal to or more
- // than the value recoverd by this command it will go to L_Fail
- if (getequippercentrefinery(EQI_HAND_L)<=rand(100)) goto L_Fail;
- ---------------------------------------
- *getareadropitem("<map name>",<x1>,<y1>,<x2>,<y2>,<item>)
- This function will count all the items with the specified ID number lying on the
- ground on the specified map within the x1/y1-x2/y2 square on it and return that
- number.
- This is the only function around where a parameter may be either a string or a
- number! If it's a number, it means that only the items with that item ID number
- will be counted. If it is a string, it is assumed to mean the 'english name'
- field from the item database. If you give it an empty string, or something that
- isn't found from the item database, it will count items number '512' (apples).
- ---------------------------------------
- *getequipcardcnt(<equipment slot>)
- This function will return the number of cards that have been compounded onto a
- specific equipped item for the invoking character. See 'getequipid' for a list
- of possible equipment slots.
- ---------------------------------------
- *getinventorylist;
- This command sets a bunch of arrays with a complete list of whatever the
- invoking character has in their inventory, including all the data needed to
- recreate these items perfectly if they are destroyed. Here's what you get:
- @inventorylist_id[] - array of item ids.
- @inventorylist_amount[] - their corresponding item amounts.
- @inventorylist_equip[] - whether the item is equipped or not.
- @inventorylist_refine[] - for how much it is refined.
- @inventorylist_identify[] - whether it is identified.
- @inventorylist_attribute[] - whether it is broken.
- @inventorylist_card1[] - These four arrays contain card data for the items.
- @inventorylist_card2[] These data slots are also used to store names
- @inventorylist_card3[] inscribed on the items, so you can explicitly check
- @inventorylist_card4[] if the character owns an item made by a specific
- craftsman.
- @inventorylist_count - the number of items in these lists.
- This could be handy to save/restore a character's inventory, since no other
- command returns such a complete set of data, and could also be the only way to
- correctly handle an NPC trader for carded and named items who could resell them
- - since NPC objects cannot own items, so they have to store item data in
- variables and recreate the items.
- Notice that the variables this command generates are all local and numeric.
- ---------------------------------------
- *cardscnt()
- This function will return the number of cards inserted into the weapon currently
- equipped on the invoking character.
- While this function was meant for item scripts, it will work outside them:
- if (cardscnt()==4) mes "So you've stuck four cards into that weapon, think you're cool now?";
- ---------------------------------------
- *getrefine()
- This function will return the number of plusses the weapon currently equipped on
- the invoking character has been refined for.
- While this function was meant for item scripts, it will work outside them:
- if (getrefine()==10) mes "Wow. That's a murder weapon.";
- ---------------------------------------
- *getnameditem(<item id>,"<name to inscribe>");
- *getnameditem("<item name>","<name to inscribe>");
- This function is equivalent to using 'getitem', however, it will not just give
- the character an item object, but will also inscribe it with a specified
- character's name. You may not inscribe items with arbitrary strings, only with
- names of characters that actually exist. While this isn't said anywhere
- specifically, apparently, named items may not have cards in them, slots or no -
- these data slots are taken by the character ID who's name is inscribed. Only one
- remains free and it's not quite clear if a card may be there.
- This function will return 1 if an item was successfully created and 0 if it
- wasn't for whatever reason. Like 'getitem', this function will also accept an
- 'english name' from the item database as an item name and will return 0 if no
- such item exists.
- ---------------------------------------
- *getitemslots(<item ID>)
- This function will look up the item with the specified ID number in the database
- and return the number of slots this kind of items has - 0 if they are not
- slotted. It will also be 0 for all non-equippable items, naturally, unless
- someone messed up the item database. It will return -1 if there is no such item.
- ---------------------------------------
- *getiteminfo(<item ID>,<type>)
- This function will look up the item with the specified ID number in the database
- and return the info set by TYPE argument.
- It will return -1 if there is no such item.
- Valid types are:
- 0 - Buy Price; 1 - Sell Price; 2 - Item Type;
- 3 - maxchance (Max drop chance of this item e.g. 1 = 0.01% , etc..
- if = 0, then monsters don't drop it at all (rare or a quest item)
- if = 10000, then this item is sold in NPC shops only
- 4 - sex; 5 - equip; 6 - weight; 7 - atk; 8 - def; 9 - range;
- 10 - slot; 11 - look; 12 - elv; 13 - wlv;
- Check sample in nps\sample\getiteminfo.txt
- ---------------------------------------
- *getequipcardid (<equipment slot>,<card slot>);
- Returns value from equipped item slot in the indicated slot:
- getequipcardid(num,slot)
- where:
- num = equip position slot
- slot = 0,1,2,3 (Card Slot N)
- This func returns CARD ID, 255,254,-255 (for card 0, if the item is produced) it's useful
- when you want to check item cards or if it's signed. Useful for such quests as
- "Sign this refined item with players name" etc;
- Hat[0] +4 -> Player's Hat[0] +4
-
- ---------------------------------------
- *getitemslots (<item id>);
- Returns the amount of slots the item has.
- Example(s):
- //@slots now has the amount of slots of the item with ID 1205.
- set @slots, getItemSlots(1205);
-
- ---------------------------------------
- //
- 2,1.- End of item-related commands.
- //
- ---------------------------------------
- *getmapxy("<variable for map name>",<variable for x>,<variable for y>,<type>{,"<search string>"})
- This function will locate a character object, NPC object or pet's coordinates
- and place their coordinates into the variables specified when calling it. It
- will return 0 if the search was successful, and -1 if the parameters given were
- not variables or the search was not successful.
- Type is the type of object to search for:
- 0 - Character object
- 1 - NPC object
- 2 - Pet object
- 3 - Monster object.
-
- While 3 is meant to look for a monster object, no searching will be done if you
- specify type 3, and the function will always return -1.
- The search string is optional. If it is not specified, the location of the
- invoking character will always be returned for types 0 and 2, the location of
- the NPC running this function for type 1.
- If a search string is specified, for types 0 and 1, the character or NPC with
- the specified name will be located. If type is 3, the search will locate the
- current pet of the character who's name is given in the search string, it will
- NOT locate a pet by name.
- What a mess. Example, a working and tested one now:
- prontera,164,301,3%TAB%script%TAB%Meh%TAB%730,{
- mes "My name is Meh. I'm here so that Nyah can find me.";
- close;
- }
- prontera,164,299,3%TAB%script%TAB%Nyah%TAB%730,{
- mes "My name is Nyah.";
- mes "I will now search for Meh all across the world!";
- if (getmapxy(@mapname$,@mapx,@mapy,1,"Meh")!=0) goto Notfound;
- mes "And I found him on map "+@mapname$+" at X:"+@mapx+" Y:"+@mapy+" !";
- close;
- Notfound:
- mes "I can't seem to find Meh anywhere!";
- close;
- }
-
- Notice that NPC objects disabled with 'disablenpc' will still be located.
- ---------------------------------------
- *getgmlevel()
- This function will return the GM level of the account to which the invoking
- character belongs. If this is somehow executed from a console command, 99 will
- be returned, and 0 will be returned if the account has no GM level.
- This allows you to make NPC's only accessable for certain GM levels, or behave
- specially when talked to by GMs.
- if (getgmlevel()) mes "What is your command, your godhood?";
- if (getgmlevel()) goto Wherever;
- ---------------------------------------
- *gettimetick(<tick type>)
- This function will return the system time in UNIX epoch time (if tick type is 2)
- or the time since the start of the current day in seconds if tick type is 1.
- Passing 0 will make it return the server's tick, which is a measurement in
- milliseconds used by the server's timer system. The server's tick is an
- unsigned int which loops every ~50 days.
- Just in case you don't know, UNIX epoch time is the number of seconds elapsed
- since 1st of January 1970, and is useful to see, for example, for how long the
- character has been online with OnPCLoginEvent and OnPCLogoutEvent, which could allow
- you to make an 'online time counted for conviction only' jail script.
- ---------------------------------------
- *gettime(<type>)
- This function will return specified information about the current system time.
- 1 - Seconds (of a minute)
- 2 - Minutes (of an hour)
- 3 - Hour (of a day)
- 4 - Week day (0 for Sunday, 6 is Saturday)
- 5 - Day of the month.
- 6 - Number of the month.
- 7 - Year.
- 8 - Day of the year.
- It will only return numbers.
- if (gettime(4)==6) mes "It's a Saturday. I don't work on Saturdays.";
- ---------------------------------------
- *gettimestr(<format string>,<max length>)
- This function will return a string containing time data as specified by the
- format string.
- This uses the C function 'strfmtime', which obeys special format characters. For
- a full description see, for example, the description of 'strfmtime' at
- http://www.delorie.com/gnu/docs/glibc/libc_437.html
- All the format characters given in there should properly work.
- Max length is the maximum length of a time string to generate.
- The example given in eAthena sample scripts works like this:
- mes gettimestr("%Y-%m/%d %H:%M:%S",21);
-
- This will print a full date and time like 'YYYY-MM/DD HH:MM:SS'.
- ---------------------------------------
- *getusers(<type>)
- This function will return a number of users on a map or the whole server. What
- it returns is specified by Type.
- Type is a bitmask, add up to get the effects you want:
- 8 - This will count all characters on the same map as the current NPC.
- (By default, it will count people on the same map as the character)
- 7 - Return the amount of players for the entire server.
- (By default, only the players on the map will be counted.)
-
- So 'getusers(0)' will return the number of characters on the same map as the
- invoking character, while 'getusers(7)' will give the count for entire server.
- ---------------------------------------
- *getmapusers("<map name>")
- This function will return the number of users currently located on the specified
- map.
- Currently being used in the PVP scripts to check if a PVP room is full of not,
- if the number returned it equal to the maximum allowed it will not let you
- enter.
- ---------------------------------------
- *getareausers("<map name>",<x1>,<y1>,<x2>,<y2>)
- This function will return the count of connected characters which are located
- within the specified area - an x1/y1-x2/y2 square on the specified map.
- This is useful for maps that are split into many buildings, such as all the
- "*_in" maps, due to all the shops and houses.
- ---------------------------------------
- *getusersname;
- This command will give the invoking character a list of names of the connected
- characters (including themselves) into an NPC script message window (see 'mes')
- paging it by 10 names as if with the 'next' command.
- You need to put a 'close' after that yourself.
- ---------------------------------------
- \\
- 2,2.- Guild-related commands
- \\
- ---------------------------------------
- *getguildname(<guild id>)
- This function returns a guild's name given an ID number. If there is no such
- guild, "null" will be returned;
- // Would print what ever guild 10007 is, in my case this would return "AlcoROhics"
- mes "The guild "+GetGuildName(10007)+" are all nice people.";
- // This will do the same as above:
- set @var,10007;
- mes "We have some friends in "+GetGuildName(@var)+", you know.";
- This is used all over the WoE controlling scripts. You could also use it for a
- guild-based event.
- ---------------------------------------
- *getguildmaster(<guild id>)
- This function return the name of the master of the guild which has the specified
- ID number. If there is no such guild, "null" will be returned.
- // Would return the guild master of guild 10007, whatever that might be.
- // In this example it would return "MissDjax" cause she owns "AlcoROhics" (10007)
- mes getguildmaster(10007)+" runs "+getguildname(10007);
- Can be used to check if the character is the guildmaster of the specified guild.
- Maybe you want to make a room only guildmasters can enter:
- set @GID,getcharid(2);
- if(@GID==0) goto L_NoGuild;
- if(strcharinfo(0)==getguildmaster(@GID)) goto L_GuildMaster;
- mes "Sorry you don't own the guild you are in";
- close;
- L_NoGuild:
- mes "Sorry you are not in a guild";
- close;
- L_GuildMaster:
- mes "Welcome guild master of "+GetGuildName(@GID);
- close;
- ---------------------------------------
- *getguildmasterid(<guild id>)
- This function will return the character ID number of the guildmaster of the
- guild specified by the ID. 0 if the character is not a guildmaster of any guild.
- ---------------------------------------
- *getcastlename("<map name>")
- This function returns the name of the castle when given the map name for that
- castle. The data is read from 'db/castle_db.txt'.
- ---------------------------------------
- *getcastledata("<map name>",<type of data>)
- *setcastledata "<map name>",<type of data>,<value>;
- This function returns the castle ownership information for the castle referred
- to by it's map name. Castle information stored in 'save\castle.txt' for the TXT
- version of the server and in 'guild_castle' table for the SQL version.
- Valid types of data are:
- 0 - Will make the map server request the castle data from the char server, and
- always return 0. This, apparently, will also cause indirectly the execution
- of an 'OnAgitInit:' event mentioned at the beginning of this document.
- 1 - Guild ID
- 2 - Castle Economy score.
- 3 - Castle Defence score.
- 4 - Number of times the economy was invested in today.
- 5 - Number of times the defence was invested in today.
- 9 - Will return 1 if a Kafra was hired for this castle, 0 otherwise.
- 10 - Is 1 if the 1st guardian is present (Soldier Guardian)
- 11 - Is 1 if the 2nd guardian is present (Soldier Guardian)
- 12 - Is 1 if the 3rd guardian is present (Soldier Guardian)
- 13 - Is 1 if the 4th guardian is present (Archer Guardian)
- 14 - Is 1 if the 5th guardian is present (Archer Guardian)
- 15 - Is 1 if the 6th guardian is present (Knight Guardian)
- 16 - Is 1 if the 7th guardian is present (Knight Guardian)
- 17 - Is 1 if the 8th guardian is present (Knight Guardian)
- 18-25 types of data will return current hit point values for guardians 1-8
- respectively.
- The 'setcastledata' command will behave identically, but instead of returning
- values for the specified types of accessible data, it will alter them and cause
- them to be sent to the char server for storage. Data type of 0 won't do
- anything, obviously.
- ---------------------------------------
- *getgdskilllv(<guild id>,<skill id>)
- *getgdskilllv(<guild id>,"<skill name>")
- This function returns the level of the skill <skill id> of the guild <guild id>.
- If the guild does not have that skill, 0 is returned.
- If the guild does not exist, -1 is returned.
- Refer to 'db/skill_db.txt' for the full list of skills. (GD_* are guild skills)
- ---------------------------------------
- *requestguildinfo <guild id>,"<event label>";
- This command requests the guild data from the char server and merrily continues
- with the execution. Whenever the guild information becomes available (which
- happens instantly if the guild information is already in memory, or later, if it
- isn't and the map server has to wait for the char server to reply) it will run
- the specified event as in a 'doevent' call.
- ---------------------------------------
- *getmapguildusers <mapname>,<guild id>;
- Returns the amount of persons from the given guild that are on the given map.
- Example(s):
- //Will set the @persons variable to the amount of persons from the guild
- //which ID's = 10 and are at prontera.
- set @persons,getMapGuildUsers "prontera",10;
- ---------------------------------------
- //
- 2,2.- End of guild-related commands
- //
- ---------------------------------------
- *getskilllv(<skill id>)
- *getskilllv("<skill name>")
- This function returns the level of the specified skill that the invoking
- character has. If they don't have the skill, 0 will be returned. The full list
- of character skills is available in 'db/skill_db.txt'.
- There are two main uses for this function, it can check whether the character
- has a skill or not, and it can tell you if the level is high enough.
- Example 1:
- if (getskilllv(152)) goto L_HasSkillThrowStone;
- mes "You don't have Throw Stone";
- close;
- L_HasSkillThrowStone:
- mes "You have got the skill Throw Stone";
- close;
- Example 2:
- if (getskilllv(28) >= 5) goto L_HasSkillHeallvl5orMore;
- if (getskilllv(28) == 10) goto L_HasSkillHealMaxed;
- mes "You heal skill is below lvl 5";
- close;
- L_HasSkillHeallvl6orMore:
- mes "Your heal lvl is 5 or more";
- close;
- L_HasSkillHealMaxed:
- mes "Your heal lvl has been maxed";
- close;
- ---------------------------------------
- *getskilllist;
- This command sets a bunch of arrays with a complete list of skills the
- invoking character has. Here's what you get:
- @skilllist_id[] - skill ids.
- @skilllist_lv[] - skill levels.
- @skilllist_flag[] - see 'skill' for the meaning of skill flags.
- @skilllist_count - number of skills in the above arrays.
- While 'getskillv' is probably more useful for most situations, this is the
- easiest way to store all the skills and make the character something else for a
- while. Advanced job for a day? :) This could also be useful to see how many
- skills a character has.
- ---------------------------------------
- *getpetinfo(<type>)
- This function will return pet information for the pet the invoking character
- currently has active. Valid types are:
- 0 - Unique pet ID number as stored by the char server and distinguishing it
- from all other pets the characters actually have. This value is currently
- useless, at most you can use it to tell pets apart reliably.
- 1 - Pet class number as per 'db/pet_db.txt' - will tell you what kind of a pet it
- is.
- 2 - Pet name. Will return "null" if there's no pet.
- 3 - Pet friendly level (intimacy score). 1000 is full loyalty.
- 4 - Pet hungry level. 100 is completely full.
- 5 - Pet rename flag. 0 means this pet has not been named yet.
- ---------------------------------------
- *gethominfo(<type>)
- This function works as a direct counterpart of 'getpetinfo':
- 0 - Homunculus unique ID
- 1 - Homunculus Class
- 2 - Name
- 3 - Friendly level (intimacy score). 100000 is full loyalty.
- 4 - Hungry level. 100 is completely full.
- 5 - Rename flag. 0 means this homunculus has not been named yet.
- 6 - Homunculus level
- ---------------------------------------
- *petstat(<flag>)
- Returns current pet status, all are integers except name.
- Returns 0 or "" if the player doesn't have pets.
- Flags usable >>
- PET_CLASS
- PET_NAME
- PET_LEVEL
- PET_HUNGRY
- PET_INTIMATE
- Example:
- set @i, petstat(PET_CLASS);
- ---------------------------------------
- *getmonsterinfo(<mob ID>,<type>)
- This function will look up the monster with the specified ID number in the
- mob database and return the info set by TYPE argument.
- It will return -1 if there is no such monster (or the type value is invalid),
- or "null" if you requested the monster's name.
- Valid types are listed in const.txt:
- MOB_NAME 0 MOB_LV 1
- MOB_MAXHP 2 MOB_BASEEXP 3
- MOB_JOBEXP 4 MOB_ATK1 5
- MOB_ATK2 6 MOB_DEF 7
- MOB_MDEF 8 MOB_STR 9
- MOB_AGI 10 MOB_VIT 11
- MOB_INT 12 JOB_DEX 13
- MOB_LUK 14 MOB_RANGE 15
- MOB_RANGE2 16 MOB_RANGE3 17
- MOB_SIZE 18 MOB_RACE 19
- MOB_ELEMENT 20 MOB_MODE 21
- Check sample in nps\sample\getmonsterinfo.txt
- ---------------------------------------
- *getmobdrops(<mob id>)
- This command will find all drops of the specified mob and return the item IDs
- and drop percentages into arrays of temporary global variables.
- 'getmobdrops' returns 1 if successful and 0 if the mob ID doesn't exist.
- Upon executing this,
- $@MobDrop_item[] is a global temporary number array which contains the
- item IDs of the monster's drops.
- $@MobDrop_rate[] is a global temporary number array which contains the
- drop percentages of each item. (1 = .01%)
- $@MobDrop_count is the number of item drops found.
- Be sure to use $@MobDrop_count to go through the arrays, and not
- 'getarraysize', because the temporary global arrays are not cleared between
- runs of 'getmobdrops'. If a mob with 7 item drops is looked up, the arrays would
- have 7 elements. But if another mob is looked up and it only has 5 item drops,
- the server will not clear the arrays for you, overwriting the values instead. So
- in addition to returning the 5 item drops, the 6th and 7th elements from the
- last call remain, and you will get 5+2 item drops, of which the last 2 don't
- belong to the new mob. $@MobDrop_count will always contain the correct number
- (5), unlike 'getarraysize()' which would return 7 in this case.
- Example:
- // get a Mob ID from the user
- input .@mob_id;
-
- if (getmobdrops(.@mob_id)) { // 'getmobdrops' returns 1 on success
- // immediately copy global temporary variables into scope variables,
- // since we don't know when 'getmobdrops' will get called again for
- // another mob, overwriting your global temporary variables
- set .@count, $@MobDrop_count;
- copyarray .@item[0],$@MobDrop_item[0],.@count;
- copyarray .@rate[0],$@MobDrop_rate[0],.@count;
-
- mes getmonsterinfo(.@mob_id,MOB_NAME) + " - " + .@count + " drops found:";
- for( set .@i,0; .@i < .@count; set .@i,.@i +1 ) {
- mes .@item[.@i] + " (" + getitemname(.@item[.@i]) + ") " + .@rate[.@i]/100 + ((.@rate[.@i]%100 < 10) ? ".0":".") + .@rate[.@i]%100 + "%";
- }
- } else {
- mes "Unknown monster ID.";
- }
- close;
- ---------------------------------------
- *getmapmobs("<map name>")
- This function will return the total count of monsters currently located on the
- specified map. If the map name is given as "this", the map the invoking
- character is on will be used. If the map is not found, or the invoker is not a
- character while the map is "this", it will return -1.
- ---------------------------------------
- *getstrlen("<string>")
- This function will return the length of the string given as an argument. It is
- useful to check if anything input by the player exceeds name length limits and
- other length limits and asking them to try to input something else.
- ---------------------------------------
- *skillpointcount()
- Returns the total amount of skill points a character posesses (SkillPoint+SP's used in skills)
- This command can be used to check the currently attached characters total amount of skillpoints.
- This means the skillpoints used in skill are counted, and added to SkillPoints (number of skill points not used).
- Example:
- //This will set the temp character variable @skillPoints to the amount of skillpoints,
- //and then tell the player the value.
- set @skillPoints, skillPointCount();
- mes "You have "+@skillPoints+" skillpoints in total!";
-
- //Self-explanatory... :P
- if (skillPointCount() > 20)
- mes "Wow, you have more then 20 Skill Points in total!";
- ---------------------------------------
- *getscrate(<effect type>,<base rate>{,<target ID number>})
- This function will return the chance of a status effect affecting the invoking
- character, in percent, modified by the their current defense against said
- status. The 'base rate' is the base chance of the status effect being inflicted,
- in percent.
- if (rand(100) > getscrate(Eff_Blind, 50)) goto BlindHimNow;
-
- You can see the full list of available effect types you can possibly inflict in
- 'db/const.txt' under 'Eff_'.
- It is pretty certain that addressing the target by an ID number will not
- currently work due to a bug.
- ---------------------------------------
- ========================
- |3.- Checking commands.|
- ========================
- -------------------------
- *playerattached()
- Returns the ID of the player currently attached to the script. It will return
- 0 if noone is attached, or if the attached player no longer exists on the map
- server. It is wise to check for the attached player in script functions that
- deal with timers as there's no guarantee the player will still be logged on
- when the timer triggers. Note that the ID of a player is actually their
- account ID.
- ---------------------------------------
- *isloggedin(<account id>{,<char id>})
- This function returns 1 if the specified account is logged in and 0 if they
- aren't. You can also pass the char_id to check for both account and char id.
- ---------------------------------------
- *checkweight(<item id>,<amount>)
- *checkweight("<item name>",<amount>)
- This function will compute and return 1 if the total weight of a specified
- number of specific items does not exceed the invoking character's carrying
- capacity, and 0 otherwise. It is important to see if a player can carry the
- items you expect to give them, failing to do that may open your script up to
- abuse or create some very unfair errors.
- This function, in addition to checking to see if the player is capable of
- holding a set amount of items, also ensures the player has room in their
- inventory for the item(s) they will be receciving.
- Like 'getitem', this function will also accept an 'english name' from the
- database as an argument.
- checkweight(502,10) // 10 apples
- if (checkweight(502,10) == 0 ) goto L_OverWeight;
- getitem 502,10;
- close;
- L_OverWeight:
- mes "Sorry you cannot hold this ammount of apples";
- close;
- Or to put this another way:
- if (checkweight("APPLE",10)) goto L_Getapples;
- mes "Sorry you cannot hold this ammount of apples";
- close;
- L_Getapples:
- getitem 502,10;
- close;
- Both these examples have the same effect.
- ---------------------------------------
- *basicskillcheck()
- This function will return the state of the configuration option
- 'basic_skill_check' in 'battle_athena.conf'. It returns 1 if the option is
- enabled and 0 if it isn't. If the 'basic_skill_check' option is enabled, which
- it is by default, characters must have a certain number of basic skill levels to
- sit, request a trade, use emoticons, etc. Making your script behave differently
- depending on whether the characters must actually have the skill to do all these
- things might in some cases be required.
- ---------------------------------------
- *checkoption(<option number>)
- *checkoption1(<option number>)
- *checkoption2(<option number>)
- *setoption <option number>{,<flag>};
- The 'setoption' series of functions check for a so-called option that is set on
- the invoking character. 'Options' are used to store status conditions and a lot
- of other non-permanent character data of the yes-no kind. For most common cases,
- it is better to use 'checkcart','checkfalcon','checkpeco' and other similar
- functions, but there are some options which you cannot get at this way. They
- return 1 if the option is set and 0 if the option is not set.
- Option numbers valid for the first (option) version of this command are:
- 0x1 - Sight in effect.
- 0x2 - Hide in effect.
- 0x4 - Cloaking in effect.
- 0x8 - Cart number 1 present.
- 0x10 - Falcon present.
- 0x20 - Peco Peco present.
- 0x40 - GM Perfect Hide in effect.
- 0x80 - Cart number 2 present.
- 0x100 - Cart number 3 present.
- 0x200 - Cart number 4 present.
- 0x400 - Cart number 5 present.
- 0x800 - Orc head present.
- 0x1000 - The character is wearing a wedding sprite.
- 0x2000 - Ruwach is in effect.
- 0x4000 - Chasewalk in effect.
- 0x8000 - Flying or Xmas suit.
- 0x10000 - Sighttrasher.
- Option numbers valid for the second version (opt1) of this command are:
- 1 - Petrified.
- 2 - Frozen.
- 3 - Stunned.
- 4 - Sleeping.
- 6 - Petrifying (the state where you can still walk)
- Option numbers valid for the third version (opt2) of this command are:
- 0x1 - Poisoned.
- 0x2 - Cursed.
- 0x4 - Silenced.
- 0x8 - Signum Crucis (plays a howl-like sound effect, but otherwise no visible effects are displayed)
- 0x10 - Blinded.
- 0x80 - Deadly poisoned.
- Option numbers (except for opt1) are bitmasks - you can add them up to check
- for several states, but the functions will return true if at least one of them
- is in effect.
- 'setoption' will set options on the invoking character. There are no second and
- third versions of this command, so you can only change the values in the first
- list (cloak, cart, ruwach, etc). if flag is 1 (default when omitted),
- the option will be added to what the character currently has; if 0, the option is removed.
- This is definitely not a complete list of available option flag numbers. Ask a
- core developer (or read the source: src/map/status.h) for the full list.
- ---------------------------------------
- *setcart {<type>};
- *checkcart()
- If <type> is 0 this command will remove the cart from the character.
- Otherwise it gives the invoking character a cart. The cart given will be
- cart number <type> and will work regardless of whether the character is a
- merchant class or not.
- Note: the character needs to have the skill MC_PUSHCART to gain a cart
- The accompanying function will return 1 if the invoking character has a cart
- (any kind of cart) and 0 if they don't.
- if (checkcart()) mes "But you already have a cart!";
- ---------------------------------------
- *setfalcon {<flag>};
- *checkfalcon()
- If <flag> is 0 this command will remove the falcon from the character.
- Otherwise it gives the invoking character a falcon. The falcon will be there
- regardless of whether the character is a hunter or not. It will (probably) not
- have any useful effects for non-hunters though.
- Note: the character needs to have the skill HT_FALCON to gain a falcon
- The accompanying function will return 1 if the invoking character has a falcon
- and 0 if they don't.
- if (checkfalcon()) mes "But you already have a falcon!";
- ---------------------------------------
- *setriding {<flag>};
- *checkriding()
- If <flag> is 0 this command will remove the mount from the character.
- Otherwise it give the invoking character a PecoPeco (if they are a Knight
- series class) or a GrandPeco (if they are a Crusader seriesclass). Unlike
- 'setfalcon' and 'setcart' this will not work at all if they aren't of a class
- which can ride.
- Note: the character needs to have the skill KN_RIDING to gain a mount
- The accompanying function will return 1 if the invoking character is riding a
- bird and 0 if they don't.
- if (checkriding()) mes "PLEASE leave your bird outside! No riding birds on the floor here!";
- ---------------------------------------
- *checkvending ({"<player name>"})
- *checkchatting ({"<Player Name>"})
- If the player's name is given, this command checks for that player
- to be online and wether he/she is chatting or vending.
- When no name is given, the attached player is used for checking.
- Returns true or false (1 or 0) when the player is chatting/vending or not.
- Example(s):
- if (checkVending("Aaron")) mes "Aaron is currently vending!";
- //This will check if Aaron is vending, and if so, put a message in front
- //of the attached player saying Aaron is vending.
- if (checkChatting()) mes "You are currently chatting!";
- //This will check if you're in a chat room or not
-
- ---------------------------------------
- *agitcheck()
- *agitcheck2()
- These function will let you check whether the server is currently in WoE mode
- (or WoE SE mode if the second function is called) and will return 1 if War of
- Emperium is on and 0 if it isn't.
- ---------------------------------------
- *isnight()
- *isday()
- These functions will return 1 or 0 depending on whether the server is in night
- mode or day mode. 'isnight' returns 1 if it's night and 0 if it isn't, 'isday'
- the other way around. They can be used interchangeably, pick the one you like
- more:
- // These two are equivalent:
- if (isday()) mes "I only prowl in the night.";
- if (isnight()!=1) mes "I only prowl in the night.";
- ---------------------------------------
- \\
- 3,1.- Item-related commands
- \\
- ---------------------------------------
- *isequipped(<id>{,<id>{,<id>{,<id>}}})
- This function will return 1 if the invoking character has all of the item
- IDs given equipped (if card IDs are passed, then it checks if the cards are
- inserted into slots in the equipment they are currently wearing). Theorically
- there is no limit to the number of items that may be tested for at the same time.
- If even one of the items given is not equipped, 0 will be returned.
- // (Poring,Santa Poring,Poporing,Marin)
- if (isequipped(4001,4005,4033,4196)) mes "Wow! You're wearing a full complement of possible poring cards!";
- // (Poring)
- if (isequipped(4001)) mes "A poring card is useful, don't you think?";
-
- The function was meant for item scripts to support the cards released by Gravity
- in February 2005, but it will work just fine in normal NPC scripts.
- ---------------------------------------
- *isequippedcnt(<card id>{,<card id>{,<card id>{,<card id>}}})
- This function is similar to 'isequipped', but instead of 1 or 0, it will return
- the number of cards in the list given that were found on the invoking character.
- if (isequippedcnt(4001,4005,4033,4196)=4) mes "Finally got all four poring cards?";
- ---------------------------------------
- *checkequipedcard(<card id>)
- This function will return 1 if the card specified by it's item ID number is
- inserted into any equipment they have in their inventory, currently equipped or
- not.
- ---------------------------------------
- *getequipisidentify(<equipment slot>)
- This function will return 1 if an item in the specified equipment slot is
- identified and 0 if it isn't. Since you can't even equip unidentified equipment,
- there's a question of whether it can actually end up there, and it will normally
- return 1 all the time if there is an item in this equipment slot.
- Which is kinda pointless.
- For a list of equipment slots see 'getequipid'.
- ---------------------------------------
- //
- 3,1.- End of item-related commands
- //
- ---------------------------------------
- ==============================
- |4.- Player-related commands.|
- ==============================
- -------------------------
- *attachrid(<account ID>)
- *detachrid;
- A 'RID' is an ID of a character who caused the NPC script to run, as has been
- explained above in the introduction section. Quite a bit of commands want a RID
- to work, since they wouldn't know where to send information otherwise. And in
- quite a few cases the script gets invoked with a RID of zero (like through
- OnTime special labels). If an NPC script needs this, it can attach a specified
- character's id to itself. by calling the 'attachrid' function.
- 'attachrid' returns 1 if the character was found online and 0 if it wasn't.
- This could also be used, while running in a script invoked by a character
- through talking to an NPC, to mess with other characters.
- Detaching the RID will make the RID of the script zero.
- ---------------------------------------
- *rid2name(<rid>)
- Converts rid to name. Note: The player/monster/NPC must be online/enabled.
- Good for PCKillEvent where you can convert 'killedrid' to the name of the player.
- Note: rid2name may not produce correct character names since rid = account id.
- It will return the current online character of the account only.
- ---------------------------------------
- *message "<character name>","<message>";
- That command will send a message to the chat window of the character specified
- by name. The text will also appear above the head of that character. It will not
- be seen by anyone else.
- ---------------------------------------
- *dispbottom "<message>";
- This command will send the given message into the invoking character's chat
- window.
- ---------------------------------------
- *warp "<map name>",<x>,<y>;
- This command will take the invoking character to the specifed map, and if
- wanted, specified coordinates too, but these can be random.
- warp "place",50,55;
- This would take them to X 50 Y 55 on the map called "place". If your X and Y
- coordinates land on an unwalkable map square, it will send the warped character
- to a random place. Same will happen if they are both zero:
- warp "place",0,0;
- Notice that while warping people to coordinates 0,0 will normally get them into
- a random place, it's not certain to always be so. Darned if I know where this is
- actually coded, it might be that this happens because square 0,0 is unwalkable
- on all official maps. If you're using custom maps, beware.
- There are also three special 'map names' you can use.
- "Random" will warp the player randomly on the current map.
- "Save" and "SavePoint" will warp the player back to their savepoint.
- ---------------------------------------
- *areawarp "<from map name>",<x1>,<y1>,<x2>,<y2>,"<to map name>",<x3>,<y3>;
- This command is similar to 'warp', however, it will not refer to the invoking
- character, but instead, all characters within a specified area, defined by the
- x1/y1-x2/y2 square, will be warped. Nobody outside the area will be affected,
- including the activating character, if they are outside the area.
- areawarp "place",10,10,120,120,"place2",150,150;
- Everyone that is in the area between X 10 Y 10 and X 120 Y 120, in a square
- shape, on the map called "place", will be affected, and warped to "place2" X 150
- Y 150
- areawarp "place",10,10,120,120,"place2",0,0;
- By using ,0,0; as the destination coordinates it will take all the characters in
- the affected area to a random set of co-ordinates on "place2".
- Like 'warp', areawarp will also explicitly warp characters randomly into the
- current map if you give the 'to map name' as "Random".
- See also 'warp'.
- ---------------------------------------
-
- *warpparty "<mapname>",<x>,<y>,<party_id>;
-
- Warps a party to specified map and coordinate given the party ID, which you can get with
- getcharid(1). You can also request another party id given a member's name with getcharid(1,<player_name>).
- You can use the following "map names" for special warping behaviour:
- Random: All party members are randomly warped in their current map (as if they
- all used a fly wing)
- SavePointAll: All party members are warped to their respective save point.
- SavePoint: All party members are warped to the save point of the currently
- attached player (will fail if there's no player attached).
- Leader: All party members are warped to the leader's position. The leader must
- be online and in the current map-server for this to work.
- Example:
- mes "[Party Warper]";
- mes "Here you go!";
- close2;
- set @id,getcharid(1);
- warpparty "prontera",150,100,@id;
- close;
-
- ---------------------------------------
-
- *warpchar "<mapname>",<x>,<y>,<char_id>;
-
- Warps another player to specified map and coordinate given the char id, which you can get with
- getcharid(0,<player_name>). Obviously this is useless if you want to warp the same player that
- is executing this script, unless it's some kind of "chosen" script.
-
- Example:
-
- warpchar "prontera",150,100,20000001;
-
- ---------------------------------------
-
- *warpguild "<mapname>",<x>,<y>,<guild_id>;
-
- Warps a guild to specified map and coordinate given the guild id, which you can get with
- getcharid(2). You can also request another guild id given the member's name with getcharid(2,<player_name>).
-
- Example:
-
- warpguild "prontera",x,y,Guild_ID;
- ---------------------------------------
- *warppartner("<map name>",<x>,<y>);
- This function will find the invoking character's marriage partner, if any, and
- warp them to the map and coordinates given. Go kidnap that spouse. :) It will
- return 1 upon success and 0 if the partner is not online, the character is not
- married, or if there's no invoking character (no RID). 0,0 will, as usual,
- normally translate to random coordinates.
- ---------------------------------------
- *savepoint "<map name>",<x>,<y>;
- *save "<map name>",<x>,<y>;
- This command saves where the invoking character will return to upon
- 'return to save point', if dead or in some other cases. The two versions are
- equivalent. Map name, X coordinate and Y coordinate should be perfectly obvious.
- This ignores any and all map flags, and can make a character respawn where no
- teleportation is otherwise possible.
- savepoint "place",350,75;
- ---------------------------------------
- *heal <hp>,<sp>;
- This command will heal a set amount of HP and/or SP on the invoking character.
- heal 30000,0; // This will heal 30,000 HP
- heal 0,30000; // This will heal 30,000 SP
- heal 300,300; // This will heal 300 HP and 300 SP
- This command just alters the hit points and spell points of the invoking
- character and produces no other output whatsoever.
- ---------------------------------------
- *itemheal <hp>,<sp>;
- This command works on the invoking character like 'heal', however, it is not
- normally used in NPC scripts and will not work as expected there, but is used
- all over in item scripts.
- Unlike 'heal', which just alters hp/sp and doesn't do anything else at all, this
- command also shows healing animations for potions and other stuff, checks
- whether the potion was made by a famous alchemist and alters the amount healed,
- etc, etc. Since which kind of effect is shown depends on what item was used,
- using it in an NPC script will not have a desired effect.
- There is also a nice example on using this with the 'rand' function, to give you
- a random ammount of healing.
- // This will heal anything thing from 100 to 150 HP and no SP
- itemheal rand(100,150),0;
- ---------------------------------------
- *percentheal <hp>,<sp>;
- This command will heal the invoking character. It heals the character, but not
- by a set value - it adds percent of their maximum HP/SP.
- percentheal 100,0; // This will heal 100% HP
- percentheal 0,100; // This will heal 100% SP
- percentheal 50,50; // This will heal 50% HP and 50% SP
- So the amount that this will heal will depend on the total ammount of HP or SP
- you have maximum. Like 'heal', this will not call up any animations or effects.
- ---------------------------------------
- *recovery;
- This command will revive and restore full HP and SP to all characters currently
- connected to the server.
- ---------------------------------------
- *jobchange <job number>{,<upper flag>};
- This command will change the job class of the invoking character.
- jobchange 1; // This would change your player into a Swordman
- jobchange 4002; // This would change your player into a Swordman High
- This command does work with numbers, but you can also use job names. The full
- list of job names and the numbers they correspond to can be found in
- 'db/const.txt'.
- // This would change your player into a Swordman
- jobchange Job_Swordman;
- // This would change your player into a Swordman High
- jobchange Job_Swordman_High;
- 'upper flag' can alternatively be used to specify the type of job one changes
- to. For example, jobchange Job_Swordman,1; will change the character to a high
- swordsman. The upper values are:
- -1 (or when omitted): preserves the current job type.
- 0: Normal/standard classes
- 1: High/Advanced classes
- 2: Baby classes
- This command will also set a permanent character-based variable
- 'jobchange_level' which will contain the job level at the time right before
- changing jobs, which can be checked for later in scripts.
- ---------------------------------------
- *jobname (<job number>)
- This command retrieves the name of the given job using the msg_athena entries 550->650.
- mes "[Kid]";
- mes "I never thought I'd met a "+jobname(Class)+" here of all places.";
- close;
- ---------------------------------------
- *eaclass ({<job number>})
- This commands returns the "eA job-number" corresponding to the given class (if none is given, it returns uses
- the invoking player's class as argument). The eA job-number is also a class number system, but it's one that
- comes with constants which make it easy to convert among classes. The command will return -1 if you pass it a
- job number which doesn't has a eA Job value equivalent.
- set @eac, eaclass();
- if ((@eac&EAJ_BASEMASK) == EAJ_SWORDMAN)
- mes "You must be a swordman, knight, crusader, paladin, high swordman, lord knight, baby swordman,";
- mes "baby knight or baby crusader.";
- if (@eac&EAJL_UPPER)
- mes "You are a rebirth job.";
- if ((@eac&EAJ_UPPERMASK) == EAJ_SWORDMAN)
- mes "You must be a Swordman, Baby Swordman or High Swordman.";
- For more information on the eA Job System, see the docs/ea_job_system.txt file.
- ---------------------------------------
- *roclass <job number> {,<gender>}
- Does the opposite of eaclass. That is, given a eA Job class, it returns which is the corresponding RO class number.
- A gender is required because both Bard and Dancers share the same eA Job value (EAJ_BARDDANCER), if it isn't given, the
- gender of the executing player is taken (if there's no player running the script, male will be used by default).
- The command returns -1 when there isn't a valid class to represent the required job (for example, if you try to get the
- baby version of a Taekwon class).
- set @eac, eaclass();
- //Check if class is already rebirth
- if (@eac&EAJL_UPPER) {
- mes "You look strong.";
- close;
- }
- set @eac, roclass(@eac|EAJL_UPPER);
- //Check if class has a rebirth version
- if (@eac != -1) {
- mes "Bet you can't wait to become a "+jobname(@eac)+"!";
- close;
- }
- ---------------------------------------
- *changebase <job ID number>;
- This will change the appearance of the invoking character to that of a specified
- job class. Nothing but appearance will change. This command is used in item
- scripts for "Wedding Dress" and "Tuxedo" so the character like job 22, which is
- the job number of the wedding sprites.
- It would be entered in the equip bonus section of an item
- 2338,Wedding_Dress,Wedding Dress,5,43000,,500,,0,,0,119529470,7,0,16,,0,1,0,{ bonus bMdef,15; changebase 22; }
- This command only works when inside item scripts.
- ---------------------------------------
- *classchange <view id>,<type>;
- This command is very ancient, it's origins are clouded in mystery.
- It will send a 'display id change' packet to everyone in the immediate area of
- the NPC object, which will supposedly make the NPC look like a different sprite,
- an NPC sprite ID, or a monster ID. This effect is not stored anywhere and will
- not persist (Which is odd, cause it would be relatively easy to make it do so)
- and most importantly, will not work at all since this command was broken with
- the introduction of advanced classes. The code is written with the assumption
- that the lowest sprite IDs are the job sprites and the anything beyond them is
- monster and NPC sprites, but since the advanced classes rolled in, they got the
- ID numbers on the other end of the number pool where monster sprites float.
- As a result it is currently impossible to call this command with a valid view
- id. It will do nothing whatsoever if the view ID is below 4047. Getting it to
- run will actually just crash the client.
- It could be a real gem if it can be gotten to actually do what it's supposed to
- do, but this will only happen in a later SVN revision.
- ---------------------------------------
- *changesex;
- This command will change the gender for the attached character's account. If it
- was male, it will become female, if it was female, it will become male. The
- change will be written to the character server, the player will receive the
- message: "Need disconnection to perform change-sex request..." and the player
- will be immediately kicked to the login screen. When they log back in, they will
- be the opposite sex.
- If there are any Dancer/Gypsy or Bard/Clown characters on the account,
- they will also have their skills reset upon 'changesex'.
- ---------------------------------------
- *getexp <base xp>,<job xp>;
- This command will give the invoking character a specified number of base and job
- experience points. Can be used as a quest reward. Negative values won't work.
- getexp 10000,5000;
- You can also use the "set" command with the constants defined in 'db/const.txt':
- // These 2 combined has the same effect as the above command
- set BaseExp,BaseExp+10000;
- set JobExp,JobExp+5000;
- You can also reduce the ammount of experience points:
- set BaseExp,BaseExp-10000;
- Note that 'getexp' is now subject to the 'quest_exp_rate' config option, which
- adjusts the gained value. If you want to bypass this, use the 'set' method.
- ---------------------------------------
- *setlook <look type>,<look value>;
- *changelook <look type>,<look value>;
- 'setlook' will alter the look data for the invoking character. It is used
- mainly for changing the palette used on hair and clothes: you specify which look
- type you want to change, then the palette you want to use. Make sure you specify
- a palette number that exists/is usable by the client you use.
- 'changelook' works the same, but is only client side (it doesn't save the look value).
- // This will change your hair(6), so that it uses palette 8, what ever your
- // palette 8 is, your hair will use that colour
- setlook 6,8;
- // This will change your clothes(7), so they are using palette 1, whatever
- // your palette 1 is, your clothes will then use that set of colours.
-
- setlook 7,1;
- Here are the possible look types:
-
- 0 - Base sprite
- 1 - Hairstyle
- 2 - Weapon
- 3 - Head bottom
- 4 - Head top
- 5 - Head mid
- 6 - Hair color
- 7 - Clothes color
- 8 - Shield
- 9 - Shoes
- Whatever 'shoes' means is anybody's guess, ask Gravity - the client does nothing
- with this value. It still wants it from the server though, so it is kept, but
- normally doesn't do a thing.
-
- Only the look data for hairstyle, hair color and clothes color are saved to the
- char server's database and will persist. The rest freely change as the character
- puts on and removes equipment, changes maps, logs in and out and otherwise you
- should not expect to set them. In fact, messing with them is generally
- hazardous, do it at your own risk, it is not tested what will this actually do -
- it won't cause database corruption and probably won't cause a server crash, but
- it's easy to crash the client with just about anything unusual.
- However, it might be an easy way to quickly check for empty view IDs for
- sprites, which is essential for making custom headgear.
- Since a lot of people have different palettes for hair and clothes, it's
- impossible to tell you what all the colour numbers are. If you want a serious
- example, there is a Stylist script inside the default eAthena installation that
- you can look at, this may help you create a Stylist of your own:
- 'custom\dye.txt'
- ---------------------------------------
- \\
- 4,1.- Item-related commands
- \\
- ---------------------------------------
- *getitem <item id>,<amount>{,<account ID>};
- *getitem "<item name>",<amount>{,<account ID>};
- This command will give a specific amount of specified items to the target
- character. If the character is not online, nothing will happen.
- If <character ID> is not specified, items will be created in the invoking
- character inventory instead.
- In the first and most commonly used version of this command, items are
- referred to by their database ID number found inside 'db/item_db.txt'.
- getitem 502,10 // The person will receive 10 apples
- getitem 617,1 // The person will receive 1 Old Violet Box
- Giving an item ID of -1 will give a specified number of random items from the
- list of those that fall out of Old Blue Box. Unlike in all other cases, these
- will be unidentified, if they turn out to be equipment. This is exactly what's
- written in the Old Blue Box's item script.
- Other negative IDs also correspond to other random item generating item tables:
- Giving an item ID of -2 will produce the effects of Old Violet Box.
- Giving an item ID of -3 will produce the effects of Old Card Album.
- Giving an item ID of -4 will produce the effects of Gift Box.
- Giving an item ID of -5 will produce the effects of Worn Out Scroll, which, in
- current SVN, drops only Jellopies anyway.
- This transaction is logged if the log script generated transactions option is
- enabled.
- You may also create an item by it's name in the 'english name' field in the
- item database:
- getitem "RED_POTION",10;
- Which will do what you'd expect. If it can't find that name in the database,
- apples will be created anyway. It is often a VERY GOOD IDEA to use it like this.
- This is used in pretty much all NPC scripts that have to do with items and
- quite a few item scripts. For more examples check just about any official script.
- ---------------------------------------
- *getitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
- *getitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
- This command will give an amount of specified items to the invoking character.
- If an optional character ID is specified, and that character is currently
- online, items will be created in their inventory instead. If they are not
- online, nothing will happen. It works essentially the same as 'getitem' (it even
- works for negative ID numbers the same way, which is kinda silly) but is a lot
- more flexible, since it allows you to give the player an item altered with it's
- specific properties.
- Those parameters that are different from 'getitem' are:
- identify - Whether you want the item to be identified or not, 0 unidentified,
- 1 identified.
- refine - For how many plusses will it be refined.
- It will not let you refine an item higher than +10, if you
- specify more it'll still be 10.
- attribute - Whether the item is broken (1) or not (0) and NOT an elemental
- attribute.
- card1,2,3,4 - If you want a card compound to it, place the card ID number into
- the specific card slot. Card ID numbers also found in
- 'db/item_db.txt'
- Card1-card4 values are also used to store name information for named items, as
- well as the elemental property of weapons and armor. You can create a named item
- in this manner, however, if you just need a named piece of standard equipment,
- it is much easier to the 'getnameditem' function instead.
- You will need to keep these values if you want to destroy and then perfectly
- recreate a named item, for this see 'getinventorylist'.
- If you still want to try creating a named item with this command because
- 'getnameditem' won't do it for you cause it's too limited, you can do it like
- this. Careful, minor magic ahead.
- // First, let's get an ID of a character who's name will be on the item.
- // Only an existing character's name may be there.
- // Let's assume our character is 'Adam' and find his ID.
-
- set @charid,getcharid(0,"Adam");
- // Now we split the character ID number into two portions with a binary
- // shift operation. If you don't understand what this does, just copy it.
-
- set @card3, @charid & 65535;
- set @card4, @charid >> 16;
- // If you're inscribing non-equipment, @card1 must be 254.
- // Arrows are also not equipment. :)
- set @card1,254;
-
- // For named equipment, card2 means the Star Crumbs and elemental
- // crystals used to make this equipment. For everything else, it's 0.
-
- set @card2,0;
-
- // Now, let's give the character who invoked the script some
- // Adam's Apples:
-
- getitem2 512,1,1,0,0,@card1,@card2,@card3,@card4;
- This wasn't tested with all possible items, so I can't give any promises,
- experiment first before relying on it.
- To create equipment, continue this example it like this:
- // We've already have card3 and card4 loaded with correct
- // values so we'll just set up card1 and card2 with data
- // for an Ice Stiletto.
- // If you're inscribing equipment, @card1 must be 255.
- set @card1,255;
-
- // That's the number of star crumbs in a weapon.
- set @sc,2;
-
- // That's the number of elemental property of the weapon.
- set @ele,1;
- // And that's the wacky formula that makes them into
- // a single number.
- set @card2,@ele+((@sc*5)<<8);
- // That will make us an Adam's +2 VVS Ice Stiletto:
-
- getitem2 1216,1,1,2,0,@card1,@card2,@card3,@card4;
- Experiment with the number of star crumbs - I'm not certain just how much will
- work most and what it depends on. The valid element numbers are:
- 1 - Ice, 2 - Earth 3 - Fire 4 - Wind.
-
- You can, apparently, even create duplicates of the same pet egg with this
- command, creating a pet which is the same, but simultaneously exists in two
- eggs, and may hatch from either, although, I'm not sure what kind of a mess will
- this really cause.
- ---------------------------------------
- *getnameditem <item name|item id>,<Character name|character ID>;
- -Note: there's a total of 4 possible combinations of this command.
- E.g: item name and character name, or with character id, etc...
- Create a item signed with the given character's name.
- This is the same as using the hard(ly) explained way with getitem2.
- The command returns 1 when the item is created succesfully, or 0 when failed.
- Failure occurs when there is:
- - no player attached
- - Item name or ID is not valid
- - The given character ID/name is offline.
- Example:
- //This will give the currently attached player a Aaron's Apple (if Aaron is online).
- getnameditem "Apple","Aaron";
-
- //Self-explanatory (I hope).
- if (getnameitem("Apple","Aaron")) {
- mes "You now have a Aaron's Apple!";
- }
- ---------------------------------------
- *rentitem <item id>,<time>;
- *rentitem "<item name>",<time>;
- Creates a rental item in the attached character's inventory. The item will expire
- in <time> seconds and be automatically deleted. When receiving a rental item,
- the character will receive a message in their chat window. The character will
- also receive warning messages in their chat window before the item disappears.
- This command can not be used to rent stackable items. Rental items cannot be
- dropped, traded, sold to npcs, or placed in guild storage. (i.e. trade mask 75)
- Note: 'delitem' in an NPC script can still remove rental items.
- ---------------------------------------
- *makeitem <item id>,<amount>,"<map name>",<X>,<Y>;
- *makeitem "<item name>",<amount>,"<map name>",<X>,<Y>;
- This command will create an item lying around on a specified map in the
- specified location.
- itemid - Found in 'db/item_db.txt'
- amount - Amount you want produced
- map name - The map name
- X - The X coordinate
- Y - The Y coordinate.
- This item will still disappear just like any other dropped item. Like 'getitem',
- it also accepts an 'english name' field from the database and creates apples if
- the name isn't found.
- If the map name is given as "this", the map the invoking character is on will be used.
- ---------------------------------------
- *delitem <item id>,<amount>{,<account ID>};
- *delitem "<item name>",<amount>{,<account ID>};
- This command will take a specified amount of items from the invoking/target character.
- As all the item commands, this one uses the ID of the item found inside
- 'db/item_db.txt'. The items are destroyed - there is no way an NPC can simply
- own items and have an inventory of them, other as by destroying and recreating
- them when needed.
- delitem 502,10 // The person will lose 10 apples
- delitem 617,1 // The person will lose 1 Old Violet Box
- It is always a good idea to check if the player actually has the items before you delete them.
- If you try to delete more items that the player has, the player will lose the ones he/she has
- and the script will be terminated with an error.
- Like 'getitem' this command will also accept an 'english name' field from the
- database. If the name is not found, nothing will be deleted.
- ---------------------------------------
- *delitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
- *delitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
- This command will take a specified amount of items from the invoking/target character.
- Check 'getitem2' to understand its expanded parameters.
- ---------------------------------------
- *countitem(<item id>)
- *countitem("<item name>")
- This function will return the number of items for the specified item ID that the
- invoking character has in the inventory.
- mes "[Item Checker]";
- mes "Hmmm, it seems you have "+countitem(502)+" apples";
- close;
- Like 'getitem', this function will also accept an 'english name' from the
- database as an argument.
- If you want to state the number at the end of a sentence, you can do it by
- adding up strings:
- mes "[Item Checker]";
- mes "Hmmm, the total number of apples you are holding is "+countitem("APPLE");
- close;
-
- ---------------------------------------
- *countitem2(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>)
- *countitem2("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>)
- Expanded version of 'countitem' function, used for created/carded/forged items.
- This function will return the number of items for the specified item ID and
- other parameters that the invoking character has in the inventory.
- Check 'getitem2' to understand the arguments of the function.
-
- ---------------------------------------
- *groupranditem <group id>;
- Returns the item_id of a random item picked from the group specified. The
- different groups and their group number are specified in db/item_group_db.txt
- When used in conjunction with other functions, you can get a random item. For
- example, for a random pet lure:
- getitem groupranditem(15),1;
- ---------------------------------------
- *enable_items;
- *disable_items;
- These commands enable item usage while an npc is running. When enable_items is
- run, items can be used during scripts until disable_items is called.
- To avoid possible exploits, when enable_items is invoked, it will only enable
- item usage while running that script in particular. Note that if a different
- script also calls enable_items, it will override the last call (so you may
- want to call this command at the start of your script without assuming the
- effect is still in effect).
- ---------------------------------------
- *itemskill <skill id>,<skill level>;
- *itemskill "<skill name>",<skill level>;
- This is a command meant for item scripts to replicate single-use skills. It will
- not work properly in NPC scripts a lot of the time because casting a skill is
- not allowed when there is a message window or menu on screen. If there isn't one
- cause you've made sure to run this when they already closed it, it should work
- just fine and even show a targeting pointer if this is a targeting skill.
- // When you use Anodyne, you will cast Endure(8) level 1,
- // and "Endure" will appear above your head as you use it.
- 605,Anodyne,Anodyne,11,2000,0,100,,,,,10477567,2,,,,,{ itemskill 8,1; },{}
- ---------------------------------------
- *produce <item level>;
- This command will open a crafting window on the client connected to the invoking
- character. The 'item level' is a number which determines what kind of a crafting
- window will pop-up. You can see the full list of such item levels in
- 'db/produce_db.txt' which determines what can actually be produced.
- The window will not be empty only if the invoking character can actually produce
- the items of that type and has the appropriate raw materials in their inventory.
- Valid item levels are:
- 1 - Level 1 Weapons
- 2 - Level 2 Weapons
- 3 - Level 3 Weapons
- 16 - Blacksmith's Stones and Metals
- 32 - Alchemist's Potions
- 64 - Whitesmith's Coins
- 123 - Whitesmith's Nuggets
- 256 - Assassin Cross's Deadly Poison
- ---------------------------------------
- *successremovecards <equipment slot>;
- This command will remove all cards from the item found in the specified
- equipment slot of the invoking character, create new card items and give them to
- the character. If any cards were removed in this manner, it will also show a
- success effect.
- ---------------------------------------
- *failedremovecards <equipment slot>,<type>;
- This command will remove all cards from the item found in the specified
- equipment slot of the invoking character. 'type' determines what happens to the
- item and the cards:
- 0 - will destroy both the item and the cards.
- 1 - will keep the item, but destroy the cards.
- 2 - will keep the cards, but destroy the item.
-
- Whatever the type is, it will also show a failure effect on screen.
- ---------------------------------------
- *repair <broken item number>;
- This command repairs a broken peice of equipment, using the same list of broken
- items as available through 'getbrokenid'.
- The official scripts seem to use the repair command as a function instead:
- 'repair(<number>)' but it returns nothing on the stack. Probably only Valaris,
- who made it, can answer why is it so.
- ---------------------------------------
- *successrefitem <equipment slot>;
- This command will refine an item in the specified equipment slot of the invoking
- character by +1. For a list of equipment slots see 'getequipid'. This command
- will not only add the +1, but also display a 'refine success' effect on the
- character and put appropriate messages into their chat window. It will also give
- the character fame points if a weapon reached +10 this way, even though these
- will only take effect for blacksmith who will later forge a weapon.
- The official scripts seem to use the 'successrefitem' command as a function
- instead: 'successrefitem(<number>)' but it returns nothing on the stack.
- This is since jAthena, so probably nobody knows for sure why is it so.
- ---------------------------------------
- *failedrefitem <equipment slot>;
- This command will fail to refine an item in the specified equipment slot of the
- invoking character. The item will be destroyed. This will also display a 'refine
- failure' effect on the character and put appropriate messages into their chat
- window.
- The official scripts seem to use the 'failedrefitem' command as a function
- instead: 'failedrefitem(<number>)' but it returns nothing on the stack. This is
- since jAthena, so probably nobody knows for sure why is it so.
- ---------------------------------------
- *unequip <equipment slot>;
- This command will unequip whatever is currently equipped in the invoking
- character's specified equipment slot. For a full list of possible equipment
- slots see 'getequipid'.
- If an item occupies several equipment slots, it will get unequipped from all of
- them. (Which is a good thing.)
- ---------------------------------------
- *clearitem;
- This command will destroy all items the invoking character has in their
- inventory. (that includes equipped items) It will not affect anything else, like
- storage or cart.
- ---------------------------------------
- *equip <item id>;
- *autoEquip <item id>,<option>;
- These commands are to equip a equipment on the attached character.
- The equip function will equip the item ID given when the player has
- this item in his/her inventory, while the autoequip function will
- equip the given item ID when this is looted. The option parameter of
- the autoequip is 1 or 0, 1 to turn it on, and 0 to turn it off.
- Example(s):
- //This will equip a 1104 (falchion) on the character if this is in the inventory.
- equip 1104;
-
- //The invoked character will now automatically equip a falchion when it's looted.
- autoequip 1104,1;
-
- //The invoked character will no longer automatically equip a falchion.
- autoequip 1104,0;
- ---------------------------------------
- //
- 4,1.- End of item-related commands
- //
- ---------------------------------------
- *openstorage;
- This will open a character's Kafra storage window on the client connected to the
- invoking character. It does not check wherever it is run from, so you can allow
- any feasible NPC to open a kafra storage. (It's not certain whether this works
- in item scripts, but if it does, it could be interesting.)
- The storage window might not open if a message box or a trade deal is present on
- screen already, so you should at least make sure the message box is closed
- before you open storage.
- mes "I will now open your stash for you";
- close2;
- openstorage;
- end;
- ---------------------------------------
- *openmail;
- This will open a character's Mail window on the client connected to the
- invoking character.
- mes "Close this window to open your mail inbox.";
- close2;
- openmail;
- end;
- ---------------------------------------
- *openauction;
- This will open the Auction window on the client connected to the invoking character.
- mes "Close this window to open the Auction window.";
- close2;
- openauction;
- end;
- ---------------------------------------
- \\
- 4,2.- Guild-related commands
- \\
- ---------------------------------------
- *guildopenstorage()
- This function works the same as 'openstorage' but will open a guild storage
- window instead for the guild storage of the guild the invoking character belongs
- to. This is a function because it returns a value - 0 if the guild storage was
- opened successfully and 1 if it wasn't. (Notice, it's a ZERO upon success.)
- Since guild storage is only accessible to one character at one time, it may fail
- if another character is accessing the guild storage at the same time.
- This will also fail and return 2 if the character does not belong to any guild.
- ---------------------------------------
- *guildchangegm(<guild id>,<new master's name>)
- This function will change the Guild Master of a guild. The ID is the guild's
- id, and the new guildmaster's name must be passed.
- Returns 1 on success, 0 otherwise.
- ---------------------------------------
- *guildgetexp <amount>;
- This will give the specified amount of guild experience points to the guild the
- invoking character belongs to. It will silently fail if they do not belong to
- any guild.
- ---------------------------------------
- *guildskill <skill id>,<level>
- *guildskill "<skill name>",<level>
- This command will bump up the specified guild skill by the specified number of
- levels. This refers to the invoking character and will only work if the invoking
- character is a member of a guild AND it's guildmaster, otherwise no failure
- message will be given and no error will occur, but nothing will happen - same
- about the guild skill trying to exceed the possible maximum. The full list of
- guild skills is available in 'db/skill_db.txt', these are all the GD_ skills at
- the end.
- The flag parameter is currently not functional and it's a mystery of what it
- would actually do. (Though probably, like for character skills, it would allow
- temporary bumping.) Using this command will bump the guild skill up permanently.
- // This would give your character's guild one level of Approval (GD_APPROVAL ID
- // 10000). Notice that if you try to add two levels of Approval, or add
- // Approval when the guild already has it, it will only have one level of
- // Approval afterwards.
- guildskill 10000,1,0;
- You might want to make a quest for getting a certain guild skill, make it hard
- enough that all the guild needs to help or something. Doing this for the Glory
- of the Guild skill, which allows your guild to use an emblem, is a good idea for
- a fun quest. (Wasting a level point on that is really annoying :D)
- ---------------------------------------
- //
- 4,2 End of guild-related commands.
- //
- ---------------------------------------
- *resetlvl <action type>;
- This is a character reset command, meant mostly for rebirth script supporting
- Advanced jobs, which will reset the invoking character's stats and level
- depending on the action type given. Valid action types are:
- 1 - Base level 1, Job level 1, 0 skill points, 0 base xp, 0 job xp, wipes the
- status effects (only the ones settable by 'setoption'), sets all stats to 1.
- If the new job is 'Novice High', give 100 status points, give First Aid and
- Play Dead skills.
- 2 - Base level 1, Job level 1, 0 skill points, 0 base xp, 0 job xp.
- Skills and attribute values are not altered.
- 3 - Base level 1, base xp 0. Nothing else is changed.
- 4 - Job level 1, job xp 0. Nothing else is changed.
- In all cases it will also unequip everything the character has on.
- Even though it doesn't return a value, it is used as a function in the official
- rebirth scripts. Ask AppleGirl why.
- ---------------------------------------
- *resetstatus;
- This is a character reset command, which will reset the stats on the invoking
- character and give back all the stat points used to raise them previously.
- Nothing will happen to any other numbers about the character.
- Used in reset NPC's (duh!)
- ---------------------------------------
- *resetskill;
- This command takes off all the skill points on the invoking character, so they
- only have Basic Skill blanked out (lvl 0) left, and returns the points for them
- to spend again. Nothing else will change but the skills. Quest skills will also
- reset if 'quest_skill_reset' option is set to Yes in 'battle_athena.conf'. If
- the 'quest_skill_learn' option is set in there, the points in the quest skills
- will also count towards the total.
- Used in reset NPC's (duh!)
- ---------------------------------------
- *sc_start <effect type>,<ticks>,<extra argument>{,<target ID number>};
- *sc_start2 <effect type>,<ticks>,<extra argument>,<percent chance>{,<target ID number>};
- *sc_start4 <effect type>,<ticks>,<value 1>,<value 2>,<value 3>,<value 4>{,<target ID number>};
- *sc_end <effect type>{,<target ID number>};
- These command bestow a status effect on the invoking character. This command is
- used a lot in the item scripts.
- // This would poison them for 10 min
- sc_start SC_Poison,600000,0;
- Effect type is a number of effect, 'db/const.txt' lists the common (mostly
- negative) status effect types as constants, starting with 'SC_'. You can also
- use this to give someone an effect of a player-cast spell:
- // This will bless someone as if with Bless 10:
- sc_start 10,240000,10;
-
- Extra argument's meaning differs depending on the effect type, for most effects
- caused by a player skill the extra argument means the level of the skill that
- would have been used to create that effect, for others it might have no meaning
- whatsoever. You can actually bless someone with a 0 bless spell level this way,
- which is fun, but weird.
- The target ID number, if given, will cause the status effect to appear on a
- specified character, instead of the one attached to the running script. This has
- not been properly tested.
- 'sc_start2' is perfectly equivalent, but unlike 'sc_start', a status change
- effect will only occur with a specified percentage chance. 10000 given as the
- chance is equivalent to a 100% chance, 0 is a zero.
- 'sc_start4' is just like sc_start, however it takes four parameters for the
- status change instead of one. What these values are depends on the status
- change in question. For example, elemental armor defense takes the following
- four values:
- - val1 is the first element, val2 is the resistance to the element val1.
- - val3 is the second element, val4 is the resistance to said element.
- eg: sc_start4 SC_DefEle,60000,Ele_Fire,20,Ele_Water,-15;
- 'sc_end' will remove a specified status effect. If SC_All is used (-1), it will
- do a complete removal of all statuses (although permanent ones will re-apply).
- You can see the full list of status effects caused by skills in
- 'src/map/status.h' - they are currently not fully documented, but most of that
- should be rather obvious.
- ---------------------------------------
- *skilleffect <skill id>,<number>;
- *skilleffect "<skill name>",<number>;
- This command will display the visual and sound effects of a specified skill (see
- 'db/skill_db.txt' for a full list of skills) on the invoking character's sprite.
- Nothing but the special effects and animation will happen. If the skill's normal
- effect displays a floating number, the number given will float up.
- // This will heal the character with 2000 hp, buff with
- // Bless 10 and Increase AGI 5, and display appropriate
- // effects.
- mes "Blessed be!";
- skilleffect 28,2000;
- heal 2000,0;
- skilleffect 34,0;
- // That's bless 10.
- sc_start 10,240000,10;
- skilleffect 29,0;
- // That's agi 5
- sc_start 12,140000,5;
- ---------------------------------------
- *npcskilleffect <skill id>,<number>,<x>,<y>;
- *npcskilleffect "<skill name>",<number>,<x>,<y>;
- This command behaves identically to 'skilleffect', however, the effect will not
- be centered on the invoking character's sprite, nor on the NPC sprite, if any,
- but will be centered at map coordinates given on the same map as the invoking
- character.
- ---------------------------------------
- *specialeffect <effect number>{,<send_target>};
- This command will display special effect with the given number, centered on the
- specified NPCs coordinates, if any. For a full list of special effect numbers
- known see 'doc/effect_list.txt'. Some effect numbers are known not to work in
- some client releases. (Notably, rain is absent from any client executables
- released after April 2005.)
- ---------------------------------------
- *specialeffect2 <effect number>{,<send_target>};
- This command behaves identically to the 'specialeffect', but the effect will be
- centered on the invoking character's sprite.
- ---------------------------------------
- *statusup <stat>;
- This command will bump a specified stat of the invoking character up by one
- permanently. Stats are to be given as number, but you can use these constants to
- replace them:
- bStr - Strength
- bVit - Vitality
- bInt - Intelligence
- bAgi - Agility
- bDex - Dexterity
- bLuk - Luck
- ---------------------------------------
- *statusup2 <stat>,<amount>;
- This command will bump a specified stat of the invoking character up by the
- specified amount permanently. The amount can be negative. See 'statusup'.
- // This will decrease a character's Vit forever.
- statusup bVit,-1;
- ---------------------------------------
- *bonus <bonus type>,<val1>;
- *bonus2 <bonus type>,<val1>,<val2>;
- *bonus3 <bonus type>,<val1>,<val2>,<val3>;
- *bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>;
- *bonus5 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5>;
- These commands are meant to be used in item scripts. They will probably work
- outside item scripts, but the bonus will not persist for long. They, as
- expected, refer only to an invoking character.
- You can find the full list of possible bonuses and which command to use for each
- kind in 'doc/item_bonus.txt'.
- ---------------------------------------
- *autobonus <bonus script>,<rate>,<duration>{,<flag>,{<other script>}};
- *autobonus2 <bonus script>,<rate>,<duration>{,<flag>,{<other script>}};
- *autobonus3 <bonus script>,<rate>,<duration>,<skill id>,{<other script>};
- *autobonus3 <bonus script>,<rate>,<duration>,"<skill name>",{<other script>};
- These commands are meant to be used in item scripts. They will probably work
- outside item scripts, but the bonus will not persist for long. They, as
- expected, refer only to an invoking character.
- What these commands do is 'attach' a script to the player which will get
- executed on attack (or when attacked in the case of autobonus2).
- Rate is the trigger rate of the script (1000 = 100%).
- Duration is the time that the bonus will last for since the script has triggered.
- The optional argument 'flag' is used to classify the type of attack where the script
- can trigger (it shares the same flags as the bAutoSpell bonus script):
- Range criteria:
- BF_SHORT: Trigger on melee attack
- BF_LONG: Trigger on ranged attack
- Default: BF_SHORT+BF_LONG
- Attack type criteria:
- BF_WEAPON: Trigger on weapon skills
- BF_MAGIC: Trigger on magic skills
- BF_MISC: Trigger on misc skills
- Default: BF_WEAPON
- Skill criteria:
- BF_NORMAL: Trigger on normal attacks
- BF_SKILL: Trigger on skills
- default: If the attack type is BF_WEAPON (only) BF_NORMAL is used,
- otherwise BF_SKILL+BF_NORMAL is used.
- The difference between the optional argument 'other script' and the 'bonus script' is that,
- the former one triggers only when attacking(or attacked) and the latter one runs on
- status calculation as well, which makes sure, within the duration, the "bonus" that get
- lost on status calculation is restored. So, 'bonus script' is technically supposed to accept
- "bonus" command only. And we usually use 'other script' to show visual effects.
- In all cases, when the script triggers, the attached player will be the one
- who holds the bonus. There is currently no way of knowing within this script
- who was the other character (the attacker in autobonus2, or the target in
- autobonus and autobonus3).
- //Grants a 1% chance of starting the state "all stats +10" for 10 seconds when
- //using weapon or misc attacks (both melee and ranged skills) and shows a special
- //effect when the bonus is active.
- autobonus "{ bonus bAllStats,10; }",10,10000,BF_WEAPON|BF_MISC,"{ specialeffect2 EF_FIRESPLASHHIT; }";
- ---------------------------------------
- *skill <skill id>,<level>{,<flag>};
- *skill "<skill name>",<level>{,<flag>};
- *addtoskill <skill id>,<level>{,<flag>};
- *addtoskill "<skill name>",<level>{,<flag>};
- These commands will give the invoking character a specified skill. This is also
- used for item scripts.
- Level is obvious. Skill id is the ID number of the skill in question as per
- 'db/skill_db.txt'. It is not known for certain whether this can be used to give
- a character a monster's skill, but you're welcome to try with the numbers given
- in 'db/mob_skill_db.txt'.
- Flag is 0 if the skill is given permanently (will get written with the character
- data) or 1 if it is temporary (will be lost eventually, this is meant for card
- item scripts usage.). The flag parameter is optional, and defaults to 1 in
- 'skill' and to 2 in 'addtoskill'.
- Flag 2 means that the level parameter is to be interpreted as a stackable
- additional bonus to the skill level. If the character did not have that skill
- previously, they will now at 0+the level given.
- // This will permanently give the character Stone Throw (TF_THROWSTONE,152), at
- // level 1.
- skill 152,1,0;
- ---------------------------------------
- *nude;
- This command will unequip anything equipped on the invoking character.
- It is not required to do this when changing jobs since 'jobchange' will unequip
- everything not equippable by the new job class anyway.
- ---------------------------------------
- *disguise <Monster ID>;
- *undisguise;
- This command disguises the current player with a monster sprite.
- The disguise lasts until 'undisguise' is issued or the player logs out.
- Example:
- disquise 1002; //Yay! You're a Poring!!!
- next;
- undisquise; //Yay!!!! You're a human again!!
- ---------------------------------------
- \\
- 4,3 Marriage-related commands
- \\
- ---------------------------------------
- *marriage("<spouse name>");
- This function will marry two characters, the invoking character and the one
- referred to by name given, together, setting them up as each other's marriage
- partner. No second function call has to be issued (in current SVN at least) to
- make sure the marriage works both ways. The function returns 1 upon success, or
- 0 if the marriage could not be completed, either because the other character
- wasn't found or because one of the two characters is already married.
- This will do nothing else for the marriage except setting up the spouse ID for
- both of these characters. No rings will be given and no effects will be shown.
- ---------------------------------------
- *wedding;
- This command will call up wedding effects - the music and confetti - centered on
- the invoking character. Example can be found in the wedding script.
- ---------------------------------------
- *divorce()
- This function will un-marry the invoking character from whoever they were
- married to. Both will no longer be each other's marriage partner, (at least in
- current SVN, which prevents the cases of multi-spouse problems). It will return
- 1 upon success or 0 if the character was not married at all.
- This function will also destroy both wedding rings and send a message to both
- players, telling them they are now divorced.
- ---------------------------------------
- *adopt "<parent name>","<parent name>","<novice name>";
- *adopt("<parent name>","<parent name>","<novice name>")
- This command will set up a novice as a baby of a married couple. All three are
- referred to by character name. The correct variables are set on all three
- characters in the same call. The command will unequip anything the novice has
- equipped and make them a Job_Baby class, as well as send them a 'your job has
- been changed' message.
- Beware of calling this from inside a 'callfunc' function, cause upon successful
- adoption, this command returns a zero, as if it were a function. This is likely
- to screw up execution of a 'return' command. You may try to call it as a
- function instead, but it doesn't return anything upon an error, which may also
- cause script execution to throw up errors.
- Nothing will happen (and nothing will be returned either) if either future
- parent is below base level 70 and/or if any of the three characters is not found
- online.
- ---------------------------------------
- //
- 4,3.- End of marriage-related commands
- //
- ---------------------------------------
- *pcfollow <id>,<target id>;
- *pcstopfollow <id>;
- Makes a character follow or stop following someone. This command does the same as the @follow command.
- The main difference is that @follow can use character names, and this commands needs the Account ID for the target.
- Example(s):
- //This will make Aaron follow Bullah, when both of these characters are online.
- PCFollow getCharID(3,"Aaron"),getCharID(3,"Bullah");
-
- //Makes Aaron stop following whoever he is following.
- PCStopFollow getCharID(3,"Aaron");
-
- ---------------------------------------
- *pcblockmove <id>,<option>;
- Prevents the given ID from moving when the option != 0, 0 enables the ID to move again.
- ID should be able to be GID of a monster/npc or AID from a character.
- Example(s):
- //prevents the current char from moving away;
- pcblockmove getcharid(3),1;
-
- //enables the current char to move again.
- pcblockmove getcharid(3),0;
- ---------------------------------------
- ==================================
- |5.- Mob / NPC -related commands.|
- ==================================
- ---------------------------------------
- *monster "<map name>",<x>,<y>,"<name to show>",<mob id>,<amount>{,"<event label>"};
- *areamonster "<map name>",<x1>,<y1>,<x2>,<y2>,"<name to show>",<mob id>,<amount>{,"<event label>"};
- This command will spawn a monster on the specified coordinates on the specified
- map. If the script is invoked by a character, a special map name, "this", will
- be recognised to mean the name of the map the invoking character is located at.
- This command works fine in the item scripts.
- The same command arguments mean the same things as described above in the
- beginning of this document when talking about permanent monster spawns. Monsters
- spawned in this manner will not respawn upon being killed.
- Unlike the permanent monster spawns, if the mob id is -1, a random monster will
- be picked from the entire database according to the rules configured in the
- server for dead branches. This will work for all other kinds of non-permanent
- monster spawns.
- The only very special thing about this command is an event label, which is an
- optional parameter. This label is written like '<NPC object name>::<label name>'
- and upon the monster being killed, it will execute the script inside of the
- specified NPC object starting from the label given. The RID of the player
- attached at this execution will be the RID of the killing character.
- monster "place",60,100,"Poring",1002,1,"NPCNAME::OnLabel";
- If you do not specify any event label, a label in the NPC object that ran this
- command, called 'OnMyMobDead:' will execute anyway, if present.
- The coordinates of 0,0 will spawn the monster on a random place on the map.
- The 'areamonster' command works much like the 'monster' command and is not
- significantly different, but spawns the monsters within a square defined by
- x1/y1-x2/y2.
- Simple monster killing script:
- <Normal NPC object definition. Let's assume you called him NPCNAME.>
- mes "[Summon Man]";
- mes "Want to start the kill?";
- next;
- menu "Yes",L_Yes,"No",-;
- mes "[Summon Man]";
- mes "Come back later";
- close;
- L_Yes:
- monster "prontera",0,0,"Quest Poring",1002,10,"NPCNAME::OnPoringKilled";
- // By using 0,0 it will spawn them in a random place.
- mes "[Summon Man]";
- mes "Now go and kill all the Poring I summoned";
- // He summoned ten.
- close;
- OnPoringKilled:
- set $PoringKilled,$PoringKilled+1;
- if ($PoringKilled==10) goto L_AllDead;
- end;
- L_AllDead:
- announce "Summon Man: Well done all the poring are dead",3;
- set $PoringKilled,0;
- end;
- For more good examples see just about any official 2-1 or 2-2 job quest script.
- ---------------------------------------
- *areamobuseskill "<map name>",<x>,<y>,<range>,<mob id>,<skill id>,<skill level>,<cast time>,<cancelable>,<emotion>,<target type>;
- *areamobuseskill "<map name>",<x>,<y>,<range>,<mob id>,"<skill name>",<skill level>,<cast time>,<cancelable>,<emotion>,<target type>;
- This command will make all monsters of the specified mob ID in the specified
- area use the specified skill. Map name, x, and y define the center of the area,
- which extending <range> cells in each direction (ex: a range of 3 would create
- a 7x7 square). The skill can be specified by skill ID or name. <cast time> is in
- milliseconds (1000 = 1 second), and the rest should be self-explanatory.
- <target type> can be:
- 0 = self
- 1 = the mob's current target
- 2 = the mob's master
- 3 = random target
- Example:
- // spawn 1 Shining Plant in the 5x5 area centered on (155,188)
- areamonster "prontera",153,186,157,190,"Shining Plant",1083,1;
- // make the plant cast level 10 Cold Bolt on a random target
- areamobuseskill "prontera",155,188,2,1083,"MG_COLDBOLT",10,3000,1,e_gg,3;
- ---------------------------------------
- *killmonster "<map name>","<event label>"{,<type>};
- This command will kill all monsters that were spawned with 'monster' or
- 'addmonster' and have a specified event label attached to them. Commonly used to
- get rid of remaining quest monsters once the quest is complete.
- If the label is given as "All", all monsters which have their respawn times set
- to -1 (like all the monsters summoned with 'monster' or 'areamonster' script
- command, and all monsters summoned with GM commands, but no other ones - that
- is, all non-permanent monsters) on the specified map will be killed regardless
- of the event label value.
- As of r12876 killmonster now supports an optional argument type. Using 1 for type
- will make the command fire "OnMyMobDead" events from any monsters that do die
- as a result of this command.
- ---------------------------------------
- *killmonsterall "<map name>"{,<type>};
- This command will kill all monsters on a specified map name, regardless of how
- they were spawned or what they are. As of r12873, The behavior has changed slightly.
- In light of a label behavior fix for mob spawning commands that will now allow the label to
- trigger when there is no player, killmonsterall has also been modified to support this.
- Using this the normal/old way means labels dont trigger when a player didn't
- attack/kill a monster. This is because it breaks compatability with older scripts if
- forced to use the new method. However, if you wish to use the new label type with this
- command, simply use 1 for type. Any other number won't be recognized.
- ---------------------------------------
- *strmobinfo(<type>,<monster id>);
- This function will return information about a monster record in the database, as
- per 'db/mob_db.txt'. Type is the kind of information returned. Valid types are:
- 1 - 'english name' field in the database, a string.
- 2 - 'japanese name' field in the database, a string.
- All other returned values are numbers:
- 3 - Level.
- 4 - Maximum HP.
- 5 - Maximum SP.
- 6 - Experience reward.
- 7 - Job experience reward.
- ---------------------------------------
- *mobcount("<map name>","<event label>")
- This function will count all the monsters on the specified map that have a given
- event label and return the number or 0 if it can't find any. Naturally, only
- monsters spawned with 'monster' and 'areamonster' script commands can be like
- this.
- However, apparently, if you pass this function an empty string for the event
- label, it should return the total count of normal permanently respawning
- monsters instead. With the current dynamic mobs system, where mobs are not kept
- in memory for maps with no actual people playing on them, this will return a 0
- for any such map.
- ---------------------------------------
- *clone "<map name>",<x>,<y>,"<event>",<char id>{,<master_id>{,<mode>{,<flag>,<duration>}}}
- This command creates a monster which is a copy of another player. The first
- four arguments serve the same purpose as in the monster script command, The
- <char id> is the character id of the player to clone (player must be online).
- If <master id> is given, the clone will be a 'slave/minion' of it. Master_id
- must be a character id of another online player.
- The mode can be specified to determine the behaviour of the clone, it's
- values are the same as the ones used for the mode field in the mob_db. The
- default mode is aggressive, assists, can move, can attack.
- Flag can be either zero or one currently. If zero, the clone is a normal
- monster that'll target players, if one, it is considered a summoned monster,
- and as such, it'll target other monsters. Defaults to zero.
- The duration specifies how long the clone will live before it is auto-removed.
- Specified in seconds, defaults to no limit (zero).
- Returned value is the monster ID of the spawned clone. If command fails,
- returned value is zero.
- ---------------------------------------
- *summon "Monster name",<monster id>{,<Time Out>{,"event label"}};
- This command will summon a monster. (see also 'monster') Unlike monsters spawned
- with other commands, this one will set up the monster to fight to protect the
- invoking character. Monster name and mob id obey the same rules as the one given
- at the beginning of this document for permanent monster spawns with the
- exceptions mentioned when describing 'monster' command.
- The effect for the skill 'Call Homonuculus' will be displayed centered on the
- invoking character.
- Timeout is the time in milliseconds the summon lives, and is set default
- to 60000 (1 minute). Note that also the value 0 will set the timer to default,
- and it is not possible to create a spawn that lastst forever.
- If an event label is given, upon the monster being killed, the event label will
- run as if by 'donpcevent'.
- // Will summon a dead branch-style monster to fight for the character.
- summon "--ja--",-1;
- ---------------------------------------
- *homevolution;
- This command will try to evolve the current player's homunculus.
- If it doesn't work, the /swt emoticon is shown.
- To evolve a homunculus, the invoking player must have a homunculus,
- the homunculus must not be the last evolution and
- the homunculus must be on at least 91000/100000 intimacy with it's owner.
- ---------------------------------------
- *unitwalk <GID>,<x>,<y>;
- *unitwalk <GID>,<mapid>;
- This is one command, but can be used in two ways. If only the first argument is given,
- the unit whose GID is given will start walking towards the map with the given mapid
- (we believe these are the mapindexes found in db/map_index.txt).
- When 2 arguments are passed, the given unit will walk to the given x,y coordinates on
- the map where the unit currently is.
- Example(s):
- //Will move/walk the poring we made to the coordinates 150,150
- unitwalk .GID,150,150;
- //Will move the poring towards alberta (if my assumed mapindexes are correct).
- unitwalk .GID,3;
- ---------------------------------------
- *unitkill <GID>;
- *unitwarp <GID>,<Mapname>,<x>,<y>;
- *unitattack <GID>,<Target ID>;
- *unitstop <GID>;
- *unittalk <GID>,<Text>;
- *unitemote <GID>,<Emote>;
- Okay, these commands should be fairly self explaining.
- For the emotions, you can look in db/const.txt for prefixes with e_
- ---------------------------------------
- *disablenpc "<NPC object name>";
- *enablenpc "<NPC object name>";
- These two commands will disable and enable, respectively, an NPC object
- specified by name. The disabled NPC will disappear from sight and will no longer
- be triggerable in the normal way. It is not clear whether it will still be
- accessible through 'donpcevent' and other triggering commands, but it probably
- will be. You can disable even warp NPCs if you know their object names, which is
- an easy way to make a map only accessible through walking half the time. Then
- you 'enablenpc' them back.
- You can also use these commands to create the illusion of an NPC switching
- between several locations, which is often better than actually moving the NPC -
- create one NPC object with a visible and a hidden part to their name, make a few
- copies, and then disable all except one.
- ---------------------------------------
- *hideonnpc "<NPC object name>";
- *hideoffnpc "<NPC object name>";
- These commands will make the NPC object specified display as hidden/visible,
- even though not actually disabled per se. Hidden as in thief Hide skill, but
- unfortunately, not detectable by Ruwach or Sight.
- As they are now, these commands are pointless, it is suggested to use
- 'disablenpc'/'enablenpc', because these two commands actually unload the NPC
- sprite location and other accompanying data from memory when it is not used.
- However, you can use these for some quest ideas (such as cloaking npcs talking
- while hidden then revealing.... you can wonder around =P
- ---------------------------------------
- *doevent "<NPC object name>::<event label>";
- This command will start a new execution thread in a specified NPC object at the
- specified label. The execution of the script running this command will not stop.
- No parameters may be passed with a doevent call.
- The script of the NPC object invoked in this manner will run as if it's been
- invoked by the RID that was active in the script that issued a 'doevent'.
- place,100,100,1%TAB%script%TAB%NPC%TAB%53,{
- mes "This is what you will see when you click me";
- close;
- Label:
- mes "This is what you will see if the doevent is activated";
- close;
- }
- ....
- doevent "NPC::Label";
- ---------------------------------------
- *donpcevent "{NPC NAME}::<event label>";
- This command is kinda confusing cause it performs in two completely different
- ways.
- If the event label is phrased like "::<label name>", all NPC objects that have a
- specified label in them will be invoked as if by a 'doevent', but no RID
- whatsoever will be attached while they execute.
- Otherwise, if the label is given as "<NPC name>::<label name>", a label within
- the NPC object that runs this command will be called, but as if it was running
- inside another, specified NPC object. No RID will be attached to it in this case
- either.
- This can be used for making another NPC react to an action that you have done
- with the NPC that has this command in it, i.e. show an emotion, or say
- something.
- place,100,100,1%TAB%script%TAB%NPC%TAB%53,{
- mes "Hey NPC2 copy what I do";
- close2;
- set @emo, rand(1,30);
- donpcevent "NPC2::Emo";
- Emo:
- emotion @emo;
- end;
- }
- place,102,100,1%TAB%script%TAB%NPC2%TAB%53,{
- mes "Hey NPC copy what I do";
- close2;
- set @emo, rand(1,30);
- donpcevent "NPC::Emo";
- Emo:
- emotion @emo;
- end;
- }
- This will make both NPC perform the same random emotion from 1 to 30, and the
- emotion will appear above each of their heads.
- ---------------------------------------
- *cmdothernpc "<npc name>","<command>";
- This is simply "donpcevent <npc name>::OnCommand<command>".
- It is an approximation of official server script language's 'cmdothernpc'.
- ---------------------------------------
- *npctalk "<message>";
- This command will display a message to the surrounding area as if the NPC object
- running it was a player talking - that is, above their head and in the chat
- window. The display name of the NPC will get appended in front of the message to
- complete the effect.
- // This will make everyone in the area see the NPC greet the character
- // who just invoked it.
- npctalk "Hello "+strcharinfo(0)+" how are you";
- ---------------------------------------
- *setnpcdisplay("<npc name>", "<display name>", <class id>, <size>)
- *setnpcdisplay("<npc name>", "<display name>", <class id>)
- *setnpcdisplay("<npc name>", "<display name>")
- *setnpcdisplay("<npc name>", <class id>)
- Changes the display name and/or display class of the target npc.
- Returns 0 is successful, 1 if the npc does not exist.
- Size is 0 = normal 1 = small 2 = big.
- Since trunk r11779
- ---------------------------------------
- \\
- 5,1.- Time-related commands
- \\
- ---------------------------------------
- *addtimer <ticks>,"<NPC object name>::<label>";
- *deltimer "<NPC object name>::<event label>";
- *addtimercount <ticks>,"<NPC object name>::<event label>";
- These commands will create and manage a player-based timer: 'addtimer' to
- create, 'deltimer' to destroy and 'addtimercount' to delay it by the specified
- number of ticks. For all three cases, the event label given is the identifier of
- that timer. A player can have multiple timers running at the same time, and
- there can even be multiple timers referencing the same label.
- When this timer runs out, a new execution thread will start in the specified NPC
- object at the specified label, and the script will run attached to that player.
- If the specified label is not found, the map server will happily print an error.
- The ticks are given in 1/1000ths of a second.
- One more thing. These timers are stored as part of player data. If the player
- logs out, all of these get immediately deleted, without executing the script.
- If this behavior is undesirable, use some other timer mechanism (like 'sleep').
- Example 1:
- <NPC Header> {
- dispbottom "Starting a 5 second timer...";
- addtimer 5000, strnpcinfo(3)+"::On5secs";
- end;
- On5secs:
- dispbottom "5 seconds have passed!";
- end;
- }
- ---------------------------------------
- *initnpctimer{ "<NPC name>" {, <Attach Flag>} } |
- { "<NPC name>" | <Attach Flag> };
- *stopnpctimer{ "<NPC name>" {, <Detach Flag>} } |
- { "<NPC name>" | <Detach Flag> };
- *startnpctimer{ "<NPC name>" {, <Attach Flag>} } |
- { "<NPC name>" | <Attach Flag> };
- *setnpctimer <tick>{,"<NPC name>"};
- *getnpctimer(<type of information>{,"<NPC name>"})
- *attachnpctimer {"<character name>"};
- *detachnpctimer {"<NPC name>"};
- This set of commands and functions will create and manage an NPC-based timer.
- The NPC name may be omitted, in which case the calling NPC is used as target.
- Contrary to addtimer/deltimer commands which let you have many different timers
- referencing different labels in the same NPC, each with their own countdown,
- 'initnpctimer' can only have one per NPC object. But it can trigger many labels
- and let you know how many were triggered already and how many still remain.
- This timer is counting up from 0 in ticks of 1/1000ths of a second each. Upon
- creating this timer, the execution will not stop, but will happily continue
- onward. The timer will then invoke new execution threads at labels
- "OnTimer<time>:" in the NPC object it is attached to.
- To create the timer, use the 'initnpctimer', which will start it running.
- 'stopnpctimer' will pause the timer, without clearing the current tick, while
- 'startnpctimer' will let the paused timer continue.
- By default timers do not have a RID attached, which lets them continue even
- if the player that started them logs off. To attach a RID to a timer, you can
- either use the optional "attach flag" when using 'initnpctimer/startnpctimer',
- or do it manually by using 'attachnpctimer'. Likewise, the optional flag of
- stopnpctimer lets you detach any RID after stopping the timer, and by using
- 'detachnpctimer' you can detach a RID at any time.
- Normally there is only a single timer per NPC, but as an exception, as long as
- you attach a player to the timer, you can have multiple timers running at once,
- because these will get stored on the players instead of the NPC.
- NOTE: You need to attach the RID before the timer _before_ you start it to
- get a player-attached timer. Otherwise it'll stay a NPC timer (no effect).
- If the player that is attached to the npctimer logs out, the "OnTimerQuit:"
- event label of that npc will be triggered, so you can do the appropiate
- cleanup (the player is still attached when this event is triggered).
- The 'setnpctimer' command will explicitly set the timer to a given tick.
- 'getnpctimer' provides timer information. Its parameter defines what type:
- 0 - Will return the current tick count of the timer.
- 1 - Will return 1 if there are remaining "OnTimer<ticks>:" labels in the
- specified NPC waiting for execution.
- 2 - Will return the number of times the timer has triggered and will trigger
- an "OnTimer<tick>:" label in the specified NPC.
- Example 1:
- <NPC Header> {
- initnpctimer;
- npctalk "I cant talk right now, give me 10 seconds";
- end;
- OnTimer5000:
- npctalk "Ok 5 seconds more";
- end;
- OnTimer6000:
- npctalk "4";
- end;
- OnTimer7000:
- npctalk "3";
- end;
- OnTimer8000:
- npctalk "2";
- end;
- OnTimer9000:
- npctalk "1";
- end;
- OnTimer10000:
- stopnpctimer; // This command is indeed not neccessary here because timer automaticly stopped due to no remaining events.
- mes "[Man]";
- mes "Ok we can talk now";
- }
- Example 2:
- OnTimer15000:
- npctalk "Another 15 seconds have passed.";
- initnpctimer; // You have to use 'initnpctimer' instead of 'setnpctimer 0'.
- // This is equal to 'setnpctimer 0' + 'startnpctimer'.
- // Alternatively, you can also insert another 'OnTimer15001' label so that the timer won't stop.
- end;
-
- // This OnInit label will run when the script is loaded, so that the timer
- // is initialised immediately as the server starts. It is dropped back to 0
- // every time the NPC says something, so it will cycle continiously.
- OnInit:
- initnpctimer;
- end;
- Example 3:
- mes "[Man]";
- mes "I have been waiting "+(getnpctimer(0)/1000)+" seconds for you";
- // we divide the timer returned by 1000 cause it will be displayed in
- // milliseconds otherwise
- close;
- Example 4:
- mes "[Man]";
- mes "Ok I will let you have 30 sec more";
- close2;
- setnpctimer (getnpctimer(0)-30000);
- // Notice the 'close2'. If there were a 'next' there the timer would be
- // changed only after the player pressed the 'next' button.
- end;
-
- ---------------------------------------
-
- *sleep {<milliseconds>};
- *sleep2 {<milliseconds>};
- *awake "<NPC name>";
- These commands are used to control the pause of a NPC.
- sleep and sleep2 will pause the script for the given amount of milliseconds.
- Awake is used to cancel a sleep. When awake is callen on a NPC it will run as
- if the sleep timer ran out, and thus making the script continue. Sleep and sleep2
- basically do the same, but the main difference is that sleep will not keep the rid,
- while sleep2 does.
- Examples:
- sleep 10000; //pause the script for 10 seconds and ditch the RID (so no player is attached anymore)
- sleep2 5000; //pause the script for 5 seconds, and continue with the RID attached.
- awake "NPC"; //Cancels any running sleep timers on the NPC 'NPC'.
- ---------------------------------------
- //
- 5,1.- End of time-related commands
- //
- *announce "<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}}};
- This command will broadcast a message to all or most players, similar to
- @kami/@kamib GM commands.
- announce "This will be shown to everyone at all in yellow.",0;
- The region the broadcast is heard in (target), source of the broadcast
- and the color the message will come up as is determined by the flags.
- The flag values are coded as constants in db/const.txt to make them easier to use.
- Target flags:
- - bc_all: Broadcast message is sent server-wide (default).
- - bc_map: Message is sent to everyone in the same map as the source of the broadcast (see below).
- - bc_area: Message is sent to players in the vecinity of the source.
- - bc_self: Message is sent only to current player.
- You cannot use more than one target flag.
- Source flags:
- - bc_pc: Broadcast source is the attached player (default).
- - bc_npc: Broadcast source is the NPC, not the player attached to the script
- (useful when a player is not attached or the message should be sent to those
- nearby the npc).
- You cannot use more than one source flag.
- Special flags:
- - bc_yellow: Broadcast will be displayed in yellow color (default).
- - bc_blue: Broadcast will be displayed in blue color.
- - bc_woe: Indicates that this broadcast is 'WoE Information' that can be disabled client-side.
- Due to the way client handles broadcasts, it is impossible to set both bc_blue and bc_woe.
- The optional parameters allow usage of broadcasts in custom colors, font-weights, sizes etc.
- If any of the optional parameters is used, special flag is ignored.
- Optional parameters may not work well (or at all) depending on a game client used.
- The color parameter is a single number which can be in hexadecimal notation.
- For example:
- announce "This will be shown to everyone at all in green.",bc_all,0x00FF00;
- Will display a global announce in green. The color format is in RGB (0xRRGGBB).
- In official scripts only two font-weights (types) are used:
- - normal (FW_NORMAL = 400, default),
- - bold (FW_BOLD = 700).
- Default font size is 12.
- Using this for private messages to players is probably not that good an idea,
- but it can be used instead in NPCs to "preview" an announce.
- // This will be a private message to the player using the NPC that made the
- // announcement
- announce "This is my message just for you",bc_blue|bc_self;
- // This will be shown on everyones screen that is in sight of the NPC.
- announce "This is my message just for you people here",bc_npc|bc_area;
- ---------------------------------------
- *mapannounce "<map name>","<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}}};
- This command will work like 'announce' but will only broadcast to characters
- currently residing on the specified map. The flag and optional paramaters
- parameters are the same as in 'announce', but target and source flags are ignored.
- ---------------------------------------
- *areaannounce "<map name>",<x1>,<y1>,<x2>,<y2>,"<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}}};
- This command works like 'announce' but will only broadcast to characters
- residing in the specified x1/y1-x2/y2 rectangle on the map given. The flags and
- optional parameters are the same as in 'announce', but target and source flags are ignored.
- areaannounce "prt_church",0,0,350,350,"God's in his heaven, all right with the world",0;
- ---------------------------------------
- *callshop "<name>",<option>;
- These are a series of commands used to create dynamic shops.
- The callshop function calls a invisible shop (view -1) as if the player clicked on it.
- For the options on callShop:
- 0 = The normal window (buy, sell and cancel)
- 1 = The buy window
- 2 = The sell window
-
- Example(s):
- callshop "DaShop",1; //Will call the shop named DaShop and opens the buy menu.
- The shop which is called by callshop (as long as an npcshop* command is executed
- from that NPC (see note 1)) will trigger the labels OnBuyItem and OnSellitem. These
- labels can take over handling for relatively the buying of items from the shop
- and selling the items to a shop. Via these labels you can customize the way an item
- is bought or sold by a player.
- In the OnBuyItem, two arrays are set (@bought_nameid and @bought_quantity), which
- hold information about the name id (item id) sold and the amount sold of it. Same
- goes for the OnSellItem label, only the variables are named different
- (@sold_nameid and @sold_quantity). An example on a shop comes with eAthena, and
- can be found in the npc/sample/npc_dynamic_shop.txt file.
-
- This example shows how to use the labels and their set variables to create a dynamic shop.
- Note 1: These labels will only be triggered if a npcshop* command is executed, this is
- because these commands set a special data on the shop npc,named master_nd in the source.
- The OnSellItem and OnBuyItem are triggered in the NPC whose master_nd is given in the shop.
- This was found out thanks to 'Hondacrx', noticing the OnBuyItem wasn't triggered unless
- npcshopitem was used. After rechecking the source, I found what caused this.
- ---------------------------------------
- *npcshopitem "<name>",<item id>,<price>{,<item id>,<price>{,<item id>,<price>{,...}}}
- This command lets you override the contents of an existing npc shop. The
- current sell list will be wiped, and only the items specified with the price
- specified will be for sale.
- The function returns 1 if shop was updated successfully, or 0 if not found.
- Note that you cannot use -1 to specify default selling price!
- ---------------------------------------
- *npcshopadditem "<name>",<item id>,<price>{,<item id>,<price>{,<item id>,<price>{,...}}}
- This command will add more items at the end of the selling list for the
- specified npc shop. If you specify an item already for sell, that item will
- appear twice on the sell list.
- The function returns 1 if shop was updated successfully, or 0 if not found.
- Note that you cannot use -1 to specify default selling price!
- ---------------------------------------
- *npcshopdelitem "<name>",<item id>{,<item id>{,<item id>{,...}}}
- This command will remove items from the specified npc shop.
- If the item to remove exists more than once on the shop, all instances will be
- removed.
- Note that the function returns 1 even if no items were removed. The return
- value is only to confirm that the shop was indeed found.
- ---------------------------------------
- *npcshopattach "<name>"{,<flag>}
- This command will attach the current script to the given npc shop.
- When a script is attached to a shop, the events "OnBuyItem" and "OnSellItem"
- of your script will be executed whenever a player buys/sells from the shop.
- Additionally, the arrays @bought_nameid[], @bought_quantity[] or @sold_nameid[]
- and @sold_quantity[] will be filled up with the items and quantities
- bought/sold.
- The optional parameter specifies whether to attach ("1") or detach ("0") from
- the shop (the default is to attach). Note that detaching will detach any npc
- attached to the shop, even if it's from another script, while attaching will
- override any other script that may be already attached.
- The function returns 0 if the shop was not found, 1 otherwise.
- ---------------------------------------
- *waitingroom "<chatroom name>",<limit>{,<event label>,<trigger>};
- This command will create a chat room, owned by the NPC object running this
- script and displayed above the NPC sprite.
- The maximum length of a chatroom name is 60 letters.
- The limit is the maximum number of people allowed to enter the chat room. If the
- optional event and trigger parameters are given, the event label
- ("<NPC object name>::<label name>") will be invoked as if with a 'doevent' upon
- the number of people in the chat room reaching the given triggering amount.
- It's funny, but for compatibility with jAthena, you can swap the event label and
- the trigger parameters, and it will still work.
- // The NPC will just show a box above its head that says "Hello World", clicking
- // it will do nothing, since the limit is zero.
- waitingroom "Hello World",0;
- // The NPC will have a box above its head, it will say "Disco - Waiting Room"
- // and will have 8 waiting slots. Clicking this will enter the chat room, where
- // the player will be able to wait until 8 people accumulate. Once this happens,
- // it will cause the NPC "Bouncer" run the label "OnStart"
- waitingroom "Disco - Waiting Room",8,"Bouncer::OnStart",8;
- Creating a waiting room does not stop the execution of the script and it will
- continue to the next line.
- For more examples see the 2-1 and 2-2 job quest scripts which make extensive use
- of waiting rooms.
- ---------------------------------------
- *delwaitingroom {"<NPC object name"};
- This command will delete a waiting room. If no parameter is given, it will
- delete a waiting room attached to the NPC object running this command, if it is,
- it will delete a waiting room owned by another NPC object. This is the only way
- to get rid of a waiting room, nothing else will cause it to disappear.
- It's not clear what happens to a waiting room if the NPC is disabled with
- 'disablenpc', by the way.
- ---------------------------------------
- *enablewaitingroomevent {"<NPC object name>"};
- *disablewaitingroomevent {"<NPC object name>"};
- *enablearena;
- *disablearena;
- This will enable and disable triggering the waiting room event (see
- 'waitingroom') respectively. Optionally giving an NPC object name will do that
- for a specified NPC object. The chat room will not disappear when triggering is
- disabled and enabled in this manner and players will not be kicked out of it.
- Enabling a chat room event will also cause it to immediately check whether the
- number of users in it exceeded the trigger amount and trigger the event
- accordingly.
- Normally, whenever a waiting room was created to make sure that only one
- character is, for example, trying to pass a job quest trial, and no other
- characters are present in the room to mess up the script.
- The 'enablearena'/'disablearena' commands are just aliases with no parameter.
- These are supposedly left here for compatibility with official server scripts,
- but no eathena script uses these at the moment.
- ---------------------------------------
- *getwaitingroomstate(<information type>{,"<NPC object name>"})
- This function will return information about the wating room state for the
- attached waiting room or for a waiting room attached to the specified NPC if
- any.
- The valid information types are:
- 0 - Number of users currently chatting.
- 1 - Maximum number of users allowed.
- 2 - Will return 1 if the waiting room has a trigger set.
- 0 otherwise.
- 3 - Will return 1 if the waiting room is currently disabled.
- 0 otherwise.
- 4 - The Title of the waiting room (string)
- 5 - Password of the waiting room, if any. Pointless, since there is no way to
- set a password on a waiting room right now.
- 16 - Event name of the waiting room (string)
- 32 - Whether or not the waiting room is full.
- 33 - Whether the amount of users in the waiting room is higher than the trigger
- number.
- ---------------------------------------
- *warpwaitingpc "<map name>",<x>,<y>{,<number of people>};
- This command will warp the amount of characters equal to the trigger number of
- the waiting room chat attached to the NPC object running this command to the
- specified map and coordinates, kicking them out of the chat. Those waiting the
- longest will get warped first. It can also do a random warp on the same map
- ("Random" instead of map name) and warp to the save point ("SavePoint").
- The list of characters to warp is taken from the list of the chat room members.
- Those not in the chat room will not be considered even if they are talking to
- the NPC in question. If the number of people is given, exactly this much people
- will be warped.
- This command can also keep track of who just got warped. It does this by setting
- special variables:
- $@warpwaitingpc[] is an array containing the character id numbers of the
- characters who were just warped.
- $@warpwaitingpcnum contains the number of the character it just warped.
- See also 'getpartymember' for advice on what to do with those variables.
- The obvious way of using this effectively would be to set up a waiting room for
- two characters to be warped onto a random PVP map for a one-on-one duel, for
- example.
- ---------------------------------------
- *kickwaitingroomall {"<NPC object name>"};
- This command would kick everybody out of a specified waiting room chat. IF it
- was properly linked into the script interpreter which it isn't, even though the
- code for it is in place. Expect this to become available in upcoming SVN
- releases.
- ---------------------------------------
- *setmapflagnosave "<map name>","<alternate map name>",<x>,<y>;
- This command sets the 'nosave' flag for the specified map and also gives an
- alternate respawn-upon-relogin point.
- It does not make a map impossible to make a savepoint on as you would normally
- think, 'savepoint' will still work. It will, however, make the specified map
- kick the reconnecting players off to the alternate map given to the coordinates
- specified.
- ---------------------------------------
- *setmapflag "<map name>",<flag>;
- This command marks a specified map with a map flag given. Map flags alter the
- behavior of the map, you can see the list of the available ones in
- 'db/const.txt' under 'mf_'.
- The map flags alter the behavior of the map regarding teleporting (mf_nomemo,
- mf_noteleport, mf_nowarp, mf_nogo), storing location when disconnected
- (mf_nosave), dead branch usage (mf_nobranch), penalties upon death
- (mf_nopenalty, mf_nozenypenalty), PVP behavior (mf_pvp, mf_pvp_noparty,
- mf_pvp_noguild), WoE behavior (mf_gvg,mf_gvg_noparty), ability to use
- skills or open up trade deals (mf_notrade, mf_novending, mf_noskill, mf_noicewall),
- current weather effects (mf_snow, mf_fog, mf_sakura, mf_leaves, mf_rain, mf_clouds,
- mf_fireworks) and whether day/night will be in effect on this map (mf_indoors).
- ---------------------------------------
- *removemapflag "<map name>",<flag>;
- This command removes a mapflag from a specified map.
- See 'setmapflag' for a list of mapflags.
- ---------------------------------------
- *getmapflag("<map name>",<flag>)
- This command checks the status of a given mapflag and returns the mapflag's state.
- 0 means OFF, and 1 means ON. See 'setmapflag' for a list of mapflags.
- ---------------------------------------
- *setbattleflag "<battle flag>",<value>;
- *getbattleflag("<battle flag>")
- Sets or gets the value of the given battle flag.
- Battle flags are the flags found in the battle/*.conf files and is also used in Lupus' variable rates script.
- Example(s):
- //will set the base experience rate to 20x (2000%)
- setBattleFlag "base_exp_rate",2000;
-
- //will return the value of the base experience rate (when used after the above example, it would print 2000).
- mes getBattleFlag("base_exp_rate");
- ---------------------------------------
- *warpportal <x>,<y>,"<mapname>",<x>,<y>;
- Creates a warp Portal as if a acolyte class character did it.
- The first x and y is the place of the warp portal on the map where the NPC is on
- The mapname and second x and y is the target area of the warp portal.
- Example(s):
- //Will create a warp portal on the NPC's map at 150,150 leading to prontera, coords 150,180.
- warpPortal 150,150,"prontera",150,180;
- ---------------------------------------
- *mapwarp "<from map>","<to map>",<x>,<y>;
- This command will collect all characters located on the From map and warp them
- wholesale to the same point on the To map, or randomly distribute them there if
- the coordinates are zero. "Random" is understood as a special To map name and
- will mean randomly shuffling everyone on the same map.
- ---------------------------------------
- \\
- 5,2.- Guild-related Commands
- \\
- ---------------------------------------
- *maprespawnguildid "<map name>",<guild id>,<flag>;
- This command goes through the specified map and for each player and monster
- found there does stuff.
- Flag is a bitmask (add up numbers to get effects you want)
- 1 - warp all guild members to their savepoints.
- 2 - warp all non-guild members to their savepoints.
- 4 - remove all monsters which are not guardian or emperium.
- Flag 7 will, therefore, mean 'wipe all mobs but guardians and the emperium and
- kick all characters out', which is what the official scripts do upon castle
- surrender. Upon start of WoE, the scripts do 2 (warp all intruiders out).
- Characters not belonging to any guild will warp out regardless of the flag setting.
- For examples, check the WoE scripts in the distribution.
- ---------------------------------------
- *agitstart;
- *agitend;
- *agitstart2;
- *agitend2;
- These four commands will start and end War of Emperium or War of Emperium SE.
- This is a bit more complex than it sounds, since the commands themselves won't
- actually do anything interesting, except causing all 'OnAgitStart:' and
- 'OnAgitEnd:', or 'OnAgitStart2:' and 'OnAgitEnd2:' in the case of latter two
- commands, events to run everywhere, respectively. They are used as simple
- triggers to run a lot of complex scripts all across the server, and they,
- in turn, are triggered by clock with an 'OnClock<time>:' time-triggering label.
- ---------------------------------------
- *gvgon "<map name>";
- *gvgoff "<map name>";
- These commands will turn GVG mode for the specified maps on and off, setting up
- appropriate map flags. In GVG mode, maps behave as if during the time of WoE,
- even though WoE itself may or may not actually be in effect.
- ---------------------------------------
- *flagemblem <guild id>;
- This command only works when run by the NPC objects which have sprite id 722,
- which is a 3D guild flag sprite. If it isn't, the data will change, but nothing
- will be seen by anyone. If it is invoked in that manner, the emblem of the
- specified guild will appear on the flag, though, if any players are watching it
- at this moment, they will not see the emblem change until they move out of sight
- of the flag and return.
- This is commonly used in official guildwar scripts with a function call which
- returns a guild id:
- // This will change the emblem on the flag to that of the guild that owns
- // "guildcastle"
- flagemblem GetCastleData("guildcastle",1);
- ---------------------------------------
- *guardian("<map name>",<x>,<y>,"<name to show>",<mob id>,<amount>{,"<event label>"}{,<guardian index>})
- This command is roughly equivalent to 'monster', but is meant to be used with
- castle guardian monsters and will only work with them. It will set the guardian
- characteristics up according to the castle's investment values and otherwise
- set the things up that only castle guardians need.
- Since trunk r12524:
- Returns the id of the mob or 0 if an error occurred.
- When 'guardian index' isn't supplied it produces a temporary guardian.
- Temporary guardians are not saved with the castle and can't be accessed by guardianinfo.
- ---------------------------------------
- *guardianinfo("<map name>", <guardian number>, <type>)
- This function will return various info about the specified guardian, or -1
- if it fails for some reason. It is primarily used in the castle manager npc.
- Map name and guardian number (value between 0 and 7) define the target.
- Type indicates what information to return:
- 0 - visibility (whether the guardian is installed or not)
- 1 - max. hp
- 2 - current hp
- ---------------------------------------
- //
- 5,2.- End of guild-related commands
- //
- ---------------------------------------
- *npcspeed <speed value>;
- *npcwalkto <x>,<y>;
- *npcstop;
- These commands will make the NPC object in question move around the map. As they
- currently are, they are a bit buggy and are not useful for much more than making
- an NPC move randomly around the map. (see 'npc/custom/devnpc.txt' for an example
- of such usage)
- 'npcspeed' will set the NPCs walking speed to a specified value. As in the
- @speed GM command, 200 is the slowest possible speed while 0 is the fastest
- possible (instant motion). 100 is the default character walking speed.
- 'npcwalkto' will start the NPC sprite moving towards the specified coordinates
- on the same map as it is currently on.
- 'npcstop' will stop the motion.
- While in transit, the NPC will be clickable, but invoking it will cause it to
- stop motion, which will make it's coordinates different from what the client
- computed based on the speed and motion coordinates. The effect is rather
- unnerving.
- Only a few NPC sprites have walking animations, and those that do, do not get
- the animation invoked when moving the NPC, due to the problem in the npc walking
- code, which looks a bit silly. You might have better success by defining a job-
- sprite based sprite id in 'db/mob-avail.txt' with this.
- ---------------------------------------
- *movenpc <NPC name>,x,y;
- This command looks like the NPCWalkToxy function,but is a little different.
- While NPCWalkToXY just makes the NPC 'walk' to the coordinates given
- (which sometimes gives problems if the path isn't a straight line without objects),
- this command just moves the NPC. It basically warps out and in on the current and given spot.
- Example(s):
- //This will move Bugga from it's current position to the coords 100,20 (if those coords are walkable (legit)).
- moveNPC "Bugga",100,20;
-
- ---------------------------------------
- =====================
- |6.- Other commands.|
- =====================
- ---------------------------------------
- *debugmes "<message>";
- This command will send the message to the server console (map-server window). It
- will not be displayed anywhere else.
- debugmes strcharinfo(0)+" has just done this that and the other";
- // You would see in the map-server window "NAME has just done this that and
- // the other"
- ---------------------------------------
- *logmes "<message>";
- This command will write the message given to the map server npc log file, as
- specified in 'conf/log_athena.conf'. In the TXT version of the server, the log
- file is 'log/npclog.log' by default. In the SQL version, if SQL logging is
- enabled, the message will go to the 'npclog' table, otherwise, it will go to the
- same log file.
- If logs are not enabled, nothing will happen.
- ---------------------------------------
- *globalmes "<message>"{,"<NPC name>"};
- This command will send a message to the chat window of all currently connected
- characters.
- If NPC name is specified, the message will be sent as if the sender would be
- the npc with the said name.
- ---------------------------------------
- *rand(<number>{,<number>});
- This function returns a number, randomly positioned between 0 and the number you
- specify (if you only specify one) and the two numbers you specify if you give it
- two.
- rand(10) would result in 0,1,2,3,4,5,6,7,8 or 9
- rand(2,10) would result in 2,3,4,5,6,7,8,9 or 10
- ---------------------------------------
- *viewpoint <action>,<x>,<y>,<point number>,<color>;
- This command will mark places on the mini map in the client connected to the
- invoking character. It uses the normal X and Y coordinates from the main map.
- The colors of the marks are defined using a hexidecimal number, same as the ones
- used to color text in 'mes' output, but are written as hexadecimal numbers in C.
- (They look like 0x<six numbers>.)
- Action is what you want to do with a point, 1 will set it, while 2 will clear
- it. Point number is the number of the point - you can have several. If more than
- one point is drawn at the same coordinates, they will cycle, which can be used
- to create flashing marks.
- // This command will show a mark at coordinates X 30 Y 40, is mark number 1,
- // and will be red.
-
- viewpoint 1,30,40,1,0xFF0000;
- This will create three points:
- viewpoint 1,30,40,1,0xFF0000;
- viewpoint 1,35,45,2,0xFF0000;
- viewpoint 1,40,50,3,0xFF0000;
- And this is how you remove them:
- viewpoint 2,30,40,1,0xFF0000;
- viewpoint 2,35,45,2,0xFF0000;
- viewpoint 2,40,50,3,0xFF0000;
-
- The client determines what it does with the points entirely, the server keeps no
- memory of where the points are set whatsoever.
- ---------------------------------------
- *cutin "<filename>",<position>;
- This command will display a picture stored in the GRF file in the client for the
- player.
- The files are taken from '\data\texture\유저인터페이스\illust' directory in the
- GRF file. Also it seems that card cutins from \cardbmp will work here as well.
- Only bitmaps (images stored in the bitmap format) will actually get displayed.
- The '.bmp' extension is optional.
- The client has no problem rendering huge 4096x4096 bitmaps, but usually they're
- around 500x500. Bright magenta (color FF00FF) is considered to be transparent in
- these pictures. You can easily add and alter them, but how to do this is outside
- of the scope of this document.
- The position determines just where on screen the picture will appear:
- 0 - bottom left corner
- 1 - bottom middle
- 2 - bottom right corner
- 3 - middle of screen in a movable window with an empty title bar.
- 4 - middle of screen without the window header, but still movable.
- 255 - will remove the cutin previously displayed.
-
- Giving an empty string for the filename and 255 for the position will remove all
- cutin pictures. Any other position value will not cause a script error but will
- cause the player's client to curl up and die. Only one cutin may be on screen at
- any given time, any new cutins will replace it.
- // This will display the picture of the 7th kafra,
- // the one in orange and the mini-skirt :P
- cutin "kafra_7",2;
- // This will remove the displayed picture.
- cutin "Kafra_7",255;
- // This will remove all pictures displayed.
- cutin "",255;
- ---------------------------------------
- *pet <pet id>;
- This command is used in all the item scripts for taming items. Running this
- command will make the pet catching cursor appear on the client connected to the
- invoking character, usable on the monsters with the specified pet ID number. It
- will still work outside an item script.
- A full list of pet IDs can be found inside 'db/pet_db.txt'
- ---------------------------------------
- *emotion <emotion number>{, target};
- This command makes an object display an emoticon sprite above their own as
- if they were doing that emotion. For a full list of emotion numbers,
- see 'db/const.txt' under 'e_'. The inobvious ones are 'e_what' (a question mark)
- and 'e_gasp' (the exclamation mark).
- The optional target parameter specifies who will get the emotion on top of
- their head. If 0 (the default if omitted), the NPC in current use will show
- the emotion, if 1, the player that is running the script will display it.
- ---------------------------------------
- *misceffect <effect number>;
- This command, if run from an NPC object that has a sprite, will call up a
- specified effect number, centered on the NPC sprite. If the running code does
- not have an object ID (a 'floating' npc) or is not running from an NPC object at
- all (an item script) the effect will be centered on the character who's RID got
- attached to the script, if any. For usable item scripts, this command will
- create an effect centered on the player using the item.
- A full list of known effects is found in 'doc/effect_list.txt'. The list of
- those that actually work may differ greatly between client versions.
- ---------------------------------------
- *soundeffect "<effect filename>",<type>
- *soundeffectall "<effect filename>",<type>{,"<map name>"}{,<x0>,<y0>,<x1>,<y1>}
- These two commands will play a sound effect to either the invoking character
- only ('soundeffect') or multiple characters ('soundeffectall'). If the running
- code does not have an object ID (a 'floating' npc) or is not running from an NPC
- object at all (an item script) the sound will be centered on the character who's
- RID got attached to the script, if any. If it does, it will be centered on that
- object. (an NPC sprite)
- Effect filename is the filename in a GRF. It must have the .wav extension.
- It's not quite certain what the 'type' actually does, it is sent to the client
- directly. It probably determines which directory to play the effect from.
- It's certain that giving 0 for the number will play sound files from 'data/wav',
- but where the other numbers will read from is unclear.
- You can add your own effects this way, naturally.
- ---------------------------------------
- *pvpon "<map name>";
- *pvpoff "<map name>";
- These commands will turn PVP mode for the specified maps on and off. Beside
- setting the flags referred to in 'setmapflag', 'pvpon' will also create a PVP
- timer and ranking as will @pvpon GM command do.
- ---------------------------------------
- *atcommand "<command line>";
- This command will run the given command line exactly as if it was typed in from
- the keyboard by the player connected to the invoking character, and that
- character belonged to an account which had GM level 99.
- // This will ask the invoker for a character name and then use the '@nuke'
- // GM command on them, killing them mercilessly.
- input @player$;
- atcommand "@nuke "+@player$;
- This command has a lot of good uses, I am sure you can have some fun with this
- one.
- ---------------------------------------
- *charcommand <command>;
- This command will run the given command line exactly as if it was typed in from
- the keyboard from a character that belonged to an account which had GM level 99.
- The commands can also run without an attached rid.
- Example(s):
- //this would do the same as above, but now doesn't need a player attached by default.
- charCommand "#option 0 0 0 Roy";
- ---------------------------------------
- *unitskilluseid <GID>,<skill id>,<skill lvl>{,<target id>};
- *unitskilluseid <GID>,"<skill name>",<skill lvl>{,<target id>};
- *unitskillusepos <GID>,<skill id>,<skill lvl>,<x>,<y>;
- *unitskillusepos <GID>,"<skill name>",<skill lvl>,<x>,<y>;
- This is the replacement of the older commands, these use the same values for
- GID as the other unit* commands (See 'GID').
- Skill ID is the ID of the skill, skill level is the level of the skill.
- For the position, the x and y are given in the unitSkillUsePos.
- ---------------------------------------
- *day;
- *night;
- These two commands will switch the entire server between day and night mode.
- Depending on the configuration, it may cause differing client effects. If your
- server is set to cycle between day and night, it will eventually return to that
- cycle.
- This example will set the night time to start at 03 AM and end at 08 AM, and the
- nighttime will persist if the server restarts during the night, if the automated
- day/night switching is turned off in the configuration files. Figure it out on
- your own:
- -%TAB%script%TAB%DayNight%TAB%-1,{
-
- end;
- OnClock0300:
-
- OnClock0800:
-
- OnInit:
- set $@minutesfrommidnight, gettime(3)*60+gettime(2);
- set $@night_start, 180; // 03:00
- set $@night_end, 480; // 08:00
- if ($@minutesfrommidnight>=$@night_start && $@minutesfrommidnight<$@night_end) goto StartNight;
- goto StartDay;
- StartNight:
- night;
- end;
- StartDay:
- day;
- end; }
- ---------------------------------------
- *defpattern <set number>,"<regular expression pattern>","<event label>";
- *activatepset <set number>;
- *deactivatepset <set number>;
- *deletepset <set number>;
- This set of commands is only available if the server is compiled with regular
- expressions library enabled. Default compilation and most binary distributions
- aren't, which is probably bad, since these, while complex to use, are quite
- fascinating.
- They will make the NPC object listen for text spoken publicly by players and
- match it against regular expression patterns, then trigger labels associated
- with these regular expression patterns.
- Patterns are organised into sets, which are referred to by a set number. You can
- have multiple sets patterns, and multiple patterns may be active at once.
- Numbers for pattern sets start at 1.
- 'defpattern' will associate a given regular expression pattern with an event
- label. This event will be triggered whenever something a player says is matched
- by this regular expression pattern, if the pattern is currently active.
- 'activatepset' will make the pattern set specified active. An active pattern
- will enable triggering labels defined with 'defpattern', which will not happen
- by default.
- 'deactivatepset' will deactivate a specified pattern set. Giving -1 as a pattern
- set number in this case will deactivate all pattern sets defined.
- 'deletepset' will delete a pattern set from memory, so you can create a new
- pattern set in it's place.
- Using regular expressions is high wizardry. But with this high wizardry comes
- unparallelled power of text manipulation. For an explanation of what a regular
- expression pattern is, see a few web pages:
- http://www.regular-expressions.info/
- http://www.weitz.de/regex-coach/
- For an example of this in use, see 'npc\sample\npc_pcre.txt'.
- With this you could, for example, automagically punish players for asking for
- zeny in public places, or alternatively, automagically give them zeny instead if
- they want it so much.
- ---------------------------------------
- *pow(<number>,<power>)
- Returns the result of the calculation.
- Example:
- set @i, pow(2,3); // @i will be 8
- ---------------------------------------
- *sqrt(<number>)
- Returns square-root of number.
- Example:
- set @i, sqrt(25); // @i will be 5
- ---------------------------------------
- *distance(<x0>,<y0>,<x1>,<y1>)
- Returns distance between 2 points.
- Example:
- set @i, distance(100,200,101,202);
- ---------------------------------------
- *md5("<string>")
- Returns the md5 checksum of a number or string.
- Example:
- mes md5(12345);
- mes md5("12345"); // Will both display 827ccb0eea8a706c4c34a16891f84e7b
- mes md5("qwerty"); // Will display d8578edf8458ce06fbc5bb76a58c5ca4
- ---------------------------------------
- *query_sql "your MySQL query", <array variable> {,<array variable>, ...};
- *query_logsql "your MySQL query", <array variable> {,<array variable>, ...};
- Puts up to 128 rows of values into the arrays and returns the number of rows.
- Example:
- set @nb, query_sql("select name,fame from `char` ORDER BY fame DESC LIMIT 5", @name$, @fame);
- mes "Hall Of Fame: TOP5";
- mes "1."+@name$[0]+"("+@fame[0]+")"; // Will return a person with the biggest fame value.
- mes "2."+@name$[1]+"("+@fame[1]+")";
- mes "3."+@name$[2]+"("+@fame[2]+")";
- mes "4."+@name$[3]+"("+@fame[3]+")";
- mes "5."+@name$[4]+"("+@fame[4]+")";
- Note: In the TXT version it doesn't fill the array and always return -1.
- Note: Use $ as suffix in the array to receive all data as text.
- Note: The difference between query_sql and query_logsql is that the latter
- uses the sql connection to the log database, and should be used when you want
- to query the server log tables.
- ---------------------------------------
- *escape_sql("<string>")
- Escapes special characters in the string, so that it is safe to use in query_sql(),
- and returns the escaped form of the given string.
- Example 1:
- set .@str$, "John's Laptop";
- set .@esc_str$, escape_sql(.@name$); // Escaped string: John\'s Laptop
- ---------------------------------------
- *setitemscript(<item id>,<"{ new item script }">{,<type>});
- Set a new script bonus to the Item. Very useful for game events.
- You can remove an item's itemscript by leaving the itemscript argument empty.
- Type can optionally be used indicates which script to set (default is 0):
- 0 - Script
- 1 - OnEquip_Script
- 2 - OnUnequip_Script
- Example:
- setitemscript 2637,"{ if(isequipped(2236)==0)end; if(getskilllv(26)){skill 40,1;}else{skill 26,1+isequipped(2636);} }";
- setitemscript 2637,"";
- ---------------------------------------
- *atoi ("<string>")
- *axtoi ("<string>")
- These commands are used to convert strings to numbers.
- atoi will convert string using normal number (0,1,2,3,etc) while axtoi converts them to
- hexadecimal numbers (0,1,11,01).
- Example:
- mes atoi("11"); // Will display 11 (can also be used to set a @var to 11)
- set @var, axtoi("FF"); // Will set the @var to 255
- mes axtoi("11"); // Will display 17 (1 = 1, 10 = 16,
- // hexadecimal number set: {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F})
- ---------------------------------------
- *compare (<string>,<substring>)
- This command returns 1 or 0 when a the substring is in the main string (1) or not (0).
- This command is not case sensitive.
- Example(s):
- //dothis; will be executed ('Bloody Murderer' contains 'Blood').
- if (compare("Bloody Murderer","Blood"))
- dothis;
- //dothat; will not be executed ('Blood butterfly' does not contain 'Bloody').
- if (compare("Blood Butterfly","Bloody"))
- dothat;
- ---------------------------------------
- *charisalpha("<string>",<position>)
- This function will return 1 if the character number Position in the given string
- is a letter, 0 if it isn't a letter but a digit or a space.
- ---------------------------------------
- * The Pet AI commands
- These commands will only work if the invoking character has a pet, and are meant
- to be executed from pet scripts. They will modify the pet AI decision-making for
- the current pet of the invoking character, and will NOT have any independent
- effect by themselves, which is why only one of them each may be in effect at any
- time for a specific pet. A pet may have 'petloot', 'petskillbonus',
- 'petskillattack' OR 'petpetskillattack2' and 'petskillsupport' OR 'petheal' at
- the same time. 'petheal' is deprecated and is no longer used in the default pet
- scripts.
- *petskillbonus <bonus type>,<value>,<duration>,<delay>;
- This command will make the pet give a bonus to the owner's stat (bonus type -
- bInt,bVit,bDex,bAgi,bLuk,bStr,bSpeedRate - for a full list, see the values
- starting with 'b' in 'db/const.txt')
- *petrecovery <status type>,<delay>;
- This command will make the pet cure a specified status condition. The curing
- actions will occur once every Delay seconds. For a full list of status
- conditions that can be cured, see the list of 'SC_' status condition constants
- in 'db/const.txt'
- *petloot <max items>;
- This command will turn on pet looting, with a maximum number of items to loot
- specified. Pet will store items and return them when the maximum is reached or
- when pet performance is activated.
- *petskillsupport <skill id>,<skill level>,<delay>,<percent hp>,<percent sp>;
- *petskillsupport "<skill name>",<skill level>,<delay>,<percent hp>,<percent sp>;
- *petheal <level>,<delay>,<percent hp>,<percent sp>;
- This will make the pet use a specified support skill on the owner whenever the
- HP and SP are below the given percent values, with a specified delay time
- between activations. The skill numbers are as per 'db/skill_db.txt'.
- 'petheal' works the same as 'petskillsupport' but has the skill ID hardcoded to
- 28 (Heal). This command is deprecated.
- It's not quite certain who's stats will be used for the skills cast, the
- character's or the pets. Probably, Skotlex can answer that question.
- *petskillattack <skill id>,<skill level>,<rate>,<bonusrate>;
- *petskillattack "<skill name>",<skill level>,<rate>,<bonusrate>;
- *petskillattack2 <skill id>,<damage>,<number of attacks>,<rate>,<bonusrate>;
- *petskillattack2 "<skill name>",<damage>,<number of attacks>,<rate>,<bonusrate>;
- These two commands will make the pet cast an attack skill on the enemy the pet's
- owner is currently fighting. Skill IDs and levels are as per 'petskillsupport'.
- 'petskillattack2' will make the pet cast the skill with a fixed amount of damage
- inflicted and the specified number of attacks.
- All commands with delays and durations will only make the behavior active for
- the specified duration of seconds, with a delay of the specified number of
- seconds between activations. Rates are a chance of the effect occuring and are
- given in percent. 'bonusrate' is added to the normal rate if the pet intimacy is
- at the maximum possible.
- The behavior modified with the abovementioned commands will only be exibited if
- the pet is loyal and appropriate configuration options are set in
- 'battle_athena.conf'.
- Pet scripts in the database normally run whenever a pet of that type hatches
- from the egg. Other commands usable in item scripts (see 'bonus') will also
- happily run from pet scripts. Apparently, the pet-specific commands will also
- work in NPC scripts and modify the behavior of the current pet up until the pet
- is hatched again. (Which will also occur when the character is logged in again
- with the pet still out of the egg.) It is not certain for how long the effect of
- such command running from an NPC script will eventually persist, but apparently,
- it is possible to usefully employ them in usable item scripts to create pet
- buffing items.
- Nobody tried this before, so you're essentially on your own here.
- ---------------------------------------
- *bpet;
- This command opens up a pet hatching window on the client connected to the
- invoking character. It is used in item script for the pet incubators and will
- let the player hatch an owned egg. If the character has no eggs, it will just
- open up an empty incubator window.
- This is still usable outside item scripts.
- ---------------------------------------
- *makepet <pet id>;
- This command will create a pet egg and put it in the invoking character's
- inventory. The kind of pet is specified by pet ID numbers listed in
- 'db/pet_db.txt'. The egg is created exactly as if the character just successfuly
- caught a pet in the normal way.
- // This will make you a poring:
- makepet 1002;
- Notice that you absolutely have to create pet eggs with this command. If you try
- to give a pet egg with 'getitem', pet data will not be created by the char
- server and the egg will disappear when anyone tries to hatch it.
- ---------------------------------------
- *homshuffle;
- This will recalculate the homunculus stats acording to its level, of the
- current invoking character.
- ---------------------------------------
- *setcell "<map name>",<x1>,<y1>,<x2>,<y2>,<type>,<flag>;
- Each map cell has several 'flags' that specify the properties of that cell.
- These include terrain properties (walkability, shootability, presence of water),
- skills (basilica, land protector, ...) and other (npc nearby, no vending, ...).
- Each of these can be 'on' or 'off'. Together they define a cell's behavior.
- This command lets you alter these flags for all map cells in the specified
- (x1,y1)-(x2,y2) rectangle. The 'flag' can be 0 or 1 (0:clear flag, 1:set flag).
- The 'type' defines which flag to modify. Possible options include cell_walkable,
- cell_shootable, cell_basilica. For a full list, see const.txt.
- Example:
- setcell "arena",0,0,300,300,cell_basilica,1;
- setcell "arena",140,140,160,160,cell_basilica,0;
- setcell "arena",135,135,165,165,cell_walkable,0;
- setcell "arena",140,140,160,160,cell_walkable,1;
- This will add a makeshift ring into the center of the map. The ring will be
- surrounded by a 5-cell wide 'gap' to prevent interference from outside, and
- the rest of the map will be marked as 'basilica', preventing observers from
- casting any offensive skills or fighting among themselves. Note that the wall
- will not be shown nor known client-side, which may cause movement problems.
- Another example:
- OnBarricadeDeploy:
- setcell "schg_cas05",114,51,125,51,cell_walkable,0;
- end;
- OnBarricadeBreak:
- setcell "schg_cas05",114,51,125,51,cell_walkable,1;
- end;
- This could be a part of the WoE:SE script, where attackers are not allowed
- to proceed until all barricades are destroyed. This script would place and
- remove a nonwalkable row of cells after the barricade mobs.
-
- ---------------------------------------
- *checkcell ("<map name>",<x>,<y>,<type>);
- This command will return 1 or 0, depending on whether the specified cell has
- the 'type' flag set or not. There are various types to check, all mimicking
- the server's cell_chk enumeration. The types can be found in db/const.txt.
- The meaning of the individual types can be confusing, so here's an overview:
- - cell_chkwall/water/cliff
- these check directly for the 'terrain component' of the specified cell
- - cell_chkpass/reach/nopass/noreach
- passable = not wall & not cliff, reachable = passable wrt. no-stacking mod
- - cell_chknpc/basilica/landprotector/novending/nochat
- these check for specific dynamic flags (their name indicates what they do)
- Example:
- mes "Pick a destination map.";
- input .@map$;
- mes "Alright, now give me the coordinates.";
- input .@x;
- input .@y;
- if( !checkcell(.@map$,.@x,.@y,cell_chkpass) )
- {
- mes "Can't warp you there, sorry!";
- close;
- }
- else
- {
- mes "Ok, get ready...";
- close2;
- warp .@map$, .@x, .@y;
- end;
- }
- ---------------------------------------
- *setwall "<map name>",<x>,<y>,<size>,<dir>,<shootable>,"<name>";
- *delwall "<name>";
- Creates an invisible wall, an array of "setcell" starting from x,y and doing a
- line of the given size in the given direction. The difference with setcell is
- this one update client part too to avoid the glith problem.
- ---------------------------------------
- *readbook <book id>,<page>;
- This will open a book item at the specified page
- ---------------------------------------
- ========================
- |7.- Instance commands.|
- ========================
- ---------------------------------------
- *instance_create("<Instance Name>",<Party ID>,<Instance>)
- Create an instance using the name "<Instance Name>" for the Party of <Party ID>.
- Instance ID currently will only be ID_ENDLESS (5) or ID_CATACOMBS (6)
- Most Instance_* commands are used in conjunction with this command and depend
- on the ID this command returns.
- Example:
- // Store the Party ID of the invoking character.
- set .@party_id, getcharid(1);
- // Atempt to create an instance using that party ID.
- set .@id, instance_create("Endless Tower", .@party_id, ID_ENDLESS);
- if (.@id == -1) { // Party ID is in use by another instance.
- ...
- }
- else (.@id < 0) { // Unspecified error while queuing instance.
- ...
- }
- ---------------------------------------
- *instance_destroy(<Instance ID>)
- Destroys instance with the ID <Instance ID>.
- ---------------------------------------
- *instance_attachmap(<Instance ID>,"<Map Name>")
- *instance_detachmap(<Instance ID>,"<Map Name>")
- Attach or detach the map "<Map Name>" to the instance with the <Instance ID>.
- ---------------------------------------
- *instance_init(<Instance ID>);
- Initiate the instance of <Instance ID>.
- ---------------------------------------
- *instance_announce <Instance ID>,"<text>",<flag>{,<color>};
- Works like announce, but has the <Instance ID> paramter, where 0 = active instance?
- ---------------------------------------
- *instance_attach(<Instance ID>);
- Attaches a script to the proviced <Instance ID>?
- ---------------------------------------
- *instance_npcname("<NPC Name>",<Instance ID>)
- Retrieve the unique name given to a copy of an NPC for an instance, the given
- "<NPC Name>" that belonds to instance <Instance ID>. Can be used with such commands
- as enablenpc and disablenpc, donpcevent, etc.
- ---------------------------------------
- *has_instance("<Map Name>")
- Check if the player has been queued for the <Map Name> instance.
- ---------------------------------------
- *instance_id(<?>)
- Apparantly returns the ID the player is currently attached too.
- ---------------------------------------
- *instance_warpall "<Map Name>",<x>,<y>;
- Warp all palyers in the instance to <map name> and given coordinates.
- ---------------------------------------
- *instance_set_timeout <Time1>,<Time2>,<Instance ID>;
- Lifetime of <Time1> for <Instance ID>, while <Time2> is how long until the
- instance times out while inactive.
- ---------------------------------------
- ========================
- |8.- Quest Log commands.|
- ========================
- ---------------------------------------
- *setquest <ID>;
- Place quest of <ID> in the users quest log, the state of which is "active".
- ---------------------------------------
- *completequest <ID>;
- Change the state for the given quest <ID> to "complete" and remove from the users quest log.
- ---------------------------------------
- *erasequest <ID>;
- Remove the quest of the given <ID> from the user's quest log.
- ---------------------------------------
- *changequest <ID>,<ID2>;
- Remove quest of the given <ID> from the user's quest log.
- Add quest of the <ID2> to the the quest log, and the state is "active".
- ---------------------------------------
- *checkquest(<ID>{,PLAYTIME|HUNTING})
- If no additonal argument supplied, return the state of the quest:
- -1 = Quest not started (not in quest log)
- 0 = Quest has been given, but the state is "inactive"
- 1 = Quest has been given, and the state is "active"
- 2 = Quest comepleted
-
- If parameter "PLAYTIME" is supplied:
- -1 = Quest not started (not in quest log)
- 0 = the time limit has not yet been reached
- 1 = the time limit has not been reached but the quest is marked as complete
- 2 = the time limit has been reached
-
- If parameter "HUNTING" is supplied:
- -1 = Quest not started (not in quest log)
- 0 = you haven't killed all of the target monsters and the time limit has not been reached.
- 1 = you haven't killed all of the target monsters but the time limit has been reached.
- 2 = you've killed all of the target monsters
- ---------------------------------------
- Whew.
- That's about all of them.
|