Skip to content

Instantly share code, notes, and snippets.

@Aerodos12
Created January 16, 2018 22:13
Show Gist options
  • Save Aerodos12/3544832da9f5e8ff53c938ffec88534c to your computer and use it in GitHub Desktop.
Save Aerodos12/3544832da9f5e8ff53c938ffec88534c to your computer and use it in GitHub Desktop.
Camos, KillService, Quest System, etc.
local Camo = {}
local RunService = game:GetService("RunService")
local RemoteService = require(game.ReplicatedStorage.RemoteService)
Camo.__index = Camo
local CamoTypeFuncs = {
["Material"] = function(camo)
return typeof(camo.Image) == "EnumItem" and camo.Image.EnumType == Enum.Material
end;
["Texture"] = function(camo)
return typeof(camo.Image) == "string" and camo.Image:find("rbxassetid://")
end;
}
function Camo.new(...)
local self = {}
local args = {...}
local title = args[1]
if typeof(title) ~= "string" or not title then return nil end
self.Title = title
local image = args[2]
if (typeof(image) ~= "string" and typeof(image) ~= "EnumItem") or not image then return nil end
self.Image = image
local slotParts = {}
for i = 3, #args do
if args[i] and typeof(args[i]) == "string" then
slotParts[#slotParts+1] = args[i]
end
end
self.Slots = slotParts
self.ButtonConnection = nil
self.ExtraData = {}
return setmetatable(self,Camo)
end
function Camo:AddData(key,value)
self.ExtraData[key] = value
end
function Camo:ToReplicatedCamo()
local camo = {}
camo.Title = self.Title
camo.Image = self.Image
camo.Slots = self.Slots
return camo
end
function Camo.FromReplicatedCamo(camo)
return Camo.new(camo.Title,camo.Image,unpack(camo.Slots))
end
function Camo:IsSlotPart(part)
local result = false
for _, slot in pairs(self.Slots) do
if slot == part.Name then
result = true
end
end
return result
end
function Camo:IsA(camoType)
return CamoTypeFuncs[camoType](self)
end
function Camo:Apply(gun)
if gun:IsA("Tool") and RunService:IsServer() then
if gun.Type.Value == "Blaster" then
if gun:FindFirstChild("CamoId") then
gun.CamoId.Value = self.Image
end
end
elseif gun:IsA("Model") then
if gun:FindFirstChild("Primary") then
for _, part in pairs(gun:GetChildren()) do
if part:IsA("BasePart") and self:IsSlotPart(part) then
if self:IsA("Texture") then
for _, texture in pairs(part:GetChildren()) do
if texture:IsA("Texture") then
texture.Texture = self.Image
end
end
elseif self:IsA("Material") then
part.Material = self.Image
if self.ExtraData["Color"] then
local camColor = self.ExtraData["Color"]
if typeof(camColor) == "BrickColor" then
part.BrickColor = self.ExtraData["Color"]
elseif typeof(camColor) == "Color3" then
part.Color = self.ExtraData["Color"]
end
end
end
end
end
end
elseif gun:IsA("Tool") and RunService:IsClient() then
RemoteService.send("Server","ChangeCamo",gun,self:ToReplicatedCamo())
end
end
function Camo:CreateButton(name,player,weaponImage,weapon)
local CamoButton = game.ReplicatedStorage.DeploymentUIs.CamoButton:Clone()
CamoButton.Name = name
CamoButton.CamoTitle.Text = self.Title:upper()
CamoButton.CamoPreview.Image = self.Image
self.ButtonConnection = CamoButton.UseButton.MouseButton1Click:connect(function()
print("Setting Camo...")
self:Apply(weaponImage)
self:Apply(weapon)
end)
return CamoButton
end
return Camo
local POW = math.pow
local RANDOM = math.random
local GetMod = require
local OBJ = Instance.new
local WS = workspace
local FLOOR = math.floor
local RepStore = game.ReplicatedStorage
local RPGM = GetMod(RepStore.RPGMathProvider)
local AvailableArmor = GetMod(WS.Settings.AvailableArmor)
local ForcePowers = require(game.Workspace.Settings.ForcePowers)
local ForceLib = GetMod(RepStore.ForceLib)
local SaveGame = GetMod(WS.Settings.SaveGame)
local ArmorSlots = require(game.ReplicatedStorage.ArmorSlots)
local MarketService = GetMod(game.ReplicatedStorage.MarketService)
local AnalyticsService = require(game.ReplicatedStorage.AnalyticsService)
local KillService = require(game.ServerScriptService.KillService)
local TSS = require(script.Parent.ToolStoreService)
local RSEED = math.randomseed
local TICK = tick
local V3 = Vector3.new
local CF = CFrame.new
local CSEQ = ColorSequence.new
local BC = BrickColor.new
local DSS = game:GetService("DataStoreService")
local DS = game:GetService('Debris')
local Types = {
["string"] = "StringValue",
["boolean"] = "BoolValue",
["number"] = "IntValue"
}
local LoadoutDefaults = {}
local CurrentSlot = {}
local CurrentXP = {}
local Settings = {}
local teams = game.Teams:GetTeams()
for _, characterClass in pairs(teams) do
LoadoutDefaults[characterClass.Name] = require(characterClass.LoadoutDefaults)
end
local EquipmentInventory = require(game.ReplicatedStorage.EquipmentInventory)
local SetttingsCache = require(game.ReplicatedStorage.SettingsCache)
local EquipmentCache = {}
local PlayerLoadouts = {}
local PlayerSquads = {}
local Slots = game.Workspace.Stages
local TutorialService = require(game.ReplicatedStorage.TutorialService)
local Soldier = require(game.ReplicatedStorage.Soldier)
local SquadClass = require(game.ReplicatedStorage.Squad)
local Squads = {}
RSEED(TICK())
local SaberfrontDB = require(game.ReplicatedStorage.SaberfrontDBService)
local DataManager = {
PData = DSS:GetDataStore(SaveGame.DSName),
SoldierData = SaberfrontDB:GetDatabase("Soldiers");
HighScores = DSS:GetOrderedDataStore("HighScores");
Settings = DSS:GetDataStore("UserSettings");
MarketplaceData = DSS:GetDataStore("MarketStats");
}
local UnitData = require(game.ReplicatedStorage.UnitPrices)
DataManager.ignoreModel = workspace.mobIgnore
local RemoteService = GetMod(game.ReplicatedStorage.RemoteService)
local BindableService = require(game.ReplicatedStorage.BindingService)()
function DataManager:UpgradePlayerByXP(Others,PerLevel,Caps,player, Starting, XP, level)
DataManager:SaveHighScore(player,"XP")
if XP.Value < 0 then
XP.Value = CurrentXP[player.UserId]
end
if XP.Value >= RPGM.EXP[Others.XPType:lower()](PerLevel,Others,level.Value) and level.Value < Caps.LevelCap then
XP.Value = XP.Value - RPGM.EXP[Others.XPType:lower()](PerLevel,Others,level.Value)
level.Value = level.Value + 1
player.attributes.APs.Value = player.attributes.APs.Value + FLOOR((level.Value / PerLevel.LevelsToGainPoints) * Others.PointGainIncrement)
end
end
local Fireworks = GetMod(WS.Settings.Fireworks)
function DataManager:Rocket(char)
local r = OBJ('Part')
r.Size = V3(0.2,0.2,0.2)
r.Position = (char.Head.CFrame + V3(0,2,0)).p
r.Parent = WS
r.CFrame = char.Head.CFrame + V3(0,2,0)
local speed = RANDOM(Fireworks.VelocityMin,Fireworks.VelocityMax)
r.Anchored = false
r.CanCollide = false
r.Transparency = 1
local BF = OBJ("BodyForce")
BF.force = V3(0, r:GetMass() * 196.2, 0)
BF.Parent = r
local trail = script:WaitForChild('Trail'):Clone()
trail.Parent = r
trail.Enabled = true
wait(0.03)
local spread = char.Head.Position + V3(RANDOM(-5,5),Fireworks.Height + RANDOM(-Fireworks.HeightSpread,Fireworks.HeightSpread),RANDOM(-5,5))
r.Velocity = (char.Head.Position - spread).unit * -speed
wait(RANDOM(Fireworks.DelayMin,Fireworks.DelayMax))
r.Anchored = true
trail:Destroy()
local explosion = Fireworks.Explosions[RANDOM(1,#Fireworks.Explosions)]:clone()
explosion.Parent = r
local scolor = Fireworks.StartColors[RANDOM(1,#Fireworks.StartColors)]
local ecolor = Fireworks.EndColors[RANDOM(1,#Fireworks.EndColors)]
explosion.Color = CSEQ(scolor,ecolor)
wait(0.03)
explosion:Emit(RANDOM(300,350))
DS:AddItem(r,explosion.Lifetime.Max)
end
function DataManager:TryTransaction(dataStoreFunction)
local tries = 0
local success = true
local err = nil
local data = nil
repeat
tries = tries + 1
success, err = pcall(function() data = dataStoreFunction() end)
if not success then print(err) wait(1) end
until tries == SaveGame.DataStoreRetries or success
if not success then
warn('Could not access DataStore! Warn players that their data might not get saved!')
end
return success, data
end
function DataManager:ConvertToCharacterAppearance(data,plr,chr,CAD)
chr["Body Colors"].HeadColor = BC(CAD.SkinColor.Value)
chr["Body Colors"].LeftArmColor = BC(CAD.SkinColor.Value)
chr["Body Colors"].RightArmColor = BC(CAD.SkinColor.Value)
chr["Body Colors"].LeftLegColor = BC(CAD.SkinColor.Value)
chr["Body Colors"].RightLegColor = BC(CAD.SkinColor.Value)
chr:WaitForChild("Shirt",600).ShirtTemplate = CAD.ShirtTemplate.Value
chr:WaitForChild("Hair").Handle.BrickColor = BC(CAD.HairColor.Value)
chr.Pants.PantsTemplate = CAD.PantsTemplate.Value
end
function DataManager:GetSquadReplicated(player)
local squad = {}
for _, squadMate in pairs(Squads[player.UserId]) do
squad[#squad+1] = squadMate:ToReplicatedSquadmate()
end
return squad
end
function DataManager:UpgradePlayerByLevel(player, XP, level)
if player.Character~=nil then
AnalyticsService.RecordLevelProgression(player,level.Value,XP.Value)
for i = 1,5 do
DataManager:Rocket(player.Character)
wait(Fireworks.ShotCooldown)
end
end
end
function DataManager:GetSaveGame(player,pvp)
local BService = require(game.ReplicatedStorage.BindingService)()
local save = {
Lvl = player.leaderstats.Lvl.Value,
XP = player.leaderstats.XP.Value,
Credits = player.leaderstats.Credits.Value,
CharacterName = player.CharacterName.Value,
PVPScore = pvp.Value,
InPvP = player.Stats.InPvP.Value,
Team = player.Team.Name,
Attributes = {
Strength = player.attributes.Strength.Value,
Constitution = player.attributes.Constitution.Value,
Intelligence = player.attributes.Intelligence.Value,
Dexterity = player.attributes.Dexterity.Value
};
KDR = {
Kills = KillService.TotalKills[player.UserId];
};
AttributePoints = player.attributes.APs.Value;
AlreadyCustomized = player.AlreadyCustomized.Value;
ForceColor = player.ForceColor.Value.Name
}
save.Achievements = BService.fetch("GetCompletedAchievements",player)
save.Traits = BService.fetch("GetAcquiredTraits",player);
save.i8Mode = player.i8Mode.Value
save.DeploymentMode = player.DeploymentMode.Value
save.EquippedArmor = {
hasArmorOn = EquipmentCache[player.UserId].On;
ArmorType = EquipmentCache[player.UserId].Type;
CurrentPlacement = EquipmentCache[player.UserId].CurrentPlacement;
};
save.Loadout = PlayerLoadouts[player.UserId]
save.Squad = DataManager:GetSquadReplicated(player)
save.Armor = {}
for _,ArmorSelection in pairs(AvailableArmor) do
save.Armor['Unlocked'..ArmorSelection] = player.UnlockedArmor:FindFirstChild('Unlocked'..ArmorSelection).Value
end
save.CA = {
HairColor = player.CharacterAppearanceData.HairColor.Value,
SkinColor = player.CharacterAppearanceData.SkinColor.Value,
PantsTemplate = player.CharacterAppearanceData.PantsTemplate.Value,
ShirtTemplate = player.CharacterAppearanceData.ShirtTemplate.Value,
}
return save
end
function DataManager:NumPlayersUnCustomized()
local num = 0
for _, player in pairs(game.Players:GetPlayers()) do
if player:FindFirstChild("AlreadyCustomized") then
if not player.AlreadyCustomized.Value then
num = num + 1
end
end
end
return num
end
function DataManager:saveScores(player,pvp)
local Starting = require(game.Workspace.Settings.Starting)
local success = DataManager:TryTransaction(function()
local save = DataManager:GetSaveGame(player,pvp)
local saveGame, marketData = DataManager:GetSavedData(player,Starting)
local saved, err
if DataManager.PData:GetAsync(player.Name .. "-id") then
saved, err = pcall(function()
DataManager.PData:UpdateAsync(player.Name.."-id",function(oldData)
return save
end)
end)
else
saved, err = pcall(function()
DataManager.PData:SetAsync(player.Name.."-id",save)
end)
end
if not err then
return true
else
print(err)
return false
end
end)
if success then
print("Data saved for ".. player.Name .. " successfully.")
end
return success
end
function DataManager:LoadDeploymentMode(player)
local result = "Ground"
local data = DataManager.PData:GetAsync(player.Name.."-id")
if data then
result = data.DeploymentMode
end
return result
end
function DataManager:GetSavedInventoryMode(player)
local result = "Loadout"
local data = DataManager.PData:GetAsync(player.Name.."-id")
if data then
result = data.i8Mode
end
return result
end
function DataManager:UpdateCredits(plr,amount)
RemoteService.send("Client",plr,"UpdateCurrency",amount)
end
game.Players.PlayerAdded:connect(function(plr)
if game.Players.NumPlayers == 1 then
RemoteService = GetMod(game.ReplicatedStorage.RemoteService)
RemoteService.listen("Server","Send","UnlockArmor",function(plr,armorName)
if not plr.UnlockedArmor:FindFirstChild("Unlocked"..armorName).Value then
plr.UnlockedArmor:FindFirstChild("Unlocked"..armorName).Value = true
end
end)
end
end)
function DataManager:GetFirstMarketplaceData()
return {
LastLoginReward = 0;
}
end
function DataManager:GetStarterSettings()
local settings = {
}
return settings
end
function DataManager:GrantDailyReward(player)
local success = DataManager:TryTransaction(function()
MarketService:CheckDailyLogin(player,DataManager.MarketplaceData)
end)
return success
end
function DataManager:GetSavedAchievements(player)
local data = DataManager.PData:GetAsync(player.Name .. "-id")
local result = {}
if data then
result = data.Achievements
end
return result
end
function DataManager:GetSavedTraits(player)
local result = {}
local data = DataManager.PData:GetAsync(player.Name .. "=id")
if data then
result = data.Traits
end
return result
end
function DataManager:GetLoadoutDefault(player,slot)
return LoadoutDefaults[player.Team.Name][slot]
end
function DataManager:GetFirstLoadSaveGame(Starting)
local save = {
Lvl = 1,
XP = 0,
Credits = Starting.StartingCurrency,
Attributes = {
Strength = Starting.StartingAttributes,
Intelligence = Starting.StartingAttributes,
Dexterity = Starting.StartingAttributes,
Constitution = Starting.StartingAttributes,
Charisma = Starting.StartingAttributes,
},
AttributePoints = RPGM:GetStartingAttributePoints(1),
PVPScore = 0,
InPvP = false,
Team = "Jedi",
CA = {
HairColor = "Really red",
SkinColor = "Really blue",
PantsTemplate = "rbxassetid://318333315",
ShirtTemplate = "rbxassetid://318333010"
},
CharacterName = "Null",
Armor = {};
AlreadyCustomized = false;
ForceColor = nil;
KDR = {
Kills = 0;
};
Squad = {
};
i8Mode = "Loadout";
Achievements = {
};
Loadout = {
Name = "Main";
};
Traits = {
};
DeploymentMode = "Ground";
}
save.EquippedArmor = {
hasArmorOn = false;
ArmorType = "None";
CurrentPlacement = "None";
}
save.Camos = {
}
for _,Armor in pairs(AvailableArmor) do
save.Armor["Unlocked"..Armor] = false
end
for name,value in pairs(LoadoutDefaults["Jedi"]) do
save.Loadout[name] = value
end
return save
end
function DataManager:GetRandomForceColor(player)
local TeamName = player.Team.Name
local SaberColors = require(game.Teams:FindFirstChild(TeamName).SaberColors)
local SaberColor = SaberColors[RANDOM(1,#SaberColors)]
return SaberColor
end
function DataManager:SetLoadoutForSaving(player,Loadout)
PlayerLoadouts[player.UserId] = Loadout
end
function DataManager:CreateMainStats(player,score1,PVP)
local stats = OBJ("Model")
stats.Name = "leaderstats"
stats.Parent = player
local clicks = OBJ("IntValue")
clicks.Name = "Lvl"
clicks.Value = score1.Lvl
clicks.Parent = stats
local clicks2 = OBJ("IntValue")
clicks2.Name = "XP"
clicks2.Value = score1.XP
clicks2.Parent = stats
CurrentXP[player.UserId] = clicks2.Value
local clicks3 = OBJ("IntValue")
clicks3.Name = "Credits"
clicks3.Value = score1.Credits
clicks3.Parent = stats
if PVP.HasPvP == true then
local clicksPvP = Instance.new("IntValue")
clicksPvP.Name = "PVPRank"
clicksPvP.Value = score1.PVPScore or 0
clicksPvP.Parent = stats
end
return stats
end
function DataManager:CreateAttributes(player,score1,level)
local attrb = OBJ("Model")
attrb.Name = "attributes"
attrb.Parent = player
local attrb1 = OBJ("IntValue")
attrb1.Name = "Strength"
attrb1.Value = score1.Attributes.Strength
attrb1.Parent = attrb
local attrb2 = OBJ("IntValue")
attrb2.Name = "Constitution"
attrb2.Value = score1.Attributes.Constitution
attrb2.Parent = attrb
local attrb3 = OBJ("IntValue")
attrb3.Name = "Intelligence"
attrb3.Value = score1.Attributes.Intelligence
attrb3.Parent = attrb
local attrb4 = OBJ("IntValue")
attrb4.Name = "Dexterity"
attrb4.Value = score1.Attributes.Dexterity
attrb4.Parent = attrb
local attrb6 = OBJ("IntValue")
attrb6.Name = "Charisma"
attrb6.Value = score1.Attributes.Charisma
attrb6.Parent = attrb
local attrb5 = OBJ("IntValue")
attrb5.Name = "APs"
attrb5.Value = score1.AttributePoints
attrb5.Parent = attrb
return attrb
end
function DataManager:CreateSecondaryStats(player,score1,level,Intelligence)
local misc = OBJ("Model")
misc.Name = "Stats"
misc.Parent = player
local inPvP = OBJ("BoolValue")
inPvP.Name = "InPvP"
inPvP.Value = score1.InPvP or false
inPvP.Parent = misc
local mana = OBJ("IntValue")
mana.Name = "Mana"
mana.Value = 100
mana.Parent = misc
local maxmana = OBJ("IntValue")
maxmana.Name = "MaxMana"
maxmana.Value = RPGM.Mana(level,Intelligence)
maxmana.Parent = misc
local class2 = OBJ("StringValue")
class2.Name = "FactionClass"
class2.Value = score1.Team
class2.Parent = misc
local maxstamina = OBJ("IntValue")
maxstamina.Name = "MaxStamina"
maxstamina.Value = RPGM.MaxStamina(player)
maxstamina.Parent = misc
local stamina = OBJ("IntValue")
stamina.Name = "Stamina"
stamina.Value = maxstamina.Value
stamina.Parent = misc
local defense = OBJ("IntValue")
defense.Name = "Defense"
defense.Value = 0
defense.Parent = misc
return misc
end
function DataManager:GetSettings(player)
local result = DataManager:GetStarterSettings()
local data = DataManager.Settings:GetAsync(player.UserId)
if data then
result = data
end
return result
end
function DataManager:CreateSoldierStats(player,SoldierObj)
local UnitAttrs = UnitData[player.Allegiance.Value][SoldierObj.Type].Attributes
Squads[player.UserId][#Squads[player.UserId]+1] = Soldier.new(SoldierObj.Type,SoldierObj.Helmet,SoldierObj.Weapon,UnitAttrs.Dexterity,UnitAttrs.Strength,UnitAttrs.Intelligence,UnitAttrs.Constitution,UnitAttrs.Charisma)
return Squads[player.UserId][#Squads[player.UserId]]
end
function DataManager:SaveHighScore(player,scoreType)
local score
if scoreType == "XP" then
score = RPGM.TotalXP(player.leaderstats.XP.Value,player.leaderstats.Lvl.Value)
elseif scoreType == "SquadPoints" then
score = 0
elseif scoreType == "Credits" then
score = player.leaderstats.Credits.Value
end
local scoreTbl = {}
scoreTbl[scoreType] = score
DataManager.HighScores:SetAsync(player.UserId .. "-" ..scoreType,scoreTbl[scoreType])
end
function DataManager:LoadHighScores(scoreType,threshold)
local pages = DataManager.HighScores:GetSortedAsync(false,threshold)
local names = {}
local scores = {}
local page = pages:GetCurrentPage()
for k, v in pairs(page) do
if string.match(v.key,"%a+") == scoreType then
names[k] = game.Players:GetNameFromUserIdAsync(tonumber(string.match(v.key,"%d+")))
scores[k] = v.Value
end
end
return names, scores
end
function DataManager:CreateArmorData(player,score1)
local armor = OBJ("Folder")
armor.Name = "UnlockedArmor"
armor.Parent = player
for armorName,armorValue in pairs(score1.Armor) do
if armorName:find("Unlocked") then
local armorTag = OBJ("BoolValue")
armorTag.Name = armorName
armorTag.Value = armorValue
armorTag.Parent = armor
end
end
return armor
end
function DataManager:CreateEquipmentData(player,score1)
local equippedArmor = EquipmentInventory.new(
score1.EquippedArmor.hasArmorOn,
score1.EquippedArmor.ArmorType,
score1.EquippedArmor.CurrentPlacement,
ArmorSlots
);
return equippedArmor
end
function DataManager:UnloadKDR(player)
player.MissionStats.TotalKills.Value = player.MissionStats.TotalKills.Value + player.MissionStats.Kills.Value
player.MissionStats.Kills.Value = 0
end
function DataManager:GetSavedData(player,Starting)
local data = DataManager:GetFirstLoadSaveGame(Starting)
local data2 = DataManager:GetFirstMarketplaceData()
if game:GetService("RunService"):IsStudio() then return data, data2 end
local success, tempData = DataManager:TryTransaction(function()
return DataManager.PData:GetAsync(player.Name.."-id")
end)
local success2, tempData2 = DataManager:TryTransaction(function()
return DataManager.MarketplaceData:GetAsync(player.UserId)
end)
if tempData then
data = tempData
end
if tempData2 then
data2 = tempData2
end
return data, data2
end
function DataManager:ResetForcePowers(player)
ForceLib:ResetForcePowers(player)
local ForceIndex = ForceLib:LoadForceTable(player) or {}
print(ForceIndex)
local StartingOut = false
if #ForceIndex == 0 then
StartingOut = true
for name, power in pairs(ForcePowers) do
local forcePowerObj = {}
if power then
forcePowerObj.Name = ((power.Label) and name or ("Force" .. name))
forcePowerObj.FriendlyName = ((power.Label) and power.Label or ("Force " .. name))
forcePowerObj.ManaCost = power.ManaCost
forcePowerObj.hasPower = power.defaultPower
forcePowerObj.Level = 1;
end
if forcePowerObj ~= {} then
ForceLib.SavePower(player,ForceLib.CreatePowerData(forcePowerObj),ForceIndex)
end
end
ForceLib:SaveForceData(player,ForceIndex)
end
end
function DataManager:LoadForceStats(player,score1,powersCache)
local ForceIndex = ForceLib:LoadForceTable(player) or {}
print(ForceIndex)
local StartingOut = false
if #ForceIndex == 0 then
StartingOut = true
for name, power in pairs(ForcePowers) do
local forcePowerObj = {}
if power then
forcePowerObj.Name = ((power.Label) and name or ("Force" .. name))
forcePowerObj.FriendlyName = ((power.Label) and power.Label or ("Force " .. name))
forcePowerObj.ManaCost = power.ManaCost
forcePowerObj.hasPower = power.defaultPower
forcePowerObj.Level = 1;
end
if forcePowerObj ~= {} then
ForceLib.SavePower(player,ForceLib.CreatePowerData(forcePowerObj),ForceIndex)
end
end
ForceLib:SaveForceData(player,ForceIndex)
end
powersCache[player.UserId] = {}
for i = 1,#ForceIndex do
local power = ForceLib:DecodePower(player,ForceIndex[i])
powersCache[player.UserId][power.Name] = power
end
local ForceColor = OBJ("BrickColorValue")
ForceColor.Name = "ForceColor"
ForceColor.Value = score1.ForceColor ~= nil and BC(score1.ForceColor) or DataManager:GetRandomForceColor(player)
ForceColor.Parent = player
return {
["Color"] = ForceColor;
}
end
function DataManager:LoadSquad(player)
local data = DataManager.PData:GetAsync(player.Name .. "-id")
if data then
for _, squadmate in pairs(data.Squad) do
Squads[player.UserId][#Squads[player.UserId] + 1] = Soldier.FromReplicatedSquadmate(squadmate)
end
end
end
function DataManager:ResetPlayer(player,Starting)
local data = DataManager:GetFirstLoadSaveGame(Starting)
local success, err = DataManager:TryTransaction(function()
DataManager.PData:UpdateAsync(player.Name.."-id",function(oldData)
return data
end)
end)
end
DataManager.LZSpawns = {
["Good"] = {
CF(316.01, -134.287, -405.26);
CF(-574.19, -124.178, -1048.49);
CF(1439.136, -99.242, -1086.094);
};
["Evil"] = {
CF(-1333.774, -118.057, -1265.183);
CF(-437.484, -118.057, -916.193);
CF(988.376, 40.568, -1299.074);
CF(988.376, 40.568, -1131.734);
}
}
function DataManager:LoadClassData(player,score1)
player.Team = game.Teams:FindFirstChild(score1.Team) or game.Teams["Jedi"]
local Allegiance = OBJ("StringValue")
Allegiance.Name = "Allegiance"
Allegiance.Value = ((player.Team.Name == "Bounty Hunters" or player.Team.Name == "Imperials") and "Evil" or "Good")
Allegiance.Parent = player
player.Changed:connect(function(prop)
if prop == "Team" then
Allegiance.Value = ((player.Team.Name == "Bounty Hunters" or player.Team.Name == "Imperials") and "Evil" or "Good")
end
end)
return Allegiance
end
function DataManager:GetSavedLoadout(player)
local result = LoadoutDefaults[player.Team.Name]
local data = DataManager.PData:GetAsync(player.Name .. "-id")
if data then
result = data.Loadout
end
return result
end
function DataManager:GetSlot(index)
return Slots:FindFirstChild("Stage"..index)
end
function DataManager:GetClassLoadout(class)
local ld = LoadoutDefaults[class]
if ld then
ld.Name = "Main"
end
return ld
end
function DataManager:HasNoTroops(playerArmy)
local result = false
local count = 0
for _, soldier in pairs(playerArmy:GetChildren()) do
if soldier:FindFirstChild("Human") then
count = count + 1
end
end
return count <= 0
end
function DataManager:loadScores(player,Starting,Others,AttributeEffect,PerLevel,Caps,PVP,powersCache)
local score1,score3 = DataManager:GetSavedData(player,Starting)
Settings[player.UserId] = SetttingsCache.new(DataManager:GetSettings(player))
local AlreadyCustomized = OBJ("BoolValue")
AlreadyCustomized.Name = "AlreadyCustomized"
AlreadyCustomized.Value = score1.AlreadyCustomized
AlreadyCustomized.Parent = player
Squads[player.UserId] = {}
PlayerLoadouts[player.UserId] = {}
local Allegiance = DataManager:LoadClassData(player,score1)
local stats = DataManager:CreateMainStats(player,score1,PVP)
local attrb = DataManager:CreateAttributes(player,score1,stats.Lvl)
local secStats = DataManager:CreateSecondaryStats(player,score1,stats.Lvl,attrb.Intelligence)
local armor = DataManager:CreateArmorData(player,score1)
local equippedArmor = DataManager:CreateEquipmentData(player,score1)
EquipmentCache[player.UserId] = equippedArmor
local ForceData = DataManager:LoadForceStats(player,score1,powersCache)
player:WaitForChild("Inventory",200).ChildAdded:connect(function(item)
if item:IsA("Tool") then
if not item:FindFirstChild("ID") then
local Id = TSS:MakeID(item)
end
end
end)
DataManager:LoadSquad(player)
local CurrentTutorialMatch = Instance.new("StringValue")
CurrentTutorialMatch.Name = "CurrentTutorialMatch"
CurrentTutorialMatch.Value = ""
CurrentTutorialMatch.Parent = player
local cn = OBJ("StringValue")
cn.Name = "CharacterName"
cn.Value = score1.CharacterName
cn.Parent = player
DataManager:GrantDailyReward(player)
local Slot = OBJ("ObjectValue")
Slot.Name = "CustomizationSlot"
Slot.Parent = player
if not AlreadyCustomized.Value then
Slot.Value = DataManager:GetSlot(DataManager:NumPlayersUnCustomized())
end
local MissionStats = OBJ("Folder")
MissionStats.Name = "MissionStats"
MissionStats.Parent = player
local Kills = OBJ("IntValue")
Kills.Name = "Kills"
Kills.Value = 0
Kills.Parent = MissionStats
local TKills = OBJ("IntValue")
TKills.Name = "TotalKills"
TKills.Value = 0
TKills.Parent = MissionStats
local playerArmy = nil
local CAD = OBJ("Folder",player)
CAD.Name = "CharacterAppearanceData"
local HairColor = OBJ("StringValue",CAD)
HairColor.Name = "HairColor"
HairColor.Value = score1.CA.HairColor
local SkinColor = OBJ("StringValue",CAD)
SkinColor.Name = "SkinColor"
SkinColor.Value = score1.CA.SkinColor
local ShirtTemplate = OBJ("StringValue",CAD)
ShirtTemplate.Name = "ShirtTemplate"
ShirtTemplate.Value = score1.CA.ShirtTemplate
local PantsTemplate = OBJ("StringValue",CAD)
PantsTemplate.Name = "PantsTemplate"
PantsTemplate.Value = score1.CA.PantsTemplate
PlayerSquads[player.UserId] = SquadClass.new(player,{})
local playerArmy = PlayerSquads[player.UserId]:GetContainer()
local playerArmyBackpackRoot = Instance.new("Folder")
playerArmyBackpackRoot.Name = playerArmy.Name .."_BackpackRoot"
playerArmyBackpackRoot.Parent = game.ReplicatedStorage.MobBackpack
local pABRT = playerArmy:FindFirstChild("playerArmyBackpackRoot") or Instance.new("ObjectValue")
pABRT.Name = "playerArmyBackpackRoot"
pABRT.Value = playerArmyBackpackRoot
pABRT.Parent = playerArmy
local MSpeaker = playerArmy:FindFirstChild("MobSpeaker") or script.MobSpeaker:Clone()
MSpeaker.Parent = playerArmy
local pAT = player:FindFirstChild("playerArmy") or Instance.new("ObjectValue")
pAT.Name = "playerArmy"
pAT.Value = playerArmy
pAT.Parent = player
local SoldierTransferPoint
SoldierTransferPoint = player:FindFirstChild("Soldier_"..player.Name) or Instance.new("Folder")
SoldierTransferPoint.Name = "Soldier_"..player.Name
SoldierTransferPoint.Parent = player
stats.XP.Changed:connect(function() DataManager:UpgradePlayerByXP(Others,PerLevel,Caps,player,Starting, stats.XP, stats.Lvl) end)
stats.Lvl.Changed:connect(function(value) DataManager:UpgradePlayerByLevel(player, stats.XP, stats.Lvl) end)
stats.Credits.Changed:connect(function(value)
DataManager:UpdateCredits(player,value)
end)
player.CharacterAdded:connect(function(c)
spawn(function()
for _, soldier in pairs(playerArmy:GetChildren()) do
if soldier:FindFirstChild("Human") or soldier.Name == "SpawnCraft" then
soldier:Destroy()
end
end
if DataManager:HasNoTroops(playerArmy) then
local ArmyReady = false
if player.DeploymentMode.Value == "Transport" then
local SpawnCraft = game.ReplicatedStorage.AirSupport:FindFirstChild(player.Allegiance.Value).SpawnCraft:Clone()
local CraftSpawns = workspace.AirSpawns:GetChildren()
local CS = CraftSpawns[RANDOM(1,#CraftSpawns)]
SpawnCraft:SetPrimaryPartCFrame(CS.CFrame + Vector3.new(0,SpawnCraft.PrimaryPart.Size.Y,0))
SpawnCraft.PrimaryPart.Owner.Value = player
local spawns = DataManager.LZSpawns[player.Allegiance.Value]
local LZSpawn = spawns[RANDOM(1,#spawns)]
-- if LZSpawn.Parent.TutorialTag.Value then
-- if (TutorialService.IsInNeedOfATutorial(player,LZSpawn.Parent.TutorialTag.Value)) then
-- local TutorialTag = TutorialService.MakeTutorialTag(player,LZSpawn.Parent.TutorialTag.Value)
-- end
-- end
SpawnCraft:SetPrimaryPartCFrame(CF(SpawnCraft.PrimaryPart.Position,SpawnCraft.PrimaryPart.Position + ((CS.FacePart.CFrame.p - SpawnCraft.PrimaryPart.Position).unit * V3(1,0,1))) * CFrame.Angles(0,math.rad(180),0))
local Spawns = SpawnCraft.Bodykit.TroopPlacement:GetChildren()
SpawnCraft.Parent = playerArmy
SpawnCraft.PrimaryPart.Anchored = true
ArmyReady = true
for i = 1,#Squads[player.UserId] do
spawn(function()
local Soldier = game.ReplicatedStorage.SquadUnitStorage:FindFirstChild(player.Allegiance.Value).Soldier:Clone()
Soldier.Leader.Value = player
Soldier.UnitName.Value = "Unit "..i
local IDVal = Instance.new("IntValue")
IDVal.Name = "ID"
IDVal.Value = i
IDVal.Parent = Soldier
Soldier.Pants.PantsTemplate = UnitData[player.Allegiance.Value][Squads[player.UserId][i].Type].Clothes.Pants
Soldier.Shirt.ShirtTemplate = UnitData[player.Allegiance.Value][Squads[player.UserId][i].Type].Clothes.Shirt
local UnitBackpack = script.SoldierPack:Clone()
UnitBackpack.Name = "Unit"..i.."Backpack"
UnitBackpack.Parent = pABRT.Value
Soldier.Backpack.Value = UnitBackpack
PlayerSquads[player.UserId]:AddMember(Soldier)
Soldier.Parent = playerArmy
local si = i
local spawnPart = Spawns[si].SkateboardPlatform
repeat
Soldier.Torso.CFrame = spawnPart.CFrame + Vector3.new(0,2,0)
wait()
until Soldier.Human.PlatformStand
end)
wait(0.2)
end
repeat wait() until SpawnCraft.Welded.Value
repeat
local si = #Squads[player.UserId] + 1
local spawnPart = Spawns[si].SkateboardPlatform
c.Torso.CFrame = spawnPart.CFrame + Vector3.new(0,1,0) game:GetService("RunService").Heartbeat:wait()
until c.Humanoid.PlatformStand
local TController = require(SpawnCraft.TransportController)
TController:EnableAutoPilot()
TController:StartEngine(false)
spawn(function()
SpawnCraft.PrimaryPart.Anchored = false
c.LZCam.InUse.Value = true
TController:TravelWithAutoPilot(LZSpawn.p,function()
BindableService.send("EquipLoadout",player)
PlayerSquads[player.UserId]:ListenServer()
PlayerSquads[player.UserId]:Listen()
TController:ReleasePassengers()
wait(10)
TController:Takeoff(true)
TController = nil
end)
end)
else
local spawns = workspace.SquadSpawns:GetChildren()
local spawnPos = spawns[RANDOM(#spawns)]
local SpawnCF = spawnPos.CFrame
c.Torso.CFrame = SpawnCF + V3(0,3,0)
for i = 1,#Squads[player.UserId] do
spawn(function()
local Soldier = game.ReplicatedStorage.SquadUnitStorage:FindFirstChild(player.Allegiance.Value).Soldier:Clone()
Soldier.Leader.Value = player
Soldier.UnitName.Value = "Unit "..i
local IDVal = Instance.new("IntValue")
IDVal.Name = "ID"
IDVal.Value = i
IDVal.Parent = Soldier
Soldier.Pants.PantsTemplate = UnitData[player.Allegiance.Value][Squads[player.UserId][i].Type].Clothes.Pants
Soldier.Shirt.ShirtTemplate = UnitData[player.Allegiance.Value][Squads[player.UserId][i].Type].Clothes.Shirt
local UnitBackpack = script.SoldierPack:Clone()
UnitBackpack.Name = "Unit"..i.."Backpack"
UnitBackpack.Parent = pABRT.Value
Soldier.Backpack.Value = UnitBackpack
PlayerSquads[player.UserId]:AddMember(Soldier)
Soldier.Parent = playerArmy
Soldier.Torso.CFrame =c.Torso.CFrame + V3(0,0,-IDVal.Value)
end)
wait(0.2)
end
BindableService.send("EquipLoadout",player)
PlayerSquads[player.UserId]:Listen()
PlayerSquads[player.UserId]:ListenServer()
end
end
end)
DataManager:ConvertToCharacterAppearance(score1.CA,player,c,CAD)
DataManager:UpdateCredits(player,stats.Credits.Value)
if Starting.DefenseMode == 3 then
if secStats:FindFirstChild("Defense") then
c.Humanoid.MaxHealth = RPGM.MaxHPWithDefense(stats.Lvl,attrb.Constitution,secStats.Defense)
else
c.Humanoid.MaxHealth = RPGM.MaxHP(player.leaderstats.Lvl,player.attributes.Constitution)
end
else
c.Humanoid.MaxHealth = RPGM.MaxHP(player.leaderstats.Lvl,player.attributes.Constitution)
end
secStats.MaxMana.Value = RPGM.Mana(stats.Lvl,attrb.Intelligence)
c.Humanoid.Health = c.Humanoid.MaxHealth
secStats.Mana.Value = secStats.MaxMana.Value
secStats.MaxStamina.Value = RPGM.MaxStamina(player)
secStats.Stamina.Value = secStats.MaxStamina.Value
c:WaitForChild("Health",200):Destroy()
end)
end
RemoteService.listen("Server","Fetch","CreateSoldier",function(player,SoldierObj)
return DataManager:CreateSoldierStats(player,SoldierObj)
end)
RemoteService.listen("Server","Send","EraseSoldierStats",function(player)
Squads[player.UserId] = {}
end)
function DataManager:UpdateCurrentEquipmentPlacement(player,placement,value)
EquipmentCache[player.UserId].Placement[placement].Armor = value
end
function DataManager:ToggleCurrentEpuipmentPlacement(player,placement,on)
EquipmentCache[player.UserId].Placement[placement].On = on
end
function DataManager:SetCurrentPlacement(player,value)
EquipmentCache[player.UserId].CurrentPlacement = value
end
function DataManager:GetArmorWithPlacement(player,placement)
return EquipmentCache[player.UserId][placement].Armor
end
function DataManager:GetCurrentPlacement(player)
return EquipmentCache[player.UserId].CurrentPlacement
end
function DataManager:IsEquipmentReady(player)
return EquipmentCache[player.UserId]
end
function DataManager:GetSquadWeapon(player,id)
return Squads[player.UserId][id]:GetWeapon()
end
function DataManager:GetSquadHelmet(player,id)
return Squads[player.UserId][id].Helmet
end
function DataManager:GetSquadAttributes(player,id)
return Squads[player.UserId][id].Attributes
end
function DataManager:CreateHBar(player,id,squadMember)
Squads[player.UserId][id]:CreateHealthBar(squadMember)
end
function DataManager:UpdateAttributes(player,id,attr,amt)
Squads[player.UserId][id]:IncreaseAttributes(attr,amt)
end
RemoteService.listen("Server","Send","SetCEPlacment",function(player,placement,value)
DataManager:UpdateCurrentEquipmentPlacement(player,placement,value)
end)
RemoteService.listen("Server","Send","SetCEPlacmentOn",function(player,placement,on)
DataManager:ToggleCurrentEpuipmentPlacement(player,placement,on)
end)
RemoteService.listen("Server","Fetch","GetPlayerArmyLocation",function(player)
return PlayerSquads[player.UserId]:GetContainer()
end)
return DataManager
local KillService = {}
local QuestService = require(script.Parent.QuestService)
KillService.Kills = {}
KillService.AllKills = {}
KillService.TotalKills = {}
KillService.WaveKills = {}
local RemoteService = require(game.ReplicatedStorage.RemoteService)
local BindingService = require(game.ReplicatedStorage.BindingService)()
local SignalAPI = require(game.ReplicatedStorage.SignalAPI)
KillService.KillAdded = SignalAPI.Create()
KillService.StreakTypes = {
[2] = {
Name = "2kill";
};
[3] = {
Name = "3kill";
};
[4] = {
Name = "4kill";
};
[5] = {
Name = "5kill";
};
[6] = {
Name = "6kill";
}
}
KillService.Achievements = {
{
Kills = 5;
ID = 4;
};
{
Kills = 10;
ID = 5;
};
{
Kills = 25;
ID = 6;
};
{
Kills = 50;
ID = 7;
};
{
Kills = 100;
ID = 8;
};
{
Kills = 250;
ID = 9;
};
{
Kills = 500;
ID = 10;
};
{
Kills = 750;
ID = 11;
};
{
Kills = 1000;
ID = 12;
};
{
Kills = 1250;
ID = 13;
};
{
Kills = 1500;
ID = 14;
};
{
Kills = 2000;
ID = 15;
}
}
KillService.Kill = require(script.Kill)
function KillService:RegisterPlayer(plr,count)
KillService.Kills[plr.UserId] = {}
KillService.AllKills[plr.UserId] = {}
KillService.TotalKills[plr.UserId] = count or 0
KillService.WaveKills[plr.UserId] = 0
plr:WaitForChild("leaderstats",200)
KillService.AllKills[plr.UserId][plr.leaderstats.Lvl.Value] = {}
spawn(function()
plr.leaderstats.Lvl.Changed:connect(function(level)
KillService.AllKills[plr.UserId][level] = {}
end)
end)
end
function KillService:AddKill(...)
local args = {...}
local kill = KillService.Kill.new(...)
KillService.KillAdded:fire(args[2],kill)
script.KillAdded:Fire(kill)
KillService.Kills[args[2].UserId][#KillService.Kills[args[2].UserId]+1] = kill
KillService.TotalKills[args[2].UserId] = KillService.TotalKills[args[2].UserId] + 1
if QuestService:HasQuest(args[2],"WaveDilemma_" .. args[2].Allegiance.Value) then KillService.WaveKills[args[2].UserId] = KillService.WaveKills[args[2].UserId] + 1 end
if KillService:GetStreakCount(args[2]) > 1 and ((KillService.Kills[args[2].UserId][#KillService.Kills[args[2].UserId]]) - (KillService.Kills[args[2].UserId][#KillService.Kills[args[2].UserId] - 1]) >= 10) then
KillService:ClearKills(args[2])
else
if KillService:GetStreakCount(args[2]) > 1 then
if KillService:GetStreakCount(args[2]) < 6 then
RemoteService.send("Client",args[2],"DisplayAward",5,KillService.StreakTypes[#KillService.Kills[args[2].UserId]].Name)
args[2].leaderstats.XP.Value = args[2].leaderstats.XP.Value + 5
else
RemoteService.send("Client",args[2],"DisplayAward",5,KillService.StreakTypes[6].Name)
args[2].leaderstats.XP.Value = args[2].leaderstats.XP.Value + 5
end
end
end
print(KillService:GetStreakCount(args[2]))
KillService.AllKills[args[2].UserId][args[2].leaderstats.Lvl.Value][#KillService.AllKills[args[2].UserId][args[2].leaderstats.Lvl.Value]+1] = KillService.Kills[args[2].UserId][#KillService.Kills[args[2].UserId]+1]
for _, AchievementMan in pairs(KillService.Achievements) do
if AchievementMan then
if KillService:GetTotalKills(args[2]) == AchievementMan.Kills then
BindingService.send("GiveAchievement",args[2],AchievementMan.ID)
end
end
end
end
function KillService:ClearKills(plr)
KillService.Kills[plr.UserId] = {}
end
function KillService:GetStreakCount(plr)
return #KillService.Kills[plr.UserId]
end
function KillService:GetTotalKills(plr)
return KillService.TotalKills[plr.UserId]
end
return KillService
local Objective = {}
Objective.__index = Objective
function Objective.new(...)
local o = {}
local args = {...}
o.Name = args[1]
o.Text = args[2]
o.Completed = false
o.Parent = args[3]
o.XPGain = math.random(5,25);
o.Type = args[4]
if o.Type == "Custom" then
elseif o.Type == "Kill" then
o.Goal = args[5]
o.GoalCount = args[6]
o.CompletedGoalCount = 0;
end
return setmetatable(o,Objective)
end
function Objective:Complete(func)
self.Completed = true
func(self)
self = nil
end
function Objective:ToReplicatedObjective()
local o = {}
o.Name = self.Name
o.Text = self.Text
o.Type = self.Type
o.Completed = self.Completed
return o
end
return Objective
local MobService = require(game.ServerScriptService.MobFunctions)
local Pathfinder = MobService.Pathfinder.new(script.Parent.HumanoidRootPart,script.Parent.Human,script.Parent)
--[[
Basic Monster by ArceusInator
Information:
Configurations.MaximumDetectionDistance (default 200)
The monster will not detect players past this point. If you set it to a negative number then the monster will be able to chase from any distance.
Configurations.CanGiveUp (default true)
If true, the monster will give up if its target goes past the MaximumDetectionDistance. This is a pretty good idea if you have people teleporting around.
Configurations.CanRespawn (default true)
If true, the monster will respawn after it dies
Configurations.AutoDetectSpawnPoint (default true)
If true, the spawn point will be auto detected based on where the monster is when it starts
Configurations.SpawnPoint (default 0,0,0)
If Settings.AutoDetectSpawnPoint is disabled, this will be set to the monster's initial position. This value will be used when the monster auto respawns to tell it where to spawn next.
Configurations.FriendlyTeam (default Really black)
The monster will not attack players on this team
Mind.CurrentTargetHumanoid (Humanoid objects only)
You can force the monster to follow a certain humanoid by setting this to that humanoid
Monster.Respawn (Function)
Arguments are: Vector3 point
Info: Respawns the monster at the given point, or at the SpawnPoint setting if none if provided
Monster.Died (Event)
Info: Fired when the monster dies
Monster.Respawned (Event)
Info: Fired when the monster respawns
--]]
local Self = script.Parent
local Mind = Self:FindFirstChild'Mind' -- Points to the monster's mind. You can edit parts of this from other scripts in-game to change the monster's behavior. Advanced users only.
local OrderList = Self:FindFirstChild'OrderQueue'
local BOTBrain = require(Self:FindFirstChild('BOT'))
Self.CurrentItem.Changed:wait()
local Weapon = Self.CurrentItem.Value
local wSettings = require(Weapon.SETTINGS)
local CF = CFrame.new
local Target = nil
Self.CurrentItem.Changed:connect(function(item)
if item then
Weapon = item
wSettings = require(Weapon.SETTINGS)
end
end)
Self.SetTarget.Event:connect(function(target)
Target = target
end)
Self.GetTarget.OnInvoke = function()
return Target
end
-- Verify that everything is where it should be
function getEnemies(Parent)
local iEnemies = Parent:GetChildren()
local eEnemies = {}
for _, enemy in pairs(iEnemies) do
table.insert(eEnemies,enemy)
end
return eEnemies
end
local Info = {
-- These are constant values. Don't change them unless you know what you're doing.
-- Advanced settings
RecomputePathFrequency = 1, -- The monster will recompute its path this many times per second
RespawnWaitTime = 5, -- How long to wait before the monster respawns
JumpCheckFrequency = 1, -- How many times per second it will do a jump check
}
local Data = {
-- These are variable values used internally by the script. Advanced users only.
LastRecomputePath = 0,
Recomputing = false, -- Reocmputing occurs async, meaning this script will still run while it's happening. This variable will prevent the script from running two recomputes at once.
IsDead = false,
TimeOfDeath = 0,
CurrentNode = nil,
CurrentNodeIndex = 1,
AutoRecompute = true,
LastJumpCheck = 0,
LastAttack = 0,
}
--
--
local Monster = {} -- Create the monster class
function Monster:GetCFrame()
-- Returns the CFrame of the monster's humanoidrootpart
local humanoidRootPart = Self:FindFirstChild('HumanoidRootPart')
if humanoidRootPart ~= nil and humanoidRootPart:IsA('BasePart') then
return humanoidRootPart.CFrame
else
return CF()
end
end
function Monster:GetMaximumDetectionDistance()
-- Returns the maximum detection distance
local setting = BOTBrain.ChaseRange
if setting < 0 then
return math.huge
else
return setting
end
end
function Monster:HeadForCover()
Self.CustomMove.Value = true
local Cover = getCoverPoints()
local CoverPoint = Cover[math.random(#Cover)]
Pathfinder.Target = CoverPoint.CFrame.p
Pathfinder:ComputePath()
Pathfinder:Start(1,function()
end)
Pathfinder.Stopped:wait()
Data.InCover = true
Self.TakingCover.Value = true
Self.CoverPoint.Value = CoverPoint.Parent
end
function Monster:GetTargetCFrame()
local targetHumanoid = Target
if Monster:TargetIsValid() and targetHumanoid.Parent.PrimaryPart ~= nil then
return targetHumanoid.Parent.PrimaryPart.CFrame
else
return CF()
end
end
function Monster:IsAlive()
return Self.Human.Health > 0 and Self.Human.Torso ~= nil
end
function Monster:TargetIsValid()
local targetHumanoid = Target
if targetHumanoid ~= nil and targetHumanoid:IsA 'Humanoid' and (not targetHumanoid:IsDescendantOf(workspace.CorpseIgnore)) and targetHumanoid.Parent ~= nil then
return true
else
return false
end
end
function Monster:HasClearLineOfSight()
-- Going to cast a ray to see if I can just see my target
local myPos, targetPos = Monster:GetCFrame().p, Monster:GetTargetCFrame().p
local hit, pos = workspace:FindPartOnRayWithIgnoreList(
Ray.new(
myPos,
targetPos - myPos
),
{
Self,
Self.CoverPoint.Value
}
)
if hit ~= nil and hit:IsDescendantOf(Mind.CurrentTargetHumanoid.Value.Parent) then
return true
else
return false
end
end
function Monster:HasClearLineOfSightFromPoint(point)
-- Going to cast a ray to see if I can just see my target
local myPos, targetPos = point.p, Monster:GetTargetCFrame().p
local hit, pos = workspace:FindPartOnRayWithIgnoreList(
Ray.new(
point.p,
point.lookVector
),
{
Self,
Self.CoverPoint.Value.Parent
}
)
if hit ~= nil and hit:IsDescendantOf(Target.Parent) then
return true
else
return false
end
end
function Monster:Update()
end
function Monster:GetClosestEnemiesWithCount(count)
local bindableService = require(game.ReplicatedStorage.BindingService)()
local enemies = {}
for _, enemy in pairs(workspace.Mobs:GetChildren()) do
if enemy then
if enemy:FindFirstChildOfClass("Humanoid") then
if require(enemy.BOT).Allegiance ~= BOTBrain.Allegiance and enemy.PrimaryPart then
local distance = (enemy.PrimaryPart.CFrame.p - Self.PrimaryPart.CFrame.p).magnitude
if distance < BOTBrain.ChaseRange then
enemies[#enemies+1] = enemy
if #enemies >= count then
break
end
end
end
end
end
end
if #enemies < count then
for _, enemy in pairs(bindableService.fetch("PlayerList")) do
if enemy then
if enemy.Character then
if enemy.Character:FindFirstChildOfClass("Humanoid") then
if enemy.Allegiance.Value ~= BOTBrain.Allegiance then
local distance = (enemy.Character.PrimaryPart.CFrame.p - Self.PrimaryPart.CFrame.p).magnitude
if distance < BOTBrain.ChaseRange then
enemies[#enemies+1] = enemy.Character
for _, secondEnemy in pairs(enemy.playerArmy.Value:GetChildren()) do
if secondEnemy:FindFirstChildOfClass("Humanoid") and secondEnemy.PrimaryPart then
local distance = (secondEnemy.PrimaryPart.CFrame.p - Self.PrimaryPart.CFrame.p).magnitude
if distance < BOTBrain.ChaseRange then
enemies[#enemies+1] = secondEnemy
end
end
end
end
end
end
end
end
end
end
return enemies
end
function Monster:Talk(message)
Self.Parent.MobSpeaker.Speak:Fire(Self.UnitName.Value,message)
end
function Monster:Initialize()
end
function Monster:InitializeUnique()
end
--
--
Monster:Initialize()
Monster:InitializeUnique()
local ExecutableOrders = {
};
local EnemyTies = {
["Good"] = "Evil";
["Evil"] = "Good";
}
ExecutableOrders["MOVETO"] = function(Order)
script.Parent.CustomMove.Value = true
Pathfinder.Target = Order.MoveToPosition.Value
Pathfinder:ComputePath(true)
Pathfinder:Start(1,function()
if Order.ForceCancel.Value then
Pathfinder.Stop("MoveToOrderCancelled")
end
end)
Pathfinder.Stopped:wait()
if not Order.ForceCancel.Value then
Order.Completed:Fire("Success")
else
Order.Cancelled:Fire()
end
script.Parent.CustomMove.Value = true
end;
ExecutableOrders["ELIMINATE"] = function(Order)
Self.CustomMove.Value = true
local DeathConnection = nil
if script.Parent.Leader.Value ~= nil then
local EnemiesContainer =workspace.Mobs
if EnemiesContainer then
local Enemies = EnemiesContainer
if Enemies ~= nil then
if #Enemies:GetChildren() > 0 then
DeathConnection = Self.Human.Died:connect(function()
Pathfinder:Stop("KIA")
Target = nil
DeathConnection:disconnect()
Order.Cancelled:Fire()
Order.ForceCancel.Value = true
end)
for _, enemy in pairs(Enemies:GetChildren()) do
if enemy.Name == Order.Target.Value then
if enemy:FindFirstChildOfClass("Humanoid") then
Target = enemy:FindFirstChildOfClass("Humanoid")
Pathfinder.Target = Monster:GetTargetCFrame().p
local Distance = (Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude
local status = Pathfinder:ComputePath(false)
if status == Enum.PathStatus.Success then
Pathfinder:Start(1,function()
Self.Human.WalkSpeed = 25 if Monster:TargetIsValid() and (Monster:HasClearLineOfSight() or((Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude >= 30)) then
Self.Shooting.Value = true
Self.Human.WalkSpeed = 0
Self.SetAimed:Fire(true)
spawn(function()
math.randomseed(tick())
repeat
Weapon.TargetCFrame.Value = Monster:GetTargetCFrame()
wait()
until
Self.Human.Health <= 0 or (not Monster:TargetIsValid()) or (not Monster:HasClearLineOfSight()) or (Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude >= 30
Self.FinishedRangeFiring:Fire()
end)
Self.FinishedRangeFiring.Event:wait()
Self.SetAimed:Fire(false)
Self.Human.WalkSpeed = 25
Self.Shooting.Value = false
end
end)
Pathfinder.Stopped:wait()
end
end
end
end
end
end
end
end
Self.CustomMove.Value = false
Self.Shooting.Value = false
if Order ~= nil then
if Order.ForceCancel.Value then
Order.Cancelled:Fire()
else
Order.Completed:Fire("Success")
end
end
end;
--ExecutableOrders["FIREONSIGHT"] = function(Order)
-- Self.CustomMove.Value = true
-- Weapon.ChangeStance:Fire("Normal")
-- local DeathConnection = nil
-- if script.Parent.Leader.Value ~= nil then
-- DeathConnection = Self.Human.Died:connect(function()
-- Pathfinder:Stop("KIA")
-- Mind.CurrentTargetHumanoid.Value = nil
-- DeathConnection:disconnect()
-- Order.Cancelled:Fire()
-- Order.ForceCancel.Value = true
-- end)
-- repeat
--
-- local npcs = getEnemies(workspace.Mobs)
-- for _, npc in pairs(npcs) do
-- if npc:FindFirstChildOfClass("Humanoid") then
-- Mind.CurrentTargetHumanoid.Value = npc:FindFirstChildOfClass("Humanoid")
-- end
-- if Monster:TargetIsValid() then
-- Monster:Talk("Target sighted, getting into position, sir!")
-- local FPs = Locale.FiringPositions:GetChildren()
-- local FP = FPs[math.random(#FPs)]
-- Self.Human:MoveTo(FP.CFrame.p)
-- repeat wait() until (FP.CFrame.p - Monster:GetCFrame().p).magnitude <= 10
-- print("Going prone for targets...")
-- Self.CurrentItem.Value.ChangeStance:Fire("Crouch",true)
-- Self.CurrentItem.Value.ChangeStance:Fire("Prone",true)
-- Weapon.TargetCFrame.Value = Monster:GetTargetCFrame()
-- Monster:Talk("Firing!")
-- Self.SetAimed:Fire(true)
-- Self.Shooting.Value = true
-- repeat
-- Weapon.TargetCFrame.Value = Monster:GetTargetCFrame()
-- wait()
-- until
-- Mind.CurrentTargetHumanoid.Value.Health <= 0 or (Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude > Monster:GetMaximumDetectionDistance()
--
-- Self.Shooting.Value = false
-- Self.CurrentItem.Value.ChangeStance:Fire("Prone",false)
-- Self.CurrentItem.Value.ChangeStance:Fire("Crouch",false)
-- Self.SetAimed:Fire(false)
--
-- end
-- if (Weapon.StoredAmmo.Value == 0 and Weapon.Ammo.Value == 0) then
-- Pathfinder:Stop("OutOfAmmo")
-- Monster:Talk("Sir, I'm outta ammo!")
-- Mind.CurrentTargetHumanoid.Value = nil
-- Order.ForceCancel.Value = true
-- break
-- end
-- if Order == nil then
-- break
-- end
-- end
--
-- wait()
-- until
-- Self.Human.Health <= 0
-- end
-- Self.Shooting.Value = false
-- Self.CustomMove.Value = false
-- if Order ~= nil then
-- if Order.ForceCancel.Value then
-- Order.Cancelled:Fire()
-- else
-- Order.Completed:Fire("Success")
-- end
-- end
--end;
function getCoverPoints()
local cPoints = {}
for _, point in pairs(workspace.CoverSystem.CoverObjects:GetChildren()) do
if point:IsA("Model") then
if point.Name:find("AI") then
table.insert(cPoints,point:FindFirstChild("AICoverSpawn"))
end
end
end
return cPoints
end;
ExecutableOrders["BAIL"] = function(Order)
Self.CustomMove.Value = true
Self.Human.Jump = true
Self.Human:Move(Self.Head.CFrame.lookVector)
wait(2)
Self.Human.Jump = true
wait(0.5)
Self.Human:Move(Vector3.new())
Self.Stats.Bailing.Value = true
Self.LandedFromBail.Event:wait()
Self.CustomMove.Value = false
Order.Completed:Fire("Success")
end
Self.RunAuxillary.Event:connect(function(reason,point,spawnPoint,ts)
if reason == "Extraction-Escape" then
Self.CancelCurrentOrder:Fire()
Self.CustomMove.Value = true
Pathfinder.Target = point
Pathfinder:ComputePath(true)
Self.Human.WalkSpeed = 25;
Pathfinder:Start(1,function()
end)
Pathfinder.Stopped:wait()
Monster:Talk("Sir, I'm at the extraction point, and I'm entering the ship!")
Self.PrimaryPart.CFrame = ts.Bodykit.TroopPlacement:GetChildren()[Self.ID.Value].SkateboardPlatform.CFrame + Vector3.new(0,3,0)
Self.CustomMove.Value = false
end
end)
local bindableService = require(game.ReplicatedStorage.BindingService)()
function getEnemiesInRange()
local result = {}
for _, enemy in pairs(workspace.Mobs:GetChildren()) do
if enemy then
if enemy:FindFirstChildOfClass("Humanoid") then
if require(enemy.BOT).Allegiance ~= BOTBrain.Allegiance and enemy.PrimaryPart then
local distance = (enemy.PrimaryPart.CFrame.p - Self.PrimaryPart.CFrame.p).magnitude
if distance < BOTBrain.ChaseRange then
result[#result+1] = enemy
end
end
end
end
end
for _, enemy in pairs(bindableService.fetch("PlayerList")) do
if enemy then
if enemy.Character then
if enemy.Character:FindFirstChildOfClass("Humanoid") then
if enemy.Allegiance.Value ~= BOTBrain.Allegiance then
local distance = (enemy.Character.PrimaryPart.CFrame.p - Self.PrimaryPart.CFrame.p).magnitude
if distance < BOTBrain.ChaseRange then
result[#result+1] = enemy.Character
for _, secondEnemy in pairs(enemy.playerArmy.Value:GetChildren()) do
if secondEnemy:FindFirstChildOfClass("Humanoid") and secondEnemy.PrimaryPart then
local distance = (secondEnemy.PrimaryPart.CFrame.p - Self.PrimaryPart.CFrame.p).magnitude
if distance < BOTBrain.ChaseRange then
result[#result+1] = secondEnemy
end
end
end
end
end
end
end
end
end
return result
end
ExecutableOrders["ELIMINATE3"] = function(Order)
Self.CustomMove.Value = true
local enemies = Monster:GetClosestEnemiesWithCount(3)
if #enemies > 0 then
for _, enemy in pairs(enemies) do
if enemy then
local eHum = enemy:FindFirstChildOfClass("Humanoid")
if eHum then
Target = eHum
Pathfinder.Target = Monster:GetTargetCFrame().p
local Distance = (Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude
local status = Pathfinder:ComputePath(false)
if status == Enum.PathStatus.Success then
Pathfinder:Start(1,function()
Self.Human.WalkSpeed = 25
if Monster:TargetIsValid() and (Monster:HasClearLineOfSight() or((Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude >= 30)) then
Self.Shooting.Value = true
Self.Human.WalkSpeed = 0
Self.SetAimed:Fire(true)
repeat
Weapon.TargetCFrame.Value = Monster:GetTargetCFrame()
wait()
until
Self.Human.Health <= 0 or (not Monster:TargetIsValid()) or (Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude >= 30 or not Monster:HasClearLineOfSight()
Self.SetAimed:Fire(false)
Self.Human.WalkSpeed = 25
Self.Shooting.Value = false
end
end)
Pathfinder.Stopped:wait()
end
end
end
end
end
Order.Completed:Fire("Success")
Self.CustomMove.Value = false
end
ExecutableOrders["SCOUTAHEAD"] = function(Order)
end
ExecutableOrders["CLEARZONE"] = function(Order)
Self.CustomMove.Value = true
local enemies = getEnemiesInRange()
for _, enemy in pairs(enemies) do
if enemy then
local eHum = enemy:FindFirstChildOfClass("Humanoid")
if eHum then
Target = eHum
Pathfinder.Target = Monster:GetTargetCFrame().p
local Distance = (Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude
local status = Pathfinder:ComputePath(false)
if status == Enum.PathStatus.Success then
Pathfinder:Start(1,function()
Self.Human.WalkSpeed = 25
if Monster:TargetIsValid() and (Monster:HasClearLineOfSight() or((Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude >= 30)) then
Self.Shooting.Value = true
Self.Human.WalkSpeed = 0
Self.SetAimed:Fire(true)
spawn(function()
math.randomseed(tick())
repeat
Weapon.TargetCFrame.Value = Monster:GetTargetCFrame()
wait()
until
Self.Human.Health <= 0 or (not Monster:TargetIsValid()) or (Monster:GetTargetCFrame().p - Monster:GetCFrame().p).magnitude >= 30
Self.FinishedRangeFiring:Fire()
end)
Self.FinishedRangeFiring.Event:wait()
Self.SetAimed:Fire(false)
Self.Human.WalkSpeed = 25
Self.Shooting.Value = false
end
end)
end
end
end
end
Self.CustomMove.Value = false
end
return ExecutableOrders
local Quest = {}
local RemoteService = require(game.ReplicatedStorage.RemoteService)
local ProgressionService = require(game.ReplicatedStorage.ProgressionService)
local AnalyticsService = require(game.ReplicatedStorage.AnalyticsService)
Quest.__index = Quest
function Quest.new(...)
local q = {}
local args = {...}
q.Name = args[1];
q.Plr = args[2];
q.Objectives = {};
q.Description = args[3];
q.Reward = args[4];
q.Reward.Parent = q
return setmetatable(q,Quest)
end
function Quest:AddObjective(objective)
self.Objectives[#self.Objectives+1] = objective
return #self.Objectives
end
function Quest:CompleteObjective(index)
self.Objectives[index]:Complete(function(obj)
RemoteService.send("Client",self.Plr,"CompleteObjective",obj.Name)
ProgressionService:AddXP(self.Plr,obj.XPGain,"ObjectiveComplete")
end)
end
function Quest:RemoveObjective(index)
self.Objectives[index] = nil
end
function Quest:GetObjectives()
local result = {}
for i, objective in pairs(self.Objectives) do
if objective then
result[#result+1] = objective:ToReplicatedObjective()
end
end
return result
end
function Quest:GetObjectiveByName(name)
local result = nil
local index = 0
for i, objective in pairs(self.Objectives) do
if objective.Name == name then
result = objective
index = i
end
end
return result, index
end
function Quest:Give()
local qrType = self.Reward.Type
if qrType == "cR" then
self.Plr.leaderstats.Credits.Value = self.Plr.leaderstats.Credits.Value + self.Reward.Amount
elseif qrType == "XP" then
ProgressionService:AddXP(self.Plr,self.Reward.Amount,"QuestComplete")
elseif typeof(qrType) == "Instance" and qrType:IsA("Tool") then
local qrTypeClone = qrType:Clone()
qrTypeClone.Parent = self.Plr.Inventory
elseif qrType == "squadMember" then
print("Unimplemented SQUAD Reward")
end
end
function Quest:Complete()
self:Give()
AnalyticsService.RecordQuestProgress(self.Plr,"Complete",self.Reward.Amount,self.Name,"Quest")
-- Add More Completion Logic here.
end
function Quest:GiveObjectives()
RemoteService.send("Client",self.Plr,"DisplayObjectives",self:GetObjectives())
end
return Quest
local QuestService = {}
QuestService.ReplicatedStorage = game:GetService("ReplicatedStorage")
QuestService.QuestObj = require(script.Quest)
QuestService.Archetypes = require(script.QuestArcheTypes)
QuestService.Quests = {}
QuestService.CurrentQuest = {}
QuestService.Objective = require(script.Objective)
local BindingService = require(game.ReplicatedStorage.BindingService)()
QuestService.RewardObj = require(script.Reward);
local RunService = game:GetService("RunService")
QuestService.Extensions = {
["Server"] = {
};
["Client"] = {
}
}
QuestService.Handlers = {
["ObjectiveComplete"] = function() end;
["StartQuest"] = function() end;
}
QuestService.Quests = {}
game.Players.PlayerAdded:connect(function(plr)
QuestService.Quests[plr.UserId] = {}
QuestService.CurrentQuest[plr.UserId] = nil
end)
game.Players.PlayerRemoving:connect(function(plr)
QuestService.Quests[plr.UserId] = nil
end)
local RemoteService = require(game.ReplicatedStorage.RemoteService)
function QuestService:CreateQuest(plr,name,...)
if QuestService.CurrentQuest[plr.UserId] then return end
QuestService.Quests[plr.UserId][name] = QuestService.QuestObj.new(...)
QuestService.CurrentQuest[plr.UserId] = QuestService.Quests[plr.UserId][name]
return QuestService.Quests[plr.UserId][name]
end
function QuestService:AddExtension(name,modelType,funcTable)
if not (funcTable["Fetch"] or funcTable["Send"] or funcTable["Bounce"]) then return end
QuestService.Extensions[modelType] = funcTable
end
function QuestService:CreateObjective(name,description,quest)
return QuestService.Objective.new(name,description,quest)
end
function QuestService.startServer()
local funcs = {
["Server"] = {
["Send"] = {};
["Fetch"] = {};
["Bounce"] = {};
};
["Client"] = {
["Send"] = {};
["Fetch"] = {};
["Bounce"] = {};
};
}
if RunService:IsServer() then
for _, funcTable in pairs(QuestService.Extensions["Server"]) do
if funcTable["Send"] then
for extensionName, extensionCodebase in pairs(funcTable["Send"]) do
funcs["Server"]["Send"][extensionName] = extensionCodebase
end
end
if funcTable["Fetch"] then
for extensionName, extensionCodebase in pairs(funcTable["Fetch"]) do
funcs["Server"]["Fetch"][extensionName] = extensionCodebase
end
end
if funcTable["Bounce"] then
for extensionName, extensionCodebase in pairs(funcTable["Bounce"]) do
funcs["Server"]["Bounce"][extensionName] = extensionCodebase
end
end
end
else
for _, funcTable in pairs(QuestService.Extensions["Client"]) do
if funcTable["Send"] then
for extensionName, extensionCodebase in pairs(funcTable["Send"]) do
funcs["Client"]["Send"][extensionName] = extensionCodebase
end
end
if funcTable["Fetch"] then
for extensionName, extensionCodebase in pairs(funcTable["Fetch"]) do
funcs["Client"]["Fetch"][extensionName] = extensionCodebase
end
end
if funcTable["Bounce"] then
for extensionName, extensionCodebase in pairs(funcTable["Bounce"]) do
funcs["Client"]["Bounce"][extensionName] = extensionCodebase
end
end
end
end
RemoteService.listen("Server","Send","RunExtension",function(player,...)
end)
RemoteService.listen("Server","Fetch","InvokeExtension",function(player,extension,...)
local args = {...}
return funcs["Server"]["Fetch"][extension](...)
end)
RemoteService.listen("Server","Bounce","RunGlobalExtension",function(player,...)
end)
end
function QuestService:CreateFromArchetype(aType,plr,...)
local args = {...}
if not plr then return nil end
if not aType then error("QuestService: Archetype MUST be specified to create quest.") end
local archeType = QuestService.Archetypes[aType];
local ArchetypeQuest
if archeType then
ArchetypeQuest = QuestService.QuestObj.new(archeType.Name(args[1]),plr,archeType.Description(args[1]),QuestService.RewardObj.new(archeType.Reward.Type,archeType.Reward.Amount(),archeType.Reward.ExtraData))
for _, objective in pairs(archeType.Objectives) do
ArchetypeQuest:AddObjective(QuestService.Objective.new(objective.Name,objective.Text,ArchetypeQuest))
end
end
if ArchetypeQuest then
QuestService.Quests[plr.UserId][ArchetypeQuest.Name] = ArchetypeQuest
end
QuestService.Handlers["StartQuest"](plr,ArchetypeQuest)
return ArchetypeQuest.Name
end
function QuestService:BroadcastToOwner(plr,qName)
local quest = QuestService.Quests[plr.UserId][qName];
if quest then
local KillChanged = {}
for i, obj in pairs(quest.Objectives) do
if obj.Type == "Kill" then
KillChanged[i] = game.ServerScriptService.KillAdded.Event:connect(function(kill)
local killed = kill.Killed
if killed.Name == self.Goal then
self.CompletedGoalCount = self.CompletedGoalCount + 1
if self.CompletedGoalCount == self.GoalCount then
self:Complete(function()
KillChanged[i]:disconnect()
end)
end
end
end)
end
end
quest:GiveObjectives()
end
end
function QuestService:MarkObjectiveAsComplete(plr,questName,objectiveName)
local quest = QuestService.Quests[plr.UserId][questName]
if quest then
local objective, oI = quest:GetObjectiveByName(objectiveName)
if objective and oI ~= 0 then
quest:CompleteObjective(oI)
QuestService.Handlers["ObjectiveComplete"](plr,objective,quest)
end
end
end
function QuestService:CompleteQuest(plr,qName)
local quest = QuestService.Quests[plr.UserId][qName]
if quest then
quest:Complete()
QuestService.Quests[plr.UserId][qName] = nil
QuestService.CurrentQuest[plr.UserId] = nil
end
end
function QuestService:HasQuest(plr,qName)
return QuestService.Quests[plr.UserId][qName] ~= nil
end
--function QuestService:GetDialog(QuestID)
-- return QuestService.Dialogs.dialog[QuestID]
--end
--function QuestService:SerializeQuest(Quest_Folder)
-- local Quest = {}
-- Quest.ID = Quest_Folder.Name
-- Quest.Number = Quest_Folder.Number.Value
-- Quest.Goal = Quest_Folder.Goal.Value
-- Quest.IsComplete = Quest_Folder.IsComplete.Value
-- Quest.OnQuest = Quest_Folder.OnQuest.Value
-- Quest.DialogCompleted_Blurb = Quest_Folder.DialogCompleted_Blurb.Value
-- Quest.QuestTitle = Quest_Folder.QuestTitle.Value
-- if Quest_Folder.Type == nil then return Quest end
-- Quest.Type = Quest_Folder.Type.Value
-- return Quest
--end
--function QuestService:CreateTutorialTag(QuestID,Quest_Data,player)
-- local Tag = QuestService.QuestTag:Clone()
-- Tag.Name = QuestID
-- Tag.Status.Text = " 0 / " .. #Quest_Data["Steps"]
-- Tag.Title.Text = Quest_Data["Name"]
-- Tag.Parent = player.PlayerGui.QUG.Container
-- return Tag,Quest_Data["Steps"]
--end
--function QuestService:CreateTutorialFolder(QuestID,Quest_Data)
--
-- local folder = Instance.new("Folder")
-- folder.Name = QuestID
--
-- local number_value = Instance.new("IntValue",folder)
-- number_value.Name = "Number"
-- local steps = Quest_Data["Steps"]
-- local goal = Instance.new("IntValue",folder)
-- goal.Name = "StepsRemaining"
-- goal.Value = #steps
-- return folder
--end
--function QuestService:StartQuest(QuestID,Quest_Data,Dialog_Data)
-- local folder = Instance.new("Folder")
-- folder.Name = QuestID
--
--
-- local title = Instance.new("StringValue",folder)
-- title.Name = "QuestTitle"
-- title.Value = Quest_Data["Name"]
--
-- local OnQuest = Instance.new("BoolValue",folder)
-- OnQuest.Name = "OnQuest"
-- OnQuest.Value = true
--
-- local number_value = Instance.new("IntValue",folder)
-- number_value.Name = "Number"
--
-- local isComplete = Instance.new("BoolValue",folder)
-- isComplete.Name = "IsComplete"
-- isComplete.Value = false
--if Quest_Data["Type"] == "EXTRACTION" then
-- local BaseSecured = Instance.new("BoolValue")
-- BaseSecured.Name = "BaseSecured"
-- BaseSecured.Value = false
-- BaseSecured.Parent = folder
--
--elseif Quest_Data["Type"] == "SLAY" then
-- local goal = Instance.new("IntValue",folder)
-- goal.Name = "Goal"
-- goal.Value = Quest_Data["Nmbr"]
--end
--
-- local Dialog_Complete = Instance.new("StringValue",folder)
-- Dialog_Complete.Name = "DialogCompleted_Blurb"
-- Dialog_Complete.Value = Dialog_Data["Quest"]["COMPLETE"]
--
-- local Quest_Type = Instance.new("StringValue",folder)
-- Quest_Type.Name = "Type"
-- Quest_Type.Value = Quest_Data["Type"]
--
--
-- return folder
--end
--
--
--function QuestService:SaveChanges(player,Folder)
-- pcall(function() QuestService.QuestStorage:PostAsync(player.UserId.."-quest",QuestService:SerializeQuest(Folder)) end)
--
--end
--
--function QuestService:WarnPlayerOfIncompleteQuest(NPCDialog,Dialog_Data,Decline_Btn)
-- NPCDialog.Text = " " .. Dialog_Data["Quest"]["INCOMPLETE"]
-- Decline_Btn.Text = "Oh , right!"
--
--end
--
--local year = 1970
--local month = 1
--local day = 1
--local Date = "January 1, 1970"
--
--local hour = 0
--local min = 0
--local sec = 0
--local tag = "AM"
--local Time = "12:00 AM"
--
--function QuestService.getDate()
--
--local Type = 0
--local Sec = true
-- local t = tick()
-- local months = {
---- {"MONTH", TOAL DAYS TO YEAR, DAYS} <- Format
-- {"January",31,31};
-- {"February",59,28};
-- {"March",90,31};
-- {"April",120,30};
-- {"May",151,31};
-- {"June",181,30};
-- {"July",212,31};
-- {"August",243,31};
-- {"September",273,30};
-- {"October",304,31};
-- {"November",334,30};
-- {"December",365,31};
-- }
-- year = math.floor(1970+(t/31579200))
-- if ((year%4) == 0) then -- Check for leap year
-- months[2][3] = 29
-- for i,v in pairs(months) do
-- if (i ~= 1) then
-- v[2] = (v[2]+1)
-- end
-- end
-- end
-- day = math.floor(((t/86400)%365.25)+1) -- Get current day of the year. Starts at 0, so 1 is added (365.25 is the average # of days in a year due to leap year)
-- for i,m in pairs(months) do
-- if ((m[2]-m[3]) <= day) then -- Get month based on day
-- month = i
-- end
-- end
-- local m = months[month]
-- day = (day+m[3]-m[2]) -- Get day of the month
-- year,day = tostring(year),tostring(day)
-- local c,s = ", "," " -- Comma, space
-- Date = (months[month][1] .. s .. day .. c .. year)
-- return Date
--end
--
--function QuestService.getTime()
--
--
--local Type = 0
--local Sec = true
-- local t = tick()
-- local sec = math.floor((t%60)) -- Sec, Min, and Hour equations I actually got off of Google. Everything else was written by me
-- local min = math.floor((t/60)%60)
-- local hour = math.floor((t/3600)%24)
-- sec = tostring((sec < 10 and "0" or "") .. sec)
-- min = tostring((min < 10 and "0" or "") .. min)
-- tag = (Type == 0 and (hour < 12 and "AM" or "PM") or "")
-- hour = ((Type == 1 and hour < 10 and "0" or "") .. tostring(Type == 0 and (hour == 0 and 12 or hour > 12 and (hour-12) or hour) or hour)) -- Ternary operators FTW. Helps get rid of 'if then' stuff. Actually learned this off of Java programming: z = (x == y ? "Yes" : "No")
-- local c,s = ":",(Type == 0 and " " or "") -- Colon, (space if 12 hr clock)
-- Time = (hour .. c .. min .. (Sec and c .. sec or "") .. s .. tag)
-- return Time
--end
--function QuestService:GetCompletedQuest(player,QuestID)
-- return QuestService.CompletedQuestStorage:GetAsync(player.UserId.."-completed-quest-"..QuestID,{
-- DecodeJSON = true
-- })
--end
--function QuestService:EraseCompletedQuest(player,QuestID)
-- return QuestService.CompletedQuestStorage:PostAsync(player.UserId.."-completed-quest-"..QuestID,{})
--end
--function QuestService:MarkCompletion(player,Folder)
-- local CompletionDate = QuestService.getDate().." , "..QuestService.getTime()
-- pcall(function()QuestService.CompletedQuestStorage:PostAsync(player.UserId.."-completed-quest-"..Folder.Name,{
-- Name = Folder.Name,
-- CompletionDate = CompletionDate
--
-- })
-- end)
--
--end
--function QuestService:RewardPlayer(player,Folder,QuestTag,GUI,removeTag,extractionQuest)
-- if QuestService.Quests.quests[Folder.Name] and not extractionQuest then
-- player:WaitForChild("leaderstats").XP.Value = player:WaitForChild("leaderstats").XP.Value + QuestService.Quests.quests[Folder.Name]["EXPg"]
-- player:WaitForChild("leaderstats").Credits.Value = player:WaitForChild("leaderstats").Credits.Value + QuestService.Quests.quests[Folder.Name]["GLDg"]
-- elseif QuestService.Quests.quests[Folder.Name]["StepQuests"][extractionQuest.Name] then
-- player:WaitForChild("leaderstats").XP.Value = player:WaitForChild("leaderstats").XP.Value + QuestService.Quests.quests[Folder.Name]["StepQuests"][extractionQuest.Name]["EXPg"]
-- player:WaitForChild("leaderstats").Credits.Value = player:WaitForChild("leaderstats").Credits.Value + QuestService.Quests.quests[Folder.Name]["StepQuests"][extractionQuest.Name]["GLDg"]
-- end
-- QuestService:MarkCompletion(player,Folder)
-- Folder:Destroy()
-- if removeTag then
-- QuestTag:Destroy()
-- end
-- game.ReplicatedStorage.RemoteService.QuestTagResolve:FireClient(player)
-- pcall(function() QuestService.QuestStorage:PostAsync(player.UserId.."-quest",{}) end)
-- player.CurrentQuest.Value = "None"
--if QuestService:GetQuestData(Folder.Name)["ContinuityQuest"] then
-- game.ReplicatedStorage.RemoteService.IntroduceTutorial:FireClient(player)
--end
-- GUI:Destroy()
--end
--
--function QuestService:EnableTrackedChanges(player,Folder,Status)
-- Folder.Number.Changed:connect(function(value)
-- Status.Text = tostring(value) .. " / " .. tostring(Folder.Goal.Value)
-- if value >= Folder.Goal.Value then
-- Folder.IsComplete.Value = true
--
-- end
-- QuestService:SaveChanges(player,Folder)
--
--
-- end)
--
--end
--
--function QuestService:ExtractData(Dialog_Data)
-- return Dialog_Data["EXIT"]
--end
--
--function QuestService:GetDialogCount(Dialog_Data)
-- local num_of_dialogs = 0
-- for key, value in pairs(Dialog_Data["NoQuest"]) do
-- if key ~= "EXIT" then
-- num_of_dialogs = num_of_dialogs + 0.5
-- end
-- end
-- return num_of_dialogs
--end
--function QuestService:DisplayInitialDialogData(Dialog_Data,NPCDialog,dialog_num,Accept_Btn)
--
-- NPCDialog.Text = Dialog_Data["NoQuest"]["NPC"..dialog_num]
--
--
-- Accept_Btn.Text = Dialog_Data["NoQuest"]["RES"..dialog_num]
--end
--function QuestService:EnableDialogChanges(player,Accept_Btn,Decline_Btn,NPCDialog,GUI,QuestTag,Folder)
-- Accept_Btn.Visible = false
--
-- NPCDialog.Text = " " .. Folder.DialogCompleted_Blurb.Value
-- Decline_Btn.Text = "Thanks!"
-- Decline_Btn.MouseButton1Click:connect(function()
-- QuestService:RewardPlayer(player,Folder,QuestTag,GUI,true)
-- end)
--end
--function QuestService:GetQuest(player,Quest)
-- return player:FindFirstChild(Quest)
--
--end
--function QuestService:CreateTag(Folder)
-- local Tag = QuestService.QuestTag:Clone()
-- Tag.Name = Folder.Name
-- if Folder.Type.Value ~= "EXTRACTION" then
-- Tag.Status.Text = " 0 / " .. Folder.Goal.Value
-- else
-- Tag.Status.Text = "BASE " .. (Folder.BaseSecured.Value and "SECURED" or "VULNERABLE")
-- end
-- Tag.Title.Text = Folder.QuestTitle.Value
-- return Tag
--end
--function QuestService:CreateSavedTag(Folder)
-- local QT = QuestService:CreateTag(Folder)
-- QT.Name = Folder.Name
--
-- QT.Status.Text = " "..Folder.Number.Value.." / ".. Folder.Goal.Value
-- QT.Title.Text = Folder.QuestTitle.Value
-- return QT
--
--
--end
--function QuestService:CreateSavedTutorialTag(Folder)
-- local QT = QuestService:CreateTutorialTag(Folder.Name)
-- QT.Status.Text = " "..Folder.Number.Value.." / ".. Folder.Goal.Value
-- QT.Title.Text = Folder.QuestTitle.Value
--end
--
--function QuestService:EnableQuestResummoningOnDeath(player,Quest,GUIContainer,Quest_Data,Dialog_Data)
-- player.Character.Humanoid.Died:connect(function()
-- player.CharacterAdded:wait()
-- local Quest_Tag = QuestService:CreateSavedTag(QuestService:GetQuest(player,Quest))
-- Quest_Tag.Parent = GUIContainer
-- local Status = GUIContainer:FindFirstChild("Status", true)
-- QuestService:EnableTrackedChanges(player,QuestService:GetQuest(player,Quest),Status)
--end)
--end
--function QuestService:EnableTutorialResummoningOnDeath(player,Quest,GUIContainer)
-- local Quest_Tag = QuestService:CreateSavedTutorialTag(QuestService:GetQuest(player,Quest))
-- Quest_Tag.Parent = GUIContainer
-- local Status = GUIContainer:FindFirstChild("Status", true)
-- QuestService:EnableTrackedChanges(QuestService:GetQuest(player,Quest),Status)
--end
--function QuestService:LoadQuest(player)
-- return QuestService.QuestStorage:GetAsync(player.UserId.."-quest",{
-- DecodeJSON = true
-- })
--
--end
--function QuestService:QuestEntryToFolder(QuestInfo)
--
-- if QuestInfo == nil then return end
-- local folder = Instance.new("Folder")
-- folder.Name = QuestInfo.ID or ""
--
--
-- local title = Instance.new("StringValue")
-- title.Name = "QuestTitle"
-- title.Value = QuestInfo.QuestTitle
-- title.Parent = folder
-- local OnQuest = Instance.new("BoolValue")
-- OnQuest.Name = "OnQuest"
-- OnQuest.Value = QuestInfo.OnQuest
-- OnQuest.Parent = folder
-- if QuestInfo.Type == "SLAY" then
-- local number_value = Instance.new("IntValue")
-- number_value.Name = "Number"
-- number_value.Value = QuestInfo.Number
-- number_value.Parent = folder
-- local goal = Instance.new("IntValue")
-- goal.Name = "Goal"
-- goal.Value = QuestInfo.Goal
-- goal.Parent = folder
-- elseif QuestInfo.Type == "EXTRACTION" then
--
-- end
-- local isComplete = Instance.new("BoolValue",folder)
-- isComplete.Name = "IsComplete"
-- isComplete.Value = QuestInfo.IsComplete
-- isComplete.Parent = folder
--
-- local Dialog_Complete = Instance.new("StringValue")
-- Dialog_Complete.Name = "DialogCompleted_Blurb"
-- Dialog_Complete.Value = QuestInfo.DialogCompleted_Blurb
-- Dialog_Complete.Parent = folder
-- local Quest_Type = Instance.new("StringValue")
-- Quest_Type.Name = "Type"
-- Quest_Type.Value = QuestInfo.Type
-- Quest_Type.Parent = folder
--
--
-- return folder
--end
--
return QuestService
local Reward = {}
Reward.__index = Reward
function Reward.new(...)
local rw = {}
local args = {...}
rw.Type = args[1]
rw.Amount = args[2]
rw.ExtraData = args[3]
return setmetatable(rw,Reward)
end
return Reward
local Engine = script.Parent.Main.Parts.Engine
local parts = script.Parent.Main.Parts
game.CollectionService:AddTag(script.Parent,game.HttpService:GenerateGUID(false))
local DamageTag = require(game.ReplicatedStorage.DamageTag)
repeat wait() until script.Parent.Welded.Value == true
local TurretWeld = script.Parent.Main.Parts.TurretRing1.TurretRingWeld
local Settings = require(script.Parent.SETTINGS)
local RS = game:GetService("RunService")
local Others = require(workspace.Settings.Others)
local CEIL = math.ceil
local CF = CFrame.new
local Tank = script.Parent
local Bot = require(Tank.BOT)
local PFS = game:GetService("PathfindingService")
local Mind = Tank.Mind
local bindableService = require(game.ReplicatedStorage.BindingService)()
local RAY = Ray.new
local HUGE = math.huge
local function tagHumanoid(humanoid,dmg)
local tag = DamageTag.new((game.Players:GetPlayerFromCharacter(humanoid.Parent) and game.CollectionService:GetTags(game.Players:GetPlayerFromCharacter(humanoid.Parent))[1] or game.CollectionService:GetTags(humanoid.Parent)[1]),dmg,game.CollectionService:GetTags(Tank)[1],game.CollectionService:GetTags(Tank)[1])
tag:MarkEnemy(humanoid)
end
local Data = {
-- These are variable values used internally by the script. Advanced users only.
LastRecomputePath = 0,
Recomputing = false, -- Reocmputing occurs async, meaning this script will still run while it's happening. This variable will prevent the script from running two recomputes at once.
CurrentNode = nil,
CurrentNodeIndex = 1,
AutoRecompute = true,
LastJumpCheck = 0,
LastAttack = 0,
EnemyAllegiance = "";
AttackTrack = nil,
}
local RayCast = workspace.FindPartOnRayWithIgnoreList
Engine.BodyVelocity.MaxForce = Vector3.new(HUGE,HUGE,HUGE)
Engine.BodyGyro.MaxTorque = Vector3.new(4e8,4e8,4e8)
function castray(cframeFirst, cframeSecond, ignoreObject, distanceToCast)
local newRay = Ray.new(cframeFirst.p, (cframeSecond.p - cframeFirst.p).unit * distanceToCast)
local hitObject, positionHit = workspace:FindPartOnRay(newRay, ignoreObject)
return positionHit, hitObject
end
local function canSeeTarget(target)
local ray = Ray.new(Engine.CFrame.p,Engine.CFrame.lookVector * 200)
local H,P,N,M =game.Workspace:FindPartOnRayWithIgnoreList(ray,{script.Parent})
if H then
if H:IsDescendantOf(target) then
return true
end
return false
end
return false
end
local ProgressionService = require(game.ReplicatedStorage.ProgressionService)
function isInPeople(first, second)
for _,v in pairs(first) do
if second == v then
return true
end
end
return false
end
function getIndexOfValue(array, val)
for i = 0, #array do
if tostring(val) == tostring(array[i]) then
return i
end
end
return nil
end
local function getFiringPoint()
return script.Parent.Main.Gun.Flash.CFrame
end
local Sine = function(X)
return math.sin(math.rad(X))
end
local Linear = function(X)
return (X / 90)
end
function numLerp(A, B, Alpha)
return A + (B - A) * Alpha
end
function RAND(Min, Max, Accuracy)
return numLerp(Min, Max, math.random())
--[[local Inverse = 1 / (Accuracy or 1)
return (math.random(Min * Inverse, Max * Inverse) / Inverse)]]
end
function Map(Val, fromLow, fromHigh, toLow, toHigh)
return (Val - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow
end
local function getYawPitch(Cf)
local LV = Cf.lookVector
local Yaw = math.atan2(LV.x, -LV.z)
local Pitch = math.atan2(LV.y, -LV.z)
return Pitch, Yaw
end
local Monster = {} -- Create the monster class
local Enemies = {}
function setTurretDirection(mode, elevation, rotation)
--parts.MantletBase.MainGunWeld.C1 = CFrame.new(0,0,0) * CFrame.fromEulerAnglesXYZ(elevation, 0, 0);
--tweenJoint(parts.MantletBase.MainGunWeld,nil,CFrame.new(0,0,0) * CFrame.Angles(0, 0, elevation),Sine,0.8)
if mode == "MainCannon" then
tweenJoint(parts.TurretRing2.TurretRingWeld,nil,CFrame.Angles(0, math.clamp(rotation,-0.5 * math.pi,0.5 * math.pi) , 0),Sine,0.8)
elseif mode == "MGTurret" then
tweenJoint(Tank.Turret.Parts.TurretRing2.TurretRingWeld,nil,CFrame.Angles(0, rotation, 0),Sine,0.2)
tweenJoint(Tank.Turret.Parts.MantletBase.MainGunWeld,nil,CFrame.Angles(elevation, 0, 0),Sine,0.2)
elseif mode == "MGTurret2" then
tweenJoint(Tank.Turret2.Parts.TurretRing2.TurretRingWeld,nil,CFrame.Angles(0, rotation, 0),Sine,0.8)
tweenJoint(Tank.Turret2.Parts.MantletBase.MainGunWeld,nil,CFrame.Angles(elevation, 0, 0),Sine,0.8)
elseif mode == "MGTurret3" then
tweenJoint(Tank.Turret3.Parts.TurretRing2.TurretRingWeld,nil,CFrame.Angles(0, rotation, 0),Sine,0.8)
tweenJoint(Tank.Turret3.Parts.MantletBase.MainGunWeld,nil,CFrame.Angles(elevation, 0, 0),Sine,0.8)
elseif mode == "MGTurret4" then
tweenJoint(Tank.Turret4.Parts.TurretRing2.TurretRingWeld,nil,CFrame.Angles(0, rotation, 0),Sine,0.8)
tweenJoint(Tank.Turret4.Parts.MantletBase.MainGunWeld,nil,CFrame.Angles(elevation, 0, 0),Sine,0.8)
end
end
function tweenJoint(Joint, newC0, newC1, Alpha, Duration)
spawn(function()
local newCode = math.random(-1e9, 1e9) --This creates a random code between -1000000000 and 1000000000
local tweenIndicator = nil
if (not Joint:findFirstChild("tweenCode")) then --If the joint isn't being tweened, then
tweenIndicator = Instance.new("IntValue")
tweenIndicator.Name = "tweenCode"
tweenIndicator.Value = newCode
tweenIndicator.Parent = Joint
else
tweenIndicator = Joint.tweenCode
tweenIndicator.Value = newCode --If the joint is already being tweened, this will change the code, and the tween loop will stop
end
--local tweenIndicator = createTweenIndicator:InvokeServer(Joint, newCode)
if Duration <= 0 then --If the duration is less than or equal to 0 then there's no need for a tweening loop
if newC0 then Joint.C0 = newC0 end
if newC1 then Joint.C1 = newC1 end
else
local startC0 = Joint.C0
local startC1 = Joint.C1
local t0 = tick()
while true do
RS.Heartbeat:wait() --This makes the for loop step every 1/60th of a second
local X = math.min((tick() - t0) / Duration, 1) * 90
if tweenIndicator.Value ~= newCode then break end --This makes sure that another tween wasn't called on the same joint
if newC0 then Joint.C0 = startC0:lerp(newC0, Alpha(X)) end
if newC1 then Joint.C1 = startC1:lerp(newC1, Alpha(X)) end
--if newC0 then lerpCF:InvokeServer(Joint, "C0", startC0, newC0, Alpha(X)) end
--if newC1 then lerpCF:InvokeServer(Joint, "C1", startC1, newC1, Alpha(X)) end
if X == 90 then break end
end
end
if tweenIndicator.Value == newCode then --If this tween functions was the last one called on a joint then it will remove the code
tweenIndicator:Destroy()
end
--deleteTweenIndicator:InvokeServer(tweenIndicator, newCode)
end)
end
local function isEnemy(Human)
local Plyr2 = game.Players:GetPlayerFromCharacter(Human.Parent)
if (not Plyr2) then
if Settings.CanDamageNPCs then
if Human.Parent:FindFirstChild("BOT") then
return (require(Human.Parent.BOT).Allegiance ~= Bot.Allegiance)
end
end
end
return Settings.AllowFriendlyFire or (Plyr2 ~= nil and (Plyr2.Allegiance.Value ~= Bot.Allegiance or Plyr2.Neutral))
end
function Monster:GetMaximumDetectionDistance()
-- Returns the maximum detection distance
local setting = Bot.ChaseRange
if setting < 0 then
return HUGE
else
return setting
end
end
function Monster:GetCFrame(mode,...)
local args = {...}
if mode == "MainCannon" then
return Tank.Main.Gun.Flash.CFrame
elseif mode == "MGTurret" then
return Tank.Turret.Gun:FindFirstChild("Flash".. args[1]).CFrame
elseif mode == "MGTurret2" then
return Tank.Turret2.Gun:FindFirstChild("Flash".. args[1]).CFrame
elseif mode == "MGTurret3" then
return Tank.Turret3.Gun:FindFirstChild("Flash".. args[1]).CFrame
elseif mode == "MGTurret4" then
return Tank.Turret4.Gun:FindFirstChild("Flash".. args[1]).CFrame
elseif mode == "Overall" then
return Tank.Main.Parts.Engine.CFrame
end
end
function Monster:TargetIsValid()
local targetHumanoid = Mind.CurrentTargetHumanoid.Value
if targetHumanoid and targetHumanoid:IsA 'Humanoid' and not targetHumanoid:IsDescendantOf(workspace.CorpseIgnore) and targetHumanoid.Parent then
return true
else
return false
end
end
function Monster:GetTargetCFrame()
local targetHumanoid = Mind.CurrentTargetHumanoid.Value
if Monster:TargetIsValid() then
if targetHumanoid.Parent.PrimaryPart then
return targetHumanoid.Parent.PrimaryPart.CFrame
else
return CF()
end
else
return CF()
end
end
function Monster:HasClearLineOfSight(mode,...)
-- Going to cast a ray to see if I can just see my target
local args = {...}
local myPos, targetPos = Monster:GetCFrame(mode,args[1]).p, Monster:GetTargetCFrame().p
local hit, pos = RayCast(workspace,
RAY(
myPos,
Monster:GetCFrame(mode,args[1]).lookVector * 300
),
{
Tank
}
)
return hit ~= nil and hit:IsDescendantOf(Mind.CurrentTargetHumanoid.Value.Parent)
end
local function fireAtTarget(mode,pointModifier,origin)
if mode == "MainCannon" then
spawn(function()
for _, item in pairs(script.Parent.Main.Gun.Flash:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = true
end
end
end)
script.Parent.Main.Gun.Muzzle.Sound:Play()
local bolt = Instance.new("Part")
bolt.Name = "TankBolt"
bolt.BrickColor = Settings.boltSettings.Color
bolt.Size = Settings.mainCannonBoltSettings.Size
bolt.Material = Enum.Material.Neon
bolt.CFrame = origin
bolt.Anchored = true
bolt.CanCollide = false
local BF = Instance.new("BodyForce")
BF.force = Vector3.new(0, bolt:GetMass() * (196.2 - 196.2), 0)
BF.Parent = bolt
bolt.Velocity = bolt.CFrame.lookVector * Settings.mainCannonBoltSettings.Velocity
bolt.Anchored = false
bolt.Parent = workspace
bolt.Touched:connect(function(hit)
if hit:IsDescendantOf(script.Parent) then return end
local exp = Instance.new("Explosion")
exp.BlastPressure =1000
exp.DestroyJointRadiusPercent = 0
exp.BlastRadius = 10;
exp.ExplosionType = Enum.ExplosionType.NoCraters
local ray =RAY(bolt.CFrame.p,(hit.CFrame.p - bolt.CFrame.p).unit * 50)
local h,p,n = RayCast(workspace,ray,{Tank})
exp.Position = p
exp.Parent = workspace
exp.Hit:connect(function(hit,dist)
if hit == bolt then return end
Damage(hit,hit.CFrame.p,(hit.CFrame.p - p).unit,bolt.CFrame.lookVector,dist + (p - getFiringPoint().p).magnitude,{script.Parent})
end)
end)
delay(1 / 4, function()
for _, item in pairs(script.Parent.Main.Gun.Flash:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = false
end
end
end)
wait(0.5)
elseif mode == "MGTurret" then
local point = Tank.Turret.Gun:FindFirstChild("Flash"..pointModifier)
spawn(function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = true
end
end
end)
Tank.Turret.Gun:FindFirstChild("Muzzle" .. pointModifier).Sound:Play()
local bolt = Instance.new("Part")
bolt.Name = "TankBolt"
bolt.Size = Settings.mainCannonBoltSettings.Size / 2
bolt.Material = Enum.Material.Neon
bolt.CFrame = point.CFrame
bolt.BrickColor = Settings.boltSettings.Color
bolt.Anchored = true
bolt.CanCollide = false
local BF = Instance.new("BodyForce")
BF.force = Vector3.new(0, bolt:GetMass() * (196.2 - 0.2), 0)
BF.Parent = bolt
bolt.Velocity = bolt.CFrame.lookVector * Settings.mainCannonBoltSettings.Velocity
bolt.Anchored = false
bolt.Parent = workspace
bolt.Touched:connect(function(hit)
if hit:IsDescendantOf(script.Parent) then return end
if hit == bolt then return end
Damage(hit,hit.CFrame.p,(hit.CFrame.p - point.Position).unit,bolt.CFrame.lookVector,(hit.CFrame.p - point.CFrame.p).magnitude,{Tank})
end)
delay(1 / 4, function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = false
end
end
end)
wait(60 / Settings.MGRPM)
elseif mode == "MGTurret2" then
local point = Tank.Turret2.Gun:FindFirstChild("Flash"..pointModifier)
spawn(function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = true
end
end
end)
Tank.Turret2.Gun:FindFirstChild("Muzzle" .. pointModifier).Sound:Play()
local bolt = Instance.new("Part")
bolt.Name = "TankBolt"
bolt.Size = Settings.mainCannonBoltSettings.Size / 2
bolt.Material = Enum.Material.Neon
bolt.CFrame = point.CFrame
bolt.Anchored = true
bolt.CanCollide = false
local BF = Instance.new("BodyForce")
BF.force = Vector3.new(0, bolt:GetMass() * (196.2 - 0.2), 0)
BF.Parent = bolt
bolt.BrickColor = Settings.boltSettings.Color
bolt.Velocity = bolt.CFrame.lookVector * Settings.mainCannonBoltSettings.Velocity
bolt.Anchored = false
bolt.Parent = workspace
bolt.Touched:connect(function(hit)
if hit:IsDescendantOf(script.Parent) then return end
if hit == bolt then return end
Damage(hit,hit.CFrame.p,(hit.CFrame.p - point.Position).unit,bolt.CFrame.lookVector,(hit.CFrame.p - point.CFrame.p).magnitude,{Tank})
end)
delay(1 / 4, function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = false
end
end
end)
wait(60 / Settings.MGRPM)
elseif mode == "MGTurret3" then
local point = Tank.Turret3.Gun:FindFirstChild("Flash"..pointModifier)
spawn(function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = true
end
end
end)
Tank.Turret3.Gun:FindFirstChild("Muzzle" .. pointModifier).Sound:Play()
local bolt = Instance.new("Part")
bolt.Name = "TankBolt"
bolt.Size = Settings.mainCannonBoltSettings.Size / 2
bolt.Material = Enum.Material.Neon
bolt.CFrame = point.CFrame
bolt.Anchored = true
bolt.CanCollide = false
bolt.BrickColor = Settings.boltSettings.Color
local BF = Instance.new("BodyForce")
BF.force = Vector3.new(0, bolt:GetMass() * (196.2 - 0.2), 0)
BF.Parent = bolt
bolt.Velocity = bolt.CFrame.lookVector * Settings.mainCannonBoltSettings.Velocity
bolt.Anchored = false
bolt.Parent = workspace
bolt.Touched:connect(function(hit)
if hit:IsDescendantOf(script.Parent) then return end
if hit == bolt then return end
Damage(hit,hit.CFrame.p,(hit.CFrame.p - point.Position).unit,bolt.CFrame.lookVector,(hit.CFrame.p - point.CFrame.p).magnitude,{Tank})
end)
delay(1 / 4, function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = false
end
end
end)
wait(60 / Settings.MGRPM)
elseif mode == "MGTurret4" then
local point = Tank.Turret4.Gun:FindFirstChild("Flash"..pointModifier)
spawn(function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = true
end
end
end)
Tank.Turret4.Gun:FindFirstChild("Muzzle" .. pointModifier).Sound:Play()
local bolt = Instance.new("Part")
bolt.Name = "TankBolt"
bolt.Size = Settings.mainCannonBoltSettings.Size / 2
bolt.Material = Enum.Material.Neon
bolt.CFrame = point.CFrame
bolt.Anchored = true
bolt.CanCollide = false
bolt.BrickColor = Settings.boltSettings.Color
local BF = Instance.new("BodyForce")
BF.force = Vector3.new(0, bolt:GetMass() * (196.2 - 0.2), 0)
BF.Parent = bolt
bolt.Velocity = bolt.CFrame.lookVector * Settings.mainCannonBoltSettings.Velocity
bolt.Anchored = false
bolt.Parent = workspace
bolt.Touched:connect(function(hit)
if hit:IsDescendantOf(script.Parent) then return end
if hit == bolt then return end
Damage(hit,hit.CFrame.p,(hit.CFrame.p - point.Position).unit,bolt.CFrame.lookVector,(hit.CFrame.p - point.CFrame.p).magnitude,{Tank})
end)
delay(1 / 4, function()
for _, item in pairs(point:GetChildren()) do
if item.Name:find("FlashFX") then
item.Enabled = false
end
end
end)
wait(60 / Settings.MGRPM)
end
end
function getBaseDamage(Dist)
local startDmg = Settings.damageSettings.Start.Damage
local startDist = Settings.damageSettings.Start.Dist
local endDmg = Settings.damageSettings.End.Damage
local endDist = Settings.damageSettings.End.Dist
return (
(
Dist < startDist * Settings.mainCannonBoltSettings.Range
) and startDmg or
(
Dist >= startDist * Settings.mainCannonBoltSettings.Range and
Dist < endDist * Settings.mainCannonBoltSettings.Range
) and numLerp(startDmg, endDmg, Map(Dist / Settings.mainCannonBoltSettings.Range, startDist, endDist, 0, 1)) or
(
Dist >= endDist * Settings.mainCannonBoltSettings.Range
) and endDmg
)
end
function Damage(H, P, N, D, Dist, customIgnore)
local hVal = Settings.damageSettings.Multipliers.Head
local cVal = Settings.damageSettings.Multipliers.Chest
local lVal = Settings.damageSettings.Multipliers.Limbs
local baseDamage = getBaseDamage(Dist)
if script.Parent.Human.Health.Value ~= 0 then
local hitHumanoid = nil
if H.Parent:IsA("Hat") then
table.insert(customIgnore, H)
local newRay = Ray.new(P - D * 0.1, D * (Settings.mainCannonBoltSettings.Range - Dist + 0.1))
local newH, newP, newN = workspace:FindPartOnRayWithIgnoreList(newRay, customIgnore)
if newH then
hitHumanoid = Damage(newH, newP, newN, D, Dist + (newP - P).magnitude, customIgnore)
end
else
hitHumanoid = H.Parent:FindFirstChildOfClass("Humanoid")
if hitHumanoid and hitHumanoid.Health > 0 and isEnemy(hitHumanoid) then
local chosenDamage = 0
if H.Name == "Head" then
chosenDamage = baseDamage * RAND(hVal, hVal + 0.1, 0.01)
elseif H.Name == "Torso" then
chosenDamage = baseDamage * RAND(cVal, cVal + 0.1, 0.01)
else
chosenDamage = baseDamage * RAND(lVal, lVal + 0.1, 0.01)
end
tagHumanoid(hitHumanoid,chosenDamage)
hitHumanoid:TakeDamage(chosenDamage)
end
end
return hitHumanoid
end
end
function Monster:GetClosestEnemies()
local result = {}
local enemyAIs = workspace.Mobs:GetChildren()
local Tanks = workspace.Tanks:GetChildren()
local enemyPlayers = bindableService.fetch("PlayerList")
for i, enemy in next, enemyAIs, nil do
if enemy then
if enemy:FindFirstChildOfClass("Humanoid") then
if require(enemy.BOT).Allegiance ~= Bot.Allegiance and enemy.PrimaryPart then
local distance = (enemy.PrimaryPart.CFrame.p - Monster:GetCFrame("Overall").p).magnitude
if distance < Monster:GetMaximumDetectionDistance() then
result[#result+1] = enemy
end
end
end
end
end
for i, enemy in next, Tanks, nil do
if enemy then
if enemy:FindFirstChild("Human") then
if require(enemy.BOT).Allegiance ~= Bot.Allegiance and enemy.PrimaryPart then
local distance = (enemy.PrimaryPart.CFrame.p - Monster:GetCFrame("Overall").p).magnitude
if distance < Monster:GetMaximumDetectionDistance() then
result[#result+1] = enemy
end
end
end
end
end
for i, enemy in next, enemyPlayers, nil do
if enemy then
if enemy.Character then
if enemy.Character:FindFirstChildOfClass("Humanoid") then
if enemy.Allegiance.Value ~= Bot.Allegiance then
local distance = (enemy.Character.PrimaryPart.CFrame.p - Monster:GetCFrame("Overall").p).magnitude
if distance < Monster:GetMaximumDetectionDistance() then
local squadMates = enemy.playerArmy.Value:GetChildren()
for j, secondEnemy in next, squadMates, nil do
if secondEnemy:FindFirstChildOfClass("Humanoid") and secondEnemy.PrimaryPart then
local distance = (secondEnemy.PrimaryPart.CFrame.p - Monster:GetCFrame("Overall").p).magnitude
if distance < Monster:GetMaximumDetectionDistance() then
result[#result+1] = secondEnemy
end
end
end
end
end
end
end
end
end
return result
end
function Monster:SearchForTarget(randomized)
-- Finds the closest player and sets the target
local npcs = Monster:GetClosestEnemies()
local closestCharacter, closestCharacterDistance
if not randomized then
for i, npc in next, npcs, nil do
local npcBOT = require(npc.BOT)
if npcBOT.Allegiance ~= Bot.Allegiance then
if npc ~= nil and npc:FindFirstChild('Human') ~= nil and npc.Human:IsA('Humanoid') then
local distance = (npc.PrimaryPart.CFrame.p - Monster:GetCFrame("Overall").p).magnitude
if distance < Monster:GetMaximumDetectionDistance() then
if closestCharacter == nil then
closestCharacter, closestCharacterDistance = npc, distance
else
if closestCharacterDistance > distance then
closestCharacter, closestCharacterDistance = npc, distance
Data.EnemyAllegiance = npcBOT.Allegiance
end
end
end
end
end
end
local players = bindableService.fetch("PlayerList")
for i, player in next, players, nil do
if player.Allegiance.Value ~= Bot.Allegiance then
local character = player.Character
if character ~= nil and character:FindFirstChild('Humanoid') ~= nil and character.Humanoid:IsA('Humanoid') then
local distance = (character.PrimaryPart.CFrame.p - Monster:GetCFrame("Overall").p).magnitude
if distance < Monster:GetMaximumDetectionDistance() then
if closestCharacter == nil then
closestCharacter, closestCharacterDistance = character, distance
else
if closestCharacterDistance > distance then
closestCharacter, closestCharacterDistance = character, distance
Data.EnemyAllegiance = player.Allegiance.Value
end
end
end
end
end
end
else
closestCharacter = npcs[math.random(1,#npcs)]
end
if closestCharacter ~= nil then
return closestCharacter
else
return nil
end
end
function Monster:Update()
local enemy = Monster:SearchForTarget(false)
if enemy then
if enemy:IsA("Model") then
if (Monster:GetTargetCFrame().p - Monster:GetCFrame("Overall").p).magnitude <= 2048 then
Mind.CurrentTargetHumanoid.Value = enemy:FindFirstChild("Human")
if not Monster:TargetIsValid() then return end
local gunModifier = math.random(1,5)
local pointModifier = math.random(1,2)
if gunModifier == 1 then
setTurretDirection("MainCannon",getYawPitch(CFrame.new(parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MainCannon",getYawPitch(CFrame.new(parts.GunBase.CFrame.p,parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - parts.GunBase.CFrame.p).unit)))
fireAtTarget("MainCannon",pointModifier,getFiringPoint())
elseif gunModifier == 2 then
setTurretDirection("MGTurret",getYawPitch(CFrame.new(Tank.Turret.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret",getYawPitch(CFrame.new(Tank.Turret.Parts.GunBase.CFrame.p,Tank.Turret.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret",pointModifier,getFiringPoint())
elseif gunModifier == 3 then
setTurretDirection("MGTurret2",getYawPitch(CFrame.new(Tank.Turret2.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret2",getYawPitch(CFrame.new(Tank.Turret2.Parts.GunBase.CFrame.p,Tank.Turret2.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret2.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret2",pointModifier,getFiringPoint())
elseif gunModifier == 4 then
setTurretDirection("MGTurret3",getYawPitch(CFrame.new(Tank.Turret3.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret3",getYawPitch(CFrame.new(Tank.Turret3.Parts.GunBase.CFrame.p,Tank.Turret3.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret3.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret3",pointModifier,getFiringPoint())
elseif gunModifier == 5 then
setTurretDirection("MGTurret4",getYawPitch(CFrame.new(Tank.Turret4.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret4",getYawPitch(CFrame.new(Tank.Turret4.Parts.GunBase.CFrame.p,Tank.Turret4.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret4.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret4",pointModifier,getFiringPoint())
end
end
elseif game.Players:GetPlayerFromCharacter(enemy) then
local player = game.Players:GetPlayerFromCharacter(enemy)
if player then
if player:DistanceFromCharacter(Engine.Position).magnitude <= 2048 then
Mind.CurrentTargetHumanoid.Value = enemy.Humanoid
local gunModifier = math.random(1,5)
local pointModifier = math.random(1,2)
if gunModifier == 1 then
setTurretDirection("MainCannon",getYawPitch(CFrame.new(parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MainCannon",getYawPitch(CFrame.new(parts.GunBase.CFrame.p,parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - parts.GunBase.CFrame.p).unit)))
fireAtTarget("MainCannon",pointModifier,getFiringPoint())
elseif gunModifier == 2 then
setTurretDirection("MGTurret",getYawPitch(CFrame.new(Tank.Turret.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret",getYawPitch(CFrame.new(Tank.Turret.Parts.GunBase.CFrame.p,Tank.Turret.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret",pointModifier,getFiringPoint())
elseif gunModifier == 3 then
setTurretDirection("MGTurret2",getYawPitch(CFrame.new(Tank.Turret2.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret2",getYawPitch(CFrame.new(Tank.Turret2.Parts.GunBase.CFrame.p,Tank.Turret2.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret2.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret2",pointModifier,getFiringPoint())
elseif gunModifier == 4 then
setTurretDirection("MGTurret3",getYawPitch(CFrame.new(Tank.Turret3.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret3",getYawPitch(CFrame.new(Tank.Turret3.Parts.GunBase.CFrame.p,Tank.Turret3.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret3.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret3",pointModifier,getFiringPoint())
elseif gunModifier == 5 then
setTurretDirection("MGTurret4",getYawPitch(CFrame.new(Tank.Turret4.Parts.GunBase.CFrame.p,Monster:GetTargetCFrame().p)))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (Monster:GetTargetCFrame().p - Engine.CFrame.p).unit * Vector3.new(1,0,1))
setTurretDirection("MGTurret4",getYawPitch(CFrame.new(Tank.Turret4.Parts.GunBase.CFrame.p,Tank.Turret4.Parts.GunBase.CFrame.p + (Monster:GetTargetCFrame().p - Tank.Turret4.Parts.GunBase.CFrame.p).unit)))
fireAtTarget("MGTurret4",pointModifier,getFiringPoint())
end
end
end
end
wait(16)
Mind.CurrentTargetHumanoid.Value = nil
else
local points = game.Workspace.TankPatrolPoints:GetChildren()
local point = points[#points].CFrame.p
Engine.BodyGyro.CFrame = CFrame.new(Engine.CFrame.p,Engine.CFrame.p + (point - Engine.CFrame.p).unit * Vector3.new(1,0,1))
Engine.BodyVelocity.Velocity = Engine.CFrame.lookVector * 25
repeat wait() until (point - Engine.CFrame.p).magnitude <= 3
end
end
spawn(function()
for _, hullPart in pairs(script.Parent.Main.Hull:GetChildren()) do
hullPart.Touched:connect(function(hit)
Damage(hit,hit.CFrame.p,(hit.CFrame.p - Engine.Position).unit,Engine.CFrame.lookVector,(Engine.Position - getFiringPoint().p).magnitude,{script.Parent})
end)
end
end)
Tank.DescendantRemoving:connect(function(item)
if item:IsA("JointInstance") then
Tank.Human.Health.Value = 0
end
end)
Engine.Start:Play()
wait(1)
Engine.Loop:Play()
spawn(function()
while wait() do
if Engine.CFrame.p.Y > -130 then
Engine.BodyPosition.MaxForce = Vector3.new(0,40000000,0)
Engine.BodyPosition.Position = Vector3.new(Engine.CFrame.p.X,-130,Engine.CFrame.p.Z)
else
Engine.BodyPosition.MaxForce = Vector3.new(0,0,0)
end
end
end)
script.Parent.Human.Health.Changed:connect(function(health)
if health <= 0 then
local Humanoid = script.Parent:FindFirstChild("Human")
local xp = 40
local gold = 0
local people = {}
local damages = {}
local weapons = {}
for _, tagStr in pairs(game:GetService("CollectionService"):GetTags(Humanoid)) do
local tag = DamageTag.ParseTag(tagStr)
if tag then
local Killer = tag:GetKiller()
local usedWeapon = tag:GetWeaponName()
if Killer then
if not isInPeople(people, Killer) then
people[#people+1] = Killer
weapons[#weapons+1] = usedWeapon
damages[#damages+1] = tag.dmg
else
if string.lower(Others.XPShareMode) ~= "classic" then
local y = getIndexOfValue(people, Killer)
damages[y] = damages[y] + CEIL(tag.dmg)
end
end
end
end
RS.Heartbeat:wait()
end
local health = 0
for i,v in pairs(damages) do
health = health + v
end
table.sort(people,function(a,b)
local damagea, damageb
local indexA, indexB = getIndexOfValue(people,a), getIndexOfValue(people,b)
damagea = damages[indexA]
damageb = damages[indexB]
return damagea > damageb
end)
table.sort(damages,function(a,b)
return a > b
end)
table.sort(weapons,function(a,b)
local damagea, damageb
local indexA, indexB = getIndexOfValue(weapons,a), getIndexOfValue(weapons,b)
damagea = damages[indexA]
damageb = damages[indexB]
return damagea > damageb
end)
spawn(function()
local prevV = nil
for d, v in pairs(people) do
print("Giving stats to ", v.Name, " | ", d)
if v ~= nil then
if prevV ~= v then
prevV = v
if v:IsA("Player") then
local ls = v:FindFirstChild("leaderstats")
if ls then
if d == 1 then
ProgressionService:AddXP(v, (damages[d]/health)*xp, "tank")
elseif d > 1 and d <= 3 then
ProgressionService:AddXP(v, (damages[d]/health)*xp, "tankassist_kill")
else
ProgressionService:AddXP(v, (damages[d]/health)*xp, "tank_assist")
end
--Module:AwardPlayerPoints(CEIL((damages[d]/health)*xp), v)
end
end
end
end
RS.Heartbeat:wait()
end
end)
local exp = Instance.new("Explosion")
exp.Position = Engine.Position
exp.BlastRadius = script.Parent:GetExtentsSize().magnitude
exp.ExplosionType = Enum.ExplosionType.NoCraters
exp.Parent = workspace
game.Debris:AddItem(script.Parent,4)
end
end)
while script.Parent.Human.Health.Value > 0 do
Monster:Update()
wait()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment