npc.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418
  1. // $Id: npc.c,v 1.5 2004/09/25 05:32:18 MouseJstr Exp $
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5. #include <string.h>
  6. #include <math.h>
  7. #include <time.h>
  8. #include "db.h"
  9. #include "timer.h"
  10. #include "nullpo.h"
  11. #include "malloc.h"
  12. #include "map.h"
  13. #include "npc.h"
  14. #include "clif.h"
  15. #include "intif.h"
  16. #include "pc.h"
  17. #include "status.h"
  18. #include "itemdb.h"
  19. #include "script.h"
  20. #include "mob.h"
  21. #include "pet.h"
  22. #include "battle.h"
  23. #include "skill.h"
  24. #include "grfio.h"
  25. #include "showmsg.h"
  26. #ifdef MEMWATCH
  27. #include "memwatch.h"
  28. #endif
  29. struct npc_src_list {
  30. struct npc_src_list * next;
  31. // struct npc_src_list * prev; //[Shinomori]
  32. char name[4];
  33. } ;
  34. static struct npc_src_list *npc_src_first=NULL;
  35. static struct npc_src_list *npc_src_last=NULL;
  36. static int npc_id=START_NPC_NUM;
  37. static int npc_warp=0;
  38. static int npc_shop=0;
  39. static int npc_script=0;
  40. static int npc_mob=0;
  41. int npc_get_new_npc_id(void){ return npc_id++; }
  42. static struct dbt *ev_db;
  43. static struct dbt *npcname_db;
  44. struct event_data {
  45. struct npc_data *nd;
  46. int pos;
  47. };
  48. static struct tm ev_tm_b; // 時計イベント用
  49. static int npc_walktimer(int,unsigned int,int,int); // [Valaris]
  50. static int npc_walktoxy_sub(struct npc_data *nd); // [Valaris]
  51. /*==========================================
  52. * NPCの無効化/有効化
  53. * npc_enable
  54. * npc_enable_sub 有効時にOnTouchイベントを実行
  55. *------------------------------------------
  56. */
  57. int npc_enable_sub( struct block_list *bl, va_list ap )
  58. {
  59. struct map_session_data *sd;
  60. struct npc_data *nd;
  61. //char *name=(char *)aCallocA(50,sizeof(char)); // fixed [Shinomori]
  62. nullpo_retr(0, bl);
  63. nullpo_retr(0, ap);
  64. nullpo_retr(0, nd=va_arg(ap,struct npc_data *));
  65. if(bl->type == BL_PC && (sd=(struct map_session_data *)bl)){
  66. char name[50]; // need 24 + 9 for the "::OnTouch"
  67. if (nd->flag&1) // 無効化されている
  68. return 1;
  69. if(sd->areanpc_id==nd->bl.id)
  70. return 1;
  71. sd->areanpc_id=nd->bl.id;
  72. sprintf(name,"%s::OnTouch", nd->name);
  73. npc_event(sd,name,0);
  74. }
  75. //aFree(name);
  76. return 0;
  77. }
  78. int npc_enable(const char *name,int flag)
  79. {
  80. struct npc_data *nd= (struct npc_data *) strdb_search(npcname_db,name);
  81. if (nd==NULL)
  82. return 0;
  83. if (flag&1) { // 有効化
  84. nd->flag&=~1;
  85. clif_spawnnpc(nd);
  86. }else if (flag&2){
  87. nd->flag&=~1;
  88. nd->option = 0x0000;
  89. clif_changeoption(&nd->bl);
  90. }else if (flag&4){
  91. nd->flag|=1;
  92. nd->option = 0x0002;
  93. clif_changeoption(&nd->bl);
  94. }else{ // 無効化
  95. nd->flag|=1;
  96. clif_clearchar(&nd->bl,0);
  97. }
  98. if(flag&3 && (nd->u.scr.xs > 0 || nd->u.scr.ys >0))
  99. map_foreachinarea( npc_enable_sub,nd->bl.m,nd->bl.x-nd->u.scr.xs,nd->bl.y-nd->u.scr.ys,nd->bl.x+nd->u.scr.xs,nd->bl.y+nd->u.scr.ys,BL_PC,nd);
  100. return 0;
  101. }
  102. /*==========================================
  103. * NPCを名前で探す
  104. *------------------------------------------
  105. */
  106. struct npc_data* npc_name2id(const char *name)
  107. {
  108. return (struct npc_data *) strdb_search(npcname_db,name);
  109. }
  110. /*==========================================
  111. * イベントキューのイベント処理
  112. *------------------------------------------
  113. */
  114. int npc_event_dequeue(struct map_session_data *sd)
  115. {
  116. nullpo_retr(0, sd);
  117. sd->npc_id=0;
  118. if (sd->eventqueue[0][0]) { // キューのイベント処理
  119. char *name=(char *)aCallocA(50,sizeof(char));
  120. int i;
  121. memcpy(name,sd->eventqueue[0],50);
  122. for(i=MAX_EVENTQUEUE-2;i>=0;i--)
  123. memcpy(sd->eventqueue[i],sd->eventqueue[i+1],50);
  124. add_timer(gettick()+100,npc_event_timer,sd->bl.id,(int)name);
  125. }
  126. return 0;
  127. }
  128. int npc_delete(struct npc_data *nd)
  129. {
  130. nullpo_retr(1, nd);
  131. if(nd->bl.prev == NULL)
  132. return 1;
  133. #ifdef PCRE_SUPPORT
  134. npc_chat_finalize(nd);
  135. #endif
  136. clif_clearchar_area(&nd->bl,1);
  137. map_delblock(&nd->bl);
  138. return 0;
  139. }
  140. /*==========================================
  141. * イベントの遅延実行
  142. *------------------------------------------
  143. */
  144. int npc_event_timer(int tid,unsigned int tick,int id,int data)
  145. {
  146. char *eventname = (char *)data;
  147. struct event_data *ev = (struct event_data *)strdb_search(ev_db,eventname);
  148. struct npc_data *nd;
  149. struct map_session_data *sd=map_id2sd(id);
  150. size_t i;
  151. if((ev==NULL || (nd=ev->nd)==NULL))
  152. {
  153. if(battle_config.error_log)
  154. printf("npc_event: event not found [%s]\n",eventname);
  155. }
  156. else
  157. {
  158. for(i=0;i<MAX_EVENTTIMER;i++) {
  159. if( nd->eventtimer[i]==tid ) {
  160. nd->eventtimer[i]=-1;
  161. npc_event(sd,eventname,0); // sd NULL check is within
  162. break;
  163. }
  164. }
  165. if(i==MAX_EVENTTIMER && battle_config.error_log)
  166. printf("npc_event_timer: event timer not found [%s]!\n",eventname);
  167. }
  168. aFree(eventname);
  169. return 0;
  170. }
  171. int npc_timer_event(const char *eventname) // Added by RoVeRT
  172. {
  173. struct event_data *ev=(struct event_data *) strdb_search(ev_db,eventname);
  174. struct npc_data *nd;
  175. // int xs,ys;
  176. if((ev==NULL || (nd=ev->nd)==NULL)){
  177. printf("npc_event: event not found [%s]\n",eventname);
  178. return 0;
  179. }
  180. run_script(nd->u.scr.script,ev->pos,nd->bl.id,nd->bl.id);
  181. return 0;
  182. }
  183. /*
  184. int npc_timer_sub_sub(void *key,void *data,va_list ap) // Added by RoVeRT
  185. {
  186. char *p=(char *)key;
  187. struct event_data *ev=(struct event_data *)data;
  188. int *c=va_arg(ap,int *);
  189. int tick=0,ctick=gettick();
  190. char temp[10];
  191. char event[100];
  192. if(ev->nd->bl.id==(int)*c && (p=strchr(p,':')) && p && strncasecmp("::OnTimer",p,8)==0 ){
  193. sscanf(&p[9],"%s",temp);
  194. tick=atoi(temp);
  195. strcpy( event, ev->nd->name);
  196. strcat( event, p);
  197. if (ctick >= ev->nd->lastaction && ctick - ev->nd->timer >= tick) {
  198. npc_timer_event(event);
  199. ev->nd->lastaction = ctick;
  200. }
  201. }
  202. return 0;
  203. }
  204. int npc_timer_sub(void *key,void *data,va_list ap) // Added by RoVeRT
  205. {
  206. struct npc_data *nd=(struct npc_data*)data;
  207. if(nd->timer == -1)
  208. return 0;
  209. strdb_foreach(ev_db,npc_timer_sub_sub,&nd->bl.id);
  210. return 0;
  211. }
  212. int npc_timer(int tid,unsigned int tick,int id,int data) // Added by RoVeRT
  213. {
  214. strdb_foreach(npcname_db,npc_timer_sub);
  215. aFree((void*)data);
  216. return 0;
  217. }*/
  218. /*==========================================
  219. * イベント用ラベルのエクスポート
  220. * npc_parse_script->strdb_foreachから呼ばれる
  221. *------------------------------------------
  222. */
  223. int npc_event_export(void *key,void *data,va_list ap)
  224. {
  225. char *lname=(char *)key;
  226. int pos=(int)data;
  227. struct npc_data *nd=va_arg(ap,struct npc_data *);
  228. if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) {
  229. struct event_data *ev;
  230. char *buf;
  231. char *p=strchr(lname,':');
  232. // エクスポートされる
  233. ev=(struct event_data *) aCalloc(sizeof(struct event_data), 1);
  234. buf=(char *) aCallocA(50, 1);
  235. if (ev==NULL || buf==NULL) {
  236. printf("npc_event_export: out of memory !\n");
  237. exit(1);
  238. }else if (p==NULL || (p-lname)>24) {
  239. printf("npc_event_export: label name error !\n");
  240. exit(1);
  241. }else{
  242. ev->nd=nd;
  243. ev->pos=pos;
  244. *p='\0';
  245. sprintf(buf,"%s::%s",nd->exname,lname);
  246. *p=':';
  247. strdb_insert(ev_db,buf,ev);
  248. // if (battle_config.etc_log)
  249. // printf("npc_event_export: export [%s]\n",buf);
  250. }
  251. }
  252. return 0;
  253. }
  254. /*==========================================
  255. * 全てのNPCのOn*イベント実行
  256. *------------------------------------------
  257. */
  258. int npc_event_doall_sub(void *key,void *data,va_list ap)
  259. {
  260. char *p=(char *)key;
  261. struct event_data *ev;
  262. int *c;
  263. const char *name;
  264. nullpo_retr(0, ev=(struct event_data *)data);
  265. nullpo_retr(0, ap);
  266. nullpo_retr(0, c=va_arg(ap,int *));
  267. name=va_arg(ap,const char *);
  268. if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 ){
  269. run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
  270. (*c)++;
  271. }
  272. return 0;
  273. }
  274. int npc_event_doall(const char *name)
  275. {
  276. int c=0;
  277. char buf[64]="::";
  278. strncpy(buf+2,name,62);
  279. strdb_foreach(ev_db,npc_event_doall_sub,&c,buf);
  280. return c;
  281. }
  282. int npc_event_do_sub(void *key,void *data,va_list ap)
  283. {
  284. char *p=(char *)key;
  285. struct event_data *ev;
  286. int *c;
  287. const char *name;
  288. nullpo_retr(0, ev=(struct event_data *)data);
  289. nullpo_retr(0, ap);
  290. nullpo_retr(0, c=va_arg(ap,int *));
  291. name=va_arg(ap,const char *);
  292. if (p && strcmpi(name,p)==0 ) {
  293. run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
  294. (*c)++;
  295. }
  296. return 0;
  297. }
  298. int npc_event_do(const char *name)
  299. {
  300. int c=0;
  301. if (*name==':' && name[1]==':') {
  302. return npc_event_doall(name+2);
  303. }
  304. strdb_foreach(ev_db,npc_event_do_sub,&c,name);
  305. return c;
  306. }
  307. /*==========================================
  308. * 時計イベント実行
  309. *------------------------------------------
  310. */
  311. int npc_event_do_clock(int tid,unsigned int tick,int id,int data)
  312. {
  313. time_t timer;
  314. struct tm *t;
  315. char buf[64];
  316. char *day="";
  317. int c=0;
  318. time(&timer);
  319. t=localtime(&timer);
  320. switch (t->tm_wday) {
  321. case 0: day = "Sun"; break;
  322. case 1: day = "Mon"; break;
  323. case 2: day = "Tue"; break;
  324. case 3: day = "Wed"; break;
  325. case 4: day = "Thu"; break;
  326. case 5: day = "Fri"; break;
  327. case 6: day = "Sat"; break;
  328. }
  329. if (t->tm_min != ev_tm_b.tm_min ) {
  330. sprintf(buf,"OnMinute%02d",t->tm_min);
  331. c+=npc_event_doall(buf);
  332. sprintf(buf,"OnClock%02d%02d",t->tm_hour,t->tm_min);
  333. c+=npc_event_doall(buf);
  334. sprintf(buf,"On%s%02d%02d",day,t->tm_hour,t->tm_min);
  335. c+=npc_event_doall(buf);
  336. }
  337. if (t->tm_hour!= ev_tm_b.tm_hour) {
  338. sprintf(buf,"OnHour%02d",t->tm_hour);
  339. c+=npc_event_doall(buf);
  340. }
  341. if (t->tm_mday!= ev_tm_b.tm_mday) {
  342. sprintf(buf,"OnDay%02d%02d",t->tm_mon+1,t->tm_mday);
  343. c+=npc_event_doall(buf);
  344. }
  345. memcpy(&ev_tm_b,t,sizeof(ev_tm_b));
  346. return c;
  347. }
  348. /*==========================================
  349. * OnInitイベント実行(&時計イベント開始)
  350. *------------------------------------------
  351. */
  352. int npc_event_do_oninit(void)
  353. {
  354. // int c = npc_event_doall("OnInit");
  355. sprintf(tmp_output,"Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"
  356. CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
  357. ShowStatus(tmp_output);
  358. add_timer_interval(gettick()+100,
  359. npc_event_do_clock,0,0,1000);
  360. return 0;
  361. }
  362. /*==========================================
  363. * OnTimer NPC event - by RoVeRT
  364. *------------------------------------------
  365. */
  366. int npc_addeventtimer(struct npc_data *nd,int tick,const char *name)
  367. {
  368. int i;
  369. for(i=0;i<MAX_EVENTTIMER;i++)
  370. if( nd->eventtimer[i]==-1 )
  371. break;
  372. if(i<MAX_EVENTTIMER){
  373. char *evname=(char *) aMallocA(24);
  374. if(evname==NULL){
  375. printf("npc_addeventtimer: out of memory !\n");exit(1);
  376. }
  377. memcpy(evname,name,24);
  378. nd->eventtimer[i]=add_timer(gettick()+tick,
  379. npc_event_timer,nd->bl.id,(int)evname);
  380. }else
  381. printf("npc_addtimer: event timer is full !\n");
  382. return 0;
  383. }
  384. int npc_deleventtimer(struct npc_data *nd,const char *name)
  385. {
  386. int i;
  387. for(i=0;i<MAX_EVENTTIMER;i++)
  388. if( nd->eventtimer[i]!=-1 && strcmp(
  389. (char *)(get_timer(nd->eventtimer[i])->data), name)==0 ){
  390. delete_timer(nd->eventtimer[i],npc_event_timer);
  391. nd->eventtimer[i]=-1;
  392. break;
  393. }
  394. return 0;
  395. }
  396. int npc_cleareventtimer(struct npc_data *nd)
  397. {
  398. int i;
  399. for(i=0;i<MAX_EVENTTIMER;i++)
  400. if( nd->eventtimer[i]!=-1 ){
  401. delete_timer(nd->eventtimer[i],npc_event_timer);
  402. nd->eventtimer[i]=-1;
  403. }
  404. return 0;
  405. }
  406. int npc_do_ontimer_sub(void *key,void *data,va_list ap)
  407. {
  408. char *p=(char *)key;
  409. struct event_data *ev=(struct event_data *)data;
  410. int *c=va_arg(ap,int *);
  411. // struct map_session_data *sd=va_arg(ap,struct map_session_data *);
  412. int option=va_arg(ap,int);
  413. int tick=0;
  414. char temp[10];
  415. char event[50];
  416. if(ev->nd->bl.id==(int)*c && (p=strchr(p,':')) && p && strnicmp("::OnTimer",p,8)==0 ){
  417. sscanf(&p[9],"%s",temp);
  418. tick=atoi(temp);
  419. strcpy( event, ev->nd->name);
  420. strcat( event, p);
  421. if (option!=0) {
  422. npc_addeventtimer(ev->nd,tick,event);
  423. } else {
  424. npc_deleventtimer(ev->nd,event);
  425. }
  426. }
  427. return 0;
  428. }
  429. int npc_do_ontimer(int npc_id, struct map_session_data *sd, int option)
  430. {
  431. strdb_foreach(ev_db,npc_do_ontimer_sub,&npc_id,sd,option);
  432. return 0;
  433. }
  434. /*==========================================
  435. * タイマーイベント用ラベルの取り込み
  436. * npc_parse_script->strdb_foreachから呼ばれる
  437. *------------------------------------------
  438. */
  439. int npc_timerevent_import(void *key,void *data,va_list ap)
  440. {
  441. char *lname=(char *)key;
  442. int pos=(int)data;
  443. struct npc_data *nd=va_arg(ap,struct npc_data *);
  444. int t=0,i=0;
  445. if(sscanf(lname,"OnTimer%d%n",&t,&i)==1 && lname[i]==':') {
  446. // タイマーイベント
  447. struct npc_timerevent_list *te=nd->u.scr.timer_event;
  448. int j,i=nd->u.scr.timeramount;
  449. if(te==NULL) te=(struct npc_timerevent_list*)aMallocA(sizeof(struct npc_timerevent_list));
  450. else te= (struct npc_timerevent_list*)aRealloc( te, sizeof(struct npc_timerevent_list) * (i+1) );
  451. if(te==NULL){
  452. printf("npc_timerevent_import: out of memory !\n");
  453. exit(1);
  454. }
  455. for(j=0;j<i;j++){
  456. if(te[j].timer>t){
  457. memmove(te+j+1,te+j,sizeof(struct npc_timerevent_list)*(i-j));
  458. break;
  459. }
  460. }
  461. te[j].timer=t;
  462. te[j].pos=pos;
  463. nd->u.scr.timer_event=te;
  464. nd->u.scr.timeramount=i+1;
  465. }
  466. return 0;
  467. }
  468. /*==========================================
  469. * タイマーイベント実行
  470. *------------------------------------------
  471. */
  472. int npc_timerevent(int tid,unsigned int tick,int id,int data)
  473. {
  474. int next,t;
  475. struct npc_data* nd=(struct npc_data *)map_id2bl(id);
  476. struct npc_timerevent_list *te;
  477. if( nd==NULL || nd->u.scr.nexttimer<0 ){
  478. printf("npc_timerevent: ??\n");
  479. return 0;
  480. }
  481. nd->u.scr.timertick=tick;
  482. te=nd->u.scr.timer_event+ nd->u.scr.nexttimer;
  483. nd->u.scr.timerid = -1;
  484. t = nd->u.scr.timer+=data;
  485. nd->u.scr.nexttimer++;
  486. if( nd->u.scr.timeramount>nd->u.scr.nexttimer ){
  487. next= nd->u.scr.timer_event[ nd->u.scr.nexttimer ].timer - t;
  488. nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,next);
  489. }
  490. run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id);
  491. return 0;
  492. }
  493. /*==========================================
  494. * タイマーイベント開始
  495. *------------------------------------------
  496. */
  497. int npc_timerevent_start(struct npc_data *nd, int rid)
  498. {
  499. int j,n, next;
  500. nullpo_retr(0, nd);
  501. n=nd->u.scr.timeramount;
  502. if( nd->u.scr.nexttimer>=0 || n==0 )
  503. return 0;
  504. for(j=0;j<n;j++){
  505. if( nd->u.scr.timer_event[j].timer > nd->u.scr.timer )
  506. break;
  507. }
  508. if(j>=n) // check if there is a timer to use !!BEFORE!! you write stuff to the structures [Shinomori]
  509. return 0;
  510. nd->u.scr.nexttimer=j;
  511. nd->u.scr.timertick=gettick();
  512. if (rid >= 0) nd->u.scr.rid=rid; // changed to: attaching to given rid by default [Shinomori]
  513. // if rid is less than 0 leave it unchanged [celest]
  514. next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer;
  515. nd->u.scr.timerid = add_timer(gettick()+next,npc_timerevent,nd->bl.id,next);
  516. return 0;
  517. }
  518. /*==========================================
  519. * タイマーイベント終了
  520. *------------------------------------------
  521. */
  522. int npc_timerevent_stop(struct npc_data *nd)
  523. {
  524. nullpo_retr(0, nd);
  525. if( nd->u.scr.nexttimer>=0 ){
  526. nd->u.scr.nexttimer = -1;
  527. nd->u.scr.timer += (int)(gettick() - nd->u.scr.timertick);
  528. if(nd->u.scr.timerid!=-1)
  529. delete_timer(nd->u.scr.timerid,npc_timerevent);
  530. nd->u.scr.timerid = -1;
  531. nd->u.scr.rid = 0;
  532. }
  533. return 0;
  534. }
  535. /*==========================================
  536. * タイマー値の所得
  537. *------------------------------------------
  538. */
  539. int npc_gettimerevent_tick(struct npc_data *nd)
  540. {
  541. int tick;
  542. nullpo_retr(0, nd);
  543. tick=nd->u.scr.timer;
  544. if( nd->u.scr.nexttimer>=0 )
  545. tick += (int)(gettick() - nd->u.scr.timertick);
  546. return tick;
  547. }
  548. /*==========================================
  549. * タイマー値の設定
  550. *------------------------------------------
  551. */
  552. int npc_settimerevent_tick(struct npc_data *nd,int newtimer)
  553. {
  554. int flag;
  555. nullpo_retr(0, nd);
  556. flag= nd->u.scr.nexttimer;
  557. npc_timerevent_stop(nd);
  558. nd->u.scr.timer=newtimer;
  559. if(flag>=0)
  560. npc_timerevent_start(nd, -1);
  561. return 0;
  562. }
  563. /*==========================================
  564. * イベント型のNPC処理
  565. *------------------------------------------
  566. */
  567. int npc_event(struct map_session_data *sd,const char *eventname,int mob_kill)
  568. {
  569. struct event_data *ev=(struct event_data *) strdb_search(ev_db,eventname);
  570. struct npc_data *nd;
  571. int xs,ys;
  572. char mobevent[100];
  573. if( sd == NULL ){
  574. printf("npc_event nullpo?\n");
  575. }
  576. if(ev==NULL && eventname && strcmp(((eventname)+strlen(eventname)-9),"::OnTouch") == 0)
  577. return 1;
  578. if(ev==NULL || (nd=ev->nd)==NULL){
  579. if(mob_kill && (ev==NULL || (nd=ev->nd)==NULL)){
  580. strcpy( mobevent, eventname);
  581. strcat( mobevent, "::OnMyMobDead");
  582. ev= (struct event_data *) strdb_search(ev_db,mobevent);
  583. if (ev==NULL || (nd=ev->nd)==NULL) {
  584. if (strnicmp(eventname,"GM_MONSTER",10)!=0)
  585. printf("npc_event: event not found [%s]\n",mobevent);
  586. return 0;
  587. }
  588. }
  589. else {
  590. if(battle_config.error_log)
  591. printf("npc_event: event not found [%s]\n",eventname);
  592. return 0;
  593. }
  594. }
  595. xs=nd->u.scr.xs;
  596. ys=nd->u.scr.ys;
  597. if (xs>=0 && ys>=0 ) {
  598. if (nd->bl.m != sd->bl.m )
  599. return 1;
  600. if ( xs>0 && (sd->bl.x<nd->bl.x-xs/2 || nd->bl.x+xs/2<sd->bl.x) )
  601. return 1;
  602. if ( ys>0 && (sd->bl.y<nd->bl.y-ys/2 || nd->bl.y+ys/2<sd->bl.y) )
  603. return 1;
  604. }
  605. if ( sd->npc_id!=0) {
  606. // if (battle_config.error_log)
  607. // printf("npc_event: npc_id != 0\n");
  608. int i;
  609. for(i=0;i<MAX_EVENTQUEUE;i++)
  610. if (!sd->eventqueue[i][0])
  611. break;
  612. if (i==MAX_EVENTQUEUE) {
  613. if (battle_config.error_log)
  614. printf("npc_event: event queue is full !\n");
  615. }else{
  616. // if (battle_config.etc_log)
  617. // printf("npc_event: enqueue\n");
  618. memcpy(sd->eventqueue[i],eventname,50);
  619. }
  620. return 1;
  621. }
  622. if (nd->flag&1) { // 無効化されている
  623. npc_event_dequeue(sd);
  624. return 0;
  625. }
  626. sd->npc_id=nd->bl.id;
  627. sd->npc_pos=run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
  628. return 0;
  629. }
  630. int npc_command_sub(void *key,void *data,va_list ap)
  631. {
  632. char *p=(char *)key;
  633. struct event_data *ev=(struct event_data *)data;
  634. char *npcname=va_arg(ap,char *);
  635. char *command=va_arg(ap,char *);
  636. char temp[100];
  637. if(strcmp(ev->nd->name,npcname)==0 && (p=strchr(p,':')) && p && strnicmp("::OnCommand",p,10)==0 ){
  638. sscanf(&p[11],"%s",temp);
  639. if (strcmp(command,temp)==0)
  640. run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
  641. }
  642. return 0;
  643. }
  644. int npc_command(struct map_session_data *sd,char *npcname,char *command)
  645. {
  646. strdb_foreach(ev_db,npc_command_sub,npcname,command);
  647. return 0;
  648. }
  649. /*==========================================
  650. * 接触型のNPC処理
  651. *------------------------------------------
  652. */
  653. int npc_touch_areanpc(struct map_session_data *sd,int m,int x,int y)
  654. {
  655. int i,f=1;
  656. int xs,ys;
  657. nullpo_retr(1, sd);
  658. if(sd->npc_id)
  659. return 1;
  660. for(i=0;i<map[m].npc_num;i++) {
  661. if (map[m].npc[i]->flag&1) { // 無効化されている
  662. f=0;
  663. continue;
  664. }
  665. switch(map[m].npc[i]->bl.subtype) {
  666. case WARP:
  667. xs=map[m].npc[i]->u.warp.xs;
  668. ys=map[m].npc[i]->u.warp.ys;
  669. break;
  670. case SCRIPT:
  671. xs=map[m].npc[i]->u.scr.xs;
  672. ys=map[m].npc[i]->u.scr.ys;
  673. break;
  674. default:
  675. continue;
  676. }
  677. if (x >= map[m].npc[i]->bl.x-xs/2 && x < map[m].npc[i]->bl.x-xs/2+xs &&
  678. y >= map[m].npc[i]->bl.y-ys/2 && y < map[m].npc[i]->bl.y-ys/2+ys)
  679. break;
  680. }
  681. if (i==map[m].npc_num) {
  682. if (f) {
  683. if (battle_config.error_log)
  684. printf("npc_touch_areanpc : some bug \n");
  685. }
  686. return 1;
  687. }
  688. switch(map[m].npc[i]->bl.subtype) {
  689. case WARP:
  690. skill_stop_dancing(&sd->bl,0);
  691. pc_setpos(sd,map[m].npc[i]->u.warp.name,map[m].npc[i]->u.warp.x,map[m].npc[i]->u.warp.y,0);
  692. break;
  693. case SCRIPT:
  694. {
  695. //char *name=(char *)aCallocA(50,sizeof(char)); // fixed [Shinomori]
  696. char name[50]; // need 24 max + 9 for "::OnTouch"
  697. if(sd->areanpc_id == map[m].npc[i]->bl.id)
  698. return 1;
  699. sd->areanpc_id = map[m].npc[i]->bl.id;
  700. sprintf(name,"%s::OnTouch", map[m].npc[i]->name);
  701. if( npc_event(sd,name,0)>0 )
  702. npc_click(sd,map[m].npc[i]->bl.id);
  703. //aFree(name);
  704. break;
  705. }
  706. }
  707. return 0;
  708. }
  709. /*==========================================
  710. * 近くかどうかの判定
  711. *------------------------------------------
  712. */
  713. int npc_checknear(struct map_session_data *sd,int id)
  714. {
  715. struct npc_data *nd;
  716. nullpo_retr(0, sd);
  717. nd=(struct npc_data *)map_id2bl(id);
  718. if (nd==NULL || nd->bl.type!=BL_NPC) {
  719. if (battle_config.error_log)
  720. printf("no such npc : %d\n",id);
  721. return 1;
  722. }
  723. if (nd->class_<0) // イベント系は常にOK
  724. return 0;
  725. // エリア判定
  726. if (nd->bl.m!=sd->bl.m ||
  727. nd->bl.x<sd->bl.x-AREA_SIZE-1 || nd->bl.x>sd->bl.x+AREA_SIZE+1 ||
  728. nd->bl.y<sd->bl.y-AREA_SIZE-1 || nd->bl.y>sd->bl.y+AREA_SIZE+1)
  729. return 1;
  730. return 0;
  731. }
  732. /*==========================================
  733. * クリック時のNPC処理
  734. *------------------------------------------
  735. */
  736. int npc_click(struct map_session_data *sd,int id)
  737. {
  738. struct npc_data *nd;
  739. nullpo_retr(1, sd);
  740. if (sd->npc_id != 0) {
  741. if (battle_config.error_log)
  742. printf("npc_click: npc_id != 0\n");
  743. return 1;
  744. }
  745. if (npc_checknear(sd,id))
  746. return 1;
  747. nd=(struct npc_data *)map_id2bl(id);
  748. if (nd->flag&1) // 無効化されている
  749. return 1;
  750. sd->npc_id=id;
  751. switch(nd->bl.subtype) {
  752. case SHOP:
  753. clif_npcbuysell(sd,id);
  754. npc_event_dequeue(sd);
  755. break;
  756. case SCRIPT:
  757. sd->npc_pos=run_script(nd->u.scr.script,0,sd->bl.id,id);
  758. break;
  759. }
  760. return 0;
  761. }
  762. /*==========================================
  763. *
  764. *------------------------------------------
  765. */
  766. int npc_scriptcont(struct map_session_data *sd,int id)
  767. {
  768. struct npc_data *nd;
  769. nullpo_retr(1, sd);
  770. if (id!=sd->npc_id)
  771. return 1;
  772. if (npc_checknear(sd,id))
  773. return 1;
  774. nd=(struct npc_data *)map_id2bl(id);
  775. sd->npc_pos=run_script(nd->u.scr.script,sd->npc_pos,sd->bl.id,id);
  776. return 0;
  777. }
  778. /*==========================================
  779. *
  780. *------------------------------------------
  781. */
  782. int npc_buysellsel(struct map_session_data *sd,int id,int type)
  783. {
  784. struct npc_data *nd;
  785. nullpo_retr(1, sd);
  786. if (npc_checknear(sd,id))
  787. return 1;
  788. nd=(struct npc_data *)map_id2bl(id);
  789. if (nd->bl.subtype!=SHOP) {
  790. if (battle_config.error_log)
  791. printf("no such shop npc : %d\n",id);
  792. sd->npc_id=0;
  793. return 1;
  794. }
  795. if (nd->flag&1) // 無効化されている
  796. return 1;
  797. sd->npc_shopid=id;
  798. if (type==0) {
  799. clif_buylist(sd,nd);
  800. } else {
  801. clif_selllist(sd);
  802. }
  803. return 0;
  804. }
  805. /*==========================================
  806. *
  807. *------------------------------------------
  808. */
  809. int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list)
  810. {
  811. struct npc_data *nd;
  812. double z;
  813. int i,j,w,skill,itemamount=0,new_=0;
  814. nullpo_retr(3, sd);
  815. nullpo_retr(3, item_list);
  816. if (npc_checknear(sd,sd->npc_shopid))
  817. return 3;
  818. nd=(struct npc_data*)map_id2bl(sd->npc_shopid);
  819. if (nd->bl.subtype!=SHOP)
  820. return 3;
  821. for(i=0,w=0,z=0;i<n;i++) {
  822. for(j=0;nd->u.shop_item[j].nameid;j++) {
  823. if (nd->u.shop_item[j].nameid==item_list[i*2+1])
  824. break;
  825. }
  826. if (nd->u.shop_item[j].nameid==0)
  827. return 3;
  828. if (itemdb_value_notdc(nd->u.shop_item[j].nameid))
  829. z+=(double)nd->u.shop_item[j].value * item_list[i*2];
  830. else
  831. z+=(double)pc_modifybuyvalue(sd,nd->u.shop_item[j].value) * item_list[i*2];
  832. itemamount+=item_list[i*2];
  833. switch(pc_checkadditem(sd,item_list[i*2+1],item_list[i*2])) {
  834. case ADDITEM_EXIST:
  835. break;
  836. case ADDITEM_NEW:
  837. new_++;
  838. break;
  839. case ADDITEM_OVERAMOUNT:
  840. return 2;
  841. }
  842. w+=itemdb_weight(item_list[i*2+1]) * item_list[i*2];
  843. }
  844. if (z > (double)sd->status.zeny)
  845. return 1; // zeny不足
  846. if (w+sd->weight > sd->max_weight)
  847. return 2; // 重量超過
  848. if (pc_inventoryblank(sd)<new_)
  849. return 3; // 種類数超過
  850. pc_payzeny(sd,(int)z);
  851. for(i=0;i<n;i++) {
  852. struct item item_tmp;
  853. memset(&item_tmp,0,sizeof(item_tmp));
  854. item_tmp.nameid = item_list[i*2+1];
  855. item_tmp.identify = 1; // npc販売アイテムは鑑定済み
  856. pc_additem(sd,&item_tmp,item_list[i*2]);
  857. }
  858. //商人経験値
  859. /* if ((sd->status.class_ == 5) || (sd->status.class_ == 10) || (sd->status.class_ == 18)) {
  860. z = z * pc_checkskill(sd,MC_DISCOUNT) / ((1 + 300 / itemamount) * 4000) * battle_config.shop_exp;
  861. pc_gainexp(sd,0,z);
  862. }*/
  863. if (battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_DISCOUNT)) > 0) {
  864. if (sd->status.skill[MC_DISCOUNT].flag != 0)
  865. skill = sd->status.skill[MC_DISCOUNT].flag - 2;
  866. if (skill > 0) {
  867. z = (log(z * (double)skill) * (double)battle_config.shop_exp/100.);
  868. if (z < 1)
  869. z = 1;
  870. pc_gainexp(sd,0,(int)z);
  871. }
  872. }
  873. return 0;
  874. }
  875. /*==========================================
  876. *
  877. *------------------------------------------
  878. */
  879. int npc_selllist(struct map_session_data *sd,int n,unsigned short *item_list)
  880. {
  881. double z;
  882. int i,skill,itemamount=0;
  883. nullpo_retr(1, sd);
  884. nullpo_retr(1, item_list);
  885. if (npc_checknear(sd,sd->npc_shopid))
  886. return 1;
  887. for(i=0,z=0;i<n;i++) {
  888. int nameid;
  889. if (item_list[i*2]-2 <0 || item_list[i*2]-2 >=MAX_INVENTORY)
  890. return 1;
  891. nameid=sd->status.inventory[item_list[i*2]-2].nameid;
  892. if (nameid == 0 ||
  893. sd->status.inventory[item_list[i*2]-2].amount < item_list[i*2+1])
  894. return 1;
  895. if (itemdb_value_notoc(nameid))
  896. z+=(double)itemdb_value_sell(nameid) * item_list[i*2+1];
  897. else
  898. z+=(double)pc_modifysellvalue(sd,itemdb_value_sell(nameid)) * item_list[i*2+1];
  899. itemamount+=item_list[i*2+1];
  900. }
  901. if (z > MAX_ZENY) z = MAX_ZENY;
  902. pc_getzeny(sd,(int)z);
  903. for(i=0;i<n;i++) {
  904. int item_id=item_list[i*2]-2;
  905. if( sd->status.inventory[item_id].nameid>0 && sd->inventory_data[item_id] != NULL &&
  906. sd->inventory_data[item_id]->type==7 && sd->status.inventory[item_id].amount>0 &&
  907. sd->status.inventory[item_id].card[0] == (short)0xff00)
  908. if(search_petDB_index(sd->status.inventory[item_id].nameid, PET_EGG) >= 0)
  909. intif_delete_petdata((*(long *)(&sd->status.inventory[item_id].card[1])));
  910. pc_delitem(sd,item_id,item_list[i*2+1],0);
  911. }
  912. //商人経験値
  913. /* if ((sd->status.class_ == 5) || (sd->status.class_ == 10) || (sd->status.class_ == 18)) {
  914. z = z * pc_checkskill(sd,MC_OVERCHARGE) / ((1 + 500 / itemamount) * 4000) * battle_config.shop_exp ;
  915. pc_gainexp(sd,0,z);
  916. }*/
  917. if (battle_config.shop_exp > 0 && z > 0 && (skill = pc_checkskill(sd,MC_OVERCHARGE)) > 0) {
  918. if (sd->status.skill[MC_OVERCHARGE].flag != 0)
  919. skill = sd->status.skill[MC_OVERCHARGE].flag - 2;
  920. if (skill > 0) {
  921. z = (log(z * (double)skill) * (double)battle_config.shop_exp/100.);
  922. if (z < 1)
  923. z = 1;
  924. pc_gainexp(sd,0,(int)z);
  925. }
  926. }
  927. return 0;
  928. }
  929. // [Valaris] NPC Walking
  930. /*==========================================
  931. * Time calculation concerning one step next to npc
  932. *------------------------------------------
  933. */
  934. static int calc_next_walk_step(struct npc_data *nd)
  935. {
  936. nullpo_retr(0, nd);
  937. if(nd->walkpath.path_pos>=nd->walkpath.path_len)
  938. return -1;
  939. if(nd->walkpath.path[nd->walkpath.path_pos]&1)
  940. return status_get_speed(&nd->bl)*14/10;
  941. return status_get_speed(&nd->bl);
  942. }
  943. /*==========================================
  944. * npc Walk processing
  945. *------------------------------------------
  946. */
  947. static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
  948. {
  949. int moveblock;
  950. int i;
  951. static int dirx[8]={0,-1,-1,-1,0,1,1,1};
  952. static int diry[8]={1,1,0,-1,-1,-1,0,1};
  953. int x,y,dx,dy;
  954. nullpo_retr(0, nd);
  955. nd->state.state=MS_IDLE;
  956. if(nd->walkpath.path_pos>=nd->walkpath.path_len || nd->walkpath.path_pos!=data)
  957. return 0;
  958. nd->walkpath.path_half ^= 1;
  959. if(nd->walkpath.path_half==0){
  960. nd->walkpath.path_pos++;
  961. if(nd->state.change_walk_target){
  962. npc_walktoxy_sub(nd);
  963. return 0;
  964. }
  965. }
  966. else {
  967. if(nd->walkpath.path[nd->walkpath.path_pos]>=8)
  968. return 1;
  969. x = nd->bl.x;
  970. y = nd->bl.y;
  971. if(map_getcell(nd->bl.m,x,y,CELL_CHKNOPASS)) {
  972. npc_stop_walking(nd,1);
  973. return 0;
  974. }
  975. nd->dir=nd->walkpath.path[nd->walkpath.path_pos];
  976. dx = dirx[nd->dir];
  977. dy = diry[nd->dir];
  978. if(map_getcell(nd->bl.m,x+dx,y+dy,CELL_CHKNOPASS)) {
  979. npc_walktoxy_sub(nd);
  980. return 0;
  981. }
  982. moveblock = ( x/BLOCK_SIZE != (x+dx)/BLOCK_SIZE || y/BLOCK_SIZE != (y+dy)/BLOCK_SIZE);
  983. nd->state.state=MS_WALK;
  984. map_foreachinmovearea(clif_npcoutsight,nd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,dx,dy,BL_PC,nd);
  985. x += dx;
  986. y += dy;
  987. if(moveblock) map_delblock(&nd->bl);
  988. nd->bl.x = x;
  989. nd->bl.y = y;
  990. if(moveblock) map_addblock(&nd->bl);
  991. map_foreachinmovearea(clif_npcinsight,nd->bl.m,x-AREA_SIZE,y-AREA_SIZE,x+AREA_SIZE,y+AREA_SIZE,-dx,-dy,BL_PC,nd);
  992. nd->state.state=MS_IDLE;
  993. }
  994. if((i=calc_next_walk_step(nd))>0){
  995. i = i>>1;
  996. if(i < 1 && nd->walkpath.path_half == 0)
  997. i = 1;
  998. nd->walktimer=add_timer(tick+i,npc_walktimer,nd->bl.id,nd->walkpath.path_pos);
  999. nd->state.state=MS_WALK;
  1000. if(nd->walkpath.path_pos>=nd->walkpath.path_len)
  1001. clif_fixnpcpos(nd); // When npc stops, retransmission current of a position.
  1002. }
  1003. return 0;
  1004. }
  1005. int npc_changestate(struct npc_data *nd,int state,int type)
  1006. {
  1007. int i;
  1008. nullpo_retr(0, nd);
  1009. if(nd->walktimer != -1)
  1010. delete_timer(nd->walktimer,npc_walktimer);
  1011. nd->walktimer=-1;
  1012. nd->state.state=state;
  1013. switch(state){
  1014. case MS_WALK:
  1015. if((i=calc_next_walk_step(nd))>0){
  1016. i = i>>2;
  1017. nd->walktimer=add_timer(gettick()+i,npc_walktimer,nd->bl.id,0);
  1018. }
  1019. else
  1020. nd->state.state=MS_IDLE;
  1021. break;
  1022. case MS_DELAY:
  1023. nd->walktimer=add_timer(gettick()+type,npc_walktimer,nd->bl.id,0);
  1024. break;
  1025. }
  1026. return 0;
  1027. }
  1028. static int npc_walktimer(int tid,unsigned int tick,int id,int data)
  1029. {
  1030. struct npc_data *nd;
  1031. nd=(struct npc_data*)map_id2bl(id);
  1032. if(nd == NULL || nd->bl.type != BL_NPC)
  1033. return 1;
  1034. if(nd->walktimer != tid){
  1035. return 0;
  1036. }
  1037. nd->walktimer=-1;
  1038. if(nd->bl.prev == NULL)
  1039. return 1;
  1040. switch(nd->state.state){
  1041. case MS_WALK:
  1042. npc_walk(nd,tick,data);
  1043. break;
  1044. case MS_DELAY:
  1045. npc_changestate(nd,MS_IDLE,0);
  1046. break;
  1047. default:
  1048. break;
  1049. }
  1050. return 0;
  1051. }
  1052. static int npc_walktoxy_sub(struct npc_data *nd)
  1053. {
  1054. struct walkpath_data wpd;
  1055. nullpo_retr(0, nd);
  1056. if(path_search(&wpd,nd->bl.m,nd->bl.x,nd->bl.y,nd->to_x,nd->to_y,nd->state.walk_easy))
  1057. return 1;
  1058. memcpy(&nd->walkpath,&wpd,sizeof(wpd));
  1059. nd->state.change_walk_target=0;
  1060. npc_changestate(nd,MS_WALK,0);
  1061. clif_movenpc(nd);
  1062. return 0;
  1063. }
  1064. int npc_walktoxy(struct npc_data *nd,int x,int y,int easy)
  1065. {
  1066. struct walkpath_data wpd;
  1067. nullpo_retr(0, nd);
  1068. if(nd->state.state == MS_WALK && path_search(&wpd,nd->bl.m,nd->bl.x,nd->bl.y,x,y,0) )
  1069. return 1;
  1070. nd->state.walk_easy = easy;
  1071. nd->to_x=x;
  1072. nd->to_y=y;
  1073. if(nd->state.state == MS_WALK) {
  1074. nd->state.change_walk_target=1;
  1075. } else {
  1076. return npc_walktoxy_sub(nd);
  1077. }
  1078. return 0;
  1079. }
  1080. int npc_stop_walking(struct npc_data *nd,int type)
  1081. {
  1082. nullpo_retr(0, nd);
  1083. if(nd->state.state == MS_WALK || nd->state.state == MS_IDLE) {
  1084. int dx=0,dy=0;
  1085. nd->walkpath.path_len=0;
  1086. if(type&4){
  1087. dx=nd->to_x-nd->bl.x;
  1088. if(dx<0)
  1089. dx=-1;
  1090. else if(dx>0)
  1091. dx=1;
  1092. dy=nd->to_y-nd->bl.y;
  1093. if(dy<0)
  1094. dy=-1;
  1095. else if(dy>0)
  1096. dy=1;
  1097. }
  1098. nd->to_x=nd->bl.x+dx;
  1099. nd->to_y=nd->bl.y+dy;
  1100. if(dx!=0 || dy!=0){
  1101. npc_walktoxy_sub(nd);
  1102. return 0;
  1103. }
  1104. npc_changestate(nd,MS_IDLE,0);
  1105. }
  1106. if(type&0x01)
  1107. clif_fixnpcpos(nd);
  1108. if(type&0x02) {
  1109. int delay=status_get_dmotion(&nd->bl);
  1110. unsigned int tick = gettick();
  1111. if(nd->canmove_tick < tick)
  1112. nd->canmove_tick = tick + delay;
  1113. }
  1114. return 0;
  1115. }
  1116. //
  1117. // 初期化関係
  1118. //
  1119. /*==========================================
  1120. * 読み込むnpcファイルのクリア
  1121. *------------------------------------------
  1122. */
  1123. void npc_clearsrcfile()
  1124. {
  1125. struct npc_src_list *p=npc_src_first;
  1126. while( p ) {
  1127. struct npc_src_list *p2=p;
  1128. p=p->next;
  1129. aFree(p2);
  1130. }
  1131. npc_src_first=NULL;
  1132. npc_src_last=NULL;
  1133. }
  1134. /*==========================================
  1135. * 読み込むnpcファイルの追加
  1136. *------------------------------------------
  1137. */
  1138. void npc_addsrcfile(char *name)
  1139. {
  1140. struct npc_src_list *new_;
  1141. size_t len;
  1142. if ( strcmpi(name,"clear")==0 ) {
  1143. npc_clearsrcfile();
  1144. return;
  1145. }
  1146. {
  1147. // prevent multiple insert of source files
  1148. struct npc_src_list *p=npc_src_first;
  1149. while( p )
  1150. { // found the file, no need to insert it again
  1151. if( 0==strcmp(name,p->name) )
  1152. return;
  1153. p=p->next;
  1154. }
  1155. }
  1156. len = sizeof(*new_) + strlen(name);
  1157. new_=(struct npc_src_list *)aCalloc(1,len);
  1158. new_->next = NULL;
  1159. strncpy(new_->name,name,strlen(name)+1);
  1160. if (npc_src_first==NULL)
  1161. npc_src_first = new_;
  1162. if (npc_src_last)
  1163. npc_src_last->next = new_;
  1164. npc_src_last=new_;
  1165. }
  1166. /*==========================================
  1167. * 読み込むnpcファイルの削除
  1168. *------------------------------------------
  1169. */
  1170. void npc_delsrcfile(char *name)
  1171. {
  1172. struct npc_src_list *p=npc_src_first,*pp=NULL,**lp=&npc_src_first;
  1173. if ( strcmpi(name,"all")==0 ) {
  1174. npc_clearsrcfile();
  1175. return;
  1176. }
  1177. for( ; p; lp=&p->next,pp=p,p=p->next ) {
  1178. if ( strcmp(p->name,name)==0 ) {
  1179. *lp=p->next;
  1180. if ( npc_src_last==p )
  1181. npc_src_last=pp;
  1182. aFree(p);
  1183. break;
  1184. }
  1185. }
  1186. }
  1187. /*==========================================
  1188. * warp行解析
  1189. *------------------------------------------
  1190. */
  1191. int npc_parse_warp(char *w1,char *w2,char *w3,char *w4)
  1192. {
  1193. int x,y,xs,ys,to_x,to_y,m;
  1194. int i,j;
  1195. char mapname[24],to_mapname[24];
  1196. struct npc_data *nd;
  1197. // 引数の個数チェック
  1198. if (sscanf(w1,"%[^,],%d,%d",mapname,&x,&y) != 3 ||
  1199. sscanf(w4,"%d,%d,%[^,],%d,%d",&xs,&ys,to_mapname,&to_x,&to_y) != 5) {
  1200. printf("bad warp line : %s\n",w3);
  1201. return 1;
  1202. }
  1203. m=map_mapname2mapid(mapname);
  1204. nd=(struct npc_data *)aCalloc(1,sizeof(struct npc_data));
  1205. nd->bl.id=npc_get_new_npc_id();
  1206. nd->n=map_addnpc(m,nd);
  1207. nd->bl.prev = nd->bl.next = NULL;
  1208. nd->bl.m=m;
  1209. nd->bl.x=x;
  1210. nd->bl.y=y;
  1211. nd->dir=0;
  1212. nd->flag=0;
  1213. memcpy(nd->name,w3,24);
  1214. memcpy(nd->exname,w3,24);
  1215. nd->chat_id=0;
  1216. if (!battle_config.warp_point_debug)
  1217. nd->class_=WARP_CLASS;
  1218. else
  1219. nd->class_=WARP_DEBUG_CLASS;
  1220. nd->speed=200;
  1221. nd->option = 0;
  1222. nd->opt1 = 0;
  1223. nd->opt2 = 0;
  1224. nd->opt3 = 0;
  1225. memcpy(nd->u.warp.name,to_mapname,16);
  1226. xs+=2; ys+=2;
  1227. nd->u.warp.x=to_x;
  1228. nd->u.warp.y=to_y;
  1229. nd->u.warp.xs=xs;
  1230. nd->u.warp.ys=ys;
  1231. for(i=0;i<ys;i++) {
  1232. for(j=0;j<xs;j++) {
  1233. if(map_getcell(m,x-xs/2+j,y-ys/2+i,CELL_CHKNOPASS))
  1234. continue;
  1235. map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC);
  1236. }
  1237. }
  1238. // printf("warp npc %s %d read done\n",mapname,nd->bl.id);
  1239. npc_warp++;
  1240. nd->bl.type=BL_NPC;
  1241. nd->bl.subtype=WARP;
  1242. map_addblock(&nd->bl);
  1243. clif_spawnnpc(nd);
  1244. strdb_insert(npcname_db,nd->name,nd);
  1245. return 0;
  1246. }
  1247. /*==========================================
  1248. * shop行解析
  1249. *------------------------------------------
  1250. */
  1251. static int npc_parse_shop(char *w1,char *w2,char *w3,char *w4)
  1252. {
  1253. char *p;
  1254. int x, y, dir, m;
  1255. int max = 100, pos = 0;
  1256. char mapname[24];
  1257. struct npc_data *nd;
  1258. // 引数の個数チェック
  1259. if (sscanf(w1, "%[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 ||
  1260. strchr(w4, ',') == NULL) {
  1261. printf("bad shop line : %s\n", w3);
  1262. return 1;
  1263. }
  1264. m = map_mapname2mapid(mapname);
  1265. nd = (struct npc_data *)aCalloc(1,sizeof(struct npc_data) +
  1266. sizeof(nd->u.shop_item[0]) * (max + 1));
  1267. p = strchr(w4, ',');
  1268. while (p && pos < max) {
  1269. int nameid,value;
  1270. struct item_data *id;
  1271. p++;
  1272. if (sscanf(p, "%d:%d", &nameid, &value) != 2)
  1273. break;
  1274. nd->u.shop_item[pos].nameid = nameid;
  1275. id = itemdb_search(nameid);
  1276. if (value < 0)
  1277. value = id->value_buy;
  1278. nd->u.shop_item[pos].value = value;
  1279. // check for bad prices that can possibly cause exploits
  1280. if (value*75/100 < id->value_sell*124/100) {
  1281. sprintf (tmp_output, "Item %s [%d] buying:%d < selling:%d\n",
  1282. id->name, id->nameid, value*75/100, id->value_sell*124/100);
  1283. ShowWarning (tmp_output);
  1284. }
  1285. pos++;
  1286. p=strchr(p,',');
  1287. }
  1288. if (pos == 0) {
  1289. aFree(nd);
  1290. return 1;
  1291. }
  1292. nd->u.shop_item[pos++].nameid = 0;
  1293. nd->bl.prev = nd->bl.next = NULL;
  1294. nd->bl.m = m;
  1295. nd->bl.x = x;
  1296. nd->bl.y = y;
  1297. nd->bl.id = npc_get_new_npc_id();
  1298. nd->dir = dir;
  1299. nd->flag = 0;
  1300. memcpy(nd->name, w3, 24);
  1301. nd->class_ = atoi(w4);
  1302. nd->speed = 200;
  1303. nd->chat_id = 0;
  1304. nd->option = 0;
  1305. nd->opt1 = 0;
  1306. nd->opt2 = 0;
  1307. nd->opt3 = 0;
  1308. nd = (struct npc_data *)aRealloc(nd,
  1309. sizeof(struct npc_data) + sizeof(nd->u.shop_item[0]) * pos);
  1310. //printf("shop npc %s %d read done\n",mapname,nd->bl.id);
  1311. npc_shop++;
  1312. nd->bl.type=BL_NPC;
  1313. nd->bl.subtype=SHOP;
  1314. nd->n=map_addnpc(m,nd);
  1315. map_addblock(&nd->bl);
  1316. clif_spawnnpc(nd);
  1317. strdb_insert(npcname_db,nd->name,nd);
  1318. return 0;
  1319. }
  1320. /*==========================================
  1321. * NPCのラベルデータコンバート
  1322. *------------------------------------------
  1323. */
  1324. int npc_convertlabel_db(void *key,void *data,va_list ap)
  1325. {
  1326. char *lname=(char *)key;
  1327. int pos=(int)data;
  1328. struct npc_data *nd;
  1329. struct npc_label_list *lst;
  1330. int num;
  1331. char *p=strchr(lname,':');
  1332. nullpo_retr(0, ap);
  1333. nullpo_retr(0, nd=va_arg(ap,struct npc_data *));
  1334. lst=nd->u.scr.label_list;
  1335. num=nd->u.scr.label_list_num;
  1336. if(!lst){
  1337. lst=(struct npc_label_list *)aCallocA(1,sizeof(struct npc_label_list));
  1338. num=0;
  1339. }else
  1340. lst=(struct npc_label_list *)aRealloc(lst,sizeof(struct npc_label_list)*(num+1));
  1341. *p='\0';
  1342. strncpy(lst[num].name,lname,24);
  1343. *p=':';
  1344. lst[num].pos=pos;
  1345. nd->u.scr.label_list=lst;
  1346. nd->u.scr.label_list_num=num+1;
  1347. return 0;
  1348. }
  1349. /*==========================================
  1350. * script行解析
  1351. *------------------------------------------
  1352. */
  1353. static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines)
  1354. {
  1355. int x,y,dir=0,m,xs=0,ys=0,class_=0; // [Valaris] thanks to fov
  1356. char mapname[24];
  1357. unsigned char *srcbuf=NULL,*script;
  1358. int srcsize=65536;
  1359. int startline=0;
  1360. unsigned char line[1024];
  1361. int i;
  1362. struct npc_data *nd;
  1363. int evflag=0;
  1364. struct dbt *label_db;
  1365. char *p;
  1366. struct npc_label_list *label_dup=NULL;
  1367. int label_dupnum=0;
  1368. int src_id=0;
  1369. if(strcmp(w1,"-")==0){
  1370. x=0;y=0;m=-1;
  1371. }else{
  1372. // 引数の個数チェック
  1373. if (sscanf(w1,"%[^,],%d,%d,%d",mapname,&x,&y,&dir) != 4 ||
  1374. ( strcmp(w2,"script")==0 && strchr(w4,',')==NULL) ) {
  1375. printf("bad script line : %s\n",w3);
  1376. return 1;
  1377. }
  1378. m = map_mapname2mapid(mapname);
  1379. }
  1380. if(strcmp(w2,"script")==0){
  1381. // スクリプトの解析
  1382. srcbuf=(unsigned char *)aCallocA(srcsize,sizeof(char));
  1383. if (strchr(first_line,'{')) {
  1384. strcpy((char *) srcbuf,strchr(first_line,'{'));
  1385. startline=*lines;
  1386. } else
  1387. srcbuf[0]=0;
  1388. while(1) {
  1389. for(i=strlen((const char *) srcbuf)-1;i>=0 && isspace(srcbuf[i]);i--);
  1390. if (i>=0 && srcbuf[i]=='}')
  1391. break;
  1392. fgets((char *) line,1020,fp);
  1393. (*lines)++;
  1394. if (feof(fp))
  1395. break;
  1396. if (strlen((char *) srcbuf)+strlen((char *) line)+1>=srcsize) {
  1397. srcsize += 65536;
  1398. srcbuf = (unsigned char *)aRealloc(srcbuf, srcsize);
  1399. memset(srcbuf + srcsize - 65536, '\0', 65536);
  1400. }
  1401. if (srcbuf[0]!='{') {
  1402. if (strchr((char *) line,'{')) {
  1403. strcpy((char *) srcbuf,strchr((const char *) line,'{'));
  1404. startline=*lines;
  1405. }
  1406. } else
  1407. strcat((char *) srcbuf,(const char *) line);
  1408. }
  1409. script=(unsigned char *) parse_script((unsigned char *) srcbuf,startline);
  1410. if (script==NULL) {
  1411. // script parse error?
  1412. aFree(srcbuf);
  1413. return 1;
  1414. }
  1415. }else{
  1416. // duplicateする
  1417. char srcname[128];
  1418. struct npc_data *nd2;
  1419. if( sscanf(w2,"duplicate(%[^)])",srcname)!=1 ){
  1420. printf("bad duplicate name! : %s",w2);
  1421. return 0;
  1422. }
  1423. if( (nd2=npc_name2id(srcname))==NULL ){
  1424. printf("bad duplicate name! (not exist) : %s\n",srcname);
  1425. return 0;
  1426. }
  1427. script=(unsigned char *)nd2->u.scr.script;
  1428. label_dup=nd2->u.scr.label_list;
  1429. label_dupnum=nd2->u.scr.label_list_num;
  1430. src_id=nd2->bl.id;
  1431. }// end of スクリプト解析
  1432. nd=(struct npc_data *)aCalloc(1,sizeof(struct npc_data));
  1433. if(m==-1){
  1434. // スクリプトコピー用のダミーNPC
  1435. }else if( sscanf(w4,"%d,%d,%d",&class_,&xs,&ys)==3) {
  1436. // 接触型NPC
  1437. int i,j;
  1438. if (xs>=0)xs=xs*2+1;
  1439. if (ys>=0)ys=ys*2+1;
  1440. if (class_>=0) {
  1441. for(i=0;i<ys;i++) {
  1442. for(j=0;j<xs;j++) {
  1443. if(map_getcell(m,x-xs/2+j,y-ys/2+i,CELL_CHKNOPASS))
  1444. continue;
  1445. map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC);
  1446. }
  1447. }
  1448. }
  1449. nd->u.scr.xs=xs;
  1450. nd->u.scr.ys=ys;
  1451. } else { // クリック型NPC
  1452. class_=atoi(w4);
  1453. nd->u.scr.xs=0;
  1454. nd->u.scr.ys=0;
  1455. }
  1456. if (class_<0 && m>=0) { // イベント型NPC
  1457. evflag=1;
  1458. }
  1459. while((p=strchr(w3,':'))) {
  1460. if (p[1]==':') break;
  1461. }
  1462. if (p) {
  1463. *p=0;
  1464. memcpy(nd->name,w3,24);
  1465. memcpy(nd->exname,p+2,24);
  1466. }else{
  1467. memcpy(nd->name,w3,24);
  1468. memcpy(nd->exname,w3,24);
  1469. }
  1470. nd->bl.prev = nd->bl.next = NULL;
  1471. nd->bl.m = m;
  1472. nd->bl.x = x;
  1473. nd->bl.y = y;
  1474. nd->bl.id=npc_get_new_npc_id();
  1475. nd->dir = dir;
  1476. nd->flag=0;
  1477. nd->class_=class_;
  1478. nd->speed=200;
  1479. nd->u.scr.script=(char *) script;
  1480. nd->u.scr.src_id=src_id;
  1481. nd->chat_id=0;
  1482. nd->option = 0;
  1483. nd->opt1 = 0;
  1484. nd->opt2 = 0;
  1485. nd->opt3 = 0;
  1486. nd->walktimer=-1;
  1487. //printf("script npc %s %d %d read done\n",mapname,nd->bl.id,nd->class_);
  1488. npc_script++;
  1489. nd->bl.type=BL_NPC;
  1490. nd->bl.subtype=SCRIPT;
  1491. if(m>=0){
  1492. nd->n=map_addnpc(m,nd);
  1493. map_addblock(&nd->bl);
  1494. if (evflag) { // イベント型
  1495. struct event_data *ev=(struct event_data *)aCalloc(1,sizeof(struct event_data));
  1496. ev->nd=nd;
  1497. ev->pos=0;
  1498. strdb_insert(ev_db,nd->exname,ev);
  1499. }else
  1500. clif_spawnnpc(nd);
  1501. }
  1502. strdb_insert(npcname_db,nd->exname,nd);
  1503. //-----------------------------------------
  1504. // ラベルデータの準備
  1505. if(srcbuf){
  1506. // script本体がある場合の処理
  1507. // ラベルデータのコンバート
  1508. label_db=script_get_label_db();
  1509. strdb_foreach(label_db,npc_convertlabel_db,nd);
  1510. // もう使わないのでバッファ解放
  1511. aFree(srcbuf);
  1512. }else{
  1513. // duplicate
  1514. // nd->u.scr.label_list=aMallocA(sizeof(struct npc_label_list)*label_dupnum);
  1515. // memcpy(nd->u.scr.label_list,label_dup,sizeof(struct npc_label_list)*label_dupnum);
  1516. nd->u.scr.label_list=label_dup; // ラベルデータ共有
  1517. nd->u.scr.label_list_num=label_dupnum;
  1518. }
  1519. //-----------------------------------------
  1520. // イベント用ラベルデータのエクスポート
  1521. for(i=0;i<nd->u.scr.label_list_num;i++){
  1522. char *lname=nd->u.scr.label_list[i].name;
  1523. int pos=nd->u.scr.label_list[i].pos;
  1524. if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) {
  1525. struct event_data *ev;
  1526. char *buf;
  1527. // エクスポートされる
  1528. ev=(struct event_data *)aCalloc(1,sizeof(struct event_data));
  1529. buf=(char *)aCallocA(50,sizeof(char));
  1530. if (strlen(lname)>24) {
  1531. printf("npc_parse_script: label name error !\n");
  1532. exit(1);
  1533. }else{
  1534. ev->nd=nd;
  1535. ev->pos=pos;
  1536. sprintf(buf,"%s::%s",nd->exname,lname);
  1537. strdb_insert(ev_db,buf,ev);
  1538. }
  1539. }
  1540. }
  1541. //-----------------------------------------
  1542. // ラベルデータからタイマーイベント取り込み
  1543. for(i=0;i<nd->u.scr.label_list_num;i++){
  1544. int t=0,k=0;
  1545. char *lname=nd->u.scr.label_list[i].name;
  1546. int pos=nd->u.scr.label_list[i].pos;
  1547. if(sscanf(lname,"OnTimer%d%n",&t,&k)==1 && lname[k]=='\0') {
  1548. // タイマーイベント
  1549. struct npc_timerevent_list *te=nd->u.scr.timer_event;
  1550. int j,k=nd->u.scr.timeramount;
  1551. if(te==NULL)
  1552. te=(struct npc_timerevent_list *)aCallocA(1,sizeof(struct npc_timerevent_list));
  1553. else
  1554. te=(struct npc_timerevent_list *)aRealloc( te, sizeof(struct npc_timerevent_list) * (k+1) );
  1555. for(j=0;j<k;j++){
  1556. if(te[j].timer>t){
  1557. memmove(te+j+1,te+j,sizeof(struct npc_timerevent_list)*(k-j));
  1558. break;
  1559. }
  1560. }
  1561. te[j].timer=t;
  1562. te[j].pos=pos;
  1563. nd->u.scr.timer_event=te;
  1564. nd->u.scr.timeramount=k+1;
  1565. }
  1566. }
  1567. nd->u.scr.nexttimer=-1;
  1568. nd->u.scr.timerid=-1;
  1569. return 0;
  1570. }
  1571. /*==========================================
  1572. * function行解析
  1573. *------------------------------------------
  1574. */
  1575. static int npc_parse_function(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines)
  1576. {
  1577. char *srcbuf=NULL,*script;
  1578. int srcsize=65536;
  1579. int startline=0;
  1580. char line[1024];
  1581. int i;
  1582. // struct dbt *label_db;
  1583. char *p;
  1584. // スクリプトの解析
  1585. srcbuf=(char *)aCallocA(srcsize,sizeof(char));
  1586. if (strchr(first_line,'{')) {
  1587. strcpy(srcbuf,strchr(first_line,'{'));
  1588. startline=*lines;
  1589. } else
  1590. srcbuf[0]=0;
  1591. while(1) {
  1592. for(i=strlen(srcbuf)-1;i>=0 && isspace(srcbuf[i]);i--);
  1593. if (i>=0 && srcbuf[i]=='}')
  1594. break;
  1595. fgets(line,1020,fp);
  1596. (*lines)++;
  1597. if (feof(fp))
  1598. break;
  1599. if (strlen(srcbuf)+strlen(line)+1>=srcsize) {
  1600. srcsize += 65536;
  1601. srcbuf = (char *)aRealloc(srcbuf, srcsize);
  1602. memset(srcbuf + srcsize - 65536, '\0', 65536);
  1603. }
  1604. if (srcbuf[0]!='{') {
  1605. if (strchr(line,'{')) {
  1606. strcpy(srcbuf,strchr(line,'{'));
  1607. startline=*lines;
  1608. }
  1609. } else
  1610. strcat(srcbuf,line);
  1611. }
  1612. script= parse_script((unsigned char *) srcbuf,startline);
  1613. if (script==NULL) {
  1614. // script parse error?
  1615. aFree(srcbuf);
  1616. return 1;
  1617. }
  1618. p=(char *)aCallocA(50,sizeof(char));
  1619. strncpy(p,w3,50);
  1620. strdb_insert(script_get_userfunc_db(),p,script);
  1621. // label_db=script_get_label_db();
  1622. // もう使わないのでバッファ解放
  1623. aFree(srcbuf);
  1624. // printf("function %s => %p\n",p,script);
  1625. return 0;
  1626. }
  1627. /*==========================================
  1628. * mob行解析
  1629. *------------------------------------------
  1630. */
  1631. int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
  1632. {
  1633. int m,x,y,xs,ys,class_,num,delay1,delay2,level;
  1634. int i;
  1635. char mapname[24];
  1636. char mobname[24];
  1637. char eventname[24]="";
  1638. struct mob_data *md;
  1639. xs=ys=0;
  1640. delay1=delay2=0;
  1641. // 引数の個数チェック
  1642. if (sscanf(w1,"%[^,],%d,%d,%d,%d",mapname,&x,&y,&xs,&ys) < 3 ||
  1643. sscanf(w4,"%d,%d,%d,%d,%s",&class_,&num,&delay1,&delay2,eventname) < 2 ) {
  1644. printf("bad monster line : %s\n",w3);
  1645. return 1;
  1646. }
  1647. m=map_mapname2mapid(mapname);
  1648. if ( num>1 && battle_config.mob_count_rate!=100) {
  1649. if ( (num=num*battle_config.mob_count_rate/100)<1 )
  1650. num=1;
  1651. }
  1652. for(i=0;i<num;i++) {
  1653. md=(struct mob_data *)aCalloc(1,sizeof(struct mob_data));
  1654. if(class_>4000) { // large/tiny mobs [Valaris]
  1655. md->size=2;
  1656. class_-=4000;
  1657. }
  1658. else if(class_>2000) {
  1659. md->size=1;
  1660. class_-=2000;
  1661. }
  1662. md->bl.prev=NULL;
  1663. md->bl.next=NULL;
  1664. md->bl.m=m;
  1665. md->bl.x=x;
  1666. md->bl.y=y;
  1667. if(sscanf(w3,"%[^,],%d",mobname,&level) > 1) {
  1668. if(strcmp(mobname,"--en--")==0)
  1669. memcpy(md->name,mob_db[class_].name,24);
  1670. else if(strcmp(mobname,"--ja--")==0)
  1671. memcpy(md->name,mob_db[class_].jname,24);
  1672. md->level=level;
  1673. }
  1674. else
  1675. memcpy(md->name,w3,24);
  1676. md->n = i;
  1677. md->base_class = md->class_ = class_;
  1678. md->bl.id=npc_get_new_npc_id();
  1679. md->m =m;
  1680. md->x0=x;
  1681. md->y0=y;
  1682. md->xs=xs;
  1683. md->ys=ys;
  1684. md->spawndelay1=delay1;
  1685. md->spawndelay2=delay2;
  1686. memset(&md->state,0,sizeof(md->state));
  1687. md->timer = -1;
  1688. md->target_id=0;
  1689. md->attacked_id=0;
  1690. md->speed=mob_db[class_].speed;
  1691. if (mob_db[class_].mode&0x02)
  1692. md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
  1693. else
  1694. md->lootitem=NULL;
  1695. if (strlen(eventname)>=4) {
  1696. memcpy(md->npc_event,eventname,24);
  1697. }else
  1698. memset(md->npc_event,0,24);
  1699. md->bl.type=BL_MOB;
  1700. map_addiddb(&md->bl);
  1701. mob_spawn(md->bl.id);
  1702. npc_mob++;
  1703. }
  1704. //printf("warp npc %s %d read done\n",mapname,nd->bl.id);
  1705. return 0;
  1706. }
  1707. /*==========================================
  1708. * マップフラグ行の解析
  1709. *------------------------------------------
  1710. */
  1711. static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4)
  1712. {
  1713. int m;
  1714. char mapname[24],savemap[16];
  1715. int savex,savey;
  1716. char drop_arg1[16],drop_arg2[16];
  1717. int drop_id=0,drop_type=0,drop_per=0;
  1718. // 引数の個数チェック
  1719. // if ( sscanf(w1,"%[^,],%d,%d,%d",mapname,&x,&y,&dir) != 4 )
  1720. if ( sscanf(w1,"%[^,]",mapname) != 1 )
  1721. return 1;
  1722. m=map_mapname2mapid(mapname);
  1723. if (m<0)
  1724. return 1;
  1725. //マップフラグ
  1726. if ( strcmpi(w3,"nosave")==0) {
  1727. if (strcmp(w4,"SavePoint")==0) {
  1728. memcpy(map[m].save.map,"SavePoint",10);
  1729. map[m].save.x=-1;
  1730. map[m].save.y=-1;
  1731. }else if (sscanf(w4,"%[^,],%d,%d",savemap,&savex,&savey)==3) {
  1732. memcpy(map[m].save.map,savemap,16);
  1733. map[m].save.x=savex;
  1734. map[m].save.y=savey;
  1735. }
  1736. map[m].flag.nosave=1;
  1737. }
  1738. else if (strcmpi(w3,"nomemo")==0) {
  1739. map[m].flag.nomemo=1;
  1740. }
  1741. else if (strcmpi(w3,"noteleport")==0) {
  1742. map[m].flag.noteleport=1;
  1743. }
  1744. else if (strcmpi(w3,"nowarp")==0) {
  1745. map[m].flag.nowarp=1;
  1746. }
  1747. else if (strcmpi(w3,"nowarpto")==0) {
  1748. map[m].flag.nowarpto=1;
  1749. }
  1750. else if (strcmpi(w3,"noreturn")==0) {
  1751. map[m].flag.noreturn=1;
  1752. }
  1753. else if (strcmpi(w3,"monster_noteleport")==0) {
  1754. map[m].flag.monster_noteleport=1;
  1755. }
  1756. else if (strcmpi(w3,"nobranch")==0) {
  1757. map[m].flag.nobranch=1;
  1758. }
  1759. else if (strcmpi(w3,"nopenalty")==0) {
  1760. map[m].flag.nopenalty=1;
  1761. }
  1762. else if (strcmpi(w3,"pvp")==0) {
  1763. map[m].flag.pvp=1;
  1764. }
  1765. else if (strcmpi(w3,"pvp_noparty")==0) {
  1766. map[m].flag.pvp_noparty=1;
  1767. }
  1768. else if (strcmpi(w3,"pvp_noguild")==0) {
  1769. map[m].flag.pvp_noguild=1;
  1770. }
  1771. else if (strcmpi(w3,"pvp_nightmaredrop")==0) {
  1772. if (sscanf(w4,"%[^,],%[^,],%d",drop_arg1,drop_arg2,&drop_per)==3) { int i;
  1773. if(strcmp(drop_arg1,"random")==0)
  1774. drop_id = -1;
  1775. else if(itemdb_exists( (drop_id=atoi(drop_arg1)) )==NULL)
  1776. drop_id = 0;
  1777. if(strcmp(drop_arg2,"inventory")==0)
  1778. drop_type = 1;
  1779. else if(strcmp(drop_arg2,"equip")==0)
  1780. drop_type = 2;
  1781. else if(strcmp(drop_arg2,"all")==0)
  1782. drop_type = 3;
  1783. if(drop_id != 0){
  1784. for (i=0;i<MAX_DROP_PER_MAP;i++){
  1785. if(map[m].drop_list[i].drop_id==0){
  1786. map[m].drop_list[i].drop_id = drop_id;
  1787. map[m].drop_list[i].drop_type = drop_type;
  1788. map[m].drop_list[i].drop_per = drop_per;
  1789. break;
  1790. }
  1791. }
  1792. map[m].flag.pvp_nightmaredrop=1;
  1793. }
  1794. }
  1795. }
  1796. else if (strcmpi(w3,"pvp_nocalcrank")==0) {
  1797. map[m].flag.pvp_nocalcrank=1;
  1798. }
  1799. else if (strcmpi(w3,"gvg")==0) {
  1800. map[m].flag.gvg=1;
  1801. }
  1802. else if (strcmpi(w3,"gvg_noparty")==0) {
  1803. map[m].flag.gvg_noparty=1;
  1804. }
  1805. else if (strcmpi(w3,"nozenypenalty")==0) {
  1806. map[m].flag.nozenypenalty=1;
  1807. }
  1808. else if (strcmpi(w3,"notrade")==0) {
  1809. map[m].flag.notrade=1;
  1810. }
  1811. else if (strcmpi(w3,"noskill")==0) {
  1812. map[m].flag.noskill=1;
  1813. }
  1814. else if (battle_config.pk_mode && strcmpi(w3,"nopvp")==0) { // nopvp for pk mode [Valaris]
  1815. map[m].flag.nopvp=1;
  1816. map[m].flag.pvp=0;
  1817. }
  1818. else if (strcmpi(w3,"noicewall")==0) { // noicewall [Valaris]
  1819. map[m].flag.noicewall=1;
  1820. }
  1821. else if (strcmpi(w3,"snow")==0) { // snow [Valaris]
  1822. map[m].flag.snow=1;
  1823. }
  1824. else if (strcmpi(w3,"fog")==0) { // fog [Valaris]
  1825. map[m].flag.fog=1;
  1826. }
  1827. else if (strcmpi(w3,"sakura")==0) { // sakura [Valaris]
  1828. map[m].flag.sakura=1;
  1829. }
  1830. else if (strcmpi(w3,"leaves")==0) { // leaves [Valaris]
  1831. map[m].flag.leaves=1;
  1832. }
  1833. else if (strcmpi(w3,"rain")==0) { // rain [Valaris]
  1834. map[m].flag.rain=1;
  1835. }
  1836. else if (strcmpi(w3,"indoors")==0) { // celest
  1837. map[m].flag.indoors=1;
  1838. }
  1839. else if (strcmpi(w3,"nogo")==0) { // celest
  1840. map[m].flag.nogo=1;
  1841. }
  1842. return 0;
  1843. }
  1844. static int npc_read_indoors(void)
  1845. {
  1846. char *buf,*p;
  1847. int s, m;
  1848. buf=(char *) grfio_reads("data\\indoorrswtable.txt",&s);
  1849. if(buf==NULL)
  1850. return -1;
  1851. buf[s]=0;
  1852. for(p=buf;p-buf<s;){
  1853. char buf2[64];
  1854. if(sscanf(p,"%[^#]#",buf2) == 1){
  1855. char map_name[64] = "";
  1856. strncpy(map_name, buf2, strlen(buf2) - 4);
  1857. strcat(map_name, ".gat");
  1858. if ((m = map_mapname2mapid(map_name)) >= 0)
  1859. map[m].flag.indoors=1;
  1860. }
  1861. p=strchr(p,10);
  1862. if(!p) break;
  1863. p++;
  1864. }
  1865. aFree(buf);
  1866. sprintf(tmp_output,"Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\indoorrswtable.txt");
  1867. ShowStatus(tmp_output);
  1868. return 0;
  1869. }
  1870. static int ev_db_final(void *key,void *data,va_list ap)
  1871. {
  1872. aFree(data);
  1873. if(strstr((const char *) key,"::")!=NULL)
  1874. aFree(key);
  1875. return 0;
  1876. }
  1877. static int npcname_db_final(void *key,void *data,va_list ap)
  1878. {
  1879. return 0;
  1880. }
  1881. /*==========================================
  1882. * 終了
  1883. *------------------------------------------
  1884. */
  1885. int do_final_npc(void)
  1886. {
  1887. int i;
  1888. struct block_list *bl;
  1889. struct npc_data *nd;
  1890. struct mob_data *md;
  1891. struct chat_data *cd;
  1892. struct pet_data *pd;
  1893. if(ev_db)
  1894. strdb_final(ev_db,ev_db_final);
  1895. if(npcname_db)
  1896. strdb_final(npcname_db,npcname_db_final);
  1897. for(i=START_NPC_NUM;i<npc_id;i++){
  1898. if((bl=map_id2bl(i))){
  1899. if(bl->type == BL_NPC && (nd = (struct npc_data *)bl)){
  1900. if(nd->chat_id && (cd=(struct chat_data*)map_id2bl(nd->chat_id))){
  1901. aFree(cd);
  1902. cd = NULL;
  1903. }
  1904. if(nd->bl.subtype == SCRIPT){
  1905. if(nd->u.scr.timer_event)
  1906. aFree(nd->u.scr.timer_event);
  1907. if(nd->u.scr.src_id==0){
  1908. if(nd->u.scr.script){
  1909. aFree(nd->u.scr.script);
  1910. nd->u.scr.script=NULL;
  1911. }
  1912. if(nd->u.scr.label_list){
  1913. aFree(nd->u.scr.label_list);
  1914. nd->u.scr.label_list = NULL;
  1915. }
  1916. }
  1917. }
  1918. aFree(nd);
  1919. nd = NULL;
  1920. }else if(bl->type == BL_MOB && (md = (struct mob_data *)bl)){
  1921. if(md->lootitem){
  1922. aFree(md->lootitem);
  1923. md->lootitem = NULL;
  1924. }
  1925. aFree(md);
  1926. md = NULL;
  1927. }else if(bl->type == BL_PET && (pd = (struct pet_data *)bl)){
  1928. aFree(pd);
  1929. pd = NULL;
  1930. }
  1931. }
  1932. }
  1933. return 0;
  1934. }
  1935. void ev_release(struct dbn *db, int which)
  1936. {
  1937. if (which & 0x1)
  1938. aFree(db->key);
  1939. if (which & 0x2)
  1940. aFree(db->data);
  1941. }
  1942. /*==========================================
  1943. * npc初期化
  1944. *------------------------------------------
  1945. */
  1946. int do_init_npc(void)
  1947. {
  1948. struct npc_src_list *nsl;
  1949. FILE *fp;
  1950. char line[1024];
  1951. int m,lines;
  1952. time_t last_time = time(0);
  1953. int busy = 0;
  1954. char c = '-';
  1955. // indoorrswtable.txt and etcinfo.txt [Celest]
  1956. npc_read_indoors();
  1957. //npc_read_weather();
  1958. ev_db=strdb_init(24);
  1959. npcname_db=strdb_init(24);
  1960. ev_db->release = ev_release;
  1961. memset(&ev_tm_b,-1,sizeof(ev_tm_b));
  1962. for(nsl=npc_src_first;nsl;nsl=nsl->next) {
  1963. /*if(nsl->prev){ // [Shinomori]
  1964. aFree(nsl->prev);
  1965. nsl->prev = NULL;
  1966. }*/
  1967. fp=fopen(nsl->name,"r");
  1968. if (fp==NULL) {
  1969. printf("file not found : %s\n",nsl->name);
  1970. exit(1);
  1971. }
  1972. lines=0;
  1973. while(fgets(line,1020,fp)) {
  1974. char w1[1024],w2[1024],w3[1024],w4[1024],mapname[1024];
  1975. int i,j,w4pos,count;
  1976. lines++;
  1977. if (line[0] == '/' && line[1] == '/')
  1978. continue;
  1979. // 不要なスペースやタブの連続は詰める
  1980. for(i=j=0;line[i];i++) {
  1981. if (line[i]==' ') {
  1982. if (!((line[i+1] && (isspace(line[i+1]) || line[i+1]==',')) ||
  1983. (j && line[j-1]==',')))
  1984. line[j++]=' ';
  1985. } else if (line[i]=='\t') {
  1986. if (!(j && line[j-1]=='\t'))
  1987. line[j++]='\t';
  1988. } else
  1989. line[j++]=line[i];
  1990. }
  1991. // 最初はタブ区切りでチェックしてみて、ダメならスペース区切りで確認
  1992. if ((count=sscanf(line,"%[^\t]\t%[^\t]\t%[^\t\r\n]\t%n%[^\t\r\n]",w1,w2,w3,&w4pos,w4)) < 3 &&
  1993. (count=sscanf(line,"%s%s%s%n%s",w1,w2,w3,&w4pos,w4)) < 3) {
  1994. continue;
  1995. }
  1996. // マップの存在確認
  1997. if( strcmp(w1,"-")!=0 && strcmpi(w1,"function")!=0 ){
  1998. sscanf(w1,"%[^,]",mapname);
  1999. m = map_mapname2mapid(mapname);
  2000. if (strlen(mapname)>16 || m<0) {
  2001. // "mapname" is not assigned to this server
  2002. continue;
  2003. }
  2004. }
  2005. if (strcmpi(w2,"warp")==0 && count > 3) {
  2006. npc_parse_warp(w1,w2,w3,w4);
  2007. } else if (strcmpi(w2,"shop")==0 && count > 3) {
  2008. npc_parse_shop(w1,w2,w3,w4);
  2009. } else if (strcmpi(w2,"script")==0 && count > 3) {
  2010. if( strcmpi(w1,"function")==0 ){
  2011. npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines);
  2012. }else{
  2013. npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
  2014. }
  2015. } else if ( (i=0,sscanf(w2,"duplicate%n",&i), (i>0 && w2[i]=='(')) && count > 3) {
  2016. npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
  2017. } else if (strcmpi(w2,"monster")==0 && count > 3) {
  2018. npc_parse_mob(w1,w2,w3,w4);
  2019. } else if (strcmpi(w2,"mapflag")==0 && count >= 3) {
  2020. npc_parse_mapflag(w1,w2,w3,w4);
  2021. }
  2022. }
  2023. fclose(fp);
  2024. printf("\r");
  2025. ShowStatus("Loading NPCs... Working: ");
  2026. if (last_time != time(0)) {
  2027. last_time = time(0);
  2028. switch(busy) {
  2029. case 0: c='\\'; busy++; break;
  2030. case 1: c='|'; busy++; break;
  2031. case 2: c='/'; busy++; break;
  2032. case 3: c='-'; busy=0;
  2033. }
  2034. }
  2035. printf("[%c]",c);
  2036. fflush(stdout);
  2037. // printf("\rLoading NPCs [%d]: %-54s",npc_id-START_NPC_NUM,nsl->name);
  2038. // fflush(stdout);
  2039. }
  2040. printf("\r");
  2041. sprintf(tmp_output,"Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'"
  2042. CL_WHITE"%d"CL_RESET"' Warps\n\t-'"
  2043. CL_WHITE"%d"CL_RESET"' Shops\n\t-'"
  2044. CL_WHITE"%d"CL_RESET"' Scripts\n\t-'"
  2045. CL_WHITE"%d"CL_RESET"' Mobs\n",
  2046. npc_id-START_NPC_NUM,"",npc_warp,npc_shop,npc_script,npc_mob);
  2047. ShowInfo(tmp_output);
  2048. add_timer_func_list(npc_walktimer,"npc_walktimer"); // [Valaris]
  2049. add_timer_func_list(npc_event_timer,"npc_event_timer");
  2050. add_timer_func_list(npc_event_do_clock,"npc_event_do_clock");
  2051. add_timer_func_list(npc_timerevent,"npc_timerevent");
  2052. //exit(1);
  2053. return 0;
  2054. }