AIHAND.CPP 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "aihand.h"
  4. #include "actor.h"
  5. #include "db.h"
  6. #include "debug4g.h"
  7. #include "dude.h"
  8. #include "engine.h"
  9. #include "eventq.h"
  10. #include "gameutil.h"
  11. #include "globals.h"
  12. #include "misc.h"
  13. #include "multi.h"
  14. #include "player.h"
  15. #include "trig.h"
  16. /****************************************************************************
  17. ** LOCAL CONSTANTS
  18. ****************************************************************************/
  19. #define kHandChokeDist M2X(1.8)
  20. #define kHandJumpDist1 M2X(16)
  21. #define kHandJumpDist2 M2X(10)
  22. /****************************************************************************
  23. ** LOCAL think/move function prototypes
  24. ****************************************************************************/
  25. static void thinkSearch( SPRITE *pSprite, XSPRITE *pXSprite );
  26. static void thinkGoto( SPRITE *pSprite, XSPRITE *pXSprite );
  27. static void thinkChase( SPRITE *pSprite, XSPRITE *pXSprite );
  28. /****************************************************************************
  29. ** GLOBAL CONSTANTS
  30. ****************************************************************************/
  31. AISTATE handIdle = { kSeqDudeIdle, NULL, 0, NULL, NULL, aiThinkTarget, NULL };
  32. AISTATE handSearch = { kSeqHandWalk, NULL, 3600, NULL, aiMoveForward, thinkSearch, &handIdle };
  33. AISTATE handChase = { kSeqHandWalk, NULL, 0, NULL, aiMoveForward, thinkChase, NULL };
  34. AISTATE handRecoil = { kSeqDudeRecoil, NULL, 0, NULL, NULL, NULL, &handSearch }; //ADD: handDodge
  35. AISTATE handGoto = { kSeqHandWalk, NULL, 3600, NULL, aiMoveForward, thinkGoto, &handIdle };
  36. AISTATE handJump = { kSeqHandWalk, NULL, 3600, NULL, aiMoveForward, thinkGoto, &handIdle }; //ADD: jumping
  37. AISTATE handChoke = { kSeqHandWalk, NULL, 3600, NULL, aiMoveForward, thinkGoto, &handIdle }; //ADD: choking
  38. /****************************************************************************
  39. ** LOCAL FUNCTIONS
  40. ****************************************************************************/
  41. /****************************************************************************
  42. ** thinkSearch()
  43. **
  44. **
  45. ****************************************************************************/
  46. static void thinkSearch( SPRITE *pSprite, XSPRITE *pXSprite )
  47. {
  48. aiChooseDirection(pSprite, pXSprite, pXSprite->goalAng);
  49. aiThinkTarget(pSprite, pXSprite);
  50. }
  51. /****************************************************************************
  52. ** thinkGoto()
  53. **
  54. **
  55. ****************************************************************************/
  56. static void thinkGoto( SPRITE *pSprite, XSPRITE *pXSprite )
  57. {
  58. int dx, dy, dist;
  59. dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
  60. DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
  61. SPRITE *pTarget = &sprite[pXSprite->target];
  62. XSPRITE *pXTarget = &xsprite[pTarget->extra];
  63. dx = pXSprite->targetX - pSprite->x;
  64. dy = pXSprite->targetY - pSprite->y;
  65. int nAngle = getangle(dx, dy);
  66. dist = qdist(dx, dy);
  67. aiChooseDirection(pSprite, pXSprite, nAngle);
  68. // if reached target, change to search mode
  69. if ( dist < M2X(1.0) && qabs(pSprite->ang - nAngle) < pDudeInfo->periphery )
  70. aiNewState(pSprite, pXSprite, &handSearch);
  71. aiThinkTarget(pSprite, pXSprite);
  72. }
  73. /****************************************************************************
  74. ** thinkChase()
  75. **
  76. **
  77. ****************************************************************************/
  78. static void thinkChase( SPRITE *pSprite, XSPRITE *pXSprite )
  79. {
  80. if ( pXSprite->target == -1)
  81. {
  82. aiNewState(pSprite, pXSprite, &handGoto);
  83. return;
  84. }
  85. int dx, dy, dist;
  86. dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
  87. DUDEINFO *pDudeInfo = &dudeInfo[pSprite->type - kDudeBase];
  88. dassert(pXSprite->target >= 0 && pXSprite->target < kMaxSprites);
  89. SPRITE *pTarget = &sprite[pXSprite->target];
  90. XSPRITE *pXTarget = &xsprite[pTarget->extra];
  91. // check target
  92. dx = pTarget->x - pSprite->x;
  93. dy = pTarget->y - pSprite->y;
  94. aiChooseDirection(pSprite, pXSprite, getangle(dx, dy));
  95. if ( pXTarget->health == 0 )
  96. {
  97. // target is dead
  98. aiNewState(pSprite, pXSprite, &handSearch);
  99. return;
  100. }
  101. if ( IsPlayerSprite( pTarget ) )
  102. {
  103. PLAYER *pPlayer = &gPlayer[ pTarget->type - kDudePlayer1 ];
  104. if ( powerupCheck( pPlayer, kItemLtdInvisibility - kItemBase ) > 0 )
  105. {
  106. aiNewState(pSprite, pXSprite, &handSearch);
  107. return;
  108. }
  109. }
  110. dist = qdist(dx, dy);
  111. if ( dist <= pDudeInfo->seeDist )
  112. {
  113. int nAngle = getangle(dx, dy);
  114. int losAngle = ((kAngle180 + nAngle - pSprite->ang) & kAngleMask) - kAngle180;
  115. int eyeAboveZ = pDudeInfo->eyeHeight * pSprite->yrepeat << 2;
  116. // is there a line of sight to the target?
  117. if ( cansee(pTarget->x, pTarget->y, pTarget->z, pTarget->sectnum,
  118. pSprite->x, pSprite->y, pSprite->z - eyeAboveZ, pSprite->sectnum) )
  119. {
  120. // is the target visible?
  121. if ( dist < pDudeInfo->seeDist && qabs(losAngle) <= pDudeInfo->periphery )
  122. {
  123. aiSetTarget(pXSprite, pXSprite->target);
  124. if ( dist < kHandJumpDist1 && dist > kHandJumpDist2 && qabs(losAngle) < kAngle15 )
  125. aiNewState(pSprite, pXSprite, &handJump);
  126. else if ( dist < kHandChokeDist && qabs(losAngle) < kAngle15 )
  127. aiNewState(pSprite, pXSprite, &handChoke);
  128. return;
  129. }
  130. }
  131. }
  132. dprintf("Hand %d lost sight of target %d\n", pXSprite->reference, pXSprite->target);
  133. aiNewState(pSprite, pXSprite, &handGoto);
  134. pXSprite->target = -1;
  135. }