NPCSegment.cs 207 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022
  1. using System.Drawing;
  2. using Server.MirDatabase;
  3. using Server.MirEnvir;
  4. using System.Globalization;
  5. using System.Numerics;
  6. using System.Text.RegularExpressions;
  7. using S = ServerPackets;
  8. using Timer = Server.MirEnvir.Timer;
  9. using Server.MirNetwork;
  10. using Server.Library.MirDatabase;
  11. namespace Server.MirObjects
  12. {
  13. public class NPCSegment
  14. {
  15. protected static Envir Envir
  16. {
  17. get { return Envir.Main; }
  18. }
  19. protected static MessageQueue MessageQueue
  20. {
  21. get { return MessageQueue.Instance; }
  22. }
  23. public NPCPage Page;
  24. public readonly string Key;
  25. public List<NPCChecks> CheckList = new List<NPCChecks>();
  26. public List<NPCActions> ActList = new List<NPCActions>(), ElseActList = new List<NPCActions>();
  27. public List<string> Say, ElseSay, Buttons, ElseButtons, GotoButtons;
  28. public string Param1;
  29. public int Param1Instance, Param2, Param3;
  30. public List<string> Args = new List<string>();
  31. public NPCSegment(NPCPage page, List<string> say, List<string> buttons, List<string> elseSay, List<string> elseButtons, List<string> gotoButtons)
  32. {
  33. Page = page;
  34. Say = say;
  35. Buttons = buttons;
  36. ElseSay = elseSay;
  37. ElseButtons = elseButtons;
  38. GotoButtons = gotoButtons;
  39. }
  40. public string[] ParseArguments(string[] words)
  41. {
  42. Regex r = new Regex(@"\%ARG\((\d+)\)");
  43. for (int i = 0; i < words.Length; i++)
  44. {
  45. foreach (Match m in r.Matches(words[i].ToUpper()))
  46. {
  47. if (!m.Success) continue;
  48. int sequence = Convert.ToInt32(m.Groups[1].Value);
  49. if (Page.Args.Count >= (sequence + 1)) words[i] = words[i].Replace(m.Groups[0].Value, Page.Args[sequence]);
  50. }
  51. }
  52. return words;
  53. }
  54. public void AddVariable(MapObject player, string key, string value)
  55. {
  56. Regex regex = new Regex(@"[A-Za-z][0-9]");
  57. if (!regex.Match(key).Success) return;
  58. for (int i = 0; i < player.NPCVar.Count; i++)
  59. {
  60. if (!String.Equals(player.NPCVar[i].Key, key, StringComparison.CurrentCultureIgnoreCase)) continue;
  61. player.NPCVar[i] = new KeyValuePair<string, string>(player.NPCVar[i].Key, value);
  62. return;
  63. }
  64. player.NPCVar.Add(new KeyValuePair<string, string>(key, value));
  65. }
  66. public string FindVariable(MapObject player, string key)
  67. {
  68. Regex regex = new Regex(@"\%[A-Za-z][0-9]");
  69. if (!regex.Match(key).Success) return key;
  70. string tempKey = key.Substring(1);
  71. foreach (KeyValuePair<string, string> t in player.NPCVar)
  72. {
  73. if (String.Equals(t.Key, tempKey, StringComparison.CurrentCultureIgnoreCase)) return t.Value;
  74. }
  75. return key;
  76. }
  77. public void ParseCheck(string line)
  78. {
  79. var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  80. parts = ParseArguments(parts);
  81. if (parts.Length == 0) return;
  82. string tempString, tempString2;
  83. var regexFlag = new Regex(@"\[(.*?)\]");
  84. var regexQuote = new Regex("\"([^\"]*)\"");
  85. Match quoteMatch;
  86. switch (parts[0].ToUpper())
  87. {
  88. case "LEVEL":
  89. if (parts.Length < 3) return;
  90. CheckList.Add(new NPCChecks(CheckType.Level, parts[1], parts[2]));
  91. break;
  92. case "CHECKGOLD":
  93. if (parts.Length < 3) return;
  94. CheckList.Add(new NPCChecks(CheckType.CheckGold, parts[1], parts[2]));
  95. break;
  96. case "CHECKGUILDGOLD":
  97. if (parts.Length < 3) return;
  98. CheckList.Add(new NPCChecks(CheckType.CheckGuildGold, parts[1], parts[2]));
  99. break;
  100. case "CHECKCREDIT":
  101. if (parts.Length < 3) return;
  102. CheckList.Add(new NPCChecks(CheckType.CheckCredit, parts[1], parts[2]));
  103. break;
  104. case "CHECKITEM":
  105. if (parts.Length < 2) return;
  106. tempString = parts.Length < 3 ? "1" : parts[2];
  107. tempString2 = parts.Length > 3 ? parts[3] : "";
  108. CheckList.Add(new NPCChecks(CheckType.CheckItem, parts[1], tempString, tempString2));
  109. break;
  110. case "CHECKGENDER":
  111. if (parts.Length < 2) return;
  112. CheckList.Add(new NPCChecks(CheckType.CheckGender, parts[1]));
  113. break;
  114. case "CHECKCLASS":
  115. if (parts.Length < 2) return;
  116. CheckList.Add(new NPCChecks(CheckType.CheckClass, parts[1]));
  117. break;
  118. case "DAYOFWEEK":
  119. if (parts.Length < 2) return;
  120. CheckList.Add(new NPCChecks(CheckType.CheckDay, parts[1]));
  121. break;
  122. case "HOUR":
  123. if (parts.Length < 2) return;
  124. CheckList.Add(new NPCChecks(CheckType.CheckHour, parts[1]));
  125. break;
  126. case "MIN":
  127. if (parts.Length < 2) return;
  128. CheckList.Add(new NPCChecks(CheckType.CheckMinute, parts[1]));
  129. break;
  130. //cant use stored var
  131. case "CHECKNAMELIST":
  132. if (parts.Length < 2) return;
  133. quoteMatch = regexQuote.Match(line);
  134. string listPath = parts[1];
  135. if (quoteMatch.Success)
  136. listPath = quoteMatch.Groups[1].Captures[0].Value;
  137. var fileName = Path.Combine(Settings.NameListPath, listPath);
  138. string sDirectory = Path.GetDirectoryName(fileName);
  139. Directory.CreateDirectory(sDirectory);
  140. if (File.Exists(fileName))
  141. CheckList.Add(new NPCChecks(CheckType.CheckNameList, fileName));
  142. break;
  143. //cant use stored var
  144. case "CHECKGUILDNAMELIST":
  145. if (parts.Length < 2) return;
  146. quoteMatch = regexQuote.Match(line);
  147. listPath = parts[1];
  148. if (quoteMatch.Success)
  149. listPath = quoteMatch.Groups[1].Captures[0].Value;
  150. fileName = Path.Combine(Settings.NameListPath, listPath);
  151. sDirectory = Path.GetDirectoryName(fileName);
  152. Directory.CreateDirectory(sDirectory);
  153. if (File.Exists(fileName))
  154. CheckList.Add(new NPCChecks(CheckType.CheckGuildNameList, fileName));
  155. break;
  156. case "ISADMIN":
  157. CheckList.Add(new NPCChecks(CheckType.IsAdmin));
  158. break;
  159. case "CHECKPKPOINT":
  160. if (parts.Length < 3) return;
  161. CheckList.Add(new NPCChecks(CheckType.CheckPkPoint, parts[1], parts[2]));
  162. break;
  163. case "CHECKRANGE":
  164. if (parts.Length < 4) return;
  165. CheckList.Add(new NPCChecks(CheckType.CheckRange, parts[1], parts[2], parts[3]));
  166. break;
  167. case "CHECKMAP":
  168. if (parts.Length < 2) return;
  169. CheckList.Add(new NPCChecks(CheckType.CheckMap, parts[1]));
  170. break;
  171. case "MAPLIGHT":
  172. if (parts.Length < 2) return;
  173. CheckList.Add(new NPCChecks(CheckType.CheckMapLight, parts[1]));
  174. break;
  175. //cant use stored var
  176. case "CHECK":
  177. if (parts.Length < 3) return;
  178. var match = regexFlag.Match(parts[1]);
  179. if (match.Success)
  180. {
  181. string flagIndex = match.Groups[1].Captures[0].Value;
  182. CheckList.Add(new NPCChecks(CheckType.Check, flagIndex, parts[2]));
  183. }
  184. break;
  185. case "CHECKHUM":
  186. if (parts.Length < 4) return;
  187. tempString = parts.Length < 5 ? "1" : parts[4];
  188. CheckList.Add(new NPCChecks(CheckType.CheckHum, parts[1], parts[2], parts[3], tempString));
  189. break;
  190. case "CHECKMON":
  191. if (parts.Length < 4) return;
  192. tempString = parts.Length < 5 ? "1" : parts[4];
  193. CheckList.Add(new NPCChecks(CheckType.CheckMon, parts[1], parts[2], parts[3], tempString));
  194. break;
  195. case "CHECKEXACTMON":
  196. if (parts.Length < 5) return;
  197. tempString = parts.Length < 6 ? "1" : parts[5];
  198. CheckList.Add(new NPCChecks(CheckType.CheckExactMon, parts[1], parts[2], parts[3], parts[4], tempString));
  199. break;
  200. case "RANDOM":
  201. if (parts.Length < 2) return;
  202. CheckList.Add(new NPCChecks(CheckType.Random, parts[1]));
  203. break;
  204. case "GROUPLEADER":
  205. CheckList.Add(new NPCChecks(CheckType.Groupleader));
  206. break;
  207. case "GROUPCOUNT":
  208. if (parts.Length < 3) return;
  209. CheckList.Add(new NPCChecks(CheckType.GroupCount, parts[1], parts[2]));
  210. break;
  211. case "GROUPCHECKNEARBY":
  212. CheckList.Add(new NPCChecks(CheckType.GroupCheckNearby));
  213. break;
  214. case "PETCOUNT":
  215. if (parts.Length < 3) return;
  216. CheckList.Add(new NPCChecks(CheckType.PetCount, parts[1], parts[2]));
  217. break;
  218. case "PETLEVEL":
  219. if (parts.Length < 3) return;
  220. CheckList.Add(new NPCChecks(CheckType.PetLevel, parts[1], parts[2]));
  221. break;
  222. case "HEROLEVEL":
  223. if (parts.Length < 3) return;
  224. CheckList.Add(new NPCChecks(CheckType.HeroLevel, parts[1], parts[2]));
  225. break;
  226. case "CHECKHEROCLASS":
  227. if (parts.Length < 2) return;
  228. CheckList.Add(new NPCChecks(CheckType.CheckHeroClass, parts[1]));
  229. break;
  230. case "CHECKHEROGENDER":
  231. if (parts.Length < 2) return;
  232. CheckList.Add(new NPCChecks(CheckType.CheckHeroGender, parts[1]));
  233. break;
  234. case "CHECKHEROITEM":
  235. if (parts.Length < 2) return;
  236. tempString = parts.Length < 3 ? "1" : parts[2];
  237. tempString2 = parts.Length > 3 ? parts[3] : "";
  238. CheckList.Add(new NPCChecks(CheckType.CheckHeroItem, parts[1], tempString, tempString2));
  239. break;
  240. case "CHECKCALC":
  241. if (parts.Length < 4) return;
  242. CheckList.Add(new NPCChecks(CheckType.CheckCalc, parts[1], parts[2], parts[3]));
  243. break;
  244. case "INGUILD":
  245. string guildName = string.Empty;
  246. if (parts.Length > 1) guildName = parts[1];
  247. CheckList.Add(new NPCChecks(CheckType.InGuild, guildName));
  248. break;
  249. case "CHECKQUEST":
  250. if (parts.Length < 3) return;
  251. CheckList.Add(new NPCChecks(CheckType.CheckQuest, parts[1], parts[2]));
  252. break;
  253. case "CHECKRELATIONSHIP":
  254. CheckList.Add(new NPCChecks(CheckType.CheckRelationship));
  255. break;
  256. case "CHECKWEDDINGRING":
  257. CheckList.Add(new NPCChecks(CheckType.CheckWeddingRing));
  258. break;
  259. case "CHECKPET":
  260. if (parts.Length < 2) return;
  261. CheckList.Add(new NPCChecks(CheckType.CheckPet, parts[1]));
  262. break;
  263. case "HASBAGSPACE":
  264. if (parts.Length < 3) return;
  265. CheckList.Add(new NPCChecks(CheckType.HasBagSpace, parts[1], parts[2]));
  266. break;
  267. case "ISNEWHUMAN":
  268. CheckList.Add(new NPCChecks(CheckType.IsNewHuman));
  269. break;
  270. case "CHECKCONQUEST":
  271. if (parts.Length < 2) return;
  272. CheckList.Add(new NPCChecks(CheckType.CheckConquest, parts[1]));
  273. break;
  274. case "AFFORDGUARD":
  275. if (parts.Length < 3) return;
  276. CheckList.Add(new NPCChecks(CheckType.AffordGuard, parts[1], parts[2]));
  277. break;
  278. case "AFFORDGATE":
  279. if (parts.Length < 3) return;
  280. CheckList.Add(new NPCChecks(CheckType.AffordGate, parts[1], parts[2]));
  281. break;
  282. case "AFFORDWALL":
  283. if (parts.Length < 3) return;
  284. CheckList.Add(new NPCChecks(CheckType.AffordWall, parts[1], parts[2]));
  285. break;
  286. case "AFFORDSIEGE":
  287. if (parts.Length < 3) return;
  288. CheckList.Add(new NPCChecks(CheckType.AffordSiege, parts[1], parts[2]));
  289. break;
  290. case "CHECKPERMISSION":
  291. if (parts.Length < 2) return;
  292. CheckList.Add(new NPCChecks(CheckType.CheckPermission, parts[1]));
  293. break;
  294. case "CONQUESTAVAILABLE":
  295. if (parts.Length < 2) return;
  296. CheckList.Add(new NPCChecks(CheckType.ConquestAvailable, parts[1]));
  297. break;
  298. case "CONQUESTOWNER":
  299. if (parts.Length < 2) return;
  300. CheckList.Add(new NPCChecks(CheckType.ConquestOwner, parts[1]));
  301. break;
  302. case "CHECKTIMER":
  303. if (parts.Length < 4) return;
  304. CheckList.Add(new NPCChecks(CheckType.CheckTimer, parts[1], parts[2], parts[3]));
  305. break;
  306. case "HASGT":
  307. if (parts.Length < 1)
  308. {
  309. return;
  310. }
  311. CheckList.Add(new NPCChecks(CheckType.HasGT));
  312. break;
  313. case "CHECKBUFF":
  314. if (parts.Length < 2) return;
  315. CheckList.Add(new NPCChecks(CheckType.CheckBuff, parts[1]));
  316. break;
  317. }
  318. }
  319. public void ParseAct(List<NPCActions> acts, string line)
  320. {
  321. var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  322. parts = ParseArguments(parts);
  323. if (parts.Length == 0) return;
  324. string fileName;
  325. var regexQuote = new Regex("\"([^\"]*)\"");
  326. var regexFlag = new Regex(@"\[(.*?)\]");
  327. Match quoteMatch = null;
  328. switch (parts[0].ToUpper())
  329. {
  330. case "MOVE":
  331. if (parts.Length < 2) return;
  332. string tempx = parts.Length > 3 ? parts[2] : "0";
  333. string tempy = parts.Length > 3 ? parts[3] : "0";
  334. acts.Add(new NPCActions(ActionType.Move, parts[1], tempx, tempy));
  335. break;
  336. case "INSTANCEMOVE":
  337. if (parts.Length < 5) return;
  338. acts.Add(new NPCActions(ActionType.InstanceMove, parts[1], parts[2], parts[3], parts[4]));
  339. break;
  340. case "GIVEGOLD":
  341. if (parts.Length < 2) return;
  342. acts.Add(new NPCActions(ActionType.GiveGold, parts[1]));
  343. break;
  344. case "TAKEGOLD":
  345. if (parts.Length < 2) return;
  346. acts.Add(new NPCActions(ActionType.TakeGold, parts[1]));
  347. break;
  348. case "GIVEGUILDGOLD":
  349. if (parts.Length < 2) return;
  350. acts.Add(new NPCActions(ActionType.GiveGuildGold, parts[1]));
  351. break;
  352. case "TAKEGUILDGOLD":
  353. if (parts.Length < 2) return;
  354. acts.Add(new NPCActions(ActionType.TakeGuildGold, parts[1]));
  355. break;
  356. case "GIVECREDIT":
  357. if (parts.Length < 2) return;
  358. acts.Add(new NPCActions(ActionType.GiveCredit, parts[1]));
  359. break;
  360. case "TAKECREDIT":
  361. if (parts.Length < 2) return;
  362. acts.Add(new NPCActions(ActionType.TakeCredit, parts[1]));
  363. break;
  364. case "GIVEPEARLS":
  365. if (parts.Length < 2) return;
  366. acts.Add(new NPCActions(ActionType.GivePearls, parts[1]));
  367. break;
  368. case "TAKEPEARLS":
  369. if (parts.Length < 2) return;
  370. acts.Add(new NPCActions(ActionType.TakePearls, parts[1]));
  371. break;
  372. case "GIVEITEM":
  373. if (parts.Length < 2) return;
  374. string count = parts.Length < 3 ? string.Empty : parts[2];
  375. acts.Add(new NPCActions(ActionType.GiveItem, parts[1], count));
  376. break;
  377. case "TAKEITEM":
  378. if (parts.Length < 3) return;
  379. count = parts.Length < 3 ? string.Empty : parts[2];
  380. string dura = parts.Length > 3 ? parts[3] : "";
  381. acts.Add(new NPCActions(ActionType.TakeItem, parts[1], count, dura));
  382. break;
  383. case "GIVEEXP":
  384. if (parts.Length < 2) return;
  385. acts.Add(new NPCActions(ActionType.GiveExp, parts[1]));
  386. break;
  387. case "GIVEPET":
  388. if (parts.Length < 2) return;
  389. string petcount = parts.Length > 2 ? parts[2] : "1";
  390. string petlevel = parts.Length > 3 ? parts[3] : "0";
  391. acts.Add(new NPCActions(ActionType.GivePet, parts[1], petcount, petlevel));
  392. break;
  393. case "REMOVEPET":
  394. if (parts.Length < 2) return;
  395. acts.Add(new NPCActions(ActionType.RemovePet, parts[1]));
  396. break;
  397. case "CLEARPETS":
  398. acts.Add(new NPCActions(ActionType.ClearPets));
  399. break;
  400. case "GOTO":
  401. if (parts.Length < 2) return;
  402. acts.Add(new NPCActions(ActionType.Goto, parts[1]));
  403. break;
  404. case "CALL":
  405. if (parts.Length < 2) return;
  406. quoteMatch = regexQuote.Match(line);
  407. string listPath = parts[1];
  408. if (quoteMatch.Success)
  409. {
  410. listPath = quoteMatch.Groups[1].Captures[0].Value;
  411. }
  412. fileName = Path.Combine(Settings.NPCPath, listPath + ".txt");
  413. if (!File.Exists(fileName)) return;
  414. var script = NPCScript.GetOrAdd(0, listPath, NPCScriptType.Called);
  415. Page.ScriptCalls.Add(script.ScriptID);
  416. acts.Add(new NPCActions(ActionType.Call, script.ScriptID.ToString()));
  417. break;
  418. case "BREAK":
  419. acts.Add(new NPCActions(ActionType.Break));
  420. break;
  421. //cant use stored var
  422. case "ADDNAMELIST":
  423. if (parts.Length < 2) return;
  424. quoteMatch = regexQuote.Match(line);
  425. listPath = parts[1];
  426. if (quoteMatch.Success)
  427. listPath = quoteMatch.Groups[1].Captures[0].Value;
  428. fileName = Path.Combine(Settings.NameListPath, listPath);
  429. string sDirectory = Path.GetDirectoryName(fileName);
  430. Directory.CreateDirectory(sDirectory);
  431. if (!File.Exists(fileName))
  432. File.Create(fileName).Close();
  433. acts.Add(new NPCActions(ActionType.AddNameList, fileName));
  434. break;
  435. //cant use stored var
  436. case "ADDGUILDNAMELIST":
  437. if (parts.Length < 2) return;
  438. quoteMatch = regexQuote.Match(line);
  439. listPath = parts[1];
  440. if (quoteMatch.Success)
  441. listPath = quoteMatch.Groups[1].Captures[0].Value;
  442. fileName = Path.Combine(Settings.NameListPath, listPath);
  443. sDirectory = Path.GetDirectoryName(fileName);
  444. Directory.CreateDirectory(sDirectory);
  445. if (!File.Exists(fileName))
  446. File.Create(fileName).Close();
  447. acts.Add(new NPCActions(ActionType.AddGuildNameList, fileName));
  448. break;
  449. //cant use stored var
  450. case "DELNAMELIST":
  451. if (parts.Length < 2) return;
  452. quoteMatch = regexQuote.Match(line);
  453. listPath = parts[1];
  454. if (quoteMatch.Success)
  455. listPath = quoteMatch.Groups[1].Captures[0].Value;
  456. fileName = Path.Combine(Settings.NameListPath, listPath);
  457. sDirectory = Path.GetDirectoryName(fileName);
  458. Directory.CreateDirectory(sDirectory);
  459. if (File.Exists(fileName))
  460. acts.Add(new NPCActions(ActionType.DelNameList, fileName));
  461. break;
  462. //cant use stored var
  463. case "DELGUILDNAMELIST":
  464. if (parts.Length < 2) return;
  465. quoteMatch = regexQuote.Match(line);
  466. listPath = parts[1];
  467. if (quoteMatch.Success)
  468. listPath = quoteMatch.Groups[1].Captures[0].Value;
  469. fileName = Path.Combine(Settings.NameListPath, listPath);
  470. sDirectory = Path.GetDirectoryName(fileName);
  471. Directory.CreateDirectory(sDirectory);
  472. if (File.Exists(fileName))
  473. acts.Add(new NPCActions(ActionType.DelGuildNameList, fileName));
  474. break;
  475. //cant use stored var
  476. case "CLEARNAMELIST":
  477. if (parts.Length < 2) return;
  478. quoteMatch = regexQuote.Match(line);
  479. listPath = parts[1];
  480. if (quoteMatch.Success)
  481. listPath = quoteMatch.Groups[1].Captures[0].Value;
  482. fileName = Path.Combine(Settings.NameListPath, listPath);
  483. sDirectory = Path.GetDirectoryName(fileName);
  484. Directory.CreateDirectory(sDirectory);
  485. if (File.Exists(fileName))
  486. acts.Add(new NPCActions(ActionType.ClearNameList, fileName));
  487. break;
  488. //cant use stored var
  489. case "CLEARGUILDNAMELIST":
  490. if (parts.Length < 2) return;
  491. quoteMatch = regexQuote.Match(line);
  492. listPath = parts[1];
  493. if (quoteMatch.Success)
  494. listPath = quoteMatch.Groups[1].Captures[0].Value;
  495. fileName = Path.Combine(Settings.NameListPath, listPath);
  496. sDirectory = Path.GetDirectoryName(fileName);
  497. Directory.CreateDirectory(sDirectory);
  498. if (File.Exists(fileName))
  499. acts.Add(new NPCActions(ActionType.ClearGuildNameList, fileName));
  500. break;
  501. case "GIVEHP":
  502. if (parts.Length < 2) return;
  503. acts.Add(new NPCActions(ActionType.GiveHP, parts[1]));
  504. break;
  505. case "GIVEMP":
  506. if (parts.Length < 2) return;
  507. acts.Add(new NPCActions(ActionType.GiveMP, parts[1]));
  508. break;
  509. case "CHANGELEVEL":
  510. if (parts.Length < 2) return;
  511. acts.Add(new NPCActions(ActionType.ChangeLevel, parts[1]));
  512. break;
  513. case "SETPKPOINT":
  514. if (parts.Length < 2) return;
  515. acts.Add(new NPCActions(ActionType.SetPkPoint, parts[1]));
  516. break;
  517. case "REDUCEPKPOINT":
  518. if (parts.Length < 2) return;
  519. acts.Add(new NPCActions(ActionType.ReducePkPoint, parts[1]));
  520. break;
  521. case "INCREASEPKPOINT":
  522. if (parts.Length < 2) return;
  523. acts.Add(new NPCActions(ActionType.IncreasePkPoint, parts[1]));
  524. break;
  525. case "CHANGEGENDER":
  526. acts.Add(new NPCActions(ActionType.ChangeGender));
  527. break;
  528. case "CHANGECLASS":
  529. if (parts.Length < 2) return;
  530. acts.Add(new NPCActions(ActionType.ChangeClass, parts[1]));
  531. break;
  532. case "CHANGEHAIR":
  533. if (parts.Length < 2)
  534. {
  535. acts.Add(new NPCActions(ActionType.ChangeHair));
  536. }
  537. else
  538. {
  539. acts.Add(new NPCActions(ActionType.ChangeHair, parts[1]));
  540. }
  541. break;
  542. case "LOCALMESSAGE":
  543. var match = regexQuote.Match(line);
  544. if (match.Success)
  545. {
  546. var message = match.Groups[1].Captures[0].Value;
  547. var last = parts.Count() - 1;
  548. acts.Add(new NPCActions(ActionType.LocalMessage, message, parts[last]));
  549. }
  550. break;
  551. case "GLOBALMESSAGE":
  552. match = regexQuote.Match(line);
  553. if (match.Success)
  554. {
  555. var message = match.Groups[1].Captures[0].Value;
  556. var last = parts.Count() - 1;
  557. acts.Add(new NPCActions(ActionType.GlobalMessage, message, parts[last]));
  558. }
  559. break;
  560. case "GIVESKILL":
  561. if (parts.Length < 3) return;
  562. string spelllevel = parts.Length > 2 ? parts[2] : "0";
  563. acts.Add(new NPCActions(ActionType.GiveSkill, parts[1], spelllevel));
  564. break;
  565. case "REMOVESKILL":
  566. if (parts.Length < 2) return;
  567. acts.Add(new NPCActions(ActionType.RemoveSkill, parts[1]));
  568. break;
  569. //cant use stored var
  570. case "SET":
  571. if (parts.Length < 3) return;
  572. match = regexFlag.Match(parts[1]);
  573. if (match.Success)
  574. {
  575. string flagIndex = match.Groups[1].Captures[0].Value;
  576. acts.Add(new NPCActions(ActionType.Set, flagIndex, parts[2]));
  577. }
  578. break;
  579. case "PARAM1":
  580. if (parts.Length < 2) return;
  581. string instanceId = parts.Length < 3 ? "1" : parts[2];
  582. acts.Add(new NPCActions(ActionType.Param1, parts[1], instanceId));
  583. break;
  584. case "PARAM2":
  585. if (parts.Length < 2) return;
  586. acts.Add(new NPCActions(ActionType.Param2, parts[1]));
  587. break;
  588. case "PARAM3":
  589. if (parts.Length < 2) return;
  590. acts.Add(new NPCActions(ActionType.Param3, parts[1]));
  591. break;
  592. case "MONGEN":
  593. if (parts.Length < 2) return;
  594. count = parts.Length < 3 ? "1" : parts[2];
  595. acts.Add(new NPCActions(ActionType.Mongen, parts[1], count));
  596. break;
  597. case "TIMERECALL":
  598. if (parts.Length < 2) return;
  599. string page = parts.Length > 2 ? parts[2] : "";
  600. acts.Add(new NPCActions(ActionType.TimeRecall, parts[1], page));
  601. break;
  602. case "TIMERECALLGROUP":
  603. if (parts.Length < 2) return;
  604. page = parts.Length > 2 ? parts[2] : "";
  605. acts.Add(new NPCActions(ActionType.TimeRecallGroup, parts[1], page));
  606. break;
  607. case "BREAKTIMERECALL":
  608. acts.Add(new NPCActions(ActionType.BreakTimeRecall));
  609. break;
  610. case "DELAYGOTO":
  611. if (parts.Length < 3) return;
  612. acts.Add(new NPCActions(ActionType.DelayGoto, parts[1], parts[2]));
  613. break;
  614. case "MONCLEAR":
  615. if (parts.Length < 2) return;
  616. instanceId = parts.Length < 3 ? "1" : parts[2];
  617. string mobName = parts.Length < 4 ? "" : parts[3];
  618. acts.Add(new NPCActions(ActionType.MonClear, parts[1], instanceId, mobName));
  619. break;
  620. case "GROUPRECALL":
  621. acts.Add(new NPCActions(ActionType.GroupRecall));
  622. break;
  623. case "GROUPTELEPORT":
  624. if (parts.Length < 2) return;
  625. string x;
  626. string y;
  627. if (parts.Length == 4)
  628. {
  629. instanceId = "1";
  630. x = parts[2];
  631. y = parts[3];
  632. }
  633. else
  634. {
  635. instanceId = parts.Length < 3 ? "1" : parts[2];
  636. x = parts.Length < 4 ? "0" : parts[3];
  637. y = parts.Length < 5 ? "0" : parts[4];
  638. }
  639. acts.Add(new NPCActions(ActionType.GroupTeleport, parts[1], instanceId, x, y));
  640. break;
  641. case "MOV":
  642. if (parts.Length < 3) return;
  643. match = Regex.Match(parts[1], @"[A-Z][0-9]", RegexOptions.IgnoreCase);
  644. quoteMatch = regexQuote.Match(line);
  645. string valueToStore = parts[2];
  646. if (quoteMatch.Success)
  647. valueToStore = quoteMatch.Groups[1].Captures[0].Value;
  648. if (match.Success)
  649. acts.Add(new NPCActions(ActionType.Mov, parts[1], valueToStore));
  650. break;
  651. case "CALC":
  652. if (parts.Length < 4) return;
  653. match = Regex.Match(parts[1], @"[A-Z][0-9]", RegexOptions.IgnoreCase);
  654. quoteMatch = regexQuote.Match(line);
  655. valueToStore = parts[3];
  656. if (quoteMatch.Success)
  657. valueToStore = quoteMatch.Groups[1].Captures[0].Value;
  658. if (match.Success)
  659. acts.Add(new NPCActions(ActionType.Calc, "%" + parts[1], parts[2], valueToStore, parts[1].Insert(1, "-")));
  660. break;
  661. case "GIVEBUFF":
  662. if (parts.Length < 4) return;
  663. string visible = "";
  664. string infinite = "";
  665. string stackable = "";
  666. if (parts.Length > 3) visible = parts[3];
  667. if (parts.Length > 4) infinite = parts[4];
  668. if (parts.Length > 5) stackable = parts[5];
  669. acts.Add(new NPCActions(ActionType.GiveBuff, parts[1], parts[2], visible, infinite, stackable));
  670. break;
  671. case "REMOVEBUFF":
  672. if (parts.Length < 2) return;
  673. acts.Add(new NPCActions(ActionType.RemoveBuff, parts[1]));
  674. break;
  675. case "ADDTOGUILD":
  676. if (parts.Length < 2) return;
  677. acts.Add(new NPCActions(ActionType.AddToGuild, parts[1]));
  678. break;
  679. case "REMOVEFROMGUILD":
  680. if (parts.Length < 2) return;
  681. acts.Add(new NPCActions(ActionType.RemoveFromGuild, parts[1]));
  682. break;
  683. case "REFRESHEFFECTS":
  684. acts.Add(new NPCActions(ActionType.RefreshEffects));
  685. break;
  686. case "CANGAINEXP":
  687. if (parts.Length < 2) return;
  688. acts.Add(new NPCActions(ActionType.CanGainExp, parts[1]));
  689. break;
  690. case "COMPOSEMAIL":
  691. match = regexQuote.Match(line);
  692. if (match.Success)
  693. {
  694. var message = match.Groups[1].Captures[0].Value;
  695. var last = parts.Count() - 1;
  696. acts.Add(new NPCActions(ActionType.ComposeMail, message, parts[last]));
  697. }
  698. break;
  699. case "ADDMAILGOLD":
  700. if (parts.Length < 2) return;
  701. acts.Add(new NPCActions(ActionType.AddMailGold, parts[1]));
  702. break;
  703. case "ADDMAILITEM":
  704. if (parts.Length < 3) return;
  705. acts.Add(new NPCActions(ActionType.AddMailItem, parts[1], parts[2]));
  706. break;
  707. case "SENDMAIL":
  708. acts.Add(new NPCActions(ActionType.SendMail));
  709. break;
  710. case "GROUPGOTO":
  711. if (parts.Length < 2) return;
  712. acts.Add(new NPCActions(ActionType.GroupGoto, parts[1]));
  713. break;
  714. case "ENTERMAP":
  715. acts.Add(new NPCActions(ActionType.EnterMap));
  716. break;
  717. case "MAKEWEDDINGRING":
  718. acts.Add(new NPCActions(ActionType.MakeWeddingRing));
  719. break;
  720. case "FORCEDIVORCE":
  721. acts.Add(new NPCActions(ActionType.ForceDivorce));
  722. break;
  723. case "LOADVALUE":
  724. if (parts.Length < 5) return;
  725. quoteMatch = regexQuote.Match(line);
  726. if (quoteMatch.Success)
  727. {
  728. fileName = Path.Combine(Settings.ValuePath, quoteMatch.Groups[1].Captures[0].Value);
  729. string group = parts[parts.Length - 2];
  730. string key = parts[parts.Length - 1];
  731. sDirectory = Path.GetDirectoryName(fileName);
  732. Directory.CreateDirectory(sDirectory);
  733. if (!File.Exists(fileName))
  734. File.Create(fileName).Close();
  735. acts.Add(new NPCActions(ActionType.LoadValue, parts[1], fileName, group, key));
  736. }
  737. break;
  738. case "SAVEVALUE":
  739. if (parts.Length < 5) return;
  740. MatchCollection matchCol = regexQuote.Matches(line);
  741. if (matchCol.Count > 0 && matchCol[0].Success)
  742. {
  743. fileName = Path.Combine(Settings.ValuePath, matchCol[0].Groups[1].Captures[0].Value);
  744. string value = parts[parts.Length - 1];
  745. if (matchCol.Count > 1 && matchCol[1].Success)
  746. value = matchCol[1].Groups[1].Captures[0].Value;
  747. string[] newParts = line.Replace(value, string.Empty).Replace("\"", "").Trim().Split(' ');
  748. string group = newParts[newParts.Length - 2];
  749. string key = newParts[newParts.Length - 1];
  750. sDirectory = Path.GetDirectoryName(fileName);
  751. Directory.CreateDirectory(sDirectory);
  752. if (!File.Exists(fileName))
  753. File.Create(fileName).Close();
  754. acts.Add(new NPCActions(ActionType.SaveValue, fileName, group, key, value));
  755. }
  756. break;
  757. case "CONQUESTGUARD":
  758. if (parts.Length < 3) return;
  759. acts.Add(new NPCActions(ActionType.ConquestGuard, parts[1], parts[2]));
  760. break;
  761. case "CONQUESTGATE":
  762. if (parts.Length < 3) return;
  763. acts.Add(new NPCActions(ActionType.ConquestGate, parts[1], parts[2]));
  764. break;
  765. case "CONQUESTWALL":
  766. if (parts.Length < 3) return;
  767. acts.Add(new NPCActions(ActionType.ConquestWall, parts[1], parts[2]));
  768. break;
  769. case "TAKECONQUESTGOLD":
  770. if (parts.Length < 2) return;
  771. acts.Add(new NPCActions(ActionType.TakeConquestGold, parts[1]));
  772. break;
  773. case "SETCONQUESTRATE":
  774. if (parts.Length < 3) return;
  775. acts.Add(new NPCActions(ActionType.SetConquestRate, parts[1], parts[2]));
  776. break;
  777. case "STARTCONQUEST":
  778. if (parts.Length < 2) return;
  779. acts.Add(new NPCActions(ActionType.StartConquest, parts[1]));
  780. break;
  781. case "SCHEDULECONQUEST":
  782. if (parts.Length < 2) return;
  783. acts.Add(new NPCActions(ActionType.ScheduleConquest, parts[1]));
  784. break;
  785. case "OPENGATE":
  786. if (parts.Length < 3) return;
  787. acts.Add(new NPCActions(ActionType.OpenGate, parts[1], parts[2]));
  788. break;
  789. case "CLOSEGATE":
  790. if (parts.Length < 3) return;
  791. acts.Add(new NPCActions(ActionType.CloseGate, parts[1], parts[2]));
  792. break;
  793. case "OPENBROWSER":
  794. if (parts.Length < 2) return;
  795. acts.Add(new NPCActions(ActionType.OpenBrowser, parts[1]));
  796. break;
  797. case "GETRANDOMTEXT":
  798. if (parts.Length < 3) return;
  799. match = Regex.Match(parts[2], @"[A-Z][0-9]", RegexOptions.IgnoreCase);
  800. if (match.Success)
  801. acts.Add(new NPCActions(ActionType.GetRandomText, parts[1], parts[2]));
  802. break;
  803. case "PLAYSOUND":
  804. if (parts.Length < 2) return;
  805. acts.Add(new NPCActions(ActionType.PlaySound, parts[1]));
  806. break;
  807. case "SETTIMER":
  808. {
  809. if (parts.Length < 4) return;
  810. string global = parts.Length < 5 ? "" : parts[4];
  811. acts.Add(new NPCActions(ActionType.SetTimer, parts[1], parts[2], parts[3], global));
  812. }
  813. break;
  814. case "EXPIRETIMER":
  815. {
  816. if (parts.Length < 2) return;
  817. acts.Add(new NPCActions(ActionType.ExpireTimer, parts[1]));
  818. }
  819. break;
  820. case "UNEQUIPITEM":
  821. var type = "";
  822. if (parts.Length >= 2)
  823. {
  824. type = parts[1];
  825. }
  826. acts.Add(new NPCActions(ActionType.UnequipItem, type));
  827. break;
  828. case "ROLLDIE":
  829. if (parts.Length < 3) return;
  830. acts.Add(new NPCActions(ActionType.RollDie, parts[1], parts[2]));
  831. break;
  832. case "ROLLYUT":
  833. if (parts.Length < 3) return;
  834. acts.Add(new NPCActions(ActionType.RollYut, parts[1], parts[2]));
  835. break;
  836. case "DROP":
  837. if (parts.Length < 2) return;
  838. quoteMatch = regexQuote.Match(line);
  839. listPath = parts[1];
  840. if (quoteMatch.Success)
  841. listPath = quoteMatch.Groups[1].Captures[0].Value;
  842. fileName = Path.Combine(Settings.DropPath, listPath);
  843. acts.Add(new NPCActions(ActionType.Drop, fileName));
  844. break;
  845. case "REVIVEHERO":
  846. acts.Add(new NPCActions(ActionType.ReviveHero));
  847. break;
  848. case "SEALHERO":
  849. acts.Add(new NPCActions(ActionType.SealHero));
  850. break;
  851. case "DELETEHERO":
  852. acts.Add(new NPCActions(ActionType.DeleteHero));
  853. break;
  854. case "CONQUESTREPAIRALL":
  855. if (parts.Length < 2) return;
  856. acts.Add(new NPCActions(ActionType.ConquestRepairAll, parts[1]));
  857. break;
  858. case "BUYGT":
  859. if (parts.Length < 1)
  860. {
  861. return;
  862. }
  863. acts.Add(new NPCActions(ActionType.BuyGT));
  864. break;
  865. case "TELEPORTGT":
  866. if (parts.Length < 1)
  867. {
  868. return;
  869. }
  870. acts.Add(new NPCActions(ActionType.TeleportGT));
  871. break;
  872. case "EXTENDGT":
  873. if (parts.Length < 1)
  874. {
  875. return;
  876. }
  877. acts.Add(new NPCActions(ActionType.ExtendGT));
  878. break;
  879. case "GTRECALL":
  880. acts.Add(new NPCActions(ActionType.GTRecall, parts[1]));
  881. break;
  882. case "GTALLRECALL":
  883. acts.Add(new NPCActions(ActionType.GTAllRecall));
  884. break;
  885. case "GTSALE":
  886. acts.Add(new NPCActions(ActionType.GTSale, parts[1]));
  887. break;
  888. case "CANCELGTSALE":
  889. acts.Add(new NPCActions(ActionType.GTCancelSale));
  890. break;
  891. case "HEROGIVESKILL":
  892. if (parts.Length < 3) return;
  893. spelllevel = parts.Length > 2 ? parts[2] : "0";
  894. acts.Add(new NPCActions(ActionType.HeroGiveSkill, parts[1], spelllevel));
  895. break;
  896. case "HEROREMOVESKILL":
  897. if (parts.Length < 2) return;
  898. acts.Add(new NPCActions(ActionType.HeroRemoveSkill, parts[1]));
  899. break;
  900. }
  901. }
  902. public List<string> ParseSay(PlayerObject player, List<string> speech)
  903. {
  904. for (var i = 0; i < speech.Count; i++)
  905. {
  906. var parts = speech[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  907. if (parts.Length == 0) continue;
  908. foreach (var part in parts)
  909. {
  910. speech[i] = speech[i].Replace(part, ReplaceValue(player, part));
  911. }
  912. }
  913. return LinkFormatter.ReplacePlaceholders(speech, (type, index) => EnsureLinkInfo(player, type, index)) ?? speech;
  914. }
  915. private static void EnsureLinkInfo(PlayerObject player, string linkType, int index)
  916. {
  917. if (player?.Connection == null) return;
  918. switch (linkType)
  919. {
  920. case "ITEM":
  921. var itemInfo = Envir.GetItemInfo(index);
  922. if (itemInfo != null)
  923. player.Connection.CheckItemInfo(itemInfo);
  924. break;
  925. case "MONSTER":
  926. player.Connection.CheckMonsterInfo(index);
  927. break;
  928. case "NPC":
  929. player.Connection.CheckNPCInfo(index);
  930. break;
  931. }
  932. }
  933. public string ReplaceValue(PlayerObject player, string param)
  934. {
  935. var regex = new Regex(@"\<\$(.*)\>");
  936. var varRegex = new Regex(@"(.*?)\(([A-Z][0-9])\)");
  937. var oneValRegex = new Regex(@"(.*?)\(((.*?))\)");
  938. var twoValRegex = new Regex(@"(.*?)\(((.*?),(.*?))\)");
  939. ConquestObject Conquest;
  940. ConquestGuildArcherInfo Archer;
  941. ConquestGuildGateInfo Gate;
  942. ConquestGuildWallInfo Wall;
  943. ConquestGuildSiegeInfo Siege;
  944. var match = regex.Match(param);
  945. if (!match.Success) return param;
  946. string innerMatch = match.Groups[1].Captures[0].Value.ToUpper();
  947. Match varMatch = varRegex.Match(innerMatch);
  948. Match oneValMatch = oneValRegex.Match(innerMatch);
  949. Match twoValMatch = twoValRegex.Match(innerMatch);
  950. if (varRegex.Match(innerMatch).Success)
  951. innerMatch = innerMatch.Replace(varMatch.Groups[2].Captures[0].Value.ToUpper(), "");
  952. else if (twoValRegex.Match(innerMatch).Success)
  953. innerMatch = innerMatch.Replace(twoValMatch.Groups[2].Captures[0].Value.ToUpper(), "");
  954. else if (oneValRegex.Match(innerMatch).Success)
  955. innerMatch = innerMatch.Replace(oneValMatch.Groups[2].Captures[0].Value.ToUpper(), "");
  956. string newValue = string.Empty;
  957. switch (innerMatch)
  958. {
  959. case "MONSTERCOUNT()":
  960. Map map = Envir.GetMapByNameAndInstance(oneValMatch.Groups[2].Captures[0].Value.ToUpper());
  961. newValue = map == null ? "N/A" : map.MonsterCount.ToString();
  962. break;
  963. case "CONQUESTGUARD()":
  964. var val1 = FindVariable(player, "%" + twoValMatch.Groups[3].Captures[0].Value.ToUpper());
  965. var val2 = FindVariable(player, "%" + twoValMatch.Groups[4].Captures[0].Value.ToUpper());
  966. int intVal1, intVal2;
  967. if (int.TryParse(val1.Replace("%", ""), out intVal1) && int.TryParse(val2.Replace("%", ""), out intVal2))
  968. {
  969. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  970. if (Conquest == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  971. Archer = Conquest.ArcherList.FirstOrDefault(x => x.Index == intVal2);
  972. if (Archer == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  973. if (Archer.Info.Name == "" || Archer.Info.Name == null)
  974. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.ConquestGuard);
  975. else
  976. newValue = Archer.Info.Name;
  977. if (Archer.GetRepairCost() == 0)
  978. newValue += GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.StillAlive);
  979. else
  980. newValue += GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GoldCost), Archer.GetRepairCost().ToString("#,##0"));
  981. }
  982. break;
  983. case "CONQUESTGATE()":
  984. val1 = FindVariable(player, "%" + twoValMatch.Groups[3].Captures[0].Value.ToUpper());
  985. val2 = FindVariable(player, "%" + twoValMatch.Groups[4].Captures[0].Value.ToUpper());
  986. if (int.TryParse(val1.Replace("%", ""), out intVal1) && int.TryParse(val2.Replace("%", ""), out intVal2))
  987. {
  988. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  989. if (Conquest == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  990. Gate = Conquest.GateList.FirstOrDefault(x => x.Index == intVal2);
  991. if (Gate == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  992. if (Gate.Info.Name == "" || Gate.Info.Name == null)
  993. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.ConquestGate);
  994. else
  995. newValue = Gate.Info.Name;
  996. if (Gate.GetRepairCost() == 0)
  997. newValue += GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoRepairRequired);
  998. else
  999. newValue += GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GoldCost), Gate.GetRepairCost().ToString("#,##0"));
  1000. }
  1001. break;
  1002. case "CONQUESTWALL()":
  1003. val1 = FindVariable(player, "%" + twoValMatch.Groups[3].Captures[0].Value.ToUpper());
  1004. val2 = FindVariable(player, "%" + twoValMatch.Groups[4].Captures[0].Value.ToUpper());
  1005. if (int.TryParse(val1.Replace("%", ""), out intVal1) && int.TryParse(val2.Replace("%", ""), out intVal2))
  1006. {
  1007. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  1008. if (Conquest == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  1009. Wall = Conquest.WallList.FirstOrDefault(x => x.Index == intVal2);
  1010. if (Wall == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  1011. if (Wall.Info.Name == "" || Wall.Info.Name == null)
  1012. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.ConquestWall);
  1013. else
  1014. newValue = Wall.Info.Name;
  1015. if (Wall.GetRepairCost() == 0)
  1016. newValue += GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoRepairRequired);
  1017. else
  1018. newValue += GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GoldCost), Wall.GetRepairCost().ToString("#,##0"));
  1019. }
  1020. break;
  1021. case "CONQUESTSIEGE()":
  1022. val1 = FindVariable(player, "%" + twoValMatch.Groups[3].Captures[0].Value.ToUpper());
  1023. val2 = FindVariable(player, "%" + twoValMatch.Groups[4].Captures[0].Value.ToUpper());
  1024. if (int.TryParse(val1.Replace("%", ""), out intVal1) && int.TryParse(val2.Replace("%", ""), out intVal2))
  1025. {
  1026. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  1027. if (Conquest == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  1028. Siege = Conquest.SiegeList.FirstOrDefault(x => x.Index == intVal2);
  1029. if (Siege == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotFound);
  1030. if (Siege.Info.Name == "" || Siege.Info.Name == null)
  1031. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.ConquestSiege);
  1032. else
  1033. newValue = Siege.Info.Name;
  1034. if (Siege.GetRepairCost() == 0)
  1035. newValue += GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.StillAlive);
  1036. else
  1037. newValue += GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GoldCost), Siege.GetRepairCost().ToString("#,##0"));
  1038. }
  1039. break;
  1040. case "CONQUESTOWNER()":
  1041. val1 = FindVariable(player, "%" + oneValMatch.Groups[2].Captures[0].Value.ToUpper());
  1042. if (int.TryParse(val1.Replace("%", ""), out intVal1))
  1043. {
  1044. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  1045. if (Conquest == null) return string.Empty;
  1046. if (Conquest.Guild == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoOwner);
  1047. newValue = Conquest.Guild.Name;
  1048. }
  1049. break;
  1050. case "CONQUESTGOLD()":
  1051. val1 = FindVariable(player, "%" + oneValMatch.Groups[2].Captures[0].Value.ToUpper());
  1052. if (int.TryParse(val1.Replace("%", ""), out intVal1))
  1053. {
  1054. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  1055. if (Conquest == null) return string.Empty;
  1056. newValue = Conquest.GuildInfo.GoldStorage.ToString();
  1057. }
  1058. break;
  1059. case "CONQUESTRATE()":
  1060. val1 = FindVariable(player, "%" + oneValMatch.Groups[2].Captures[0].Value.ToUpper());
  1061. if (int.TryParse(val1.Replace("%", ""), out intVal1))
  1062. {
  1063. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  1064. if (Conquest == null) return string.Empty;
  1065. newValue = Conquest.GuildInfo.NPCRate.ToString() + "%";
  1066. }
  1067. break;
  1068. case "CONQUESTSCHEDULE()":
  1069. val1 = FindVariable(player, "%" + oneValMatch.Groups[2].Captures[0].Value.ToUpper());
  1070. if (int.TryParse(val1.Replace("%", ""), out intVal1))
  1071. {
  1072. Conquest = Envir.Conquests.FirstOrDefault(x => x.Info.Index == intVal1);
  1073. if (Conquest == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.ConquestNotFound);
  1074. if (Conquest.GuildInfo.AttackerID == -1) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoWarScheduled);
  1075. if (Envir.Guilds.FirstOrDefault(x => x.Guildindex == Conquest.GuildInfo.AttackerID) == null)
  1076. {
  1077. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoWarScheduled);
  1078. }
  1079. else
  1080. {
  1081. newValue = (Envir.Guilds.FirstOrDefault(x => x.Guildindex == Conquest.GuildInfo.AttackerID).Name);
  1082. }
  1083. }
  1084. break;
  1085. case "OUTPUT()":
  1086. newValue = FindVariable(player, "%" + varMatch.Groups[2].Captures[0].Value.ToUpper());
  1087. break;
  1088. case "NPCNAME":
  1089. for (int i = 0; i < player.CurrentMap.NPCs.Count; i++)
  1090. {
  1091. NPCObject ob = player.CurrentMap.NPCs[i];
  1092. if (ob.ObjectID != player.NPCObjectID) continue;
  1093. newValue = ob.Name.Replace("_", " ");
  1094. }
  1095. break;
  1096. case "USERNAME":
  1097. newValue = player.Name;
  1098. break;
  1099. case "LEVEL":
  1100. newValue = player.Level.ToString(CultureInfo.InvariantCulture);
  1101. break;
  1102. case "CLASS":
  1103. newValue = player.Class.ToString();
  1104. break;
  1105. case "MAP":
  1106. newValue = player.CurrentMap.Info.FileName;
  1107. break;
  1108. case "X_COORD":
  1109. newValue = player.CurrentLocation.X.ToString();
  1110. break;
  1111. case "Y_COORD":
  1112. newValue = player.CurrentLocation.Y.ToString();
  1113. break;
  1114. case "HP":
  1115. newValue = player.HP.ToString(CultureInfo.InvariantCulture);
  1116. break;
  1117. case "MAXHP":
  1118. newValue = player.Stats[Stat.HP].ToString(CultureInfo.InvariantCulture);
  1119. break;
  1120. case "MP":
  1121. newValue = player.MP.ToString(CultureInfo.InvariantCulture);
  1122. break;
  1123. case "MAXMP":
  1124. newValue = player.Stats[Stat.MP].ToString(CultureInfo.InvariantCulture);
  1125. break;
  1126. case "GAMEGOLD":
  1127. newValue = player.Account.Gold.ToString(CultureInfo.InvariantCulture);
  1128. break;
  1129. case "CREDIT":
  1130. newValue = player.Account.Credit.ToString(CultureInfo.InvariantCulture);
  1131. break;
  1132. case "ARMOUR":
  1133. newValue = player.Info.Equipment[(int)EquipmentSlot.Armour] != null ?
  1134. player.Info.Equipment[(int)EquipmentSlot.Armour].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoArmour);
  1135. break;
  1136. case "WEAPON":
  1137. newValue = player.Info.Equipment[(int)EquipmentSlot.Weapon] != null ?
  1138. player.Info.Equipment[(int)EquipmentSlot.Weapon].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoWeapon);
  1139. break;
  1140. case "RING_L":
  1141. newValue = player.Info.Equipment[(int)EquipmentSlot.RingL] != null ?
  1142. player.Info.Equipment[(int)EquipmentSlot.RingL].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoRing);
  1143. break;
  1144. case "RING_R":
  1145. newValue = player.Info.Equipment[(int)EquipmentSlot.RingR] != null ?
  1146. player.Info.Equipment[(int)EquipmentSlot.RingR].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoRing);
  1147. break;
  1148. case "BRACELET_L":
  1149. newValue = player.Info.Equipment[(int)EquipmentSlot.BraceletL] != null ?
  1150. player.Info.Equipment[(int)EquipmentSlot.BraceletL].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoBracelet);
  1151. break;
  1152. case "BRACELET_R":
  1153. newValue = player.Info.Equipment[(int)EquipmentSlot.BraceletR] != null ?
  1154. player.Info.Equipment[(int)EquipmentSlot.BraceletR].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoBracelet);
  1155. break;
  1156. case "NECKLACE":
  1157. newValue = player.Info.Equipment[(int)EquipmentSlot.Necklace] != null ?
  1158. player.Info.Equipment[(int)EquipmentSlot.Necklace].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoNecklace);
  1159. break;
  1160. case "BELT":
  1161. newValue = player.Info.Equipment[(int)EquipmentSlot.Belt] != null ?
  1162. player.Info.Equipment[(int)EquipmentSlot.Belt].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoBelt);
  1163. break;
  1164. case "BOOTS":
  1165. newValue = player.Info.Equipment[(int)EquipmentSlot.Boots] != null ?
  1166. player.Info.Equipment[(int)EquipmentSlot.Boots].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoBoots);
  1167. break;
  1168. case "HELMET":
  1169. newValue = player.Info.Equipment[(int)EquipmentSlot.Helmet] != null ?
  1170. player.Info.Equipment[(int)EquipmentSlot.Helmet].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoHelmet);
  1171. break;
  1172. case "AMULET":
  1173. newValue = player.Info.Equipment[(int)EquipmentSlot.Amulet] != null ?
  1174. player.Info.Equipment[(int)EquipmentSlot.Amulet].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoAmulet);
  1175. break;
  1176. case "STONE":
  1177. newValue = player.Info.Equipment[(int)EquipmentSlot.Stone] != null ?
  1178. player.Info.Equipment[(int)EquipmentSlot.Stone].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoStone);
  1179. break;
  1180. case "TORCH":
  1181. newValue = player.Info.Equipment[(int)EquipmentSlot.Torch] != null ?
  1182. player.Info.Equipment[(int)EquipmentSlot.Torch].FriendlyName : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoTorch);
  1183. break;
  1184. case "DATE":
  1185. newValue = Envir.Now.ToShortDateString();
  1186. break;
  1187. case "MAPLIGHT":
  1188. newValue = Envir.Lights.ToString();
  1189. break;
  1190. case "USERCOUNT":
  1191. newValue = Envir.PlayerCount.ToString(CultureInfo.InvariantCulture);
  1192. break;
  1193. case "PKPOINT":
  1194. newValue = player.PKPoints.ToString();
  1195. break;
  1196. case "GUILDWARTIME":
  1197. newValue = Settings.Guild_WarTime.ToString();
  1198. break;
  1199. case "GUILDWARFEE":
  1200. newValue = Settings.Guild_WarCost.ToString();
  1201. break;
  1202. case "PARCELAMOUNT":
  1203. newValue = player.GetMailAwaitingCollectionAmount().ToString();
  1204. break;
  1205. case "GUILDNAME":
  1206. if (player.MyGuild == null) return GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoGuild);
  1207. else
  1208. newValue = string.Format("{0} {1}",player.MyGuild.Name, GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.Guild));
  1209. break;
  1210. case "ROLLRESULT":
  1211. newValue = player.NPCData.TryGetValue("NPCRollResult", out object _rollResult) ? _rollResult.ToString() : GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NotRolled);
  1212. break;
  1213. case "MOUNTLOYALTY":
  1214. if (!player.Mount.HasMount)
  1215. {
  1216. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoMount);
  1217. }
  1218. else
  1219. {
  1220. newValue = $"{player.Info.Equipment[(int)EquipmentSlot.Mount].CurrentDura} ({player.Info.Equipment[(int)EquipmentSlot.Mount].MaxDura})";
  1221. }
  1222. break;
  1223. case "MOUNT":
  1224. if (player.Mount.HasMount)
  1225. {
  1226. newValue = player.Info.Equipment[(int)EquipmentSlot.Mount].FriendlyName;
  1227. }
  1228. else
  1229. {
  1230. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoMount);
  1231. }
  1232. break;
  1233. default:
  1234. newValue = string.Empty;
  1235. break;
  1236. case "GUILDEXTENDFEE":
  1237. if (player.MyGuild != null && player.MyGuild.HasGT)
  1238. {
  1239. newValue = GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ExpireOnExtendFee), player.MyGuild.GTRent.ToString(), Settings.ExtendGT.ToString())
  1240. ;
  1241. }
  1242. else
  1243. {
  1244. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.None);
  1245. }
  1246. break;
  1247. case "GUILDRENTFEE":
  1248. newValue = Settings.BuyGTGold.ToString();
  1249. break;
  1250. case "GUILDGTRENTALDAYSLEFT":
  1251. if (player.MyGuild == null)
  1252. {
  1253. newValue = "0";
  1254. break;
  1255. }
  1256. newValue = (player.MyGuild.GTRent - Envir.Now).Days.ToString();
  1257. break;
  1258. case "AGITGUILDNAME":
  1259. if (player.MyGuild == null)
  1260. {
  1261. newValue = GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.UpperNoGuild);
  1262. break;
  1263. }
  1264. newValue = (player.MyGuild.Name);
  1265. break;
  1266. }
  1267. if (string.IsNullOrEmpty(newValue)) return param;
  1268. return param.Replace(match.Value, newValue);
  1269. }
  1270. public string ReplaceValue(MonsterObject Monster, string param)
  1271. {
  1272. var regex = new Regex(@"\<\$(.*)\>");
  1273. var varRegex = new Regex(@"(.*?)\(([A-Z][0-9])\)");
  1274. var match = regex.Match(param);
  1275. if (!match.Success) return param;
  1276. string innerMatch = match.Groups[1].Captures[0].Value.ToUpper();
  1277. Match varMatch = varRegex.Match(innerMatch);
  1278. if (varRegex.Match(innerMatch).Success)
  1279. innerMatch = innerMatch.Replace(varMatch.Groups[2].Captures[0].Value.ToUpper(), "");
  1280. string newValue = string.Empty;
  1281. switch (innerMatch)
  1282. {
  1283. case "OUTPUT()":
  1284. newValue = FindVariable(Monster, "%" + varMatch.Groups[2].Captures[0].Value.ToUpper());
  1285. break;
  1286. case "USERNAME":
  1287. newValue = Monster.Name;
  1288. break;
  1289. case "LEVEL":
  1290. newValue = Monster.Level.ToString(CultureInfo.InvariantCulture);
  1291. break;
  1292. case "MAP":
  1293. newValue = Monster.CurrentMap.Info.FileName;
  1294. break;
  1295. case "X_COORD":
  1296. newValue = Monster.CurrentLocation.X.ToString();
  1297. break;
  1298. case "Y_COORD":
  1299. newValue = Monster.CurrentLocation.Y.ToString();
  1300. break;
  1301. case "HP":
  1302. newValue = Monster.HP.ToString(CultureInfo.InvariantCulture);
  1303. break;
  1304. case "MAXHP":
  1305. newValue = Monster.Stats[Stat.HP].ToString(CultureInfo.InvariantCulture);
  1306. break;
  1307. case "DATE":
  1308. newValue = Envir.Now.ToShortDateString();
  1309. break;
  1310. case "MAPLIGHT":
  1311. newValue = Envir.Lights.ToString();
  1312. break;
  1313. case "USERCOUNT":
  1314. newValue = Envir.PlayerCount.ToString(CultureInfo.InvariantCulture);
  1315. break;
  1316. case "GUILDWARTIME":
  1317. newValue = Settings.Guild_WarTime.ToString();
  1318. break;
  1319. case "GUILDWARFEE":
  1320. newValue = Settings.Guild_WarCost.ToString();
  1321. break;
  1322. default:
  1323. newValue = string.Empty;
  1324. break;
  1325. }
  1326. if (string.IsNullOrEmpty(newValue)) return param;
  1327. return param.Replace(match.Value, newValue);
  1328. }
  1329. public bool Check()
  1330. {
  1331. var failed = false;
  1332. for (int i = 0; i < CheckList.Count; i++)
  1333. {
  1334. NPCChecks check = CheckList[i];
  1335. List<string> param = check.Params.ToList();
  1336. uint tempUint;
  1337. int tempInt;
  1338. int tempInt2;
  1339. Map map;
  1340. switch (check.Type)
  1341. {
  1342. case CheckType.CheckDay:
  1343. var day = Envir.Now.DayOfWeek.ToString().ToUpper();
  1344. var dayToCheck = param[0].ToUpper();
  1345. failed = day != dayToCheck;
  1346. break;
  1347. case CheckType.CheckHour:
  1348. if (!uint.TryParse(param[0], out tempUint))
  1349. {
  1350. failed = true;
  1351. break;
  1352. }
  1353. var hour = Envir.Now.Hour;
  1354. var hourToCheck = tempUint;
  1355. failed = hour != hourToCheck;
  1356. break;
  1357. case CheckType.CheckMinute:
  1358. if (!uint.TryParse(param[0], out tempUint))
  1359. {
  1360. failed = true;
  1361. break;
  1362. }
  1363. var minute = Envir.Now.Minute;
  1364. var minuteToCheck = tempUint;
  1365. failed = minute != minuteToCheck;
  1366. break;
  1367. case CheckType.CheckMapLight:
  1368. var globalLight = Envir.Lights.ToString().ToUpperInvariant();
  1369. var checkValue = param.Count > 0 ? param[0]?.Trim().ToUpperInvariant() : string.Empty;
  1370. failed = string.IsNullOrEmpty(checkValue) || globalLight != checkValue;
  1371. break;
  1372. case CheckType.CheckHum:
  1373. if (!int.TryParse(param[1], out tempInt) || !int.TryParse(param[3], out tempInt2))
  1374. {
  1375. failed = true;
  1376. break;
  1377. }
  1378. map = Envir.GetMapByNameAndInstance(param[2], tempInt2);
  1379. if (map == null)
  1380. {
  1381. failed = true;
  1382. break;
  1383. }
  1384. failed = !Compare(param[0], map.Players.Count(), tempInt);
  1385. break;
  1386. case CheckType.CheckMon:
  1387. if (!int.TryParse(param[1], out tempInt) || !int.TryParse(param[3], out tempInt2))
  1388. {
  1389. failed = true;
  1390. break;
  1391. }
  1392. map = Envir.GetMapByNameAndInstance(param[2], tempInt2);
  1393. if (map == null)
  1394. {
  1395. failed = true;
  1396. break;
  1397. }
  1398. failed = !Compare(param[0], map.MonsterCount, tempInt);
  1399. break;
  1400. case CheckType.CheckExactMon:
  1401. if (Envir.GetMonsterInfo(param[0]) == null)
  1402. {
  1403. failed = true;
  1404. break;
  1405. }
  1406. if (!int.TryParse(param[2], out tempInt) || !int.TryParse(param[4], out tempInt2))
  1407. {
  1408. failed = true;
  1409. break;
  1410. }
  1411. map = Envir.GetMapByNameAndInstance(param[3], tempInt2);
  1412. if (map == null)
  1413. {
  1414. failed = true;
  1415. break;
  1416. }
  1417. failed = (!Compare(param[1], Envir.Objects.Count((
  1418. d => d.CurrentMap == map &&
  1419. d.Race == ObjectType.Monster &&
  1420. string.Equals(d.Name.Replace(" ", ""), param[0], StringComparison.OrdinalIgnoreCase) &&
  1421. !d.Dead)), tempInt));
  1422. break;
  1423. case CheckType.Random:
  1424. if (!int.TryParse(param[0], out tempInt))
  1425. {
  1426. failed = true;
  1427. break;
  1428. }
  1429. failed = 0 != Envir.Random.Next(0, tempInt);
  1430. break;
  1431. case CheckType.CheckCalc:
  1432. int left;
  1433. int right;
  1434. if (!int.TryParse(param[0], out left) || !int.TryParse(param[2], out right))
  1435. {
  1436. failed = true;
  1437. break;
  1438. }
  1439. try
  1440. {
  1441. failed = !Compare(param[1], left, right);
  1442. }
  1443. catch (ArgumentException)
  1444. {
  1445. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[1], Key));
  1446. return true;
  1447. }
  1448. break;
  1449. }
  1450. if (!failed) continue;
  1451. Failed();
  1452. return false;
  1453. }
  1454. Success();
  1455. return true;
  1456. }
  1457. public bool Check(MonsterObject monster)
  1458. {
  1459. var failed = false;
  1460. for (int i = 0; i < CheckList.Count; i++)
  1461. {
  1462. NPCChecks check = CheckList[i];
  1463. List<string> param = check.Params.Select(t => FindVariable(monster, t)).ToList();
  1464. for (int j = 0; j < param.Count; j++)
  1465. {
  1466. var parts = param[j].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  1467. if (parts.Length == 0) continue;
  1468. foreach (var part in parts)
  1469. {
  1470. param[j] = param[j].Replace(part, ReplaceValue(monster, part));
  1471. }
  1472. }
  1473. uint tempUint;
  1474. int tempInt;
  1475. int tempInt2;
  1476. Map map;
  1477. switch (check.Type)
  1478. {
  1479. case CheckType.Level:
  1480. {
  1481. if (!ushort.TryParse(param[1], out ushort level))
  1482. {
  1483. failed = true;
  1484. break;
  1485. }
  1486. try
  1487. {
  1488. failed = !Compare(param[0], monster.Level, level);
  1489. }
  1490. catch (ArgumentException)
  1491. {
  1492. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  1493. return true;
  1494. }
  1495. }
  1496. break;
  1497. case CheckType.CheckDay:
  1498. var day = Envir.Now.DayOfWeek.ToString().ToUpper();
  1499. var dayToCheck = param[0].ToUpper();
  1500. failed = day != dayToCheck;
  1501. break;
  1502. case CheckType.CheckHour:
  1503. if (!uint.TryParse(param[0], out tempUint))
  1504. {
  1505. failed = true;
  1506. break;
  1507. }
  1508. var hour = Envir.Now.Hour;
  1509. var hourToCheck = tempUint;
  1510. failed = hour != hourToCheck;
  1511. break;
  1512. case CheckType.CheckMinute:
  1513. if (!uint.TryParse(param[0], out tempUint))
  1514. {
  1515. failed = true;
  1516. break;
  1517. }
  1518. var minute = Envir.Now.Minute;
  1519. var minuteToCheck = tempUint;
  1520. failed = minute != minuteToCheck;
  1521. break;
  1522. case CheckType.CheckRange:
  1523. int x, y, range;
  1524. if (!int.TryParse(param[0], out x) || !int.TryParse(param[1], out y) || !int.TryParse(param[2], out range))
  1525. {
  1526. failed = true;
  1527. break;
  1528. }
  1529. var target = new Point { X = x, Y = y };
  1530. failed = !Functions.InRange(monster.CurrentLocation, target, range);
  1531. break;
  1532. case CheckType.CheckMap:
  1533. map = Envir.GetMapByNameAndInstance(param[0]);
  1534. failed = monster.CurrentMap != map;
  1535. break;
  1536. case CheckType.CheckMapLight:
  1537. var monsterLight = Envir.Lights.ToString().ToUpperInvariant();
  1538. var monsterCheck = param.Count > 0 ? param[0]?.Trim().ToUpperInvariant() : string.Empty;
  1539. failed = string.IsNullOrEmpty(monsterCheck) || monsterLight != monsterCheck;
  1540. break;
  1541. case CheckType.CheckHum:
  1542. if (!int.TryParse(param[1], out tempInt) || !int.TryParse(param[3], out tempInt2))
  1543. {
  1544. failed = true;
  1545. break;
  1546. }
  1547. map = Envir.GetMapByNameAndInstance(param[2], tempInt2);
  1548. if (map == null)
  1549. {
  1550. failed = true;
  1551. break;
  1552. }
  1553. failed = !Compare(param[0], map.Players.Count(), tempInt);
  1554. break;
  1555. case CheckType.CheckMon:
  1556. if (!int.TryParse(param[1], out tempInt) || !int.TryParse(param[3], out tempInt2))
  1557. {
  1558. failed = true;
  1559. break;
  1560. }
  1561. map = Envir.GetMapByNameAndInstance(param[2], tempInt2);
  1562. if (map == null)
  1563. {
  1564. failed = true;
  1565. break;
  1566. }
  1567. failed = !Compare(param[0], map.MonsterCount, tempInt);
  1568. break;
  1569. case CheckType.CheckExactMon:
  1570. if (Envir.GetMonsterInfo(param[0]) == null)
  1571. {
  1572. failed = true;
  1573. break;
  1574. }
  1575. if (!int.TryParse(param[2], out tempInt) || !int.TryParse(param[4], out tempInt2))
  1576. {
  1577. failed = true;
  1578. break;
  1579. }
  1580. map = Envir.GetMapByNameAndInstance(param[3], tempInt2);
  1581. if (map == null)
  1582. {
  1583. failed = true;
  1584. break;
  1585. }
  1586. failed = (!Compare(param[1], Envir.Objects.Count((
  1587. d => d.CurrentMap == map &&
  1588. d.Race == ObjectType.Monster &&
  1589. string.Equals(d.Name.Replace(" ", ""), param[0], StringComparison.OrdinalIgnoreCase) &&
  1590. !d.Dead)), tempInt));
  1591. break;
  1592. case CheckType.Random:
  1593. if (!int.TryParse(param[0], out tempInt))
  1594. {
  1595. failed = true;
  1596. break;
  1597. }
  1598. failed = 0 != Envir.Random.Next(0, tempInt);
  1599. break;
  1600. case CheckType.CheckCalc:
  1601. int left;
  1602. int right;
  1603. if (!int.TryParse(param[0], out left) || !int.TryParse(param[2], out right))
  1604. {
  1605. failed = true;
  1606. break;
  1607. }
  1608. try
  1609. {
  1610. failed = !Compare(param[1], left, right);
  1611. }
  1612. catch (ArgumentException)
  1613. {
  1614. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[1], Key));
  1615. return true;
  1616. }
  1617. break;
  1618. }
  1619. if (!failed) continue;
  1620. Failed(monster);
  1621. return false;
  1622. }
  1623. Success(monster);
  1624. return true;
  1625. }
  1626. public bool Check(PlayerObject player)
  1627. {
  1628. var failed = false;
  1629. for (int i = 0; i < CheckList.Count; i++)
  1630. {
  1631. NPCChecks check = CheckList[i];
  1632. List<string> param = check.Params.Select(t => FindVariable(player, t)).ToList();
  1633. for (int j = 0; j < param.Count; j++)
  1634. {
  1635. var parts = param[j].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  1636. if (parts.Length == 0) continue;
  1637. foreach (var part in parts)
  1638. {
  1639. param[j] = param[j].Replace(part, ReplaceValue(player, part));
  1640. }
  1641. }
  1642. uint tempUint;
  1643. int tempInt;
  1644. int tempInt2;
  1645. switch (check.Type)
  1646. {
  1647. case CheckType.Level:
  1648. {
  1649. if (!ushort.TryParse(param[1], out ushort level))
  1650. {
  1651. failed = true;
  1652. break;
  1653. }
  1654. try
  1655. {
  1656. failed = !Compare(param[0], player.Level, level);
  1657. }
  1658. catch (ArgumentException)
  1659. {
  1660. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  1661. return true;
  1662. }
  1663. }
  1664. break;
  1665. case CheckType.CheckGold:
  1666. if (!uint.TryParse(param[1], out tempUint))
  1667. {
  1668. failed = true;
  1669. break;
  1670. }
  1671. try
  1672. {
  1673. failed = !Compare(param[0], player.Account.Gold, tempUint);
  1674. }
  1675. catch (ArgumentException)
  1676. {
  1677. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  1678. return true;
  1679. }
  1680. break;
  1681. case CheckType.CheckGuildGold:
  1682. if (!uint.TryParse(param[1], out tempUint))
  1683. {
  1684. failed = true;
  1685. break;
  1686. }
  1687. try
  1688. {
  1689. failed = !Compare(param[0], player.MyGuild.Gold, tempUint);
  1690. }
  1691. catch (ArgumentException)
  1692. {
  1693. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  1694. return true;
  1695. }
  1696. break;
  1697. case CheckType.CheckCredit:
  1698. if (!uint.TryParse(param[1], out tempUint))
  1699. {
  1700. failed = true;
  1701. break;
  1702. }
  1703. try
  1704. {
  1705. failed = !Compare(param[0], player.Account.Credit, tempUint);
  1706. }
  1707. catch (ArgumentException)
  1708. {
  1709. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  1710. return true;
  1711. }
  1712. break;
  1713. case CheckType.CheckItem:
  1714. ushort count;
  1715. ushort dura;
  1716. if (!ushort.TryParse(param[1], out count))
  1717. {
  1718. failed = true;
  1719. break;
  1720. }
  1721. bool checkDura = ushort.TryParse(param[2], out dura);
  1722. var info = Envir.GetItemInfo(param[0]);
  1723. foreach (var item in player.Info.Inventory.Where(item => item != null && item.Info == info))
  1724. {
  1725. if (checkDura)
  1726. if (item.CurrentDura < (dura * 1000)) continue;
  1727. if (count > item.Count)
  1728. {
  1729. count -= item.Count;
  1730. continue;
  1731. }
  1732. if (count > item.Count) continue;
  1733. count = 0;
  1734. break;
  1735. }
  1736. if (count > 0)
  1737. failed = true;
  1738. break;
  1739. case CheckType.CheckGender:
  1740. MirGender gender;
  1741. if (!MirGender.TryParse(param[0], false, out gender))
  1742. {
  1743. failed = true;
  1744. break;
  1745. }
  1746. failed = player.Gender != gender;
  1747. break;
  1748. case CheckType.CheckClass:
  1749. MirClass mirClass;
  1750. if (!MirClass.TryParse(param[0], true, out mirClass))
  1751. {
  1752. failed = true;
  1753. break;
  1754. }
  1755. failed = player.Class != mirClass;
  1756. break;
  1757. case CheckType.CheckDay:
  1758. var day = Envir.Now.DayOfWeek.ToString().ToUpper();
  1759. var dayToCheck = param[0].ToUpper();
  1760. failed = day != dayToCheck;
  1761. break;
  1762. case CheckType.CheckHour:
  1763. if (!uint.TryParse(param[0], out tempUint))
  1764. {
  1765. failed = true;
  1766. break;
  1767. }
  1768. var hour = Envir.Now.Hour;
  1769. var hourToCheck = tempUint;
  1770. failed = hour != hourToCheck;
  1771. break;
  1772. case CheckType.CheckMinute:
  1773. if (!uint.TryParse(param[0], out tempUint))
  1774. {
  1775. failed = true;
  1776. break;
  1777. }
  1778. var minute = Envir.Now.Minute;
  1779. var minuteToCheck = tempUint;
  1780. failed = minute != minuteToCheck;
  1781. break;
  1782. case CheckType.CheckNameList:
  1783. if (!File.Exists(param[0]))
  1784. {
  1785. failed = true;
  1786. break;
  1787. }
  1788. var read = File.ReadAllLines(param[0]);
  1789. failed = !read.Contains(player.Name);
  1790. break;
  1791. case CheckType.CheckGuildNameList:
  1792. if (!File.Exists(param[0]))
  1793. {
  1794. failed = true;
  1795. break;
  1796. }
  1797. read = File.ReadAllLines(param[0]);
  1798. failed = player.MyGuild == null || !read.Contains(player.MyGuild.Name);
  1799. break;
  1800. case CheckType.IsAdmin:
  1801. failed = !player.IsGM;
  1802. break;
  1803. case CheckType.CheckPkPoint:
  1804. if (!int.TryParse(param[1], out tempInt))
  1805. {
  1806. failed = true;
  1807. break;
  1808. }
  1809. try
  1810. {
  1811. failed = !Compare(param[0], player.PKPoints, tempInt);
  1812. }
  1813. catch (ArgumentException)
  1814. {
  1815. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  1816. return true;
  1817. }
  1818. break;
  1819. case CheckType.CheckRange:
  1820. int x, y, range;
  1821. if (!int.TryParse(param[0], out x) || !int.TryParse(param[1], out y) || !int.TryParse(param[2], out range))
  1822. {
  1823. failed = true;
  1824. break;
  1825. }
  1826. var target = new Point { X = x, Y = y };
  1827. failed = !Functions.InRange(player.CurrentLocation, target, range);
  1828. break;
  1829. case CheckType.CheckMap:
  1830. Map map = Envir.GetMapByNameAndInstance(param[0]);
  1831. failed = player.CurrentMap != map;
  1832. break;
  1833. case CheckType.CheckMapLight:
  1834. var playerLight = Envir.Lights.ToString().ToUpperInvariant();
  1835. var playerCheck = param.Count > 0 ? param[0]?.Trim().ToUpperInvariant() : string.Empty;
  1836. failed = string.IsNullOrEmpty(playerCheck) || playerLight != playerCheck;
  1837. break;
  1838. case CheckType.Check:
  1839. uint onCheck;
  1840. if (!uint.TryParse(param[0], out tempUint) || !uint.TryParse(param[1], out onCheck) || tempUint > Globals.FlagIndexCount)
  1841. {
  1842. failed = true;
  1843. break;
  1844. }
  1845. bool tempBool = Convert.ToBoolean(onCheck);
  1846. bool flag = player.Info.Flags[tempUint];
  1847. failed = flag != tempBool;
  1848. break;
  1849. case CheckType.CheckHum:
  1850. if (!int.TryParse(param[1], out tempInt) || !int.TryParse(param[3], out tempInt2))
  1851. {
  1852. failed = true;
  1853. break;
  1854. }
  1855. map = Envir.GetMapByNameAndInstance(param[2], tempInt2);
  1856. if (map == null)
  1857. {
  1858. failed = true;
  1859. break;
  1860. }
  1861. failed = !Compare(param[0], map.Players.Count(), tempInt);
  1862. break;
  1863. case CheckType.CheckMon:
  1864. if (!int.TryParse(param[1], out tempInt) || !int.TryParse(param[3], out tempInt2))
  1865. {
  1866. failed = true;
  1867. break;
  1868. }
  1869. map = Envir.GetMapByNameAndInstance(param[2], tempInt2);
  1870. if (map == null)
  1871. {
  1872. failed = true;
  1873. break;
  1874. }
  1875. failed = !Compare(param[0], map.MonsterCount, tempInt);
  1876. break;
  1877. case CheckType.CheckExactMon:
  1878. if (Envir.GetMonsterInfo(param[0]) == null)
  1879. {
  1880. failed = true;
  1881. break;
  1882. }
  1883. if (!int.TryParse(param[2], out tempInt) || !int.TryParse(param[4], out tempInt2))
  1884. {
  1885. failed = true;
  1886. break;
  1887. }
  1888. map = Envir.GetMapByNameAndInstance(param[3], tempInt2);
  1889. if (map == null)
  1890. {
  1891. failed = true;
  1892. break;
  1893. }
  1894. failed = (!Compare(param[1], Envir.Objects.Count((
  1895. d => d.CurrentMap == map &&
  1896. d.Race == ObjectType.Monster &&
  1897. string.Equals(d.Name.Replace(" ", ""), param[0], StringComparison.OrdinalIgnoreCase) &&
  1898. !d.Dead)), tempInt));
  1899. break;
  1900. case CheckType.Random:
  1901. if (!int.TryParse(param[0], out tempInt))
  1902. {
  1903. failed = true;
  1904. break;
  1905. }
  1906. failed = 0 != Envir.Random.Next(0, tempInt);
  1907. break;
  1908. case CheckType.Groupleader:
  1909. failed = (player.GroupMembers == null || player.GroupMembers[0] != player);
  1910. break;
  1911. case CheckType.GroupCount:
  1912. if (!int.TryParse(param[1], out tempInt))
  1913. {
  1914. failed = true;
  1915. break;
  1916. }
  1917. failed = (player.GroupMembers == null || !Compare(param[0], player.GroupMembers.Count, tempInt));
  1918. break;
  1919. case CheckType.GroupCheckNearby:
  1920. target = new Point(-1, -1);
  1921. for (int j = 0; j < player.CurrentMap.NPCs.Count; j++)
  1922. {
  1923. NPCObject ob = player.CurrentMap.NPCs[j];
  1924. if (ob.ObjectID != player.NPCObjectID) continue;
  1925. target = ob.CurrentLocation;
  1926. break;
  1927. }
  1928. if (target.X == -1)
  1929. {
  1930. failed = true;
  1931. break;
  1932. }
  1933. if (player.GroupMembers == null)
  1934. failed = true;
  1935. else
  1936. {
  1937. for (int j = 0; j < player.GroupMembers.Count; j++)
  1938. {
  1939. if (player.GroupMembers[j] == null) continue;
  1940. failed |= !Functions.InRange(player.GroupMembers[j].CurrentLocation, target, 9);
  1941. if (failed) break;
  1942. }
  1943. }
  1944. break;
  1945. case CheckType.PetCount:
  1946. if (!int.TryParse(param[1], out tempInt))
  1947. {
  1948. failed = true;
  1949. break;
  1950. }
  1951. failed = !Compare(param[0], player.Pets.Count(), tempInt);
  1952. break;
  1953. case CheckType.PetLevel:
  1954. if (!int.TryParse(param[1], out tempInt))
  1955. {
  1956. failed = true;
  1957. break;
  1958. }
  1959. for (int p = 0; p < player.Pets.Count(); p++)
  1960. {
  1961. failed = !Compare(param[0], player.Pets[p].PetLevel, tempInt);
  1962. }
  1963. break;
  1964. case CheckType.CheckCalc:
  1965. int left;
  1966. int right;
  1967. try
  1968. {
  1969. if (!int.TryParse(param[0], out left) || !int.TryParse(param[2], out right))
  1970. {
  1971. failed = !Compare(param[1], param[0], param[2]);
  1972. }
  1973. else
  1974. {
  1975. failed = !Compare(param[1], left, right);
  1976. }
  1977. }
  1978. catch (ArgumentException)
  1979. {
  1980. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[1], Key));
  1981. return true;
  1982. }
  1983. break;
  1984. case CheckType.InGuild:
  1985. if (param[0].Length > 0)
  1986. {
  1987. failed = player.MyGuild == null || player.MyGuild.Name != param[0];
  1988. break;
  1989. }
  1990. failed = player.MyGuild == null;
  1991. break;
  1992. case CheckType.CheckQuest:
  1993. if (!int.TryParse(param[0], out tempInt))
  1994. {
  1995. failed = true;
  1996. break;
  1997. }
  1998. string tempString = param[1].ToUpper();
  1999. if (tempString == "ACTIVE")
  2000. {
  2001. failed = !player.CurrentQuests.Any(e => e.Index == tempInt);
  2002. }
  2003. else //COMPLETE
  2004. {
  2005. failed = !player.CompletedQuests.Contains(tempInt);
  2006. }
  2007. break;
  2008. case CheckType.CheckRelationship:
  2009. if (player.Info.Married == 0)
  2010. {
  2011. failed = true;
  2012. }
  2013. break;
  2014. case CheckType.CheckWeddingRing:
  2015. failed = !player.CheckMakeWeddingRing();
  2016. break;
  2017. case CheckType.CheckPet:
  2018. bool petMatch = false;
  2019. for (int c = player.Pets.Count - 1; c >= 0; c--)
  2020. {
  2021. if (string.Compare(player.Pets[c].Info.Name, param[0], true) != 0) continue;
  2022. petMatch = true;
  2023. }
  2024. failed = !petMatch;
  2025. break;
  2026. case CheckType.HasBagSpace:
  2027. if (!int.TryParse(param[1], out tempInt))
  2028. {
  2029. failed = true;
  2030. break;
  2031. }
  2032. int slotCount = 0;
  2033. for (int k = 0; k < player.Info.Inventory.Length; k++)
  2034. if (player.Info.Inventory[k] == null) slotCount++;
  2035. failed = !Compare(param[0], slotCount, tempInt);
  2036. break;
  2037. case CheckType.IsNewHuman:
  2038. failed = player.Info.AccountInfo.Characters.Count > 1;
  2039. break;
  2040. case CheckType.CheckConquest:
  2041. if (!int.TryParse(param[0], out tempInt))
  2042. {
  2043. failed = true;
  2044. break;
  2045. }
  2046. try
  2047. {
  2048. ConquestObject Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  2049. if (Conquest == null)
  2050. {
  2051. failed = true;
  2052. break;
  2053. }
  2054. failed = Conquest.WarIsOn;
  2055. }
  2056. catch (ArgumentException)
  2057. {
  2058. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2059. return true;
  2060. }
  2061. break;
  2062. case CheckType.AffordGuard:
  2063. if (!int.TryParse(param[0], out tempInt) || !int.TryParse(param[1], out tempInt2))
  2064. {
  2065. failed = true;
  2066. break;
  2067. }
  2068. try
  2069. {
  2070. ConquestObject Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  2071. if (Conquest == null)
  2072. {
  2073. failed = true;
  2074. break;
  2075. }
  2076. ConquestGuildArcherInfo Archer = Conquest.ArcherList.FirstOrDefault(g => g.Info.Index == tempInt2);
  2077. if (Archer == null || Archer.GetRepairCost() == 0)
  2078. {
  2079. failed = true;
  2080. break;
  2081. }
  2082. if (player.MyGuild != null)
  2083. failed = (player.MyGuild.Gold < Archer.GetRepairCost());
  2084. else
  2085. failed = true;
  2086. }
  2087. catch (ArgumentException)
  2088. {
  2089. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2090. return true;
  2091. }
  2092. break;
  2093. case CheckType.AffordGate:
  2094. if (!int.TryParse(param[0], out tempInt) || !int.TryParse(param[1], out tempInt2))
  2095. {
  2096. failed = true;
  2097. break;
  2098. }
  2099. try
  2100. {
  2101. ConquestObject Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  2102. if (Conquest == null)
  2103. {
  2104. failed = true;
  2105. break;
  2106. }
  2107. ConquestGuildGateInfo Gate = Conquest.GateList.FirstOrDefault(f => f.Info.Index == tempInt2);
  2108. if (Gate == null || Gate.GetRepairCost() == 0)
  2109. {
  2110. failed = true;
  2111. break;
  2112. }
  2113. if (player.MyGuild != null)
  2114. failed = (player.MyGuild.Gold < Gate.GetRepairCost());
  2115. else
  2116. failed = true;
  2117. }
  2118. catch (ArgumentException)
  2119. {
  2120. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2121. return true;
  2122. }
  2123. break;
  2124. case CheckType.AffordWall:
  2125. if (!int.TryParse(param[0], out tempInt) || !int.TryParse(param[1], out tempInt2))
  2126. {
  2127. failed = true;
  2128. break;
  2129. }
  2130. try
  2131. {
  2132. ConquestObject Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  2133. if (Conquest == null)
  2134. {
  2135. failed = true;
  2136. break;
  2137. }
  2138. ConquestGuildWallInfo Wall = Conquest.WallList.FirstOrDefault(h => h.Info.Index == tempInt2);
  2139. if (Wall == null || Wall.GetRepairCost() == 0)
  2140. {
  2141. failed = true;
  2142. break;
  2143. }
  2144. if (player.MyGuild != null)
  2145. failed = (player.MyGuild.Gold < Wall.GetRepairCost());
  2146. else
  2147. failed = true;
  2148. }
  2149. catch (ArgumentException)
  2150. {
  2151. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2152. return true;
  2153. }
  2154. break;
  2155. case CheckType.AffordSiege:
  2156. if (!int.TryParse(param[0], out tempInt) || !int.TryParse(param[1], out tempInt2))
  2157. {
  2158. failed = true;
  2159. break;
  2160. }
  2161. try
  2162. {
  2163. ConquestObject Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  2164. if (Conquest == null)
  2165. {
  2166. failed = true;
  2167. break;
  2168. }
  2169. ConquestGuildGateInfo Gate = Conquest.GateList.FirstOrDefault(f => f.Info.Index == tempInt2);
  2170. if (Gate == null || Gate.GetRepairCost() == 0)
  2171. {
  2172. failed = true;
  2173. break;
  2174. }
  2175. if (player.MyGuild != null)
  2176. failed = (player.MyGuild.Gold < Gate.GetRepairCost());
  2177. else
  2178. failed = true;
  2179. }
  2180. catch (ArgumentException)
  2181. {
  2182. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2183. return true;
  2184. }
  2185. break;
  2186. case CheckType.CheckPermission:
  2187. GuildRankOptions guildPermissions;
  2188. if (!Enum.TryParse(param[0], true, out guildPermissions))
  2189. {
  2190. failed = true;
  2191. break;
  2192. }
  2193. if (player.MyGuild == null)
  2194. {
  2195. failed = true;
  2196. break;
  2197. }
  2198. failed = !(player.MyGuildRank.Options.HasFlag(guildPermissions));
  2199. break;
  2200. case CheckType.ConquestAvailable:
  2201. if (!int.TryParse(param[0], out tempInt))
  2202. {
  2203. failed = true;
  2204. break;
  2205. }
  2206. try
  2207. {
  2208. ConquestObject Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  2209. if (Conquest == null)
  2210. {
  2211. failed = true;
  2212. break;
  2213. }
  2214. if (player.MyGuild != null)
  2215. failed = (Conquest.GuildInfo.AttackerID != -1);
  2216. else
  2217. failed = true;
  2218. }
  2219. catch (ArgumentException)
  2220. {
  2221. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2222. return true;
  2223. }
  2224. break;
  2225. case CheckType.ConquestOwner:
  2226. if (!int.TryParse(param[0], out tempInt))
  2227. {
  2228. failed = true;
  2229. break;
  2230. }
  2231. try
  2232. {
  2233. ConquestObject Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  2234. if (Conquest == null)
  2235. {
  2236. failed = true;
  2237. break;
  2238. }
  2239. if (player.MyGuild != null && player.MyGuild.Guildindex == Conquest.GuildInfo.Owner)
  2240. failed = false;
  2241. else
  2242. failed = true;
  2243. }
  2244. catch (ArgumentException)
  2245. {
  2246. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2247. return true;
  2248. }
  2249. break;
  2250. case CheckType.CheckTimer:
  2251. {
  2252. if (!long.TryParse(param[1], out long time))
  2253. {
  2254. failed = true;
  2255. break;
  2256. }
  2257. try
  2258. {
  2259. var globalTimerKey = "_-" + param[0];
  2260. Timer timer;
  2261. if (Envir.Timers.ContainsKey(globalTimerKey))
  2262. {
  2263. timer = Envir.Timers[globalTimerKey];
  2264. }
  2265. else
  2266. {
  2267. timer = player.GetTimer(param[0]);
  2268. }
  2269. long remainingTime = 0;
  2270. if (timer != null)
  2271. {
  2272. remainingTime = (timer.RelativeTime - Envir.Time) / 1000;
  2273. break;
  2274. }
  2275. failed = !Compare(param[0], remainingTime, time);
  2276. }
  2277. catch (ArgumentException)
  2278. {
  2279. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[0], Key));
  2280. return true;
  2281. }
  2282. }
  2283. break;
  2284. case CheckType.HeroLevel:
  2285. if (!int.TryParse(param[1], out tempInt))
  2286. {
  2287. failed = true;
  2288. break;
  2289. }
  2290. if (player.CurrentHero == null)
  2291. {
  2292. failed = true;
  2293. }
  2294. else
  2295. {
  2296. failed = !Compare(param[0], player.CurrentHero.Level, tempInt);
  2297. }
  2298. break;
  2299. case CheckType.CheckHeroClass:
  2300. MirClass heroClass;
  2301. if (!MirClass.TryParse(param[0], true, out heroClass))
  2302. {
  2303. failed = true;
  2304. break;
  2305. }
  2306. if (player.CurrentHero == null)
  2307. {
  2308. failed = true;
  2309. }
  2310. else
  2311. {
  2312. failed = player.CurrentHero.Class != heroClass;
  2313. }
  2314. break;
  2315. case CheckType.CheckHeroGender:
  2316. MirGender heroGender;
  2317. if (!MirGender.TryParse(param[0], false, out heroGender))
  2318. {
  2319. failed = true;
  2320. break;
  2321. }
  2322. if (player.CurrentHero == null)
  2323. {
  2324. failed = true;
  2325. }
  2326. else
  2327. {
  2328. failed = player.CurrentHero.Gender != heroGender;
  2329. }
  2330. break;
  2331. case CheckType.CheckHeroItem:
  2332. ushort heroItemCount;
  2333. ushort heroItemDura;
  2334. if (!ushort.TryParse(param[1], out heroItemCount))
  2335. {
  2336. failed = true;
  2337. break;
  2338. }
  2339. bool heroCheckDura = ushort.TryParse(param[2], out heroItemDura);
  2340. var heroItemInfo = Envir.GetItemInfo(param[0]);
  2341. if (player.CurrentHero == null || player.CurrentHero.Inventory == null)
  2342. {
  2343. failed = true;
  2344. break;
  2345. }
  2346. foreach (var item in player.CurrentHero.Inventory.Where(item => item != null && item.Info == heroItemInfo))
  2347. {
  2348. if (heroCheckDura)
  2349. if (item.CurrentDura < (heroItemDura * 1000)) continue;
  2350. if (heroItemCount > item.Count)
  2351. {
  2352. heroItemCount -= item.Count;
  2353. continue;
  2354. }
  2355. heroItemCount = 0;
  2356. break;
  2357. }
  2358. if (heroItemCount > 0)
  2359. failed = true;
  2360. break;
  2361. case CheckType.CheckBuff:
  2362. {
  2363. if (!Enum.TryParse(param[0], true, out BuffType buffType))
  2364. {
  2365. failed = true;
  2366. break;
  2367. }
  2368. failed = !player.HasBuff(buffType);
  2369. }
  2370. break;
  2371. }
  2372. if (!failed) continue;
  2373. Failed(player);
  2374. return false;
  2375. }
  2376. Success(player);
  2377. return true;
  2378. }
  2379. private void Act(IList<NPCActions> acts)
  2380. {
  2381. for (var i = 0; i < acts.Count; i++)
  2382. {
  2383. string tempString = string.Empty;
  2384. int tempInt;
  2385. byte tempByte;
  2386. Packet p;
  2387. MonsterInfo monInfo;
  2388. NPCActions act = acts[i];
  2389. List<string> param = act.Params.ToList();
  2390. Map map;
  2391. ChatType chatType;
  2392. switch (act.Type)
  2393. {
  2394. case ActionType.ClearNameList:
  2395. tempString = param[0];
  2396. File.WriteAllLines(tempString, new string[] { });
  2397. break;
  2398. case ActionType.GlobalMessage:
  2399. if (!Enum.TryParse(param[1], true, out chatType)) return;
  2400. p = new S.Chat { Message = param[0], Type = chatType };
  2401. Envir.Broadcast(p);
  2402. break;
  2403. case ActionType.Break:
  2404. Page.BreakFromSegments = true;
  2405. break;
  2406. case ActionType.Param1:
  2407. if (!int.TryParse(param[1], out tempInt)) return;
  2408. Param1 = param[0];
  2409. Param1Instance = tempInt;
  2410. break;
  2411. case ActionType.Param2:
  2412. if (!int.TryParse(param[0], out tempInt)) return;
  2413. Param2 = tempInt;
  2414. break;
  2415. case ActionType.Param3:
  2416. if (!int.TryParse(param[0], out tempInt)) return;
  2417. Param3 = tempInt;
  2418. break;
  2419. case ActionType.Mongen:
  2420. if (Param1 == null || Param2 == 0 || Param3 == 0) return;
  2421. if (!byte.TryParse(param[1], out tempByte)) return;
  2422. map = Envir.GetMapByNameAndInstance(Param1, Param1Instance);
  2423. if (map == null) return;
  2424. monInfo = Envir.GetMonsterInfo(param[0]);
  2425. if (monInfo == null) return;
  2426. for (int j = 0; j < tempByte; j++)
  2427. {
  2428. MonsterObject monster = MonsterObject.GetMonster(monInfo);
  2429. if (monster == null) return;
  2430. monster.Direction = 0;
  2431. monster.ActionTime = Envir.Time + 1000;
  2432. monster.Spawn(map, new Point(Param2, Param3));
  2433. }
  2434. break;
  2435. case ActionType.MonClear:
  2436. if (!int.TryParse(param[1], out tempInt)) return;
  2437. map = Envir.GetMapByNameAndInstance(param[0], tempInt);
  2438. if (map == null) return;
  2439. foreach (var cell in map.Cells)
  2440. {
  2441. if (cell == null || cell.Objects == null) continue;
  2442. for (int j = 0; j < cell.Objects.Count(); j++)
  2443. {
  2444. MapObject ob = cell.Objects[j];
  2445. if (ob.Race != ObjectType.Monster) continue;
  2446. if (ob.Dead) continue;
  2447. ob.Die();
  2448. }
  2449. }
  2450. break;
  2451. }
  2452. }
  2453. }
  2454. private void Act(IList<NPCActions> acts, PlayerObject player)
  2455. {
  2456. MailInfo mailInfo = null;
  2457. for (var i = 0; i < acts.Count; i++)
  2458. {
  2459. NPCActions act = acts[i];
  2460. List<string> param = act.Params.Select(t => FindVariable(player, t)).ToList();
  2461. for (int j = 0; j < param.Count; j++)
  2462. {
  2463. var parts = param[j].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  2464. if (parts.Length == 0) continue;
  2465. foreach (var part in parts)
  2466. {
  2467. param[j] = param[j].Replace(part, ReplaceValue(player, part));
  2468. }
  2469. if (player.NPCData.TryGetValue("NPCInputStr", out object _npcInputStr))
  2470. {
  2471. param[j] = param[j].Replace("%INPUTSTR", (string)_npcInputStr);
  2472. }
  2473. }
  2474. switch (act.Type)
  2475. {
  2476. case ActionType.Move:
  2477. {
  2478. Map targetmap = Envir.GetMapByNameAndInstance(param[0]);
  2479. if (targetmap == null) return;
  2480. if (!int.TryParse(param[1], out int x)) return;
  2481. if (!int.TryParse(param[2], out int y)) return;
  2482. var coords = new Point(x, y);
  2483. if (coords.X > 0 && coords.Y > 0) player.Teleport(targetmap, coords);
  2484. else player.TeleportRandom(200, 0, targetmap);
  2485. }
  2486. break;
  2487. case ActionType.InstanceMove:
  2488. {
  2489. if (!int.TryParse(param[1], out int instanceId)) return;
  2490. if (!int.TryParse(param[2], out int x)) return;
  2491. if (!int.TryParse(param[3], out int y)) return;
  2492. var targetmap = Envir.GetMapByNameAndInstance(param[0], instanceId);
  2493. if (targetmap == null) return;
  2494. player.Teleport(targetmap, new Point(x, y));
  2495. }
  2496. break;
  2497. case ActionType.BuyGT:
  2498. if (player.MyGuild == null || player.MyGuildRank == null) return;
  2499. if (player.MyGuildRank != player.MyGuild.Ranks[0])
  2500. {
  2501. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouNeedGuildLeader), ChatType.System);
  2502. return;
  2503. }
  2504. if (player.MyGuild.Gold < Settings.BuyGTGold)
  2505. {
  2506. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.GuildFundsInsufficient), ChatType.System);
  2507. return;
  2508. }
  2509. if (player.MyGuild.HasGT)
  2510. {
  2511. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouAlreadyOwnGuildTerritory), ChatType.System);
  2512. return;
  2513. }
  2514. GTMap GTmap = null;
  2515. foreach (var gt in Envir.GTMapList)
  2516. {
  2517. if (gt.Owner == "None")
  2518. {
  2519. GTmap = gt;
  2520. break;
  2521. }
  2522. }
  2523. if (GTmap == null)
  2524. {
  2525. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoGuildTerritoryAvailable), ChatType.System);
  2526. return;
  2527. }
  2528. player.MyGuild.Gold -= (uint)Settings.BuyGTGold;
  2529. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 2, Amount = (uint)Settings.BuyGTGold });
  2530. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouRentedGuildTerritory), ChatType.System);
  2531. player.MyGuild.GTIndex = GTmap.Index;
  2532. player.MyGuild.GTRent = DateTime.Now.AddDays(Settings.GTDays);
  2533. player.MyGuild.GTKey = Envir.Random.Next(100, int.MaxValue - 100);
  2534. player.MyGuild.GTPrice = 0;
  2535. GTmap.Owner = player.MyGuild.Name;
  2536. GTmap.Leader = player.MyGuild.Ranks[0].Members[0].Name;
  2537. if (player.MyGuild.Ranks[0].Members.Count > 1)
  2538. GTmap.Leader = player.MyGuild.Ranks[0].Members[1].Name;
  2539. GTmap.Price = 0;
  2540. GTmap.Key = player.MyGuild.GTKey;
  2541. break;
  2542. case ActionType.TeleportGT:
  2543. if (player.MyGuild == null)
  2544. {
  2545. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouNeedGuild), ChatType.System);
  2546. return;
  2547. }
  2548. if (!player.MyGuild.HasGT)
  2549. {
  2550. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouDontOwnGuildTerritory), ChatType.System);
  2551. return;
  2552. }
  2553. GTmap = null;
  2554. foreach (var gt in Envir.GTMapList)
  2555. {
  2556. if (gt.Index == player.MyGuild.GTIndex)
  2557. {
  2558. GTmap = gt;
  2559. break;
  2560. }
  2561. }
  2562. if (GTmap == null)
  2563. {
  2564. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoGTFoundContactGM), ChatType.System);
  2565. return;
  2566. }
  2567. if (!(GTmap.Maps.Count > 0))
  2568. {
  2569. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoGTMapsContactGM), ChatType.System);
  2570. return;
  2571. }
  2572. if (player.MyGuild.GTBegin > Envir.Now)
  2573. {
  2574. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.RecentSalePending), ChatType.System);
  2575. return;
  2576. }
  2577. var map = GTmap.Maps[0];
  2578. if (map == null || map.Info.SafeZones == null || map.Info.SafeZones.Count == 0)
  2579. {
  2580. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoSafezoneContactGM), ChatType.System);
  2581. return;
  2582. }
  2583. player.Teleport(map, map.Info.SafeZones[0].Location);
  2584. break;
  2585. case ActionType.ExtendGT:
  2586. if (player.MyGuild == null || player.MyGuildRank == null) return;
  2587. if (player.MyGuildRank != player.MyGuild.Ranks[0])
  2588. {
  2589. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouNeedGuildLeader), ChatType.System);
  2590. return;
  2591. }
  2592. if (player.MyGuild.Gold < Settings.ExtendGT)
  2593. {
  2594. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.InsufficientFunds), ChatType.System);
  2595. return;
  2596. }
  2597. GTmap = null;
  2598. foreach (var gt in Envir.GTMapList)
  2599. {
  2600. if (gt.Owner == player.MyGuild.Name)
  2601. {
  2602. GTmap = gt;
  2603. break;
  2604. }
  2605. }
  2606. if (GTmap == null)
  2607. {
  2608. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouDontOwnGT), ChatType.System);
  2609. return;
  2610. }
  2611. player.MyGuild.Gold -= (uint)Settings.ExtendGT;
  2612. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 2, Amount = (uint)Settings.ExtendGT });
  2613. player.MyGuild.GTRent = player.MyGuild.GTRent.AddDays(Settings.GTDays);
  2614. GTmap.Price = 10000000;
  2615. break;
  2616. case ActionType.GiveGold:
  2617. {
  2618. if (!uint.TryParse(param[0], out uint gold)) return;
  2619. if (gold + player.Account.Gold >= uint.MaxValue)
  2620. gold = uint.MaxValue - player.Account.Gold;
  2621. player.GainGold(gold);
  2622. }
  2623. break;
  2624. case ActionType.TakeGold:
  2625. {
  2626. if (!uint.TryParse(param[0], out uint gold)) return;
  2627. if (gold >= player.Account.Gold) gold = player.Account.Gold;
  2628. player.Account.Gold -= gold;
  2629. player.Enqueue(new S.LoseGold { Gold = gold });
  2630. }
  2631. break;
  2632. case ActionType.GiveGuildGold:
  2633. {
  2634. if (!uint.TryParse(param[0], out uint gold)) return;
  2635. if (gold + player.MyGuild.Gold >= uint.MaxValue)
  2636. gold = uint.MaxValue - player.MyGuild.Gold;
  2637. player.MyGuild.Gold += gold;
  2638. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 3, Amount = gold });
  2639. }
  2640. break;
  2641. case ActionType.TakeGuildGold:
  2642. {
  2643. if (!uint.TryParse(param[0], out uint gold)) return;
  2644. if (gold >= player.MyGuild.Gold) gold = player.MyGuild.Gold;
  2645. player.MyGuild.Gold -= gold;
  2646. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 2, Amount = gold });
  2647. }
  2648. break;
  2649. case ActionType.GiveCredit:
  2650. {
  2651. if (!uint.TryParse(param[0], out uint credit)) return;
  2652. if (credit + player.Account.Credit >= uint.MaxValue)
  2653. credit = uint.MaxValue - player.Account.Credit;
  2654. player.GainCredit(credit);
  2655. }
  2656. break;
  2657. case ActionType.TakeCredit:
  2658. {
  2659. if (!uint.TryParse(param[0], out uint credit)) return;
  2660. if (credit >= player.Account.Credit) credit = player.Account.Credit;
  2661. player.Account.Credit -= credit;
  2662. player.Enqueue(new S.LoseCredit { Credit = credit });
  2663. }
  2664. break;
  2665. case ActionType.GivePearls:
  2666. {
  2667. if (!uint.TryParse(param[0], out uint pearls)) return;
  2668. if (pearls + player.Info.PearlCount >= int.MaxValue)
  2669. pearls = (uint)(int.MaxValue - player.Info.PearlCount);
  2670. player.IntelligentCreatureGainPearls((int)pearls);
  2671. }
  2672. break;
  2673. case ActionType.TakePearls:
  2674. {
  2675. if (!uint.TryParse(param[0], out uint pearls)) return;
  2676. if (pearls >= player.Info.PearlCount) pearls = (uint)player.Info.PearlCount;
  2677. player.IntelligentCreatureLosePearls((int)pearls);
  2678. }
  2679. break;
  2680. case ActionType.GiveItem:
  2681. {
  2682. if (param.Count < 2 || !ushort.TryParse(param[1], out ushort count)) count = 1;
  2683. var info = Envir.GetItemInfo(param[0]);
  2684. if (info == null)
  2685. {
  2686. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.FailedToGetItemInfoPage), param[0], Key));
  2687. break;
  2688. }
  2689. while (count > 0)
  2690. {
  2691. UserItem item = Envir.CreateFreshItem(info);
  2692. if (item == null)
  2693. {
  2694. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.FailedCreateUserItemPage), param[0], Key));
  2695. return;
  2696. }
  2697. if (item.Info.StackSize > count)
  2698. {
  2699. item.Count = count;
  2700. count = 0;
  2701. }
  2702. else
  2703. {
  2704. count -= item.Info.StackSize;
  2705. item.Count = item.Info.StackSize;
  2706. }
  2707. if (player.CanGainItem(item))
  2708. player.GainItem(item);
  2709. }
  2710. }
  2711. break;
  2712. case ActionType.TakeItem:
  2713. {
  2714. if (param.Count < 2 || !ushort.TryParse(param[1], out ushort count)) count = 1;
  2715. var info = Envir.GetItemInfo(param[0]);
  2716. ushort dura;
  2717. bool checkDura = ushort.TryParse(param[2], out dura);
  2718. if (info == null)
  2719. {
  2720. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.FailedGetItemInfo), param[0], Key));
  2721. break;
  2722. }
  2723. for (int j = 0; j < player.Info.Inventory.Length; j++)
  2724. {
  2725. UserItem item = player.Info.Inventory[j];
  2726. if (item == null) continue;
  2727. if (item.Info != info) continue;
  2728. if (checkDura)
  2729. {
  2730. if (item.CurrentDura < (dura * 1000)) continue;
  2731. }
  2732. if (count > item.Count)
  2733. {
  2734. player.Enqueue(new S.DeleteItem { UniqueID = item.UniqueID, Count = item.Count });
  2735. player.Info.Inventory[j] = null;
  2736. count -= item.Count;
  2737. continue;
  2738. }
  2739. player.Enqueue(new S.DeleteItem { UniqueID = item.UniqueID, Count = count });
  2740. if (count == item.Count)
  2741. player.Info.Inventory[j] = null;
  2742. else
  2743. item.Count -= count;
  2744. break;
  2745. }
  2746. player.RefreshStats();
  2747. }
  2748. break;
  2749. case ActionType.GiveExp:
  2750. {
  2751. uint tempUint;
  2752. if (!uint.TryParse(param[0], out tempUint)) return;
  2753. player.GainExp(tempUint);
  2754. }
  2755. break;
  2756. case ActionType.GivePet:
  2757. {
  2758. byte petcount = 0;
  2759. byte petlevel = 0;
  2760. var monInfo = Envir.GetMonsterInfo(param[0]);
  2761. if (monInfo == null) return;
  2762. if (param.Count > 1)
  2763. petcount = byte.TryParse(param[1], out petcount) ? Math.Min((byte)5, petcount) : (byte)1;
  2764. if (param.Count > 2)
  2765. petlevel = byte.TryParse(param[2], out petlevel) ? Math.Min((byte)7, petlevel) : (byte)0;
  2766. for (int j = 0; j < petcount; j++)
  2767. {
  2768. MonsterObject monster = MonsterObject.GetMonster(monInfo);
  2769. if (monster == null) return;
  2770. monster.PetLevel = petlevel;
  2771. monster.Master = player;
  2772. monster.MaxPetLevel = 7;
  2773. monster.Direction = player.Direction;
  2774. monster.ActionTime = Envir.Time + 1000;
  2775. monster.Spawn(player.CurrentMap, player.CurrentLocation);
  2776. player.Pets.Add(monster);
  2777. }
  2778. }
  2779. break;
  2780. case ActionType.RemovePet:
  2781. {
  2782. for (int c = player.Pets.Count - 1; c >= 0; c--)
  2783. {
  2784. if (string.Compare(player.Pets[c].Info.Name, param[0], true) != 0) continue;
  2785. player.Pets[c].Die();
  2786. }
  2787. }
  2788. break;
  2789. case ActionType.ClearPets:
  2790. {
  2791. for (int c = player.Pets.Count - 1; c >= 0; c--)
  2792. {
  2793. player.Pets[c].DieNextTurn = true;
  2794. }
  2795. }
  2796. break;
  2797. case ActionType.AddNameList:
  2798. {
  2799. var tempString = param[0];
  2800. if (File.ReadAllLines(tempString).All(t => player.Name != t))
  2801. {
  2802. using (var line = File.AppendText(tempString))
  2803. {
  2804. line.WriteLine(player.Name);
  2805. }
  2806. }
  2807. }
  2808. break;
  2809. case ActionType.AddGuildNameList:
  2810. {
  2811. var tempString = param[0];
  2812. if (player.MyGuild == null) break;
  2813. if (File.ReadAllLines(tempString).All(t => player.MyGuild.Name != t))
  2814. {
  2815. using (var line = File.AppendText(tempString))
  2816. {
  2817. line.WriteLine(player.MyGuild.Name);
  2818. }
  2819. }
  2820. }
  2821. break;
  2822. case ActionType.DelNameList:
  2823. {
  2824. var tempString = param[0];
  2825. File.WriteAllLines(tempString, File.ReadLines(tempString).Where(l => l != player.Name).ToList());
  2826. }
  2827. break;
  2828. case ActionType.DelGuildNameList:
  2829. {
  2830. if (player.MyGuild == null) break;
  2831. var tempString = param[0];
  2832. File.WriteAllLines(tempString, File.ReadLines(tempString).Where(l => l != player.MyGuild.Name).ToList());
  2833. }
  2834. break;
  2835. case ActionType.ClearNameList:
  2836. {
  2837. var tempString = param[0];
  2838. File.WriteAllLines(tempString, new string[] { });
  2839. }
  2840. break;
  2841. case ActionType.ClearGuildNameList:
  2842. {
  2843. if (player.MyGuild == null) break;
  2844. var tempString = param[0];
  2845. File.WriteAllLines(tempString, new string[] { });
  2846. }
  2847. break;
  2848. case ActionType.GiveHP:
  2849. {
  2850. if (!int.TryParse(param[0], out int tempInt)) return;
  2851. player.ChangeHP(tempInt);
  2852. }
  2853. break;
  2854. case ActionType.GiveMP:
  2855. {
  2856. if (!int.TryParse(param[0], out int tempInt)) return;
  2857. player.ChangeMP(tempInt);
  2858. }
  2859. break;
  2860. case ActionType.ChangeLevel:
  2861. {
  2862. if (!ushort.TryParse(param[0], out ushort tempuShort)) return;
  2863. tempuShort = Math.Min(ushort.MaxValue, tempuShort);
  2864. player.Level = tempuShort;
  2865. player.Experience = 0;
  2866. player.LevelUp();
  2867. }
  2868. break;
  2869. case ActionType.SetPkPoint:
  2870. {
  2871. if (!int.TryParse(param[0], out int tempInt)) return;
  2872. player.PKPoints = tempInt;
  2873. }
  2874. break;
  2875. case ActionType.ReducePkPoint:
  2876. {
  2877. if (!int.TryParse(param[0], out int tempInt)) return;
  2878. player.PKPoints -= tempInt;
  2879. if (player.PKPoints < 0) player.PKPoints = 0;
  2880. }
  2881. break;
  2882. case ActionType.IncreasePkPoint:
  2883. {
  2884. if (!int.TryParse(param[0], out int tempInt)) return;
  2885. player.PKPoints += tempInt;
  2886. }
  2887. break;
  2888. case ActionType.ChangeGender:
  2889. {
  2890. switch (player.Info.Gender)
  2891. {
  2892. case MirGender.Male:
  2893. player.Info.Gender = MirGender.Female;
  2894. break;
  2895. case MirGender.Female:
  2896. player.Info.Gender = MirGender.Male;
  2897. break;
  2898. }
  2899. }
  2900. break;
  2901. case ActionType.ChangeHair:
  2902. {
  2903. if (param.Count < 1)
  2904. {
  2905. player.Info.Hair = (byte)Envir.Random.Next(0, 9);
  2906. }
  2907. else
  2908. {
  2909. byte.TryParse(param[0], out byte tempByte);
  2910. if (tempByte >= 0 && tempByte <= 9)
  2911. {
  2912. player.Info.Hair = tempByte;
  2913. }
  2914. }
  2915. }
  2916. break;
  2917. case ActionType.ChangeClass:
  2918. {
  2919. if (!Enum.TryParse(param[0], true, out MirClass mirClass)) return;
  2920. switch (mirClass)
  2921. {
  2922. case MirClass.Warrior:
  2923. player.Info.Class = MirClass.Warrior;
  2924. break;
  2925. case MirClass.Taoist:
  2926. player.Info.Class = MirClass.Taoist;
  2927. break;
  2928. case MirClass.Wizard:
  2929. player.Info.Class = MirClass.Wizard;
  2930. break;
  2931. case MirClass.Assassin:
  2932. player.Info.Class = MirClass.Assassin;
  2933. break;
  2934. case MirClass.Archer:
  2935. player.Info.Class = MirClass.Archer;
  2936. break;
  2937. }
  2938. }
  2939. break;
  2940. case ActionType.LocalMessage:
  2941. {
  2942. ChatType chatType;
  2943. if (!Enum.TryParse(param[1], true, out chatType)) return;
  2944. player.ReceiveChat(param[0], chatType);
  2945. }
  2946. break;
  2947. case ActionType.GlobalMessage:
  2948. {
  2949. if (!Enum.TryParse(param[1], true, out ChatType chatType)) return;
  2950. var p = new S.Chat { Message = param[0], Type = chatType };
  2951. Envir.Broadcast(p);
  2952. }
  2953. break;
  2954. case ActionType.GiveSkill:
  2955. {
  2956. byte spellLevel = 0;
  2957. Spell skill;
  2958. if (!Enum.TryParse(param[0], true, out skill)) return;
  2959. if (player.Info.Magics.Any(e => e.Spell == skill)) break;
  2960. if (param.Count > 1)
  2961. spellLevel = byte.TryParse(param[1], out spellLevel) ? Math.Min((byte)3, spellLevel) : (byte)0;
  2962. var magic = new UserMagic(skill) { Level = spellLevel };
  2963. if (magic.Info == null) return;
  2964. player.Info.Magics.Add(magic);
  2965. player.SendMagicInfo(magic);
  2966. }
  2967. break;
  2968. case ActionType.RemoveSkill:
  2969. {
  2970. if (!Enum.TryParse(param[0], true, out Spell skill)) return;
  2971. if (!player.Info.Magics.Any(e => e.Spell == skill)) break;
  2972. for (var j = player.Info.Magics.Count - 1; j >= 0; j--)
  2973. {
  2974. if (player.Info.Magics[j].Spell != skill) continue;
  2975. player.Info.Magics.RemoveAt(j);
  2976. player.Enqueue(new S.RemoveMagic { PlaceId = j });
  2977. }
  2978. }
  2979. break;
  2980. case ActionType.Goto:
  2981. {
  2982. DelayedAction action = new DelayedAction(DelayedType.NPC, -1, player.NPCObjectID, player.NPCScriptID, "[" + param[0] + "]");
  2983. player.ActionList.Add(action);
  2984. }
  2985. break;
  2986. case ActionType.Call:
  2987. {
  2988. if (!int.TryParse(param[0], out int scriptID)) return;
  2989. var action = new DelayedAction(DelayedType.NPC, -1, player.NPCObjectID, scriptID, "[@MAIN]");
  2990. player.ActionList.Add(action);
  2991. }
  2992. break;
  2993. case ActionType.Break:
  2994. {
  2995. Page.BreakFromSegments = true;
  2996. }
  2997. break;
  2998. case ActionType.Set:
  2999. {
  3000. int flagIndex;
  3001. uint onCheck;
  3002. if (!int.TryParse(param[0], out flagIndex)) return;
  3003. if (!uint.TryParse(param[1], out onCheck)) return;
  3004. if (flagIndex < 0 || flagIndex >= Globals.FlagIndexCount) return;
  3005. var flagIsOn = Convert.ToBoolean(onCheck);
  3006. player.Info.Flags[flagIndex] = flagIsOn;
  3007. for (int f = player.CurrentMap.NPCs.Count - 1; f >= 0; f--)
  3008. {
  3009. if (Functions.InRange(player.CurrentMap.NPCs[f].CurrentLocation, player.CurrentLocation, Globals.DataRange))
  3010. player.CurrentMap.NPCs[f].CheckVisible(player);
  3011. }
  3012. if (flagIsOn) player.CheckNeedQuestFlag(flagIndex);
  3013. }
  3014. break;
  3015. case ActionType.Param1:
  3016. {
  3017. if (!int.TryParse(param[1], out int tempInt)) return;
  3018. Param1 = param[0];
  3019. Param1Instance = tempInt;
  3020. }
  3021. break;
  3022. case ActionType.Param2:
  3023. {
  3024. if (!int.TryParse(param[0], out int tempInt)) return;
  3025. Param2 = tempInt;
  3026. }
  3027. break;
  3028. case ActionType.Param3:
  3029. {
  3030. if (!int.TryParse(param[0], out int tempInt)) return;
  3031. Param3 = tempInt;
  3032. }
  3033. break;
  3034. case ActionType.Mongen:
  3035. {
  3036. if (Param1 == null || Param2 == 0 || Param3 == 0) return;
  3037. if (!byte.TryParse(param[1], out byte tempByte)) return;
  3038. Map targetmap = Envir.GetMapByNameAndInstance(Param1, Param1Instance);
  3039. if (targetmap == null) return;
  3040. var monInfo = Envir.GetMonsterInfo(param[0]);
  3041. if (monInfo == null) return;
  3042. for (int j = 0; j < tempByte; j++)
  3043. {
  3044. MonsterObject monster = MonsterObject.GetMonster(monInfo);
  3045. if (monster == null) return;
  3046. monster.Direction = 0;
  3047. monster.ActionTime = Envir.Time + 1000;
  3048. monster.Spawn(targetmap, new Point(Param2, Param3));
  3049. }
  3050. }
  3051. break;
  3052. case ActionType.TimeRecall:
  3053. {
  3054. var tempString = "";
  3055. if (!long.TryParse(param[0], out long tempLong)) return;
  3056. if (param[1].Length > 0) tempString = "[" + param[1] + "]";
  3057. Map tempMap = player.CurrentMap;
  3058. Point tempPoint = player.CurrentLocation;
  3059. var action = new DelayedAction(DelayedType.NPC, Envir.Time + (tempLong * 1000), player.NPCObjectID, player.NPCScriptID, tempString, tempMap, tempPoint);
  3060. player.ActionList.Add(action);
  3061. }
  3062. break;
  3063. case ActionType.TimeRecallGroup:
  3064. {
  3065. var tempString = "";
  3066. if (player.GroupMembers == null) return;
  3067. if (!long.TryParse(param[0], out long tempLong)) return;
  3068. if (param[1].Length > 0) tempString = "[" + param[1] + "]";
  3069. for (int j = 0; j < player.GroupMembers.Count(); j++)
  3070. {
  3071. var groupMember = player.GroupMembers[j];
  3072. var action = new DelayedAction(DelayedType.NPC, Envir.Time + (tempLong * 1000), player.NPCObjectID, player.NPCScriptID, tempString, player.CurrentMap, player.CurrentLocation);
  3073. groupMember.ActionList.Add(action);
  3074. }
  3075. }
  3076. break;
  3077. case ActionType.BreakTimeRecall:
  3078. {
  3079. foreach (DelayedAction ac in player.ActionList.Where(u => u.Type == DelayedType.NPC))
  3080. {
  3081. ac.FlaggedToRemove = true;
  3082. }
  3083. }
  3084. break;
  3085. case ActionType.DelayGoto:
  3086. {
  3087. if (!long.TryParse(param[0], out long tempLong)) return;
  3088. var action = new DelayedAction(DelayedType.NPC, Envir.Time + (tempLong * 1000), player.NPCObjectID, player.NPCScriptID, "[" + param[1] + "]");
  3089. player.ActionList.Add(action);
  3090. }
  3091. break;
  3092. case ActionType.MonClear:
  3093. {
  3094. if (!int.TryParse(param[1], out int tempInt)) return;
  3095. var targetmap = Envir.GetMapByNameAndInstance(param[0], tempInt);
  3096. if (targetmap == null) return;
  3097. foreach (var cell in targetmap.Cells)
  3098. {
  3099. if (cell == null || cell.Objects == null) continue;
  3100. for (int j = 0; j < cell.Objects.Count(); j++)
  3101. {
  3102. MapObject ob = cell.Objects[j];
  3103. if (ob.Race != ObjectType.Monster) continue;
  3104. if (ob.Dead) continue;
  3105. if (!string.IsNullOrEmpty(param[2]) && string.Compare(param[2], ((MonsterObject)ob).Info.Name, true) != 0)
  3106. continue;
  3107. ob.Die();
  3108. }
  3109. }
  3110. }
  3111. break;
  3112. case ActionType.GroupRecall:
  3113. {
  3114. if (player.GroupMembers == null) return;
  3115. for (int j = 0; j < player.GroupMembers.Count(); j++)
  3116. {
  3117. player.GroupMembers[j].Teleport(player.CurrentMap, player.CurrentLocation);
  3118. }
  3119. }
  3120. break;
  3121. case ActionType.GroupTeleport:
  3122. {
  3123. if (player.GroupMembers == null) return;
  3124. if (!int.TryParse(param[1], out int tempInt)) return;
  3125. if (!int.TryParse(param[2], out int x)) return;
  3126. if (!int.TryParse(param[3], out int y)) return;
  3127. var targetmap = Envir.GetMapByNameAndInstance(param[0], tempInt);
  3128. if (targetmap == null) return;
  3129. for (int j = 0; j < player.GroupMembers.Count(); j++)
  3130. {
  3131. if (x == 0 || y == 0)
  3132. {
  3133. player.GroupMembers[j].TeleportRandom(200, 0, targetmap);
  3134. }
  3135. else
  3136. {
  3137. player.GroupMembers[j].Teleport(targetmap, new Point(x, y));
  3138. }
  3139. }
  3140. }
  3141. break;
  3142. case ActionType.Mov:
  3143. {
  3144. string value = param[0];
  3145. AddVariable(player, value, param[1]);
  3146. }
  3147. break;
  3148. case ActionType.Calc:
  3149. {
  3150. int left;
  3151. int right;
  3152. bool resultLeft = int.TryParse(param[0], out left);
  3153. bool resultRight = int.TryParse(param[2], out right);
  3154. if (resultLeft && resultRight)
  3155. {
  3156. try
  3157. {
  3158. int result = Calculate(param[1], left, right);
  3159. AddVariable(player, param[3].Replace("-", ""), result.ToString());
  3160. }
  3161. catch (ArgumentException)
  3162. {
  3163. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[1], Key));
  3164. }
  3165. }
  3166. else
  3167. {
  3168. AddVariable(player, param[3].Replace("-", ""), param[0] + param[2]);
  3169. }
  3170. }
  3171. break;
  3172. case ActionType.GiveBuff:
  3173. {
  3174. if (!Enum.IsDefined(typeof(BuffType), param[0])) return;
  3175. int.TryParse(param[1], out int duration);
  3176. bool.TryParse(param[2], out bool infinite);
  3177. bool.TryParse(param[3], out bool visible);
  3178. bool.TryParse(param[4], out bool stackable);
  3179. player.AddBuff((BuffType)(byte)Enum.Parse(typeof(BuffType), param[0], true), player, Settings.Second * duration, new Stats(), visible);
  3180. }
  3181. break;
  3182. case ActionType.RemoveBuff:
  3183. {
  3184. if (!Enum.IsDefined(typeof(BuffType), param[0])) return;
  3185. BuffType bType = (BuffType)(byte)Enum.Parse(typeof(BuffType), param[0]);
  3186. player.RemoveBuff(bType);
  3187. }
  3188. break;
  3189. case ActionType.AddToGuild:
  3190. {
  3191. if (player.MyGuild != null) return;
  3192. GuildObject guild = Envir.GetGuild(param[0]);
  3193. if (guild == null) return;
  3194. player.PendingGuildInvite = guild;
  3195. player.GuildInvite(true);
  3196. }
  3197. break;
  3198. case ActionType.RemoveFromGuild:
  3199. {
  3200. if (player.MyGuild == null) return;
  3201. if (player.MyGuildRank == null) return;
  3202. if (player.MyGuild.Name == Settings.NewbieGuild) player.RemoveBuff(BuffType.Newbie);
  3203. if (player.HasBuff(BuffType.Guild)) player.RemoveBuff(BuffType.Guild);
  3204. player.MyGuild.DeleteMember(player, player.Name);
  3205. }
  3206. break;
  3207. case ActionType.RefreshEffects:
  3208. {
  3209. player.SetLevelEffects();
  3210. var p = new S.ObjectLevelEffects { ObjectID = player.ObjectID, LevelEffects = player.LevelEffects };
  3211. player.Enqueue(p);
  3212. player.Broadcast(p);
  3213. }
  3214. break;
  3215. case ActionType.CanGainExp:
  3216. {
  3217. bool.TryParse(param[0], out bool tempBool);
  3218. player.CanGainExp = tempBool;
  3219. }
  3220. break;
  3221. case ActionType.ComposeMail:
  3222. {
  3223. mailInfo = new MailInfo(player.Info.Index, false)
  3224. {
  3225. Sender = param[1],
  3226. Message = param[0]
  3227. };
  3228. }
  3229. break;
  3230. case ActionType.AddMailGold:
  3231. {
  3232. if (mailInfo == null) return;
  3233. uint.TryParse(param[0], out uint tempUint);
  3234. mailInfo.Gold += tempUint;
  3235. }
  3236. break;
  3237. case ActionType.AddMailItem:
  3238. {
  3239. if (mailInfo == null) return;
  3240. if (mailInfo.Items.Count > 5) return;
  3241. if (param.Count < 2 || !ushort.TryParse(param[1], out ushort count)) count = 1;
  3242. var info = Envir.GetItemInfo(param[0]);
  3243. if (info == null)
  3244. {
  3245. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.FailedGetItemInfo), param[0], Key));
  3246. break;
  3247. }
  3248. while (count > 0 && mailInfo.Items.Count < 5)
  3249. {
  3250. UserItem item = Envir.CreateFreshItem(info);
  3251. if (item == null)
  3252. {
  3253. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.FailedCreateUserItemPage), param[0], Key));
  3254. return;
  3255. }
  3256. if (item.Info.StackSize > count)
  3257. {
  3258. item.Count = count;
  3259. count = 0;
  3260. }
  3261. else
  3262. {
  3263. count -= item.Info.StackSize;
  3264. item.Count = item.Info.StackSize;
  3265. }
  3266. mailInfo.Items.Add(item);
  3267. }
  3268. }
  3269. break;
  3270. case ActionType.SendMail:
  3271. {
  3272. if (mailInfo == null) return;
  3273. mailInfo.Send();
  3274. }
  3275. break;
  3276. case ActionType.GroupGoto:
  3277. {
  3278. if (player.GroupMembers == null) return;
  3279. for (int j = 0; j < player.GroupMembers.Count(); j++)
  3280. {
  3281. var action = new DelayedAction(DelayedType.NPC, Envir.Time, player.NPCObjectID, player.NPCScriptID, "[" + param[0] + "]");
  3282. player.GroupMembers[j].ActionList.Add(action);
  3283. }
  3284. }
  3285. break;
  3286. case ActionType.EnterMap:
  3287. {
  3288. if (!player.NPCData.TryGetValue("NPCMoveMap", out object _npcMoveMap) || !player.NPCData.TryGetValue("NPCMoveCoord", out object _npcMoveCoord)) return;
  3289. player.Teleport((Map)_npcMoveMap, (Point)_npcMoveCoord, false);
  3290. player.NPCData.Remove("NPCMoveMap");
  3291. player.NPCData.Remove("NPCMoveCoord");
  3292. }
  3293. break;
  3294. case ActionType.MakeWeddingRing:
  3295. {
  3296. player.MakeWeddingRing();
  3297. }
  3298. break;
  3299. case ActionType.ForceDivorce:
  3300. {
  3301. player.NPCDivorce();
  3302. }
  3303. break;
  3304. case ActionType.LoadValue:
  3305. {
  3306. string val = param[0];
  3307. string filePath = param[1];
  3308. string header = param[2];
  3309. string key = param[3];
  3310. InIReader reader = new InIReader(filePath);
  3311. string loadedString = reader.ReadString(header, key, "");
  3312. if (loadedString == "") break;
  3313. AddVariable(player, val, loadedString);
  3314. }
  3315. break;
  3316. case ActionType.SaveValue:
  3317. {
  3318. string filePath = param[0];
  3319. string header = param[1];
  3320. string key = param[2];
  3321. string val = param[3];
  3322. InIReader reader = new InIReader(filePath);
  3323. reader.Write(header, key, val);
  3324. }
  3325. break;
  3326. case ActionType.ConquestGuard:
  3327. {
  3328. if (!int.TryParse(param[0], out int tempInt)) return;
  3329. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3330. if (conquest == null) return;
  3331. if (!int.TryParse(param[1], out tempInt)) return;
  3332. ConquestGuildArcherInfo conquestArcher = conquest.ArcherList.FirstOrDefault(z => z.Index == tempInt);
  3333. if (conquestArcher == null) return;
  3334. if (conquestArcher.ArcherMonster != null)
  3335. if (!conquestArcher.ArcherMonster.Dead) return;
  3336. if (player.IsGM)
  3337. {
  3338. conquestArcher.Spawn(true);
  3339. }
  3340. else
  3341. {
  3342. if (player.MyGuild == null || player.MyGuild.Gold < conquestArcher.GetRepairCost()) return;
  3343. player.MyGuild.Gold -= conquestArcher.GetRepairCost();
  3344. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 2, Amount = conquestArcher.GetRepairCost() });
  3345. conquestArcher.Spawn(true);
  3346. }
  3347. }
  3348. break;
  3349. case ActionType.ConquestGate:
  3350. {
  3351. if (!int.TryParse(param[0], out int tempInt)) return;
  3352. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3353. if (conquest == null) return;
  3354. if (!int.TryParse(param[1], out tempInt)) return;
  3355. ConquestGuildGateInfo conquestGate = conquest.GateList.FirstOrDefault(z => z.Index == tempInt);
  3356. if (conquestGate == null) return;
  3357. if (player.IsGM)
  3358. {
  3359. conquestGate.Repair();
  3360. }
  3361. else
  3362. {
  3363. if (player.MyGuild == null || player.MyGuild.Gold < conquestGate.GetRepairCost()) return;
  3364. player.MyGuild.Gold -= (uint)conquestGate.GetRepairCost();
  3365. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 2, Amount = (uint)conquestGate.GetRepairCost() });
  3366. conquestGate.Repair();
  3367. }
  3368. }
  3369. break;
  3370. case ActionType.ConquestWall:
  3371. {
  3372. if (!int.TryParse(param[0], out int tempInt)) return;
  3373. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3374. if (conquest == null) return;
  3375. if (!int.TryParse(param[1], out tempInt)) return;
  3376. ConquestGuildWallInfo conquestWall = conquest.WallList.FirstOrDefault(z => z.Index == tempInt);
  3377. if (conquestWall == null) return;
  3378. if (player.IsGM)
  3379. {
  3380. conquestWall.Repair();
  3381. }
  3382. else
  3383. {
  3384. if (player.MyGuild == null || player.MyGuild.Gold < conquestWall.GetRepairCost()) return;
  3385. player.MyGuild.Gold -= (uint)conquestWall.GetRepairCost();
  3386. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 2, Amount = (uint)conquestWall.GetRepairCost() });
  3387. conquestWall.Repair();
  3388. }
  3389. }
  3390. break;
  3391. case ActionType.ConquestSiege:
  3392. {
  3393. if (!int.TryParse(param[0], out int tempInt)) return;
  3394. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3395. if (conquest == null) return;
  3396. if (!int.TryParse(param[1], out tempInt)) return;
  3397. ConquestGuildSiegeInfo conquestSiege = conquest.SiegeList.FirstOrDefault(z => z.Index == tempInt);
  3398. if (conquestSiege == null) return;
  3399. if (conquestSiege.Gate != null)
  3400. {
  3401. if (!conquestSiege.Gate.Dead) return;
  3402. }
  3403. if (player.IsGM)
  3404. {
  3405. conquestSiege.Repair();
  3406. }
  3407. else
  3408. {
  3409. if (player.MyGuild == null || player.MyGuild.Gold < conquestSiege.GetRepairCost()) return;
  3410. player.MyGuild.Gold -= (uint)conquestSiege.GetRepairCost();
  3411. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 2, Amount = (uint)conquestSiege.GetRepairCost() });
  3412. conquestSiege.Repair();
  3413. }
  3414. }
  3415. break;
  3416. case ActionType.TakeConquestGold:
  3417. {
  3418. if (!int.TryParse(param[0], out int tempInt)) return;
  3419. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3420. if (conquest == null) return;
  3421. if (player.MyGuild != null && player.MyGuild.Guildindex == conquest.GuildInfo.Owner)
  3422. {
  3423. player.MyGuild.Gold += conquest.GuildInfo.GoldStorage;
  3424. player.MyGuild.SendServerPacket(new S.GuildStorageGoldChange() { Type = 3, Amount = conquest.GuildInfo.GoldStorage });
  3425. conquest.GuildInfo.GoldStorage = 0;
  3426. }
  3427. }
  3428. break;
  3429. case ActionType.SetConquestRate:
  3430. {
  3431. if (!int.TryParse(param[0], out int tempInt)) return;
  3432. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3433. if (conquest == null) return;
  3434. if (!byte.TryParse(param[1], out byte tempByte)) return;
  3435. if (player.MyGuild != null && player.MyGuild.Guildindex == conquest.GuildInfo.Owner)
  3436. {
  3437. conquest.GuildInfo.NPCRate = tempByte;
  3438. }
  3439. }
  3440. break;
  3441. case ActionType.StartConquest:
  3442. {
  3443. if (!int.TryParse(param[0], out int tempInt)) return;
  3444. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3445. if (conquest == null) return;
  3446. if (!conquest.WarIsOn)
  3447. {
  3448. conquest.StartType = ConquestType.Forced;
  3449. conquest.StartWar(conquest.GameType);
  3450. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.WarStarted), conquest.Info.Name));
  3451. }
  3452. else
  3453. {
  3454. conquest.WarIsOn = false;
  3455. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.WarStopped), conquest.Info.Name));
  3456. }
  3457. foreach (var pl in Envir.Players)
  3458. {
  3459. if (conquest.WarIsOn)
  3460. {
  3461. pl.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.WarStarted), conquest.Info.Name), ChatType.System);
  3462. }
  3463. else
  3464. {
  3465. pl.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.WarStopped), conquest.Info.Name), ChatType.System);
  3466. }
  3467. pl.BroadcastInfo();
  3468. }
  3469. }
  3470. break;
  3471. case ActionType.ScheduleConquest:
  3472. {
  3473. if (!int.TryParse(param[0], out int tempInt)) return;
  3474. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3475. if (conquest == null) return;
  3476. if (player.MyGuild != null && player.MyGuild.Guildindex != conquest.GuildInfo.Owner && !conquest.WarIsOn)
  3477. {
  3478. conquest.GuildInfo.AttackerID = player.MyGuild.Guildindex;
  3479. }
  3480. }
  3481. break;
  3482. case ActionType.OpenGate:
  3483. {
  3484. if (!int.TryParse(param[0], out int tempInt)) return;
  3485. var Conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3486. if (Conquest == null) return;
  3487. if (!int.TryParse(param[1], out tempInt)) return;
  3488. ConquestGuildGateInfo OpenGate = Conquest.GateList.FirstOrDefault(z => z.Index == tempInt);
  3489. if (OpenGate == null) return;
  3490. if (OpenGate.Gate == null) return;
  3491. OpenGate.Gate.OpenDoor();
  3492. }
  3493. break;
  3494. case ActionType.CloseGate:
  3495. {
  3496. if (!int.TryParse(param[0], out int tempInt)) return;
  3497. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3498. if (conquest == null) return;
  3499. if (!int.TryParse(param[1], out tempInt)) return;
  3500. ConquestGuildGateInfo CloseGate = conquest.GateList.FirstOrDefault(z => z.Index == tempInt);
  3501. if (CloseGate == null) return;
  3502. if (CloseGate.Gate == null) return;
  3503. CloseGate.Gate.CloseDoor();
  3504. }
  3505. break;
  3506. case ActionType.OpenBrowser:
  3507. {
  3508. player.Enqueue(new S.OpenBrowser { Url = param[0] });
  3509. }
  3510. break;
  3511. case ActionType.GetRandomText:
  3512. {
  3513. string randomTextPath = Path.Combine(Settings.NPCPath, param[0]);
  3514. if (!File.Exists(randomTextPath))
  3515. {
  3516. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.RandomTextFileNotExist), randomTextPath));
  3517. }
  3518. else
  3519. {
  3520. var lines = File.ReadAllLines(randomTextPath);
  3521. int index = Envir.Random.Next(0, lines.Length);
  3522. string randomText = lines[index];
  3523. AddVariable(player, param[1], randomText);
  3524. }
  3525. }
  3526. break;
  3527. case ActionType.PlaySound:
  3528. {
  3529. if (!int.TryParse(param[0], out int soundID)) return;
  3530. player.Enqueue(new S.PlaySound { Sound = soundID });
  3531. }
  3532. break;
  3533. case ActionType.SetTimer:
  3534. {
  3535. if (!int.TryParse(param[1], out int seconds) || !byte.TryParse(param[2], out byte type)) return;
  3536. bool.TryParse(param[3], out bool global);
  3537. if (seconds < 0) seconds = 0;
  3538. if (global)
  3539. {
  3540. var timerKey = "_-" + param[0];
  3541. Envir.Timers[timerKey] = new Timer(timerKey, seconds, type);
  3542. }
  3543. else
  3544. {
  3545. player.SetTimer(param[0], seconds, type);
  3546. }
  3547. }
  3548. break;
  3549. case ActionType.ExpireTimer:
  3550. {
  3551. var globalTimerKey = "_-" + param[0];
  3552. if (Envir.Timers.ContainsKey(globalTimerKey))
  3553. {
  3554. Envir.Timers.Remove(globalTimerKey);
  3555. }
  3556. player.ExpireTimer(param[0]);
  3557. }
  3558. break;
  3559. case ActionType.UnequipItem:
  3560. {
  3561. var slot = param[0];
  3562. for (int e = 0; e < player.Info.Equipment.Length; e++)
  3563. {
  3564. var item = player.Info.Equipment[e];
  3565. if (item == null) continue;
  3566. var slotName = (EquipmentSlot)e;
  3567. if (!string.IsNullOrEmpty(slot) && slot.ToLower() != slotName.ToString().ToLower()) continue;
  3568. if (!player.CanRemoveItem(MirGridType.Inventory, item) || item.Cursed || item.WeddingRing != -1) continue;
  3569. for (int k = 0; k < player.Info.Inventory.Length; k++)
  3570. {
  3571. var freeSlot = player.Info.Inventory[k];
  3572. if (freeSlot != null) continue;
  3573. player.Info.Equipment[e] = null;
  3574. player.Info.Inventory[k] = item;
  3575. player.Report.ItemMoved(item, MirGridType.Equipment, MirGridType.Inventory, e, k);
  3576. break;
  3577. }
  3578. }
  3579. S.UserSlotsRefresh packet = new S.UserSlotsRefresh
  3580. {
  3581. Inventory = new UserItem[player.Info.Inventory.Length],
  3582. Equipment = new UserItem[player.Info.Equipment.Length],
  3583. };
  3584. player.Info.Inventory.CopyTo(packet.Inventory, 0);
  3585. player.Info.Equipment.CopyTo(packet.Equipment, 0);
  3586. player.Enqueue(packet);
  3587. player.RefreshStats();
  3588. }
  3589. break;
  3590. case ActionType.GTAllRecall:
  3591. if (player.MyGuild == null)
  3592. {
  3593. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.SummonGuildMembersMustBeInGuild), ChatType.System);
  3594. return;
  3595. }
  3596. if (player.MyGuildRank.Index != 0)
  3597. {
  3598. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GuildLeaderSummonMembers), player.MyGuild.Name), ChatType.System);
  3599. return;
  3600. }
  3601. //ok were confident the player has a guild and is rank 0 (which we assume is leader)
  3602. foreach (PlayerObject ob in Envir.Players) //thers no accessable member list from the player.myguild....hmmm ok we will look at all players curently online
  3603. {
  3604. if (ob == null)
  3605. {
  3606. continue;//ignore people that dont exist, shouldnt happen but lets check for it
  3607. }
  3608. if (ob.Connection == null)
  3609. {
  3610. continue; //really shouldnt be needed but better safe than sorry
  3611. }
  3612. if (ob.Connection.Stage != GameStage.Game)
  3613. {
  3614. continue; //shouldnt be needed but lets make sure the player is in game
  3615. }
  3616. if (ob.MyGuild == null)
  3617. {
  3618. continue; //they aint in a guild? lets not check them further (oops)
  3619. }
  3620. if (ob.MyGuild.Name != player.MyGuild.Name)
  3621. {
  3622. continue; //not in my guild?who wants you!?
  3623. }
  3624. if (ob.Name == player.Name)
  3625. {
  3626. continue;//dont try to recall yourself
  3627. }
  3628. ob.Teleport(player.CurrentMap, new Point(player.CurrentLocation.X + Envir.Random.Next(4), player.CurrentLocation.Y + Envir.Random.Next(4)));
  3629. ob.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouHaveBeenSummoned)+player.Name, ChatType.System);
  3630. }
  3631. break;
  3632. case ActionType.GTRecall:
  3633. if (player.MyGuild == null)
  3634. {
  3635. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.SummonGuildMemberRequiresGuild), ChatType.System);
  3636. return;
  3637. }
  3638. if (player.MyGuildRank.Index != 0)
  3639. {
  3640. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.LeaderMaySummonMembers), player.MyGuild.Name), ChatType.System);
  3641. return;
  3642. }
  3643. PlayerObject guildmember = Envir.GetPlayer(param[0]);
  3644. if (guildmember == null)
  3645. {
  3646. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ICanNotSummonNotExist), param[0]), ChatType.System);
  3647. return;
  3648. }
  3649. if (guildmember.Connection == null)
  3650. {
  3651. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ICannotSummon), param[0]), ChatType.System);
  3652. continue; //really shouldnt be needed but better safe than sorry
  3653. }
  3654. if (guildmember.Connection.Stage != GameStage.Game)
  3655. {
  3656. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.PlayerNotInGame), param[0]), ChatType.System);
  3657. return;
  3658. }
  3659. if (guildmember.MyGuild == null)
  3660. {
  3661. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.PlayerNotInGuild), param[0]), ChatType.System);
  3662. return;
  3663. }
  3664. if (guildmember.MyGuild.Name != player.MyGuild.Name)
  3665. {
  3666. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.PlayerNotInGuildButInAnother), param[0], player.MyGuild.Name, guildmember.MyGuild.Name), ChatType.System);
  3667. return;
  3668. }
  3669. guildmember.Teleport(player.CurrentMap, new Point(player.CurrentLocation.X + Envir.Random.Next(4), player.CurrentLocation.Y + Envir.Random.Next(4)));
  3670. guildmember.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.YouHaveBeenSummonedBy), player.Name), ChatType.System);
  3671. break;
  3672. case ActionType.GTSale:
  3673. if (player.MyGuild == null)
  3674. return;
  3675. if (player.MyGuildRank.Index != 0 || player.CurrentMap.Info.GTIndex != player.MyGuild.GTIndex)
  3676. {
  3677. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.LeaderInitiateSale), player.MyGuild.Name), ChatType.System);
  3678. return;
  3679. }
  3680. if (!int.TryParse(param[0], out int saleprice))
  3681. return;
  3682. if (saleprice < 2000000)
  3683. {
  3684. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.MinimumSalePriceMustBe2000000), ChatType.System);
  3685. return;
  3686. }
  3687. if (!player.MyGuild.GTForSale(player, saleprice))
  3688. return;
  3689. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.TerritoryListedForSale), ChatType.System);
  3690. break;
  3691. case ActionType.GTCancelSale:
  3692. if (player.MyGuild == null)
  3693. return;
  3694. if (player.MyGuildRank.Index != 0 || player.CurrentMap.Info.GTIndex != player.MyGuild.GTIndex)
  3695. {
  3696. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.OnlyLeaderMayCancelSale), player.MyGuild.Name), ChatType.System);
  3697. return;
  3698. }
  3699. if (!player.MyGuild.EndGTSale(player))
  3700. return;
  3701. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.TerritorySaleCancelled), ChatType.System);
  3702. break;
  3703. case ActionType.RollDie:
  3704. {
  3705. bool.TryParse(param[1], out bool autoRoll);
  3706. var result = Envir.Random.Next(1, 7);
  3707. S.Roll p = new S.Roll { Type = 0, Page = param[0], AutoRoll = autoRoll, Result = result };
  3708. player.NPCData["NPCRollResult"] = result;
  3709. player.Enqueue(p);
  3710. }
  3711. break;
  3712. case ActionType.RollYut:
  3713. {
  3714. bool.TryParse(param[1], out bool autoRoll);
  3715. var result = Envir.Random.Next(1, 7);
  3716. S.Roll p = new S.Roll { Type = 1, Page = param[0], AutoRoll = autoRoll, Result = result };
  3717. player.NPCData["NPCRollResult"] = result;
  3718. player.Enqueue(p);
  3719. }
  3720. break;
  3721. case ActionType.Drop:
  3722. {
  3723. var path = param[0];
  3724. var drops = new List<DropInfo>();
  3725. DropInfo.Load(drops, "NPC", path, 0, false);
  3726. foreach (var drop in drops)
  3727. {
  3728. var reward = drop.AttemptDrop(player?.Stats[Stat.ItemDropRatePercent] ?? 0, player?.Stats[Stat.GoldDropRatePercent] ?? 0);
  3729. if (reward != null)
  3730. {
  3731. if (reward.Gold > 0)
  3732. {
  3733. player.GainGold(reward.Gold);
  3734. }
  3735. foreach (var dropItem in reward.Items)
  3736. {
  3737. UserItem item = Envir.CreateDropItem(dropItem);
  3738. if (item == null) continue;
  3739. if (player != null && player.Race == ObjectType.Player)
  3740. {
  3741. PlayerObject ob = (PlayerObject)player;
  3742. if (ob.CheckGroupQuestItem(item))
  3743. {
  3744. continue;
  3745. }
  3746. }
  3747. if (drop.QuestRequired) continue;
  3748. if (player.CanGainItem(item))
  3749. {
  3750. player.GainItem(item);
  3751. }
  3752. }
  3753. }
  3754. }
  3755. }
  3756. break;
  3757. case ActionType.ReviveHero:
  3758. player.ReviveHero();
  3759. break;
  3760. case ActionType.SealHero:
  3761. player.SealHero();
  3762. break;
  3763. case ActionType.DeleteHero:
  3764. player.DeleteHero();
  3765. break;
  3766. case ActionType.HeroGiveSkill:
  3767. {
  3768. if (player.Hero == null || player.Hero.Info == null) return;
  3769. byte spellLevel = 0;
  3770. Spell skill;
  3771. if (!Enum.TryParse(param[0], true, out skill)) return;
  3772. if (player.Hero.Info.Magics.Any(e => e.Spell == skill)) break;
  3773. if (param.Count > 1)
  3774. spellLevel = byte.TryParse(param[1], out spellLevel) ? Math.Min((byte)3, spellLevel) : (byte)0;
  3775. var magic = new UserMagic(skill) { Level = spellLevel };
  3776. if (magic.Info == null) return;
  3777. player.Hero.Info.Magics.Add(magic);
  3778. player.Hero.SendMagicInfo(magic);
  3779. }
  3780. break;
  3781. case ActionType.HeroRemoveSkill:
  3782. {
  3783. if (player.Hero == null || player.Hero.Info == null) return;
  3784. if (!Enum.TryParse(param[0], true, out Spell skill)) return;
  3785. if (!player.Hero.Info.Magics.Any(e => e.Spell == skill)) break;
  3786. for (var j = player.Hero.Info.Magics.Count - 1; j >= 0; j--)
  3787. {
  3788. if (player.Hero.Info.Magics[j].Spell != skill) continue;
  3789. player.Hero.Info.Magics.RemoveAt(j);
  3790. player.Hero.Enqueue(new S.RemoveMagic { PlaceId = j });
  3791. }
  3792. }
  3793. break;
  3794. case ActionType.ConquestRepairAll:
  3795. {
  3796. if (!player.IsGM)
  3797. {
  3798. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.YouNotGMCommandDisabled), ChatType.System);
  3799. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GMCommandConquestRepairAllNonGMInvoked), player.Name));
  3800. return;
  3801. }
  3802. if (!int.TryParse(param[0], out int tempInt)) return;
  3803. var conquest = Envir.Conquests.FirstOrDefault(z => z.Info.Index == tempInt);
  3804. if (conquest == null) return;
  3805. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ConquestRepairAllInvokedByGM), player.Name, player.Info.AccountInfo.Index));
  3806. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.Conquest), conquest.Info.Name));
  3807. if (conquest.Guild != null)
  3808. {
  3809. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.OwnerName), conquest.Guild.Name));
  3810. }
  3811. else
  3812. {
  3813. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization(ServerTextKeys.NoCurrentOwner));
  3814. }
  3815. int _fixed = 0;
  3816. foreach (ConquestGuildArcherInfo archer in conquest.ArcherList)
  3817. {
  3818. if (archer.ArcherMonster != null &&
  3819. archer.ArcherMonster.Dead)
  3820. {
  3821. archer.Spawn(true);
  3822. _fixed++;
  3823. }
  3824. }
  3825. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ArchersRepaired), _fixed, conquest.ArcherList.Count), ChatType.System);
  3826. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.ArchersRepaired), _fixed, conquest.ArcherList.Count));
  3827. _fixed = 0;
  3828. foreach (ConquestGuildGateInfo conquestGate in conquest.GateList)
  3829. {
  3830. if (conquestGate != null)
  3831. {
  3832. conquestGate.Repair();
  3833. _fixed++;
  3834. }
  3835. }
  3836. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GatesRepaired), _fixed, conquest.GateList.Count), ChatType.System);
  3837. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.GatesRepaired), _fixed, conquest.GateList.Count));
  3838. _fixed = 0;
  3839. foreach (ConquestGuildWallInfo conquestWall in conquest.WallList)
  3840. {
  3841. if (conquestWall != null)
  3842. {
  3843. conquestWall.Repair();
  3844. _fixed++;
  3845. }
  3846. }
  3847. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.WallsRepaired), _fixed, conquest.WallList.Count), ChatType.System);
  3848. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.WallsRepaired), _fixed, conquest.WallList.Count));
  3849. _fixed = 0;
  3850. foreach (ConquestGuildSiegeInfo conquestSiege in conquest.SiegeList)
  3851. {
  3852. if (conquestSiege != null)
  3853. {
  3854. conquestSiege.Repair();
  3855. _fixed++;
  3856. }
  3857. }
  3858. player.ReceiveChat(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.SiegesRepaired), _fixed, conquest.SiegeList.Count), ChatType.System);
  3859. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.SiegesRepaired), _fixed, conquest.SiegeList.Count));
  3860. break;
  3861. }
  3862. }
  3863. }
  3864. }
  3865. private void Act(IList<NPCActions> acts, MonsterObject monster)
  3866. {
  3867. for (var i = 0; i < acts.Count; i++)
  3868. {
  3869. NPCActions act = acts[i];
  3870. List<string> param = act.Params.Select(t => FindVariable(monster, t)).ToList();
  3871. for (int j = 0; j < param.Count; j++)
  3872. {
  3873. var parts = param[j].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  3874. if (parts.Length == 0) continue;
  3875. foreach (var part in parts)
  3876. {
  3877. param[j] = param[j].Replace(part, ReplaceValue(monster, part));
  3878. }
  3879. }
  3880. switch (act.Type)
  3881. {
  3882. case ActionType.GiveHP:
  3883. {
  3884. if (!int.TryParse(param[0], out int tempInt)) return;
  3885. monster.ChangeHP(tempInt);
  3886. }
  3887. break;
  3888. case ActionType.GlobalMessage:
  3889. {
  3890. if (!Enum.TryParse(param[1], true, out ChatType chatType)) return;
  3891. var p = new S.Chat { Message = param[0], Type = chatType };
  3892. Envir.Broadcast(p);
  3893. }
  3894. break;
  3895. /* //mobs have no real "delayed" npc code so not added this yet
  3896. case ActionType.Goto:
  3897. DelayedAction action = new DelayedAction(DelayedType.NPC, -1, player.NPCID, "[" + param[0] + "]");
  3898. player.ActionList.Add(action);
  3899. break;
  3900. */
  3901. case ActionType.Break:
  3902. {
  3903. Page.BreakFromSegments = true;
  3904. }
  3905. break;
  3906. case ActionType.Param1:
  3907. {
  3908. if (!int.TryParse(param[1], out int tempInt)) return;
  3909. Param1 = param[0];
  3910. Param1Instance = tempInt;
  3911. }
  3912. break;
  3913. case ActionType.Param2:
  3914. {
  3915. if (!int.TryParse(param[0], out int tempInt)) return;
  3916. Param2 = tempInt;
  3917. }
  3918. break;
  3919. case ActionType.Param3:
  3920. {
  3921. if (!int.TryParse(param[0], out int tempInt)) return;
  3922. Param3 = tempInt;
  3923. }
  3924. break;
  3925. case ActionType.Mongen:
  3926. {
  3927. if (Param1 == null || Param2 == 0 || Param3 == 0) return;
  3928. if (!byte.TryParse(param[1], out byte tempByte)) return;
  3929. var map = Envir.GetMapByNameAndInstance(Param1, Param1Instance);
  3930. if (map == null) return;
  3931. var monInfo = Envir.GetMonsterInfo(param[0]);
  3932. if (monInfo == null) return;
  3933. for (int j = 0; j < tempByte; j++)
  3934. {
  3935. MonsterObject mob = MonsterObject.GetMonster(monInfo);
  3936. if (mob == null) return;
  3937. mob.Direction = 0;
  3938. mob.ActionTime = Envir.Time + 1000;
  3939. mob.Spawn(map, new Point(Param2, Param3));
  3940. }
  3941. }
  3942. break;
  3943. case ActionType.MonClear:
  3944. {
  3945. if (!int.TryParse(param[1], out int tempInt)) return;
  3946. var map = Envir.GetMapByNameAndInstance(param[0], tempInt);
  3947. if (map == null) return;
  3948. foreach (var cell in map.Cells)
  3949. {
  3950. if (cell == null || cell.Objects == null) continue;
  3951. for (int j = 0; j < cell.Objects.Count(); j++)
  3952. {
  3953. MapObject ob = cell.Objects[j];
  3954. if (ob.Race != ObjectType.Monster) continue;
  3955. if (ob.Dead) continue;
  3956. ob.Die();
  3957. }
  3958. }
  3959. }
  3960. break;
  3961. case ActionType.Mov:
  3962. {
  3963. string value = param[0];
  3964. AddVariable(monster, value, param[1]);
  3965. }
  3966. break;
  3967. case ActionType.Calc:
  3968. {
  3969. int left;
  3970. int right;
  3971. bool resultLeft = int.TryParse(param[0], out left);
  3972. bool resultRight = int.TryParse(param[2], out right);
  3973. if (resultLeft && resultRight)
  3974. {
  3975. try
  3976. {
  3977. int result = Calculate(param[1], left, right);
  3978. AddVariable(monster, param[3].Replace("-", ""), result.ToString());
  3979. }
  3980. catch (ArgumentException)
  3981. {
  3982. MessageQueue.Enqueue(GameLanguage.ServerTextMap.GetLocalization((ServerTextKeys.IncorrectOperatorPage), param[1], Key));
  3983. }
  3984. }
  3985. else
  3986. {
  3987. AddVariable(monster, param[3].Replace("-", ""), param[0] + param[2]);
  3988. }
  3989. }
  3990. break;
  3991. case ActionType.GiveBuff:
  3992. {
  3993. if (!Enum.IsDefined(typeof(BuffType), param[0])) return;
  3994. int.TryParse(param[1], out int tempInt);
  3995. bool.TryParse(param[2], out bool infinite);
  3996. bool.TryParse(param[3], out bool visible);
  3997. bool.TryParse(param[4], out bool stackable);
  3998. monster.AddBuff((BuffType)(byte)Enum.Parse(typeof(BuffType), param[0], true), monster, Settings.Second * tempInt, new Stats(), visible);
  3999. }
  4000. break;
  4001. case ActionType.RemoveBuff:
  4002. {
  4003. if (!Enum.IsDefined(typeof(BuffType), param[0])) return;
  4004. BuffType bType = (BuffType)(byte)Enum.Parse(typeof(BuffType), param[0]);
  4005. monster.RemoveBuff(bType);
  4006. }
  4007. break;
  4008. case ActionType.LoadValue:
  4009. {
  4010. string val = param[0];
  4011. string filePath = param[1];
  4012. string header = param[2];
  4013. string key = param[3];
  4014. var reader = new InIReader(filePath);
  4015. string loadedString = reader.ReadString(header, key, "");
  4016. if (loadedString == "") break;
  4017. AddVariable(monster, val, loadedString);
  4018. }
  4019. break;
  4020. case ActionType.SaveValue:
  4021. {
  4022. string filePath = param[0];
  4023. string header = param[1];
  4024. string key = param[2];
  4025. string val = param[3];
  4026. var reader = new InIReader(filePath);
  4027. reader.Write(header, key, val);
  4028. }
  4029. break;
  4030. }
  4031. }
  4032. }
  4033. private void Success(PlayerObject player)
  4034. {
  4035. Act(ActList, player);
  4036. var parseSay = new List<String>(Say);
  4037. parseSay = ParseSay(player, parseSay);
  4038. player.NPCSpeech.AddRange(parseSay);
  4039. }
  4040. private void Failed(PlayerObject player)
  4041. {
  4042. Act(ElseActList, player);
  4043. var parseElseSay = new List<String>(ElseSay);
  4044. parseElseSay = ParseSay(player, parseElseSay);
  4045. player.NPCSpeech.AddRange(parseElseSay);
  4046. }
  4047. private void Success(MonsterObject Monster)
  4048. {
  4049. Act(ActList, Monster);
  4050. }
  4051. private void Failed(MonsterObject Monster)
  4052. {
  4053. Act(ElseActList, Monster);
  4054. }
  4055. private void Success()
  4056. {
  4057. Act(ActList);
  4058. }
  4059. private void Failed()
  4060. {
  4061. Act(ElseActList);
  4062. }
  4063. public static bool Compare<T>(string op, T left, T right) where T : IComparable<T>
  4064. {
  4065. switch (op)
  4066. {
  4067. case "<": return left.CompareTo(right) < 0;
  4068. case ">": return left.CompareTo(right) > 0;
  4069. case "<=": return left.CompareTo(right) <= 0;
  4070. case ">=": return left.CompareTo(right) >= 0;
  4071. case "==": return left.Equals(right);
  4072. case "!=": return !left.Equals(right);
  4073. default: throw new ArgumentException("Invalid comparison operator: {0}", op);
  4074. }
  4075. }
  4076. public static int Calculate(string op, int left, int right)
  4077. {
  4078. switch (op)
  4079. {
  4080. case "+": return left + right;
  4081. case "-": return left - right;
  4082. case "*": return left * right;
  4083. case "/": return left / right;
  4084. default: throw new ArgumentException("Invalid sum operator: {0}", op);
  4085. }
  4086. }
  4087. }
  4088. }