Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local ServerScriptService = game:GetService("ServerScriptService")
- local ReplicatedStorage = game:GetService("ReplicatedStorage")
- local server = ServerScriptService.Server
- local serverModules = server.ServerModules
- local CharacterUtil = require(serverModules.CharacterUtil)
- local EnemyManager = require(serverModules.EnemyManager)
- local sharedModules = ReplicatedStorage.Shared.SharedModules
- local AliveCharacters = require(sharedModules.AliveCharacters)
- local EnemySwordClass = {}
- EnemySwordClass.__index = EnemySwordClass
- function EnemySwordClass.new(newInstance, zone, enemyInfo, spawnLocation)
- local self = setmetatable({
- instance = newInstance,
- humanoid = newInstance.Humanoid,
- walkAnim = nil,
- attackAnim = nil,
- rootPart = newInstance.PrimaryPart,
- sword = enemyInfo.sword:Clone(),
- zone = zone,
- players = zone.players,
- enemies = zone.enemies,
- parent = zone.enemyFolder,
- enemyInfo = enemyInfo,
- respawnTime = enemyInfo.respawnTime,
- health = enemyInfo.maxHealth,
- maxHealth = enemyInfo.maxHealth,
- damage = enemyInfo.damage,
- attackRange = enemyInfo.attackRange,
- moveSpeed = enemyInfo.moveSpeed,
- attackDuration = enemyInfo.attackDuration,
- aggroRange = enemyInfo.aggroRange,
- chaseRange = enemyInfo.chaseRange,
- attackers = {},
- spawnLocation = spawnLocation,
- target = nil,
- targetPrimary = nil,
- dead = false,
- retreating = false,
- attacking = false,
- active = true,
- }, EnemySwordClass)
- self:Spawn()
- return self
- end
- function EnemySwordClass:InChaseRange()
- return (self.rootPart.Position - self.spawnLocation.Position).magnitude < self.chaseRange
- end
- function EnemySwordClass:InAggroRange(position)
- return (self.rootPart.Position - position).magnitude < self.aggroRange
- end
- function EnemySwordClass:InAttackRange(position)
- return (self.rootPart.Position - position).magnitude <= self.attackRange
- end
- function EnemySwordClass:AttackTarget(humanoid, moveSpeed)
- local damage = self.damage
- local attackDuration = self.attackDuration
- local attackAnim = self.attackAnim
- humanoid.WalkSpeed = 0
- attackAnim:Play()
- attackAnim:AdjustSpeed(attackAnim.Length / attackDuration)
- wait(attackDuration)
- end
- function EnemySwordClass:ChaseTarget(players)
- local humanoid = self.humanoid
- local moveSpeed = self.moveSpeed
- local target = self.target
- local targetPrimary = self.targetPrimary
- local stationary = false
- while self.active and target and targetPrimary and players[target] and AliveCharacters[target] do
- local targetPrimaryPosition = targetPrimary.Position
- if not self:InChaseRange() then
- self:Retreat()
- break
- end
- if self:InAttackRange(targetPrimaryPosition) then
- stationary = true
- self:AttackTarget(humanoid, moveSpeed)
- else
- humanoid:MoveTo(targetPrimaryPosition)
- if stationary then stationary = false humanoid.WalkSpeed = moveSpeed end
- end
- target = self.target
- targetPrimary = self.targetPrimary
- wait()
- end
- self:Retreat()
- end
- function EnemySwordClass:SetTarget(target)
- local targetCharacter = AliveCharacters[target]
- if targetCharacter then
- self.target = target
- self.targetPrimary = targetCharacter.PrimaryPart
- else
- self.target = nil
- self.targetPrimary = nil
- end
- end
- function EnemySwordClass:LookForTarget(players)
- for playerName, _ in pairs(players) do
- local character = AliveCharacters[playerName]
- if character and self:InAggroRange(character.PrimaryPart.Position) then
- return playerName
- end
- end
- end
- function EnemySwordClass:LookForTargetLoop()
- local players = self.players
- spawn(function()
- while self.active and not self.dead and not self.retreating do
- local target = self:LookForTarget(players)
- if target then
- self:SetTarget(target)
- self:ChaseTarget(players)
- end
- wait(.1)
- end
- end)
- end
- function EnemySwordClass:Retreat()
- local humanoid = self.humanoid
- local moveSpeed = self.moveSpeed
- local maxHealth = self.maxHealth
- local connection
- self.retreating = true
- self:SetTarget(nil)
- connection = humanoid.MoveToFinished:Connect(function(reached)
- -- TODO do actions based on if moveto reached
- if not reached then
- CharacterUtil.TeleportToLocation(self.instance, self.spawnLocation.Position)
- -- teleports enemy if they get stuck on their way back to their spawn
- end
- self.health = maxHealth
- self.retreating = false
- self:LookForTargetLoop()
- connection:Disconnect()
- end)
- humanoid.WalkSpeed = moveSpeed
- humanoid:MoveTo(self.spawnLocation.Position)
- end
- function EnemySwordClass:TakeDamage(playerName, damage)
- local maxHealth = self.maxHealth
- local origHealth = self.health
- local newHealth = (origHealth - damage)
- if newHealth <= 0 then
- self:Die()
- else
- -- TODO set target
- self:SetTarget(playerName)
- self.health = newHealth
- end
- end
- function EnemySwordClass:Die()
- self.dead = true
- self:SetTarget(nil)
- EnemyManager:CreateEnemy(self.zone, self.enemyInfo, self.spawnLocation, self.respawnTime)
- self:Destroy()
- end
- function EnemySwordClass:EquipSword()
- local instance = self.instance
- local sword = self.sword
- sword.Parent = instance
- CharacterUtil.WeldWeaponToHand(instance, sword)
- end
- function EnemySwordClass:LoadAnimations()
- local humanoid = self.humanoid
- local walkAnim = Instance.new("Animation")
- walkAnim.AnimationId = "http://www.roblox.com/asset/?id=180426354"
- self.walkAnim = humanoid:LoadAnimation(walkAnim)
- local attackAnim = Instance.new("Animation")
- attackAnim.AnimationId = "http://www.roblox.com/asset/?id=4476665450"
- self.attackAnim = humanoid:LoadAnimation(attackAnim)
- end
- function EnemySwordClass:AnimationController()
- local humanoid = self.humanoid
- local walkAnim = self.walkAnim
- humanoid.Running:Connect(function(speed)
- if not walkAnim.IsPlaying and speed > 0 then
- walkAnim:Play()
- elseif walkAnim.IsPlaying and speed <= 0 then
- walkAnim:Stop()
- end
- wait()
- end)
- end
- function EnemySwordClass:Spawn()
- local instance = self.instance
- local humanoid = self.humanoid
- instance.Parent = self.parent
- CharacterUtil.TeleportToLocation(instance, self.spawnLocation.Position)
- self:EquipSword()
- self:LoadAnimations()
- self:AnimationController()
- self:LookForTargetLoop()
- end
- function EnemySwordClass:Destroy()
- local instance = self.instance
- self.active = false
- self.zone.enemies[instance] = nil
- instance:Destroy()
- end
- return EnemySwordClass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement