npc.c 53 KB

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