Advertisement
Guest User

Untitled

a guest
Dec 6th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.74 KB | None | 0 0
  1. local AIC = { };
  2.  
  3. -- ** Game Services ** --
  4. local ServerScriptService = game:GetService ("ServerScriptService");
  5. local CollectionService = game:GetService ("CollectionService");
  6.  
  7. -- ** Game Structure ** --
  8. local modules = ServerScriptService.Modules;
  9. local classes = modules.ParentClasses;
  10.  
  11. -- ** Dependencies ** --
  12. local EventSystem = require (classes.EventSystem);
  13.  
  14. local Character = require (script.Character);
  15. local Attacking = require (script.Attacking);
  16. local Movements = require (script.Movements);
  17.  
  18. local Characters = require (CollectionService:GetTagged (_G.GameTags.Characters) [1]).get();
  19.  
  20. -- ** Defaults ** --
  21. -- Once the player gets attacked, determines how long they'll check for
  22. -- the attacker
  23. local DAMAGE_SENSE_LENGTH = 5;
  24.  
  25. -- Default parent
  26. local DEF_PARENT = workspace;
  27.  
  28. -- ** Constructor ** --
  29. local AIControl = EventSystem.new ();
  30. function AIC.new (floorPlan, character, characterId, floorNum, settings)
  31. local aiControl = setmetatable ({
  32. _moduleName = "AIController",
  33.  
  34. _details = {
  35. floorPlan = floorPlan,
  36. character = character,
  37. characterId = characterId,
  38.  
  39. floorNum = floorNum
  40. },
  41.  
  42. _parent = settings.parent or DEF_PARENT,
  43.  
  44. _movementLogic = settings.movementLogic,
  45.  
  46. _character = nil,
  47. _movement = nil,
  48. _attacking = nil,
  49.  
  50. _characterObj = nil,
  51.  
  52. _isAttacking = false,
  53.  
  54. _removed = false,
  55.  
  56. Died = Instance.new ("BindableEvent")
  57. }, AIControl);
  58.  
  59. aiControl:_init ();
  60. return aiControl;
  61. end
  62.  
  63. -- ** Public Getters ** --
  64. function AIControl:getCharacter ()
  65. return self._characterObj;
  66. end
  67.  
  68. -- ** Public Methods ** --
  69. function AIControl:remove ()
  70. self._removed = true;
  71. self._character:remove ()
  72. self._attacking:stop();
  73. end
  74.  
  75. -- ** Private Methods ** --
  76. -- Initialization
  77. function AIControl:_init ()
  78. self:_initCharacter ();
  79. self:_initMovements ();
  80. self:_initAttacking ();
  81.  
  82. self:_move ();
  83. end
  84. function AIControl:_initCharacter ()
  85. local details = self._details;
  86.  
  87. local character = Character.new (details.floorPlan, details.character, details.characterId, self._parent);
  88. self._character = character;
  89.  
  90. self:_addHelper (character)
  91.  
  92. character:applyCharacterStats (details.characterId);
  93. character:spawn ();
  94.  
  95. -- event connections
  96. self:_connect (character.MoveToFinished.Event, self._characterFinishedMoving);
  97. self:_connect (character.Died.Event, self._characterDied);
  98. self:_connect (character.Damaged.Event, self._characterDamaged);
  99.  
  100. self._character = character;
  101. self._characterObj = character:getCharacter();
  102. end
  103. function AIControl:_initMovements ()
  104. local movements = Movements.new (self._details.floorPlan);
  105. self:_addHelper (movements);
  106.  
  107. self._movement = movements;
  108. end
  109. function AIControl:_initAttacking ()
  110. local characterStats = Characters:getById (self._details.characterId);
  111. local attackStats = characterStats.AttackStats;
  112.  
  113. self._attacking = Attacking.new(self._characterObj, attackStats);
  114. end
  115.  
  116. -- Adds the helper function
  117. function AIControl:_addHelper (object)
  118. local function getTarget (space, position)
  119. local char = self._character:getCharacter();
  120. local part = self._details.floorPlan:getPart (space);
  121. if (not position) then
  122. position = self._details.floorPlan:getSpacePosition (space);
  123. end
  124.  
  125. return self:getTarget (char, part, position);
  126. end
  127.  
  128. local function getPosition ()
  129. return self._character:getPosition();
  130. end
  131.  
  132. object.getTarget = getTarget;
  133. if (not object.getPosition) then
  134. object.getPosition = getPosition;
  135. end
  136. end
  137.  
  138. -- Character events
  139. function AIControl:_characterFinishedMoving ()
  140. self:_proceed ();
  141. end
  142. function AIControl:_characterDied ()
  143. self.Died:Fire();
  144. end
  145. function AIControl:_characterDamaged ()
  146. self._character.hasTakenDamage = true;
  147. wait (DAMAGE_SENSE_LENGTH);
  148. self._character.hasTakenDamage = false;
  149. end
  150.  
  151. -- Proceed - Determines the next course of action & proceeds
  152. function AIControl:_proceed ()
  153. local playerWithinRange, player = self:_hasPlayerWithinRange ();
  154.  
  155. if (playerWithinRange) then
  156. self:_attack (player);
  157. else
  158. self:_move ();
  159. end
  160.  
  161. self._isAttacking = playerWithinRange;
  162. end
  163.  
  164. -- Main movement function
  165. function AIControl:_move ()
  166. if (self._removed) then return end
  167.  
  168. if (not self._movement) then
  169. self:_warn ("Movement not found");
  170. return;
  171. end
  172.  
  173. -- Don't want to attack at this point
  174. self._attacking:stop ();
  175.  
  176. -- Find the next space to go after
  177. local space = self._character:getSpace();
  178. local nextPos, moveAction = self._movement:calculateNextMove (space);
  179. if (not nextPos and not moveAction) then
  180. self._character:reset();
  181. return
  182. end
  183.  
  184. if (moveAction == Enum.PathWaypointAction.Jump) then
  185. self._character:jump();
  186. self:_move()
  187. else
  188. self._character:moveTo (nextPos);
  189. end
  190. end
  191.  
  192. -- Main attack function
  193. function AIControl:_attack (player)
  194. self._target = player;
  195.  
  196. -- Start attacking
  197. if (not self._isAttacking) then
  198. self._attacking:startAttacking (player);
  199. end
  200.  
  201. -- Move towards the attack's target
  202. local targetPos = self._attacking:getTargetPos();
  203. self._character:moveTo (targetPos)
  204. end
  205.  
  206. function AIControl:_isAttackingPlayer (player)
  207. return self._isAttacking and self._target == player;
  208. end
  209.  
  210. -- Check if a player is within range of the AI
  211. function AIControl:_hasPlayerWithinRange ()
  212. for _,player in pairs(game.Players:GetPlayers()) do
  213. local isAttacking = self:_isAttackingPlayer (player);
  214. if (self._character:playerWithinRange (player, self._details.floorNum, isAttacking)) then
  215. return true, player;
  216. end
  217. end
  218. return false, nil;
  219. end
  220.  
  221. -- Helper function for smaller modules
  222. -- From a given space, find the target position
  223. function AIControl:getTarget (...)
  224. return self._movementLogic (...);
  225. end
  226.  
  227. AIControl.__index = AIControl;
  228. return AIC;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement