PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/map/mob.c

https://gitlab.com/evol/evol-server-code-old
C | 5316 lines | 4209 code | 620 blank | 487 comment | 1598 complexity | fe609cbf4779ab22df05854d298ea26e MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. // $Id: mob.c,v 1.7 2004/09/25 05:32:18 MouseJstr Exp $
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include "timer.h"
  8. #include "socket.h"
  9. #include "db.h"
  10. #include "nullpo.h"
  11. #include "malloc.h"
  12. #include "map.h"
  13. #include "clif.h"
  14. #include "intif.h"
  15. #include "pc.h"
  16. #include "mob.h"
  17. #include "guild.h"
  18. #include "itemdb.h"
  19. #include "skill.h"
  20. #include "battle.h"
  21. #include "party.h"
  22. #include "npc.h"
  23. #include "tmw.h"
  24. #ifdef MEMWATCH
  25. #include "memwatch.h"
  26. #endif
  27. #ifndef max
  28. #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
  29. #endif
  30. #define MIN_MOBTHINKTIME 100
  31. #define MOB_LAZYMOVEPERC 50 // Move probability in the negligent mode MOB (rate of 1000 minute)
  32. #define MOB_LAZYWARPPERC 20 // Warp probability in the negligent mode MOB (rate of 1000 minute)
  33. struct mob_db mob_db[2001];
  34. /*==========================================
  35. * Local prototype declaration (only required thing)
  36. *------------------------------------------
  37. */
  38. static int distance (int, int, int, int);
  39. static int mob_makedummymobdb (int);
  40. static int mob_timer (int, unsigned int, int, int);
  41. //int mobskill_use (struct mob_data *md, unsigned int tick, int event);
  42. int mobskill_deltimer (struct mob_data *md);
  43. int mob_skillid2skillidx (int class, int skillid);
  44. int mobskill_use_id (struct mob_data *md, struct block_list *target,
  45. int skill_idx);
  46. static int mob_unlocktarget (struct mob_data *md, int tick);
  47. /*==========================================
  48. * Mob is searched with a name.
  49. *------------------------------------------
  50. */
  51. int mobdb_searchname (const char *str)
  52. {
  53. if (!str)
  54. return 0;
  55. int i;
  56. for (i = 0; i < sizeof (mob_db) / sizeof (mob_db[0]); i++)
  57. {
  58. if (strcmpi (mob_db[i].name, str) == 0
  59. || strcmp (mob_db[i].jname, str) == 0
  60. || memcmp (mob_db[i].name, str, 24) == 0
  61. || memcmp (mob_db[i].jname, str, 24) == 0)
  62. return i;
  63. }
  64. return 0;
  65. }
  66. /*==========================================
  67. * Id Mob is checked.
  68. *------------------------------------------
  69. */
  70. int mobdb_checkid (const int id)
  71. {
  72. if (id <= 0 || id >= (sizeof (mob_db) / sizeof (mob_db[0]))
  73. || mob_db[id].name[0] == '\0')
  74. return 0;
  75. return id;
  76. }
  77. static void mob_init (struct mob_data *md);
  78. /*==========================================
  79. * The minimum data set for MOB spawning
  80. *------------------------------------------
  81. */
  82. int mob_spawn_dataset (struct mob_data *md, const char *mobname, int class)
  83. {
  84. nullpo_retr (0, md);
  85. nullpo_retr (0, mobname);
  86. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  87. return 0;
  88. if (strcmp (mobname, "--en--") == 0)
  89. memcpy (md->name, mob_db[class].name, 24);
  90. else if (strcmp (mobname, "--ja--") == 0)
  91. memcpy (md->name, mob_db[class].jname, 24);
  92. else
  93. memcpy (md->name, mobname, 24);
  94. md->bl.prev = NULL;
  95. md->bl.next = NULL;
  96. md->n = 0;
  97. md->base_class = md->class = class;
  98. md->bl.id = npc_get_new_npc_id ();
  99. memset (&md->state, 0, sizeof (md->state));
  100. md->timer = -1;
  101. md->target_id = 0;
  102. md->attacked_id = 0;
  103. mob_init (md);
  104. return 0;
  105. }
  106. // Mutation values indicate how `valuable' a change to each stat is, XP wise.
  107. // For one 256th of change, we give out that many 1024th fractions of XP change
  108. // (i.e., 1024 means a 100% XP increase for a single point of adjustment, 4 means 100% XP bonus for doubling the value)
  109. static int mutation_value[MOB_XP_BONUS] = {
  110. 2, // MOB_LV
  111. 3, // MOB_MAX_HP
  112. 1, // MOB_STR
  113. 2, // MOB_AGI
  114. 1, // MOB_VIT
  115. 0, // MOB_INT
  116. 2, // MOB_DEX
  117. 2, // MOB_LUK
  118. 1, // MOB_ATK1
  119. 1, // MOB_ATK2
  120. 2, // MOB_ADELAY
  121. 2, // MOB_DEF
  122. 2, // MOB_MDEF
  123. 2, // MOB_SPEED
  124. };
  125. // The mutation scale indicates how far `up' we can go, with 256 indicating 100% Note that this may stack with multiple
  126. // calls to `mutate'.
  127. static int mutation_scale[MOB_XP_BONUS] = {
  128. 16, // MOB_LV
  129. 256, // MOB_MAX_HP
  130. 32, // MOB_STR
  131. 48, // MOB_AGI
  132. 48, // MOB_VIT
  133. 48, // MOB_INT
  134. 48, // MOB_DEX
  135. 64, // MOB_LUK
  136. 48, // MOB_ATK1
  137. 48, // MOB_ATK2
  138. 80, // MOB_ADELAY
  139. 48, // MOB_DEF
  140. 48, // MOB_MDEF
  141. 80, // MOB_SPEED
  142. };
  143. // The table below indicates the `average' value for each of the statistics, or -1 if there is none.
  144. // This average is used to determine XP modifications for mutations. The experience point bonus is
  145. // based on mutation_value and mutation_base as follows:
  146. // (1) first, compute the percentage change of the attribute (p0)
  147. // (2) second, determine the absolute stat change
  148. // (3) third, compute the percentage stat change relative to mutation_base (p1)
  149. // (4) fourth, compute the XP mofication based on the smaller of (p0, p1).
  150. static int mutation_base[MOB_XP_BONUS] = {
  151. 30, // MOB_LV
  152. -1, // MOB_MAX_HP
  153. 20, // MOB_STR
  154. 20, // MOB_AGI
  155. 20, // MOB_VIT
  156. 20, // MOB_INT
  157. 20, // MOB_DEX
  158. 20, // MOB_LUK
  159. -1, // MOB_ATK1
  160. -1, // MOB_ATK2
  161. -1, // MOB_ADELAY
  162. -1, // MOB_DEF
  163. 20, // MOB_MDEF
  164. -1, // MOB_SPEED
  165. };
  166. /*========================================
  167. * Mutates a MOB. For large `direction' values, calling this multiple times will give bigger XP boni.
  168. *----------------------------------------
  169. */
  170. static void mob_mutate (struct mob_data *md, int stat, int intensity) // intensity: positive: strengthen, negative: weaken. 256 = 100%.
  171. {
  172. if (!md || stat < 0 || stat >= MOB_XP_BONUS || intensity == 0)
  173. return;
  174. int old_stat;
  175. int new_stat;
  176. int real_intensity; // relative intensity
  177. const int mut_base = mutation_base[stat];
  178. int sign = 1;
  179. while (intensity > mutation_scale[stat])
  180. {
  181. mob_mutate (md, stat, mutation_scale[stat]); // give better XP assignments
  182. intensity -= mutation_scale[stat];
  183. }
  184. while (intensity < -mutation_scale[stat])
  185. {
  186. mob_mutate (md, stat, mutation_scale[stat]); // give better XP assignments
  187. intensity += mutation_scale[stat];
  188. }
  189. if (!intensity)
  190. return;
  191. // MOB_ADELAY and MOB_SPEED are special because going DOWN is good here.
  192. if (stat == MOB_ADELAY || stat == MOB_SPEED)
  193. sign = -1;
  194. // Now compute the new stat
  195. old_stat = md->stats[stat];
  196. new_stat = old_stat + ((old_stat * sign * intensity) / 256);
  197. if (new_stat < 0)
  198. new_stat = 0;
  199. if (old_stat == 0)
  200. real_intensity = 0;
  201. else
  202. real_intensity = (((new_stat - old_stat) << 8) / old_stat);
  203. if (mut_base != -1)
  204. {
  205. // Now compute the mutation intensity relative to an absolute value.
  206. // Take the lesser of the two effects.
  207. int real_intensity2 = (((new_stat - old_stat) << 8) / mut_base);
  208. if (real_intensity < 0)
  209. if (real_intensity2 > real_intensity)
  210. real_intensity = real_intensity2;
  211. if (real_intensity > 0)
  212. if (real_intensity2 < real_intensity)
  213. real_intensity = real_intensity2;
  214. }
  215. real_intensity *= sign;
  216. md->stats[stat] = new_stat;
  217. // Adjust XP value
  218. md->stats[MOB_XP_BONUS] += mutation_value[stat] * real_intensity;
  219. if (md->stats[MOB_XP_BONUS] <= 0)
  220. md->stats[MOB_XP_BONUS] = 1;
  221. // Sanitise
  222. if (md->stats[MOB_ATK1] > md->stats[MOB_ATK2])
  223. {
  224. int swap = md->stats[MOB_ATK2];
  225. md->stats[MOB_ATK2] = md->stats[MOB_ATK1];
  226. md->stats[MOB_ATK1] = swap;
  227. }
  228. }
  229. // This calculates the exp of a given mob
  230. int mob_gen_exp (struct mob_db *mob)
  231. {
  232. if (!mob)
  233. return 1;
  234. if (mob->max_hp <= 1)
  235. return 1;
  236. double mod_def = 100 - mob->def;
  237. if (mod_def == 0)
  238. mod_def = 1;
  239. double effective_hp =
  240. ((50 - mob->luk) * mob->max_hp / 50.0) +
  241. (2 * mob->luk * mob->max_hp / mod_def);
  242. double attack_factor =
  243. (mob->atk1 + mob->atk2 + mob->str / 3.0 + mob->dex / 2.0 +
  244. mob->luk) * (1872.0 / mob->adelay) / 4;
  245. double dodge_factor =
  246. pow (mob->lv + mob->agi + mob->luk / 2.0, 4.0 / 3.0);
  247. double persuit_factor =
  248. (3 + mob->range) * (mob->mode % 2) * 1000 / mob->speed;
  249. double aggression_factor = (mob->mode & 4) == 4 ? 10.0 / 9.0 : 1.0;
  250. int xp =
  251. (int) floor (effective_hp *
  252. pow (sqrt (attack_factor) + sqrt (dodge_factor) +
  253. sqrt (persuit_factor) + 55,
  254. 3) * aggression_factor / 2000000.0 *
  255. (double) battle_config.base_exp_rate / 100.);
  256. if (xp < 1)
  257. xp = 1;
  258. printf ("Exp for mob '%s' generated: %d\n", mob->name, xp);
  259. return xp;
  260. }
  261. static void mob_init (struct mob_data *md)
  262. {
  263. if (!md)
  264. return;
  265. int i;
  266. const int class = md->class;
  267. const int mutations_nr = mob_db[class].mutations_nr;
  268. const int mutation_power = mob_db[class].mutation_power;
  269. md->stats[MOB_LV] = mob_db[class].lv;
  270. md->stats[MOB_MAX_HP] = mob_db[class].max_hp;
  271. md->stats[MOB_STR] = mob_db[class].str;
  272. md->stats[MOB_AGI] = mob_db[class].agi;
  273. md->stats[MOB_VIT] = mob_db[class].vit;
  274. md->stats[MOB_INT] = mob_db[class].int_;
  275. md->stats[MOB_DEX] = mob_db[class].dex;
  276. md->stats[MOB_LUK] = mob_db[class].luk;
  277. md->stats[MOB_ATK1] = mob_db[class].atk1;
  278. md->stats[MOB_ATK2] = mob_db[class].atk2;
  279. md->stats[MOB_ADELAY] = mob_db[class].adelay;
  280. md->stats[MOB_DEF] = mob_db[class].def;
  281. md->stats[MOB_MDEF] = mob_db[class].mdef;
  282. md->stats[MOB_SPEED] = mob_db[class].speed;
  283. md->stats[MOB_XP_BONUS] = MOB_XP_BONUS_BASE;
  284. if (!(mutation_power >> 1))
  285. return;
  286. for (i = 0; i < mutations_nr; i++)
  287. {
  288. int stat_nr = MRAND (MOB_XP_BONUS + 1);
  289. int strength;
  290. if (stat_nr >= MOB_XP_BONUS)
  291. stat_nr = MOB_MAX_HP;
  292. strength =
  293. ((MRAND ((mutation_power >> 1)) +
  294. (MRAND ((mutation_power >> 1))) +
  295. 2) * mutation_scale[stat_nr]) / 100;
  296. strength = MRAND (2) ? strength : -strength;
  297. if (strength < -240)
  298. strength = -240; /* Don't go too close to zero */
  299. mob_mutate (md, stat_nr, strength);
  300. }
  301. }
  302. /*==========================================
  303. * The MOB appearance for one time (for scripts)
  304. *------------------------------------------
  305. */
  306. int mob_once_spawn (struct map_session_data *sd, char *mapname,
  307. int x, int y, const char *mobname, int class, int amount,
  308. const char *event)
  309. {
  310. if (!mapname)
  311. return 0;
  312. struct mob_data *md = NULL;
  313. int m, count, lv = 255, r = class;
  314. if (sd)
  315. lv = sd->status.base_level;
  316. if (sd && strcmp (mapname, "this") == 0)
  317. m = sd->bl.m;
  318. else
  319. m = map_mapname2mapid (mapname);
  320. if (m < 0 || amount <= 0 || (class >= 0 && class <= 1000) || class > 2000) // 値が異常なら召喚を止める
  321. return 0;
  322. if (class < 0)
  323. { // ランダムに召喚
  324. int j = -class - 1;
  325. if (j >= 0 && j < MAX_RANDOMMONSTER)
  326. {
  327. int i = 0;
  328. int k;
  329. do
  330. {
  331. class = MPRAND (1001, 1000);
  332. k = MRAND (1000000);
  333. }
  334. while ((mob_db[class].max_hp <= 0
  335. || mob_db[class].summonper[j] <= k
  336. || (lv < mob_db[class].lv
  337. && battle_config.random_monster_checklv == 1))
  338. && (i++) < 2000);
  339. if (i >= 2000)
  340. {
  341. class = mob_db[0].summonper[j];
  342. }
  343. }
  344. else
  345. {
  346. return 0;
  347. }
  348. // if(battle_config.etc_log==1)
  349. // printf("mobclass=%d try=%d\n",class,i);
  350. }
  351. if (sd)
  352. {
  353. if (x <= 0)
  354. x = sd->bl.x;
  355. if (y <= 0)
  356. y = sd->bl.y;
  357. }
  358. else if (x <= 0 || y <= 0)
  359. {
  360. printf ("mob_once_spawn: ??\n");
  361. }
  362. for (count = 0; count < amount; count++)
  363. {
  364. md = (struct mob_data *) aCalloc (1, sizeof (struct mob_data));
  365. memset (md, '\0', sizeof *md);
  366. if (mob_db[class].mode & 0x02)
  367. md->lootitem =
  368. (struct item *) aCalloc (LOOTITEM_SIZE, sizeof (struct item));
  369. else
  370. md->lootitem = NULL;
  371. mob_spawn_dataset (md, mobname, class);
  372. md->bl.m = m;
  373. md->bl.x = x;
  374. md->bl.y = y;
  375. if (r < 0 && battle_config.dead_branch_active == 1)
  376. md->mode = 0x1 + 0x4 + 0x80; //移動してアクティブで反撃する
  377. md->m = m;
  378. md->x0 = x;
  379. md->y0 = y;
  380. md->xs = 0;
  381. md->ys = 0;
  382. md->spawndelay1 = -1; // Only once is a flag.
  383. md->spawndelay2 = -1; // Only once is a flag.
  384. memcpy (md->npc_event, event, sizeof (md->npc_event));
  385. md->bl.type = BL_MOB;
  386. map_addiddb (&md->bl);
  387. mob_spawn (md->bl.id);
  388. if (class == 1288)
  389. { // emperium hp based on defense level [Valaris]
  390. struct guild_castle *gc = guild_mapname2gc (map[md->bl.m].name);
  391. if (gc)
  392. {
  393. mob_db[class].max_hp += 2000 * gc->defense;
  394. md->hp = mob_db[class].max_hp;
  395. }
  396. } // end addition [Valaris]
  397. }
  398. return (amount > 0) ? md->bl.id : 0;
  399. }
  400. /*==========================================
  401. * The MOB appearance for one time (& area specification for scripts)
  402. *------------------------------------------
  403. */
  404. int mob_once_spawn_area (struct map_session_data *sd, char *mapname,
  405. int x0, int y0, int x1, int y1,
  406. const char *mobname, int class, int amount,
  407. const char *event)
  408. {
  409. if (!mapname)
  410. return 0;
  411. int x, y, i, c, max, lx = -1, ly = -1, id = 0;
  412. int m;
  413. if (strcmp (mapname, "this") == 0)
  414. {
  415. if (!sd)
  416. return 0;
  417. m = sd->bl.m;
  418. }
  419. else
  420. m = map_mapname2mapid (mapname);
  421. max = (y1 - y0 + 1) * (x1 - x0 + 1) * 3;
  422. if (max > 1000)
  423. max = 1000;
  424. if (m < 0 || amount <= 0 || (class >= 0 && class <= 1000) || class > 2000) // A summon is stopped if a value is unusual
  425. return 0;
  426. for (i = 0; i < amount; i++)
  427. {
  428. int j = 0;
  429. do
  430. {
  431. x = MPRAND (x0, (x1 - x0 + 1));
  432. y = MPRAND (y0, (y1 - y0 + 1));
  433. }
  434. while (((c = map_getcell (m, x, y)) == 1 || c == 5) && (++j) < max);
  435. if (j >= max)
  436. {
  437. if (lx >= 0)
  438. { // Since reference went wrong, the place which boiled before is used.
  439. x = lx;
  440. y = ly;
  441. }
  442. else
  443. return 0; // Since reference of the place which boils first went wrong, it stops.
  444. }
  445. id = mob_once_spawn (sd, mapname, x, y, mobname, class, 1, event);
  446. lx = x;
  447. ly = y;
  448. }
  449. return id;
  450. }
  451. /*==========================================
  452. * Summoning Guardians [Valaris]
  453. *------------------------------------------
  454. */
  455. int mob_spawn_guardian (struct map_session_data *sd, char *mapname,
  456. int x, int y, const char *mobname, int class,
  457. int amount, const char *event, int guardian)
  458. {
  459. if (!mapname)
  460. return 0;
  461. struct mob_data *md = NULL;
  462. int m, count = 1;
  463. if (sd && strcmp (mapname, "this") == 0)
  464. m = sd->bl.m;
  465. else
  466. m = map_mapname2mapid (mapname);
  467. if (m < 0 || amount <= 0 || (class >= 0 && class <= 1000) || class > 2000) // 値が異常なら召喚を止める
  468. return 0;
  469. if (class < 0)
  470. return 0;
  471. if (sd)
  472. {
  473. if (x <= 0)
  474. x = sd->bl.x;
  475. if (y <= 0)
  476. y = sd->bl.y;
  477. }
  478. else if (x <= 0 || y <= 0)
  479. printf ("mob_spawn_guardian: ??\n");
  480. for (count = 0; count < amount; count++)
  481. {
  482. struct guild_castle *gc;
  483. md = calloc (sizeof (struct mob_data), 1);
  484. if (md == NULL)
  485. {
  486. printf ("mob_spawn_guardian: out of memory !\n");
  487. exit (1);
  488. }
  489. memset (md, '\0', sizeof *md);
  490. mob_spawn_dataset (md, mobname, class);
  491. md->bl.m = m;
  492. md->bl.x = x;
  493. md->bl.y = y;
  494. md->m = m;
  495. md->x0 = x;
  496. md->y0 = y;
  497. md->xs = 0;
  498. md->ys = 0;
  499. md->spawndelay1 = -1; // Only once is a flag.
  500. md->spawndelay2 = -1; // Only once is a flag.
  501. memcpy (md->npc_event, event, sizeof (md->npc_event));
  502. md->bl.type = BL_MOB;
  503. map_addiddb (&md->bl);
  504. mob_spawn (md->bl.id);
  505. gc = guild_mapname2gc (map[md->bl.m].name);
  506. if (gc)
  507. {
  508. mob_db[class].max_hp += 2000 * gc->defense;
  509. if (guardian == 0)
  510. {
  511. md->hp = gc->Ghp0;
  512. gc->GID0 = md->bl.id;
  513. }
  514. if (guardian == 1)
  515. {
  516. md->hp = gc->Ghp1;
  517. gc->GID1 = md->bl.id;
  518. }
  519. if (guardian == 2)
  520. {
  521. md->hp = gc->Ghp2;
  522. gc->GID2 = md->bl.id;
  523. }
  524. if (guardian == 3)
  525. {
  526. md->hp = gc->Ghp3;
  527. gc->GID3 = md->bl.id;
  528. }
  529. if (guardian == 4)
  530. {
  531. md->hp = gc->Ghp4;
  532. gc->GID4 = md->bl.id;
  533. }
  534. if (guardian == 5)
  535. {
  536. md->hp = gc->Ghp5;
  537. gc->GID5 = md->bl.id;
  538. }
  539. if (guardian == 6)
  540. {
  541. md->hp = gc->Ghp6;
  542. gc->GID6 = md->bl.id;
  543. }
  544. if (guardian == 7)
  545. {
  546. md->hp = gc->Ghp7;
  547. gc->GID7 = md->bl.id;
  548. }
  549. }
  550. }
  551. return (amount > 0) ? md->bl.id : 0;
  552. }
  553. /*==========================================
  554. * Appearance income of mob
  555. *------------------------------------------
  556. */
  557. int mob_get_viewclass (int class)
  558. {
  559. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  560. return 0;
  561. return mob_db[class].view_class;
  562. }
  563. int mob_get_sex (int class)
  564. {
  565. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  566. return 0;
  567. return mob_db[class].sex;
  568. }
  569. short mob_get_hair (int class)
  570. {
  571. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  572. return 0;
  573. return mob_db[class].hair;
  574. }
  575. short mob_get_hair_color (int class)
  576. {
  577. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  578. return 0;
  579. return mob_db[class].hair_color;
  580. }
  581. short mob_get_weapon (int class)
  582. {
  583. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  584. return 0;
  585. return mob_db[class].weapon;
  586. }
  587. short mob_get_shield (int class)
  588. {
  589. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  590. return 0;
  591. return mob_db[class].shield;
  592. }
  593. short mob_get_head_top (int class)
  594. {
  595. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  596. return 0;
  597. return mob_db[class].head_top;
  598. }
  599. short mob_get_head_mid (int class)
  600. {
  601. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  602. return 0;
  603. return mob_db[class].head_mid;
  604. }
  605. short mob_get_head_buttom (int class)
  606. {
  607. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  608. return 0;
  609. return mob_db[class].head_buttom;
  610. }
  611. short mob_get_clothes_color (int class) // Add for player monster dye - Valaris
  612. {
  613. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  614. return 0;
  615. return mob_db[class].clothes_color; // End
  616. }
  617. int mob_get_equip (int class) // mob equip [Valaris]
  618. {
  619. if (class < 0 || class >= (sizeof (mob_db) / sizeof (mob_db[0])))
  620. return 0;
  621. return mob_db[class].equip;
  622. }
  623. /*==========================================
  624. * Is MOB in the state in which the present movement is possible or not?
  625. *------------------------------------------
  626. */
  627. int mob_can_move (struct mob_data *md)
  628. {
  629. nullpo_retr (0, md);
  630. if (md->canmove_tick > gettick () || (md->opt1 > 0 && md->opt1 != 6)
  631. || md->option & 2)
  632. return 0;
  633. // アンクル中で動けないとか
  634. if (md->sc_data[SC_ANKLE].timer != -1 || //アンクルスネア
  635. md->sc_data[SC_AUTOCOUNTER].timer != -1 || //オートカウンター
  636. md->sc_data[SC_BLADESTOP].timer != -1 || //白刃取り
  637. md->sc_data[SC_SPIDERWEB].timer != -1 //スパイダーウェッブ
  638. )
  639. return 0;
  640. return 1;
  641. }
  642. /*==========================================
  643. * Time calculation concerning one step next to mob
  644. *------------------------------------------
  645. */
  646. static int calc_next_walk_step (struct mob_data *md)
  647. {
  648. nullpo_retr (0, md);
  649. if (md->walkpath.path_pos >= md->walkpath.path_len)
  650. return -1;
  651. if (md->walkpath.path[md->walkpath.path_pos] & 1)
  652. return battle_get_speed (&md->bl) * 14 / 10;
  653. return battle_get_speed (&md->bl);
  654. }
  655. static int mob_walktoxy_sub (struct mob_data *md);
  656. /*==========================================
  657. * Mob Walk processing
  658. *------------------------------------------
  659. */
  660. static int mob_walk (struct mob_data *md, unsigned int tick, int data)
  661. {
  662. int i;
  663. static int dirx[8] = { 0, -1, -1, -1, 0, 1, 1, 1 };
  664. static int diry[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
  665. nullpo_retr (0, md);
  666. md->state.state = MS_IDLE;
  667. if (md->walkpath.path_pos >= md->walkpath.path_len
  668. || md->walkpath.path_pos != data)
  669. return 0;
  670. md->walkpath.path_half ^= 1;
  671. if (md->walkpath.path_half == 0)
  672. {
  673. md->walkpath.path_pos++;
  674. if (md->state.change_walk_target)
  675. {
  676. mob_walktoxy_sub (md);
  677. return 0;
  678. }
  679. }
  680. else
  681. {
  682. int moveblock;
  683. int ctype;
  684. int x, y, dx, dy;
  685. if (md->walkpath.path[md->walkpath.path_pos] >= 8)
  686. return 1;
  687. x = md->bl.x;
  688. y = md->bl.y;
  689. ctype = map_getcell (md->bl.m, x, y);
  690. if (ctype == 1 || ctype == 5)
  691. {
  692. mob_stop_walking (md, 1);
  693. return 0;
  694. }
  695. md->dir = md->walkpath.path[md->walkpath.path_pos];
  696. dx = dirx[md->dir];
  697. dy = diry[md->dir];
  698. ctype = map_getcell (md->bl.m, x + dx, y + dy);
  699. if (ctype == 1 || ctype == 5)
  700. {
  701. mob_walktoxy_sub (md);
  702. return 0;
  703. }
  704. moveblock = (x / BLOCK_SIZE != (x + dx) / BLOCK_SIZE
  705. || y / BLOCK_SIZE != (y + dy) / BLOCK_SIZE);
  706. md->state.state = MS_WALK;
  707. map_foreachinmovearea (clif_moboutsight, md->bl.m, x - AREA_SIZE,
  708. y - AREA_SIZE, x + AREA_SIZE, y + AREA_SIZE,
  709. dx, dy, BL_PC, md);
  710. x += dx;
  711. y += dy;
  712. if (md->min_chase > 13)
  713. md->min_chase--;
  714. if (moveblock)
  715. map_delblock (&md->bl);
  716. md->bl.x = x;
  717. md->bl.y = y;
  718. if (moveblock)
  719. map_addblock (&md->bl);
  720. map_foreachinmovearea (clif_mobinsight, md->bl.m, x - AREA_SIZE,
  721. y - AREA_SIZE, x + AREA_SIZE, y + AREA_SIZE,
  722. -dx, -dy, BL_PC, md);
  723. md->state.state = MS_IDLE;
  724. if (md->option & 4)
  725. skill_check_cloaking (&md->bl);
  726. skill_unit_move (&md->bl, tick, 1); // Inspection of a skill unit
  727. }
  728. if ((i = calc_next_walk_step (md)) > 0)
  729. {
  730. i = i >> 1;
  731. if (i < 1 && md->walkpath.path_half == 0)
  732. i = 1;
  733. md->timer =
  734. add_timer (tick + i, mob_timer, md->bl.id, md->walkpath.path_pos);
  735. md->state.state = MS_WALK;
  736. if (md->walkpath.path_pos >= md->walkpath.path_len)
  737. clif_fixmobpos (md); // When mob stops, retransmission current of a position.
  738. }
  739. return 0;
  740. }
  741. /*==========================================
  742. * Check if mob should be attempting to attack
  743. *------------------------------------------
  744. */
  745. static int mob_check_attack (struct mob_data *md)
  746. {
  747. struct block_list *tbl = NULL;
  748. struct map_session_data *tsd = NULL;
  749. struct mob_data *tmd = NULL;
  750. int mode, race, range;
  751. nullpo_retr (0, md);
  752. md->min_chase = 13;
  753. md->state.state = MS_IDLE;
  754. md->state.skillstate = MSS_IDLE;
  755. if (md->skilltimer != -1)
  756. return 0;
  757. if (md->opt1 > 0 || md->option & 2)
  758. return 0;
  759. if (md->sc_data[SC_AUTOCOUNTER].timer != -1)
  760. return 0;
  761. if (md->sc_data[SC_BLADESTOP].timer != -1)
  762. return 0;
  763. if ((tbl = map_id2bl (md->target_id)) == NULL)
  764. {
  765. md->target_id = 0;
  766. md->state.targettype = NONE_ATTACKABLE;
  767. return 0;
  768. }
  769. if (tbl->type == BL_PC)
  770. tsd = (struct map_session_data *) tbl;
  771. else if (tbl->type == BL_MOB)
  772. tmd = (struct mob_data *) tbl;
  773. else
  774. return 0;
  775. if (tsd)
  776. {
  777. if (pc_isdead (tsd) || tsd->invincible_timer != -1
  778. || pc_isinvisible (tsd) || md->bl.m != tbl->m || tbl->prev == NULL
  779. || distance (md->bl.x, md->bl.y, tbl->x, tbl->y) >= 13)
  780. {
  781. md->target_id = 0;
  782. md->state.targettype = NONE_ATTACKABLE;
  783. return 0;
  784. }
  785. }
  786. if (tmd)
  787. {
  788. if (md->bl.m != tbl->m || tbl->prev == NULL
  789. || distance (md->bl.x, md->bl.y, tbl->x, tbl->y) >= 13)
  790. {
  791. md->target_id = 0;
  792. md->state.targettype = NONE_ATTACKABLE;
  793. return 0;
  794. }
  795. }
  796. if (!md->mode)
  797. mode = mob_db[md->class].mode;
  798. else
  799. mode = md->mode;
  800. race = mob_db[md->class].race;
  801. if (!(mode & 0x80) && !(mode & 0x10000))
  802. {
  803. md->target_id = 0;
  804. md->state.targettype = NONE_ATTACKABLE;
  805. return 0;
  806. }
  807. if (tsd && !(mode & 0x20) && (tsd->sc_data[SC_TRICKDEAD].timer != -1 ||
  808. ((pc_ishiding (tsd)
  809. || tsd->state.gangsterparadise)
  810. && race != 4 && race != 6)))
  811. {
  812. md->target_id = 0;
  813. md->state.targettype = NONE_ATTACKABLE;
  814. return 0;
  815. }
  816. range = mob_db[md->class].range;
  817. if (mode & 1)
  818. range++;
  819. if (distance (md->bl.x, md->bl.y, tbl->x, tbl->y) > range)
  820. return 0;
  821. return 1;
  822. }
  823. /*==========================================
  824. * Attack processing of mob
  825. *------------------------------------------
  826. */
  827. static int mob_attack (struct mob_data *md, unsigned int tick,
  828. int data __attribute__ ((unused)))
  829. {
  830. struct block_list *tbl = NULL;
  831. int mode;
  832. nullpo_retr (0, md);
  833. if (!mob_check_attack (md))
  834. return 0;
  835. if ((tbl = map_id2bl (md->target_id)) == NULL)
  836. return 0;
  837. if (battle_config.monster_attack_direction_change)
  838. md->dir = map_calc_dir (&md->bl, tbl->x, tbl->y); // 向き設定
  839. //clif_fixmobpos(md);
  840. md->state.skillstate = MSS_ATTACK;
  841. if (mobskill_use (md, tick, -2)) // スキル使用
  842. return 0;
  843. if (!md->mode)
  844. mode = mob_db[md->class].mode;
  845. else
  846. mode = md->mode;
  847. if (mode & 0x80)
  848. md->target_lv = battle_weapon_attack (&md->bl, tbl, tick, 0);
  849. else
  850. md->target_lv = 0;
  851. if (!(battle_config.monster_cloak_check_type & 2)
  852. && md->sc_data[SC_CLOAKING].timer != -1)
  853. skill_status_change_end (&md->bl, SC_CLOAKING, -1);
  854. md->attackabletime = tick + battle_get_adelay (&md->bl);
  855. md->timer = add_timer (md->attackabletime, mob_timer, md->bl.id, 0);
  856. md->state.state = MS_ATTACK;
  857. return 0;
  858. }
  859. /*==========================================
  860. * The attack of PC which is attacking id is stopped.
  861. * The callback function of clif_foreachclient
  862. *------------------------------------------
  863. */
  864. int mob_stopattacked (struct map_session_data *sd, va_list ap)
  865. {
  866. int id;
  867. nullpo_retr (0, sd);
  868. nullpo_retr (0, ap);
  869. id = va_arg (ap, int);
  870. if (sd->attacktarget == id)
  871. pc_stopattack (sd);
  872. return 0;
  873. }
  874. /*==========================================
  875. * The timer in which the mob's states changes
  876. *------------------------------------------
  877. */
  878. int mob_changestate (struct mob_data *md, int state, int type)
  879. {
  880. unsigned int tick;
  881. int i;
  882. nullpo_retr (0, md);
  883. if (md->timer != -1)
  884. delete_timer (md->timer, mob_timer);
  885. md->timer = -1;
  886. md->state.state = state;
  887. switch (state)
  888. {
  889. case MS_WALK:
  890. if ((i = calc_next_walk_step (md)) > 0)
  891. {
  892. i = i >> 2;
  893. md->timer =
  894. add_timer (gettick () + i, mob_timer, md->bl.id, 0);
  895. }
  896. else
  897. md->state.state = MS_IDLE;
  898. break;
  899. case MS_ATTACK:
  900. tick = gettick ();
  901. i = DIFF_TICK (md->attackabletime, tick);
  902. if (i > 0 && i < 2000)
  903. md->timer =
  904. add_timer (md->attackabletime, mob_timer, md->bl.id, 0);
  905. else if (type)
  906. {
  907. md->attackabletime = tick + battle_get_amotion (&md->bl);
  908. md->timer =
  909. add_timer (md->attackabletime, mob_timer, md->bl.id, 0);
  910. }
  911. else
  912. {
  913. md->attackabletime = tick + 1;
  914. md->timer =
  915. add_timer (md->attackabletime, mob_timer, md->bl.id, 0);
  916. }
  917. break;
  918. case MS_DELAY:
  919. md->timer =
  920. add_timer (gettick () + type, mob_timer, md->bl.id, 0);
  921. break;
  922. case MS_DEAD:
  923. skill_castcancel (&md->bl, 0);
  924. // mobskill_deltimer(md);
  925. md->state.skillstate = MSS_DEAD;
  926. md->last_deadtime = gettick ();
  927. // Since it died, all aggressors' attack to this mob is stopped.
  928. clif_foreachclient (mob_stopattacked, md->bl.id);
  929. skill_unit_out_all (&md->bl, gettick (), 1);
  930. skill_status_change_clear (&md->bl, 2); // The abnormalities in status are canceled.
  931. skill_clear_unitgroup (&md->bl); // All skill unit groups are deleted.
  932. skill_cleartimerskill (&md->bl);
  933. if (md->deletetimer != -1)
  934. delete_timer (md->deletetimer, mob_timer_delete);
  935. md->deletetimer = -1;
  936. md->hp = md->target_id = md->attacked_id = 0;
  937. md->state.targettype = NONE_ATTACKABLE;
  938. break;
  939. default:
  940. break;
  941. }
  942. return 0;
  943. }
  944. /*==========================================
  945. * timer processing of mob (timer function)
  946. * It branches to a walk and an attack.
  947. *------------------------------------------
  948. */
  949. static int mob_timer (int tid, unsigned int tick, int id, int data)
  950. {
  951. struct mob_data *md;
  952. struct block_list *bl;
  953. if ((bl = map_id2bl (id)) == NULL)
  954. { //攻撃してきた敵がもういないのは正常のようだ
  955. return 1;
  956. }
  957. if (!bl || !bl->type || bl->type != BL_MOB)
  958. return 1;
  959. nullpo_retr (1, md = (struct mob_data *) bl);
  960. if (!md->bl.type || md->bl.type != BL_MOB)
  961. return 1;
  962. if (md->timer != tid)
  963. {
  964. if (battle_config.error_log == 1)
  965. printf ("mob_timer %d != %d\n", md->timer, tid);
  966. return 0;
  967. }
  968. md->timer = -1;
  969. if (md->bl.prev == NULL || md->state.state == MS_DEAD)
  970. return 1;
  971. map_freeblock_lock ();
  972. switch (md->state.state)
  973. {
  974. case MS_WALK:
  975. mob_check_attack (md);
  976. mob_walk (md, tick, data);
  977. break;
  978. case MS_ATTACK:
  979. mob_attack (md, tick, data);
  980. break;
  981. case MS_DELAY:
  982. mob_changestate (md, MS_IDLE, 0);
  983. break;
  984. default:
  985. if (battle_config.error_log == 1)
  986. printf ("mob_timer : %d ?\n", md->state.state);
  987. break;
  988. }
  989. map_freeblock_unlock ();
  990. return 0;
  991. }
  992. /*==========================================
  993. *
  994. *------------------------------------------
  995. */
  996. static int mob_walktoxy_sub (struct mob_data *md)
  997. {
  998. struct walkpath_data wpd;
  999. nullpo_retr (0, md);
  1000. if (path_search
  1001. (&wpd, md->bl.m, md->bl.x, md->bl.y, md->to_x, md->to_y,
  1002. md->state.walk_easy))
  1003. return 1;
  1004. memcpy (&md->walkpath, &wpd, sizeof (wpd));
  1005. md->state.change_walk_target = 0;
  1006. mob_changestate (md, MS_WALK, 0);
  1007. clif_movemob (md);
  1008. return 0;
  1009. }
  1010. /*==========================================
  1011. * mob move start
  1012. *------------------------------------------
  1013. */
  1014. int mob_walktoxy (struct mob_data *md, int x, int y, int easy)
  1015. {
  1016. struct walkpath_data wpd;
  1017. nullpo_retr (0, md);
  1018. if (md->state.state == MS_WALK
  1019. && path_search (&wpd, md->bl.m, md->bl.x, md->bl.y, x, y, easy))
  1020. return 1;
  1021. md->state.walk_easy = easy;
  1022. md->to_x = x;
  1023. md->to_y = y;
  1024. if (md->state.state == MS_WALK)
  1025. {
  1026. md->state.change_walk_target = 1;
  1027. }
  1028. else
  1029. {
  1030. return mob_walktoxy_sub (md);
  1031. }
  1032. return 0;
  1033. }
  1034. /*==========================================
  1035. * mob spawn with delay (timer function)
  1036. *------------------------------------------
  1037. */
  1038. static int mob_delayspawn (int tid __attribute__ ((unused)),
  1039. unsigned int tick __attribute__ ((unused)),
  1040. int m, int n __attribute__ ((unused)))
  1041. {
  1042. mob_spawn (m);
  1043. return 0;
  1044. }
  1045. /*==========================================
  1046. * spawn timing calculation
  1047. *------------------------------------------
  1048. */
  1049. int mob_setdelayspawn (int id)
  1050. {
  1051. unsigned int spawntime, spawntime1, spawntime2, spawntime3;
  1052. struct mob_data *md;
  1053. struct block_list *bl;
  1054. if ((bl = map_id2bl (id)) == NULL)
  1055. return -1;
  1056. if (!bl || !bl->type || bl->type != BL_MOB)
  1057. return -1;
  1058. nullpo_retr (-1, md = (struct mob_data *) bl);
  1059. if (!md || md->bl.type != BL_MOB)
  1060. return -1;
  1061. // Processing of MOB which is not revitalized
  1062. if (md->spawndelay1 == -1 && md->spawndelay2 == -1 && md->n == 0)
  1063. {
  1064. map_deliddb (&md->bl);
  1065. if (md->lootitem)
  1066. {
  1067. map_freeblock (md->lootitem);
  1068. md->lootitem = NULL;
  1069. }
  1070. map_freeblock (md); // Instead of [ of free ]
  1071. return 0;
  1072. }
  1073. spawntime1 = md->last_spawntime + md->spawndelay1;
  1074. spawntime2 = md->last_deadtime + md->spawndelay2;
  1075. spawntime3 = gettick () + 5000;
  1076. // spawntime = max(spawntime1,spawntime2,spawntime3);
  1077. if (DIFF_TICK (spawntime1, spawntime2) > 0)
  1078. {
  1079. spawntime = spawntime1;
  1080. }
  1081. else
  1082. {
  1083. spawntime = spawntime2;
  1084. }
  1085. if (DIFF_TICK (spawntime3, spawntime) > 0)
  1086. {
  1087. spawntime = spawntime3;
  1088. }
  1089. add_timer (spawntime, mob_delayspawn, id, 0);
  1090. return 0;
  1091. }
  1092. /*==========================================
  1093. * Mob spawning. Initialization is also variously here.
  1094. *------------------------------------------
  1095. */
  1096. int mob_spawn (int id)
  1097. {
  1098. int x = 0, y = 0, i = 0, c;
  1099. unsigned int tick = gettick ();
  1100. struct mob_data *md;
  1101. struct block_list *bl;
  1102. nullpo_retr (-1, bl = map_id2bl (id));
  1103. if (!bl || !bl->type || bl->type != BL_MOB)
  1104. return -1;
  1105. nullpo_retr (-1, md = (struct mob_data *) bl);
  1106. if (!md || !md->bl.type || md->bl.type != BL_MOB || map[md->bl.m].mob_num > battle_config.mob_map_limit)
  1107. return -1;
  1108. md->last_spawntime = tick;
  1109. if (md->bl.prev != NULL)
  1110. {
  1111. // clif_clearchar_area(&md->bl,3);
  1112. skill_unit_out_all (&md->bl, gettick (), 1);
  1113. map_delblock (&md->bl);
  1114. }
  1115. else
  1116. md->class = md->base_class;
  1117. md->bl.m = md->m;
  1118. do
  1119. {
  1120. if (md->x0 == 0 && md->y0 == 0)
  1121. {
  1122. x = MPRAND (1, (map[md->bl.m].xs - 2));
  1123. y = MPRAND (1, (map[md->bl.m].ys - 2));
  1124. }
  1125. else
  1126. {
  1127. x = MPRAND (md->x0, (md->xs + 1)) - md->xs / 2;
  1128. y = MPRAND (md->y0, (md->ys + 1)) - md->ys / 2;
  1129. }
  1130. i++;
  1131. }
  1132. while (((c = map_getcell (md->bl.m, x, y)) == 1 || c == 5) && i < 50);
  1133. if (i >= 50)
  1134. {
  1135. // if(battle_config.error_log==1)
  1136. // printf("MOB spawn error %d @ %s\n",id,map[md->bl.m].name);
  1137. add_timer (tick + 5000, mob_delayspawn, id, 0);
  1138. return 1;
  1139. }
  1140. md->to_x = md->bl.x = x;
  1141. md->to_y = md->bl.y = y;
  1142. md->dir = 0;
  1143. map_addblock (&md->bl);
  1144. memset (&md->state, 0, sizeof (md->state));
  1145. md->attacked_id = 0;
  1146. md->target_id = 0;
  1147. md->move_fail_count = 0;
  1148. mob_init (md);
  1149. if (!md->stats[MOB_SPEED])
  1150. md->stats[MOB_SPEED] = mob_db[md->class].speed;
  1151. md->def_ele = mob_db[md->class].element;
  1152. // md->master_id = 0;
  1153. md->master_dist = 0;
  1154. md->state.state = MS_IDLE;
  1155. md->state.skillstate = MSS_IDLE;
  1156. md->timer = -1;
  1157. md->last_thinktime = tick;
  1158. md->next_walktime = tick + MPRAND (5000, 50);
  1159. md->attackabletime = tick;
  1160. md->canmove_tick = tick;
  1161. md->sg_count = 0;
  1162. md->deletetimer = -1;
  1163. md->skilltimer = -1;
  1164. for (i = 0, c = tick - 1000 * 3600 * 10; i < MAX_MOBSKILL; i++)
  1165. md->skilldelay[i] = c;
  1166. md->skillid = 0;
  1167. md->skilllv = 0;
  1168. memset (md->dmglog, 0, sizeof (md->dmglog));
  1169. if (md->lootitem)
  1170. memset (md->lootitem, 0, sizeof (md->lootitem));
  1171. md->lootitem_count = 0;
  1172. for (i = 0; i < MAX_MOBSKILLTIMERSKILL; i++)
  1173. md->skilltimerskill[i].timer = -1;
  1174. for (i = 0; i < MAX_STATUSCHANGE; i++)
  1175. {
  1176. md->sc_data[i].timer = -1;
  1177. md->sc_data[i].val1 = md->sc_data[i].val2 = md->sc_data[i].val3 =
  1178. md->sc_data[i].val4 = 0;
  1179. }
  1180. md->sc_count = 0;
  1181. md->opt1 = md->opt2 = md->opt3 = md->option = 0;
  1182. memset (md->skillunit, 0, sizeof (md->skillunit));
  1183. memset (md->skillunittick, 0, sizeof (md->skillunittick));
  1184. md->hp = battle_get_max_hp (&md->bl);
  1185. if (md->hp <= 0)
  1186. {
  1187. mob_makedummymobdb (md->class);
  1188. md->hp = battle_get_max_hp (&md->bl);
  1189. }
  1190. md->max_hp = md->hp;
  1191. clif_spawnmob (md);
  1192. return 0;
  1193. }
  1194. /*==========================================
  1195. * Distance calculation between two points
  1196. *------------------------------------------
  1197. */
  1198. static int distance (int x0, int y0, int x1, int y1)
  1199. {
  1200. int dx, dy;
  1201. dx = abs (x0 - x1);
  1202. dy = abs (y0 - y1);
  1203. return dx > dy ? dx : dy;
  1204. }
  1205. /*==========================================
  1206. * The stop of MOB's attack
  1207. *------------------------------------------
  1208. */
  1209. int mob_stopattack (struct mob_data *md)
  1210. {
  1211. nullpo_retr (0, md);
  1212. md->target_id = 0;
  1213. md->state.targettype = NONE_ATTACKABLE;
  1214. md->attacked_id = 0;
  1215. return 0;
  1216. }
  1217. /*==========================================
  1218. * The stop of MOB's walking
  1219. *------------------------------------------
  1220. */
  1221. int mob_stop_walking (struct mob_data *md, int type)
  1222. {
  1223. nullpo_retr (0, md);
  1224. if (md->state.state == MS_WALK || md->state.state == MS_IDLE)
  1225. {
  1226. int dx = 0, dy = 0;
  1227. md->walkpath.path_len = 0;
  1228. if (type & 4)
  1229. {
  1230. dx = md->to_x - md->bl.x;
  1231. if (dx < 0)
  1232. dx = -1;
  1233. else if (dx > 0)
  1234. dx = 1;
  1235. dy = md->to_y - md->bl.y;
  1236. if (dy < 0)
  1237. dy = -1;
  1238. else if (dy > 0)
  1239. dy = 1;
  1240. }
  1241. md->to_x = md->bl.x + dx;
  1242. md->to_y = md->bl.y + dy;
  1243. if (dx != 0 || dy != 0)
  1244. {
  1245. mob_walktoxy_sub (md);
  1246. return 0;
  1247. }
  1248. mob_changestate (md, MS_IDLE, 0);
  1249. }
  1250. if (type & 0x01)
  1251. clif_fixmobpos (md);
  1252. if (type & 0x02)
  1253. {
  1254. int delay = battle_get_dmotion (&md->bl);
  1255. unsigned int tick = gettick ();
  1256. if (md->canmove_tick < tick)
  1257. md->canmove_tick = tick + delay;
  1258. }
  1259. return 0;
  1260. }
  1261. /*==========================================
  1262. * Reachability to a Specification ID existence place
  1263. *------------------------------------------
  1264. */
  1265. int mob_can_reach (struct mob_data *md, struct block_list *bl, int range)
  1266. {
  1267. int dx, dy;
  1268. struct walkpath_data wpd;
  1269. int i;
  1270. nullpo_retr (0, md);
  1271. nullpo_retr (0, bl);
  1272. dx = abs (bl->x - md->bl.x);
  1273. dy = abs (bl->y - md->bl.y);
  1274. //=========== guildcastle guardian no search start===========
  1275. //when players are the guild castle member not attack them !
  1276. if (md->class == 1285 || md->class == 1286 || md->class == 1287)
  1277. {
  1278. struct map_session_data *sd;
  1279. struct guild *g = NULL;
  1280. struct guild_castle *gc = guild_mapname2gc (map[bl->m].name);
  1281. if (gc && agit_flag == 0) // Guardians will not attack during non-woe time [Valaris]
  1282. return 0; // end addition [Valaris]
  1283. if (bl && bl->type == BL_PC)
  1284. {
  1285. if ((sd = (struct map_session_data *) bl) == NULL)
  1286. {
  1287. printf ("mob_can_reach nullpo\n");
  1288. return 0;
  1289. }
  1290. if (gc && sd && sd->status.guild_id && sd->status.guild_id > 0)
  1291. {
  1292. g = guild_search (sd->status.guild_id); // don't attack guild members [Valaris]
  1293. if (g && g->guild_id > 0 && g->guild_id == gc->guild_id)
  1294. return 0;
  1295. if (g && gc && guild_isallied (g, gc))
  1296. return 0;
  1297. }
  1298. }
  1299. }
  1300. //========== guildcastle guardian no search eof==============
  1301. if (bl && bl->type == BL_PC && battle_config.monsters_ignore_gm == 1)
  1302. { // option to have monsters ignore GMs [Valaris]
  1303. struct map_session_data *sd;
  1304. if ((sd = (struct map_session_data *) bl) != NULL && pc_isGM (sd))
  1305. return 0;
  1306. }
  1307. if (md->bl.m != bl->m) // 違うャbプ
  1308. return 0;
  1309. if (range > 0 && range < ((dx > dy) ? dx : dy)) // 遠すぎる
  1310. return 0;
  1311. if (md->bl.x == bl->x && md->bl.y == bl->y) // 同じャX
  1312. return 1;
  1313. // Obstacle judging
  1314. wpd.path_len = 0;
  1315. wpd.path_pos = 0;
  1316. wpd.path_half = 0;
  1317. if (path_search (&wpd, md->bl.m, md->bl.x, md->bl.y, bl->x, bl->y, 0) !=
  1318. -1)
  1319. return 1;
  1320. if (bl->type != BL_PC && bl->type != BL_MOB)
  1321. return 0;
  1322. // It judges whether it can adjoin or not.
  1323. dx = (dx > 0) ? 1 : ((dx < 0) ? -1 : 0);
  1324. dy = (dy > 0) ? 1 : ((dy < 0) ? -1 : 0);
  1325. if (path_search
  1326. (&wpd, md->bl.m, md->bl.x, md->bl.y, bl->x - dx, bl->y - dy, 0) != -1)
  1327. return 1;
  1328. for (i = 0; i < 9; i++)
  1329. {
  1330. if (path_search
  1331. (&wpd, md->bl.m, md->bl.x, md->bl.y, bl->x - 1 + i / 3,
  1332. bl->y - 1 + i % 3, 0) != -1)
  1333. return 1;
  1334. }
  1335. return 0;
  1336. }
  1337. /*==========================================
  1338. * Determination for an attack of a monster
  1339. *------------------------------------------
  1340. */
  1341. int mob_target (struct mob_data *md, struct block_list *bl, int dist)
  1342. {
  1343. struct map_session_data *sd;
  1344. struct status_change *sc_data;
  1345. short *option;
  1346. int mode, race;
  1347. nullpo_retr (0, md);
  1348. nullpo_retr (0, bl);
  1349. sc_data = battle_get_sc_data (bl);
  1350. option = battle_get_option (bl);
  1351. race = mob_db[md->class].race;
  1352. if (!md->mode)
  1353. {
  1354. mode = mob_db[md->class].mode;
  1355. }
  1356. else
  1357. {
  1358. mode = md->mode;
  1359. }
  1360. if (!(mode & 0x80))
  1361. {
  1362. md->target_id = 0;
  1363. return 0;
  1364. }
  1365. // Nothing will be carried out if there is no mind of changing TAGE by TAGE ending.
  1366. if ((md->target_id > 0 && md->state.targettype == ATTACKABLE)
  1367. && (!(mode & 0x04) || MRAND (100) > 25))
  1368. return 0;
  1369. if (mode & 0x20 || // Coercion is exerted if it is MVPMOB.
  1370. (sc_data && sc_data[SC_TRICKDEAD].timer == -1 &&
  1371. ((option && !(*option & 0x06)) || race == 4 || race == 6)))
  1372. {
  1373. if (bl->type == BL_PC)
  1374. {
  1375. nullpo_retr (0, sd = (struct map_session_data *) bl);
  1376. if (sd->invincible_timer != -1 || pc_isinvisible (sd))
  1377. return 0;
  1378. if (!(mode & 0x20) && race != 4 && race != 6
  1379. && sd->state.gangsterparadise)
  1380. return 0;
  1381. }
  1382. md->target_id = bl->id; // Since there was no disturbance, it locks on to target.
  1383. if (bl->type == BL_PC || bl->type == BL_MOB)
  1384. md->state.targettype = ATTACKABLE;
  1385. else
  1386. md->state.targettype = NONE_ATTACKABLE;
  1387. md->min_chase = dist + 13;
  1388. if (md->min_chase > 26)
  1389. md->min_chase = 26;
  1390. }
  1391. return 0;
  1392. }
  1393. /*==========================================
  1394. * The ?? routine of an active monster
  1395. *------------------------------------------
  1396. */
  1397. static int mob_ai_sub_hard_activesearch (struct block_list *bl, va_list ap)
  1398. {
  1399. struct map_session_data *tsd = NULL;
  1400. struct mob_data *smd, *tmd = NULL;
  1401. int mode, *pcc;
  1402. nullpo_retr (0, bl);
  1403. nullpo_retr (0, ap);
  1404. nullpo_retr (0, smd = va_arg (ap, struct mob_data *));
  1405. nullpo_retr (0, pcc = va_arg (ap, int *));
  1406. if (bl->type == BL_PC)
  1407. tsd = (struct map_session_data *) bl;
  1408. else if (bl->type == BL_MOB)
  1409. tmd = (struct mob_data *) bl;
  1410. else
  1411. return 0;
  1412. //敵味方判定
  1413. if (battle_check_target (&smd->bl, bl, BCT_ENEMY) == 0)
  1414. return 0;
  1415. if (!smd->mode)
  1416. mode = mob_db[smd->class].mode;
  1417. else
  1418. mode = smd->mode;
  1419. // アクティブでターゲット射程内にいるなら、ロックする
  1420. if (mode & 0x04)
  1421. {
  1422. int race;
  1423. race = mob_db[smd->class].race;
  1424. //対象がPCの場合
  1425. if (tsd &&
  1426. !pc_isdead (tsd) &&
  1427. tsd->bl.m == smd->bl.m &&
  1428. tsd->invincible_timer == -1 &&
  1429. !pc_isinvisible (tsd) &&
  1430. (distance (smd->bl.x, smd->bl.y, tsd->bl.x, tsd->bl.y)) < 9)
  1431. {
  1432. if (mode & 0x20 ||
  1433. (tsd->sc_data[SC_TRICKDEAD].timer == -1 &&
  1434. ((!pc_ishiding (tsd) && !tsd->state.gangsterparadise)
  1435. || race == 4 || race == 6)))
  1436. { // 妨害がないか判定
  1437. if (mob_can_reach (smd, bl, 12) && // 到達可能性判定
  1438. MRAND (1000) < 1000 / (++(*pcc)))
  1439. { // 範囲内PCで等確率にする
  1440. smd->target_id = tsd->bl.id;
  1441. smd->state.targettype = ATTACKABLE;
  1442. smd->min_chase = 13;
  1443. }
  1444. }
  1445. }
  1446. //対象がMobの場合
  1447. else if (tmd &&
  1448. tmd->bl.m == smd->bl.m &&
  1449. (distance (smd->bl.x, smd->bl.y, tmd->bl.x, tmd->bl.y)) < 9)
  1450. {
  1451. if (mob_can_reach (smd, bl, 12) && // 到達可能性判定
  1452. MRAND (1000) < 1000 / (++(*pcc)))
  1453. { // 範囲内で等確率にする
  1454. smd->target_id = bl->id;
  1455. smd->state.targettype = ATTACKABLE;
  1456. smd->min_chase = 13;
  1457. }
  1458. }
  1459. }
  1460. return 0;
  1461. }
  1462. /*==========================================
  1463. * loot monster item search
  1464. *------------------------------------------
  1465. */
  1466. static int mob_ai_sub_hard_lootsearch (struct block_list *bl, va_list ap)
  1467. {
  1468. struct mob_data *md;
  1469. int mode, *itc;
  1470. nullpo_retr (0, bl);
  1471. nullpo_retr (0, ap);
  1472. nullpo_retr (0, md = va_arg (ap, struct mob_data *));
  1473. nullpo_retr (0, itc = va_arg (ap, int *));
  1474. if (!md->mode)
  1475. {
  1476. mode = mob_db[md->class].mode;
  1477. }
  1478. else
  1479. {
  1480. mode = md->mode;
  1481. }
  1482. if (!md->target_id && mode & 0x02)
  1483. {
  1484. if (!md->lootitem
  1485. || (battle_config.monster_loot_type == 1
  1486. && md->lootitem_count >= LOOTITEM_SIZE))
  1487. return 0;
  1488. if (bl->m == md->bl.m
  1489. && distance (md->bl.x, md->bl.y, bl->x, bl->y) < 9)
  1490. {
  1491. if (mob_can_reach (md, bl, 12) && // Reachability judging
  1492. MRAND (1000) < 1000 / (++(*itc)))
  1493. { // It is made a probability, such as within the limits PC.
  1494. md->target_id = bl->id;
  1495. md->state.targettype = NONE_ATTACKABLE;
  1496. md->min_chase = 13;
  1497. }
  1498. }
  1499. }
  1500. return 0;
  1501. }
  1502. /*==========================================
  1503. * The ?? routine of a link monster
  1504. *------------------------------------------
  1505. */
  1506. static int mob_ai_sub_hard_linksearch (struct block_list *bl, va_list ap)
  1507. {
  1508. struct mob_data *tmd;
  1509. struct mob_data *md;
  1510. struct block_list *target;
  1511. nullpo_retr (0, bl);
  1512. nullpo_retr (0, ap);
  1513. nullpo_retr (0, tmd = (struct mob_data *) bl);
  1514. nullpo_retr (0, md = va_arg (ap, struct mob_data *));
  1515. nullpo_retr (0, target = va_a

Large files files are truncated, but you can click here to view the full file