1.  
  2.  
  3.  
  4. /*
  5. ==================================
  6. =
  7. = SelectDodgeDir
  8. =
  9. = Attempts to choose and initiate a movement for ob that sends it towards
  10. = the player while dodging
  11. =
  12. = If there is no possible move (ob is totally surrounded)
  13. =
  14. = ob->dir = nodir
  15. =
  16. = Otherwise
  17. =
  18. = ob->dir = new direction to follow
  19. = ob->distance = TILEGLOBAL or -doornumber
  20. = ob->tilex = new destination
  21. = ob->tiley
  22. = ob->areanumber = the floor tile number (0-(NUMAREAS-1)) of destination
  23. =
  24. ==================================
  25. */
  26.  
  27. void SelectDodgeDir (objtype *ob)
  28. {
  29. int deltax,deltay,i;
  30. unsigned absdx,absdy;
  31. dirtype dirtry[5];
  32. dirtype turnaround,tdir;
  33.  
  34. if (ob->flags & FL_FIRSTATTACK)
  35. {
  36. //
  37. // turning around is only ok the very first time after noticing the
  38. // player
  39. //
  40. turnaround = nodir;
  41. ob->flags &= ~FL_FIRSTATTACK;
  42. }
  43. else
  44. turnaround=opposite[ob->dir];
  45.  
  46. deltax = player->tilex - ob->tilex;
  47. deltay = player->tiley - ob->tiley;
  48.  
  49. //
  50. // arange 5 direction choices in order of preference
  51. // the four cardinal directions plus the diagonal straight towards
  52. // the player
  53. //
  54.  
  55. if (deltax>0)
  56. {
  57. dirtry[1]= east;
  58. dirtry[3]= west;
  59. }
  60. else
  61. {
  62. dirtry[1]= west;
  63. dirtry[3]= east;
  64. }
  65.  
  66. if (deltay>0)
  67. {
  68. dirtry[2]= south;
  69. dirtry[4]= north;
  70. }
  71. else
  72. {
  73. dirtry[2]= north;
  74. dirtry[4]= south;
  75. }
  76.  
  77. //
  78. // randomize a bit for dodging
  79. //
  80. absdx = abs(deltax);
  81. absdy = abs(deltay);
  82.  
  83. if (absdx > absdy)
  84. {
  85. tdir = dirtry[1];
  86. dirtry[1] = dirtry[2];
  87. dirtry[2] = tdir;
  88. tdir = dirtry[3];
  89. dirtry[3] = dirtry[4];
  90. dirtry[4] = tdir;
  91. }
  92.  
  93. if (US_RndT() < 128)
  94. {
  95. tdir = dirtry[1];
  96. dirtry[1] = dirtry[2];
  97. dirtry[2] = tdir;
  98. tdir = dirtry[3];
  99. dirtry[3] = dirtry[4];
  100. dirtry[4] = tdir;
  101. }
  102.  
  103. dirtry[0] = diagonal [ dirtry[1] ] [ dirtry[2] ];
  104.  
  105. //
  106. // try the directions util one works
  107. //
  108. for (i=0;i<5;i++)
  109. {
  110. if ( dirtry[i] == nodir || dirtry[i] == turnaround)
  111. continue;
  112.  
  113. ob->dir = dirtry[i];
  114. if (TryWalk(ob))
  115. return;
  116. }
  117.  
  118. //
  119. // turn around only as a last resort
  120. //
  121. if (turnaround != nodir)
  122. {
  123. ob->dir = turnaround;
  124.  
  125. if (TryWalk(ob))
  126. return;
  127. }
  128.  
  129. ob->dir = nodir;
  130. }
  131.  
  132.  
  133. /*
  134. ============================
  135. =
  136. = SelectChaseDir
  137. =
  138. = As SelectDodgeDir, but doesn't try to dodge
  139. =
  140. ============================
  141. */
  142.  
  143. void SelectChaseDir (objtype *ob)
  144. {
  145. int deltax,deltay,i;
  146. dirtype d[3];
  147. dirtype tdir, olddir, turnaround;
  148.  
  149.  
  150. olddir=ob->dir;
  151. turnaround=opposite[olddir];
  152.  
  153. deltax=player->tilex - ob->tilex;
  154. deltay=player->tiley - ob->tiley;
  155.  
  156. d[1]=nodir;
  157. d[2]=nodir;
  158.  
  159. if (deltax>0)
  160. d[1]= east;
  161. else if (deltax<0)
  162. d[1]= west;
  163. if (deltay>0)
  164. d[2]=south;
  165. else if (deltay<0)
  166. d[2]=north;
  167.  
  168. if (abs(deltay)>abs(deltax))
  169. {
  170. tdir=d[1];
  171. d[1]=d[2];
  172. d[2]=tdir;
  173. }
  174.  
  175. if (d[1]==turnaround)
  176. d[1]=nodir;
  177. if (d[2]==turnaround)
  178. d[2]=nodir;
  179.  
  180.  
  181. if (d[1]!=nodir)
  182. {
  183. ob->dir=d[1];
  184. if (TryWalk(ob))
  185. return; /*either moved forward or attacked*/
  186. }
  187.  
  188. if (d[2]!=nodir)
  189. {
  190. ob->dir=d[2];
  191. if (TryWalk(ob))
  192. return;
  193. }
  194.  
  195. /* there is no direct path to the player, so pick another direction */
  196.  
  197. if (olddir!=nodir)
  198. {
  199. ob->dir=olddir;
  200. if (TryWalk(ob))
  201. return;
  202. }
  203.  
  204. if (US_RndT()>128) /*randomly determine direction of search*/
  205. {
  206. for (tdir=north;tdir<=west;tdir++)
  207. {
  208. if (tdir!=turnaround)
  209. {
  210. ob->dir=tdir;
  211. if ( TryWalk(ob) )
  212. return;
  213. }
  214. }
  215. }
  216. else
  217. {
  218. for (tdir=west;tdir>=north;tdir--)
  219. {
  220. if (tdir!=turnaround)
  221. {
  222. ob->dir=tdir;
  223. if ( TryWalk(ob) )
  224. return;
  225. }
  226. }
  227. }
  228.  
  229. if (turnaround != nodir)
  230. {
  231. ob->dir=turnaround;
  232. if (ob->dir != nodir)
  233. {
  234. if ( TryWalk(ob) )
  235. return;
  236. }
  237. }
  238.  
  239. ob->dir = nodir; // can't move
  240. }
  241.  
  242.  
  243. /*
  244. ============================
  245. =
  246. = SelectRunDir
  247. =
  248. = Run Away from player
  249. =
  250. ============================
  251. */
  252.  
  253. void SelectRunDir (objtype *ob)
  254. {
  255. int deltax,deltay,i;
  256. dirtype d[3];
  257. dirtype tdir, olddir, turnaround;
  258.  
  259.  
  260. deltax=player->tilex - ob->tilex;
  261. deltay=player->tiley - ob->tiley;
  262.  
  263. if (deltax<0)
  264. d[1]= east;
  265. else
  266. d[1]= west;
  267. if (deltay<0)
  268. d[2]=south;
  269. else
  270. d[2]=north;
  271.  
  272. if (abs(deltay)>abs(deltax))
  273. {
  274. tdir=d[1];
  275. d[1]=d[2];
  276. d[2]=tdir;
  277. }
  278.  
  279. ob->dir=d[1];
  280. if (TryWalk(ob))
  281. return; /*either moved forward or attacked*/
  282.  
  283. ob->dir=d[2];
  284. if (TryWalk(ob))
  285. return;
  286.  
  287. /* there is no direct path to the player, so pick another direction */
  288.  
  289. if (US_RndT()>128) /*randomly determine direction of search*/
  290. {
  291. for (tdir=north;tdir<=west;tdir++)
  292. {
  293. ob->dir=tdir;
  294. if ( TryWalk(ob) )
  295. return;
  296. }
  297. }
  298. else
  299. {
  300. for (tdir=west;tdir>=north;tdir--)
  301. {
  302. ob->dir=tdir;
  303. if ( TryWalk(ob) )
  304. return;
  305. }
  306. }
  307.  
  308. ob->dir = nodir; // can't move
  309. }