Fifkee

Bloxsona 5 Battle System Prototype Source

Mar 17th, 2020
1,518
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 145.41 KB | None | 0 0
  1. math.randomseed(tick()) --set math.randomseed to tick
  2. local Battle = {FinishedAttacking = true}
  3. --dummy variables
  4. local CameraShaker = require(game:GetService('ReplicatedStorage').ModuleScripts.CameraShaker);
  5. local Difficulty;
  6. local OneMore = false
  7. local Player = game.Players.LocalPlayer;
  8. local PlayerGui = Player.PlayerGui;
  9. local Character = Player.Character or Player.CharacterAdded:Wait();
  10. local RichText = require(PlayerGui:WaitForChild('RichText'))
  11. --note: for attacks that hit everyone, do the effect on all targets and then damage
  12. --useful variables
  13. local ReplicatedStorage = game:GetService('ReplicatedStorage')
  14. local Music = game:GetService('ReplicatedStorage'):WaitForChild('Music');
  15. local Shouts = ReplicatedStorage:WaitForChild('Shouts')
  16. local Items = ReplicatedStorage:WaitForChild('ModuleScripts'):WaitForChild('Items');
  17. Items = require(Items);
  18. local Attacks = ReplicatedStorage:WaitForChild("ModuleScripts"):WaitForChild('Attacks')
  19. Attacks = require(Attacks)
  20. local Personas = ReplicatedStorage:WaitForChild("ModuleScripts"):WaitForChild('PersonaList')
  21. Personas = require(Personas)
  22. local EnemyAPI = require(ReplicatedStorage:WaitForChild("ModuleScripts"):WaitForChild'EnemyAPI')
  23. local Effects = require(ReplicatedStorage:WaitForChild'ModuleScripts':WaitForChild('Effects'))
  24. local UIS = game:GetService('UserInputService');
  25. local E = Enum;
  26. local CollectionService = game:GetService('CollectionService');
  27. local Shake = ReplicatedStorage:WaitForChild('ModuleScripts'):WaitForChild('Shake')
  28. Shake = require(Shake);
  29. function recalculateHipHeight(TargetModel)
  30.     local bottomOfHumanoidRootPart = TargetModel.HumanoidRootPart.Position.Y - (1/2 * TargetModel.HumanoidRootPart.Size.Y)
  31.     local bottomOfFoot = TargetModel.LeftFoot.Position.Y - (1/2 * TargetModel.LeftFoot.Size.Y) -- Left or right. Chose left arbitrarily
  32.     local newHipHeight = bottomOfHumanoidRootPart - bottomOfFoot
  33.  
  34.     return newHipHeight
  35. end
  36. local K = E.KeyCode;
  37. impwarn = warn;
  38. impprint = print;
  39. local currentTween;
  40. if not _G.Dev then
  41.     warn = function() end;
  42.     print = function() end;
  43.     --print = function() end;
  44. end
  45. function Battle:InvisibleParty()
  46.     self.InvisiblePartyFlag = not self.InvisiblePartyFlag;
  47.     if (self.InvisiblePartyFlag) then
  48.         for i, v in pairs(self.PartyContainer:GetChildren()) do
  49.             v.PrimaryPart.Anchored = true
  50.             v:SetPrimaryPartCFrame(v:GetPrimaryPartCFrame() - Vector3.new(0,200, 0))
  51.         end
  52.         Character:SetPrimaryPartCFrame(Character:GetPrimaryPartCFrame() - Vector3.new(0, 200, 0))
  53.     else
  54.         for i, v in pairs(self.PartyContainer:GetChildren()) do
  55.             v:SetPrimaryPartCFrame(v:GetPrimaryPartCFrame() + Vector3.new(0,200, 0))
  56.             v.PrimaryPart.Anchored = false
  57.         end
  58.         Character:SetPrimaryPartCFrame(Character:GetPrimaryPartCFrame() + Vector3.new(0, 200, 0))
  59.     end
  60. end
  61. function Battle:InvisibleEnemies()
  62.     self.InvisibleEnemiesFlag = not self.InvisibleEnemiesFlag;
  63.     if (self.InvisibleEnemiesFlag) then
  64.         for i, v in pairs(self.EnemyContainer:GetChildren()) do
  65.             v.PrimaryPart.Anchored = true
  66.             v:SetPrimaryPartCFrame(v:GetPrimaryPartCFrame() - Vector3.new(0,200, 0))
  67.         end
  68.     else
  69.         for i, v in pairs(self.EnemyContainer:GetChildren()) do
  70.             v:SetPrimaryPartCFrame(v:GetPrimaryPartCFrame() + Vector3.new(0,200, 0))
  71.             v.PrimaryPart.Anchored = false;
  72.         end
  73.     end
  74. end
  75. function Battle:EndBattleProtocol(NoHealth, NHealth, force)
  76.     if force or (NoHealth == #self.Enemies or NHealth == #self.Characters) then
  77.         CurrentCameraShake:StopSustained(1)
  78.         spawn(function()
  79.             wait(1)
  80.             CurrentCameraShake:Stop()
  81.         end)
  82.        
  83.         self:EndBattle();
  84.        
  85.         for i, v in pairs(Character.Humanoid:GetPlayingAnimationTracks()) do
  86.             v:Stop(); --stop all playing animations, the default animator will replay animations again so it doesn't matter'
  87.         end
  88.         local PLighting = ReplicatedStorage:FindFirstChild('Previous Lighting');
  89.         if (PLighting) then
  90.             for i, v in pairs(PLighting:GetChildren()) do
  91.                 pcall(function()
  92.                     game:GetService('Lighting')[v.Name] = v.Value;
  93.                 end)
  94.             end
  95.         end
  96.         self.BattleArea:Destroy();
  97.         for i, v in pairs(game:GetService'Lighting':GetChildren()) do
  98.             if (v.ClassName:match('Effect') and v.Name ~= 'e') then
  99.                 v.Enabled = true
  100.             end
  101.         end
  102.         Character:SetPrimaryPartCFrame(self.PositionBeforeBattle)
  103.         Character:WaitForChild('HumanoidRootPart').Anchored = false;
  104.        
  105.         pcall(StopAnimation, nil, Character:WaitForChild('Humanoid'))
  106.         _G.Music:Resume();
  107.         return true, script:Destroy(); --self destruct script just to be safe
  108.     end
  109. end
  110. repeat wait() until _G.BattleAnnouncement;
  111. --stupid shit
  112.  
  113. function GS(s)
  114.     return game:GetService(s)
  115. end
  116.  
  117. function playAnimOnModel(m, Anim, waittime)
  118.     if (not m) then return nil end
  119.     local m2 = m:Clone();
  120.     m2.Parent = workspace;
  121.     local CFThingToDisconnect = game:GetService('RunService').RenderStepped:Connect(function(Step)
  122.         for i, v in pairs(m:GetChildren()) do
  123.             if (not v:FindFirstChild('originalCFrame') and v:IsA('BasePart')) then
  124.                 local CF = Instance.new('CFrameValue', v)
  125.                 CF.Name = 'originalCFrame';
  126.                 CF.Value = v.CFrame;
  127.             end
  128.             for i,x in pairs(m2:GetChildren()) do
  129.                 if (v.Name == x.Name and v:IsA('BasePart')) then
  130.                     v.CFrame = x.CFrame;
  131.                     --
  132.                 end
  133.             end
  134.         end
  135.     end)
  136.    
  137.     if (not Anim) then CFThingToDisconnect:Disconnect(); return nil end
  138.    
  139.     local anim = m2:WaitForChild('Humanoid'):LoadAnimation(Anim);
  140.     anim:Play()
  141.     --
  142.     if (waittime) then
  143.         wait(waittime)
  144.     end
  145.    
  146.     --
  147.    
  148.     spawn(function(s)
  149.         wait(anim.Length+0.25)
  150.         CFThingToDisconnect:Disconnect();
  151.         for i, v in pairs(m:GetChildren()) do
  152.             if (v:FindFirstChild('originalCFrame')) then
  153.                 v.CFrame = v.originalCFrame.Value;
  154.                 --
  155.             end
  156.         end
  157.     end)
  158.     --
  159.     --
  160.     --
  161.     m2:Destroy();
  162.     return true;
  163. end
  164.  
  165. function showMaskSteal()
  166.     local ViewportFrame = PlayerGui:WaitForChild('MaskStealAnimation'):WaitForChild('ViewportFrame')
  167.     local XYZ = ViewportFrame;
  168.     for i = 1, 0, -0.25 do
  169.         GS('RunService').RenderStepped:Wait()
  170.         XYZ.ImageTransparency = i;
  171.     end
  172.    
  173.    
  174.     local MaskSteal = GS'ReplicatedStorage':WaitForChild('AnimationAssets'):WaitForChild('Mask Steal');
  175.     local A1 = ViewportFrame:WaitForChild('maskSteal'):WaitForChild('person1');
  176.     local B1 = ViewportFrame:WaitForChild('maskSteal'):WaitForChild('person2');
  177.     playAnimOnModel(A1, MaskSteal.person1, nil)
  178.     playAnimOnModel(B1, MaskSteal.person2, nil)
  179.     --playAnimOnModel(animModel, Anim, waittime)
  180.  
  181.     spawn(function(xyz) --to prevent people from doing the stuffs
  182.         wait(2.4)
  183.         for i = 0, 1, 0.25 do
  184.             GS('RunService').RenderStepped:Wait()
  185.             XYZ.ImageTransparency = i;
  186.         end
  187.     end)
  188.     spawn(function(xyztwo)
  189.         wait(1.25)
  190.         ReplicatedStorage.Music:WaitForChild('Glass Shattering'):Play();
  191.     end)
  192.    
  193.     wait(2.1)
  194.     --
  195.     return true
  196. end
  197.  
  198. BattleInfo = { --Independant turns for every character.
  199.     EnemyTurns = {}; --one for the enemies
  200.     PlayerTurns = {}; --one for the player. this allows for rakukaja to turn on/off not when it's Akira's turn
  201.     EnemyActions = {};
  202.    
  203.     MemberActions = {};
  204.     MemberAnimations = {};
  205.     SelectedPersonaAttack = nil;
  206.    
  207.     BattleStage = 'Main'; --using general identifiers for battlestage
  208.     SelectedMember = 0; --Default to 0 so we can know this is the start of the battle.
  209. }
  210.  
  211. function Battle:GetFirstLivingEnemy()
  212.     for i, v in pairs(self.Enemies) do
  213.         if v.Health > 0 then
  214.             return i, v;
  215.         end
  216.     end
  217. end
  218.  
  219. function Battle:showOneMore()
  220.     ReplicatedStorage.Music:WaitForChild('Explosion'):Play();
  221.     PlayerGui.OneMore.Frame.BackgroundTransparency = 0;
  222.     spawn(function(x)
  223.         for i = 0, 1, 0.1 do
  224.             wait();
  225.             PlayerGui.OneMore.Frame.BackgroundTransparency = i;
  226.         end
  227.     end)
  228.     PlayerGui.OneMore.ViewportFrame.ImageTransparency = 0;
  229.     wait(1.15)
  230.     for i = 0, 1, 0.1 do
  231.         wait()
  232.         PlayerGui.OneMore.ViewportFrame.ImageTransparency = i;
  233.     end
  234. end
  235.  
  236. function Battle:MoveCameraToCharacter(i, varia)
  237.     if (currentTween) then currentTween:Cancel(); currentTween = nil; end
  238.     varia = typeof(varia) == 'table' and varia or {};
  239.     local pointTo = varia.PointTo
  240.     local instant = varia.Instant or varia.instant;
  241.     local yield = varia.Yield or varia.yield;
  242.    
  243.     local Char = self:GetCharacterFromID(i);
  244.     local SpawnCFValue = Char.PrimaryPart.CFrame;
  245.     local SpawnLookVector = SpawnCFValue.LookVector * 8.5;
  246.     local ROT =  CFrame.Angles(CFrame.new(SpawnLookVector + SpawnCFValue.Position, Char.PrimaryPart.Position):ToEulerAnglesXYZ());
  247.     local RealCFValue = CFrame.new(SpawnLookVector)-- * ROT
  248.     local CFValue = RealCFValue.Position + Char.PrimaryPart.CFrame.p
  249.    
  250.     if (pointTo) then
  251.         CFValue = CFrame.new(CFValue) * CFrame.Angles(CFrame.new(CFValue, typeof(pointTo) == 'Instance' and pointTo.Position or pointTo):ToEulerAnglesXYZ())
  252.     else
  253.         CFValue = CFrame.new(CFValue) * ROT
  254.     end
  255.    
  256.     currentTween = Tween(workspace.CurrentCamera, TweenInfo.new(instant and 0.1 or 0.25), {CFrame = CFValue})
  257.     currentTween = currentTween:Play();
  258.     local x = yield and wait(0.25);
  259.     return true
  260. end
  261.  
  262.     --face camera towards players if not ambush, if ambush then just move the reticle   --iiifat
  263. --add zeroes
  264. local function safetyZero(num, places)
  265.     --
  266.     --
  267.     places = places or 2
  268.     num = num or 1
  269.     return ('0'):rep(#tostring(places)-#tostring(num))..tostring(num)
  270. end
  271.  
  272. function Battle:GetEnemyFromID(i, returnChar)
  273.    
  274.     --iterate over all enemies in the enemies table
  275.    
  276.     for index, value in pairs(self.Enemies) do
  277.         if (value.Health > 0 and index >= i) then --if the ID is invalid, then return the first available enemy
  278.             if (returnChar) then
  279.                 return self.EnemyContainer:WaitForChild(tostring(index))
  280.             else
  281.                 return index, value
  282.             end
  283.         end
  284.     end
  285.    
  286.    
  287. end
  288.  
  289.  
  290. function Battle:MoveCameraToEnemy(i, yield, offset)
  291.    
  292.     --let's use getChildren for this, we'll switch to an ID-based system in case the game gets confused with their sorting for some reason
  293.    
  294.     local Char = self.EnemyContainer[tostring(i)]--:GetChildren()[i]
  295.     local SpawnCFValue = Char.PrimaryPart.CFrame--self.EnemySpawns['Spawn'..i].CFrame;
  296.     local SpawnLookVector = SpawnCFValue.LookVector * (8.5 * (Char.PrimaryPart.Size.Y / 1.459))
  297.     local ROT =  CFrame.Angles(CFrame.new(SpawnLookVector + SpawnCFValue.Position, Char.PrimaryPart.Position):ToEulerAnglesXYZ());
  298.     local RealCFValue = CFrame.new(SpawnLookVector) * ROT
  299.     local CFValue = RealCFValue + Char.PrimaryPart.CFrame.p;
  300.     Tween(workspace.CurrentCamera, TweenInfo.new(0.25), {CFrame = CFValue}):Play();
  301.     local x = yield and wait(0.25);
  302.     return true;
  303. end
  304.  
  305.  
  306. DifficultyModifiers = { --difficulty modifiers to get rates of exchange
  307.     Safety = {
  308.         DamageRecieved=0.5;
  309.         DamageDealt=2.0;
  310.         Experience=3.0;
  311.         Money=5.0;
  312.     };
  313.    
  314.     Easy = {
  315.         DamageRecieved=0.75;
  316.         DamageDealt=1.5;
  317.         Experience=1.5;
  318.         Money=1.5;
  319.     };
  320.    
  321.     Normal = {
  322.         DamageRecieved=1.0;
  323.         DamageDealt=1.0;
  324.         Experience=1.0;
  325.         Money=1.0;
  326.     };
  327.    
  328.     Hard = {
  329.         DamageRecieved=1.15;
  330.         DamageDealt=0.9;
  331.         Experience=1.0;
  332.         Money=1.0;
  333.     };
  334.    
  335.     Merciless={
  336.         DamageRecieved=1.25;
  337.         DamageDealt=0.8;
  338.         Experience=0.77;
  339.         Money=0.67;
  340.     };
  341.     Satanic = {
  342.         DamageRecieved = 1.35;
  343.         DamageDealt = 0.71;
  344.         Experience = 0.765;
  345.         Money = 0.625;
  346.     }
  347.    
  348. }
  349.  
  350. --function to turn any table into a table ready for battle, can be used as many times as needed
  351. local Dropped;
  352. function Metatable(t)
  353.     for i,v in pairs(t) do
  354.         if (not v.MaxHealth) and (v.Attacks) then
  355.             v.MaxHealth = v.Health;
  356.         end
  357.        
  358.         if (not v.Persona) then
  359.             v.ID = i;
  360.             print('Name:', v.Name);
  361.             for i,v in pairs(v) do
  362.                 if (i ~= 'Name') then
  363.                     if (typeof(v) == 'table') then
  364.                         for x, v in pairs(v) do
  365.                             print(i..'.'..x..':', v)
  366.                         end
  367.                     else
  368.                         print(i..':', v)
  369.                     end
  370.                 end
  371.             end
  372.             local Likings = require(game:GetService('ReplicatedStorage').ModuleScripts.Dialogue.PersonaLikings);
  373.             v.Personality = Likings[math.random(1, #Likings)].Type
  374.             local ShouldDropItem = math.random() < (math.random(1, math.random(100)))/100
  375.             if (not Dropped and ShouldDropItem) then
  376.                 local ViableItemsList = {};
  377.                 for i, v in pairs(Items) do
  378.                     if ( (v.HP or v.SP) and v.Price and v.NoBattle) then
  379.                         ViableItemsList[#ViableItemsList+1] = i;
  380.                     end
  381.                 end
  382.                
  383.                 local SelectedItem = ViableItemsList[math.random(1, #ViableItemsList)];
  384.                 v.BoundItem = SelectedItem;
  385.             end
  386.         end
  387.         local mt = setmetatable(v, {});
  388.         mt.__index = v;
  389.         function v:GetHealth()
  390.             return self.Health;
  391.         end
  392.         function v:SubtractHealth(amt)
  393.             if (typeof(amt) == 'string') then
  394.                 if (amt:lower() == 'all') then amt = self.MaxHealth end;
  395.                 if (amt:lower() == 'half') then amt = self.Health/2 end;
  396.             end
  397.             self.Health = math.floor(math.clamp(self.Health - amt, 0, math.huge));
  398.             return self.Health;
  399.         end
  400.        
  401.         function v:Heal(amt, dismiss)
  402.            
  403.             --impwarn("amount:", amt)
  404.            
  405.             amt = amt or 0;
  406.             amt = tostring(amt):lower() == 'half' and self.MaxHealth/2 or amt;
  407.            
  408.             amt = tostring(amt):lower() == 'max' and math.huge or 100;
  409.            
  410.             self.Health = math.ceil(math.clamp(self.Health + amt, 0, self.MaxHealth));
  411.             if (not dismiss) then
  412.                 if (amt < self.MaxHealth*0.356789) then
  413.                     local Audio = ReplicatedStorage:WaitForChild('SFX'):WaitForChild('LowHeal');
  414.                     Audio = Audio:Clone();
  415.                     Audio.Parent = PlayerGui;
  416.                     Audio.PlayOnRemove = true;
  417.                     Audio:Destroy();
  418.                 else
  419.                     local Audio = ReplicatedStorage:WaitForChild('SFX'):WaitForChild('LowHeal');
  420.                     Audio = Audio:Clone();
  421.                     Audio.Parent = PlayerGui;
  422.                     Audio.PlayOnRemove = true;
  423.                     Audio:Destroy();
  424.                 end;
  425.             end
  426.             return self.Health;
  427.         end
  428.        
  429.         function v:BuffDamage(amt)
  430.             self.AddedAttack = self.AddedAttack+amt;
  431.             return self.AddedAttack;
  432.         end
  433.    
  434.         function v:AddDebuff(table)
  435.             print('Added debuff:', table.Name or #self.Debuffs+1);
  436.             table.Length = table.Length+1;
  437.             self.Debuffs = self.Debuffs or {};
  438.             self.Debuffs[table.Name or #self.Debuffs+1] = table
  439.         end
  440.    
  441.         function v:BuffDefense(amt)
  442.             self.AddedDefense = self.AddedDefense+amt;
  443.             return self.AddedDefense;
  444.         end
  445.        
  446.         function v:SubtractAmmo()
  447.             local EquippedGun = Items[self.Equipped.Gun];
  448.             if (self.Ammo == -1) then self.Ammo = EquippedGun.Ammo-1; return self.Ammo; end;
  449.             self.Ammo = self.Ammo - 1;
  450.             return self.Ammo;
  451.         end
  452.        
  453.         function v:GetAmmo()
  454.             local EquippedGun = Items[self.Equipped.Gun];
  455.             if (self.Ammo == -1) then self.Ammo = EquippedGun.Ammo end;
  456.             return self.Ammo;  
  457.         end
  458.        
  459.         function v:SubtractSP(amt)
  460.             self.SP = self.SP and math.clamp(self.SP-amt, 0, self.MaxSP or 100) or 0
  461.         end
  462.         function v:AddSP(amt)
  463.             self.SP = self.SP and math.clamp(self.SP+amt, 0, self.MaxSP or 100) or 0
  464.         end
  465.         function v:concatKey(sep)
  466.             local str = '';
  467.             for i, v in pairs(self) do
  468.                 str = str..string.format('%s - %s%s\n', tostring(i), tostring(v), sep or ', ')
  469.             end
  470.             return str
  471.         end
  472.     end
  473. end
  474.  
  475.  
  476. --functions for animations
  477.  
  478.  
  479. --function to get enemies from strings
  480. function getPersonaFromString(s, r)
  481.    
  482.     local n = Personas[s];
  483.     local newTable = {};
  484.    
  485.     --two layer-deep unpack monkaW
  486.    
  487.     for i, v in pairs(n) do
  488.         if (typeof(v) == 'table') then
  489.             newTable[i] = {};
  490.             for z,v in pairs(v) do
  491.                 newTable[i][z] = v;
  492.             end
  493.         else
  494.             newTable[i] = v;
  495.         end
  496.     end
  497.    
  498.     return newTable;
  499. end
  500.  
  501. --useless but useful get attacks function
  502. function getAttack(n)
  503.     return Attacks[n]
  504. end
  505.  
  506.  
  507.  
  508.  
  509. --modify damage function to calculate HP costs based on max health
  510. function modifyDamage(n,mx)
  511.     return math.ceil(mx - (((100-n)/100)*mx))
  512. end
  513.  
  514.  
  515. function Battle:getCharacterOnRight(iv, include_dead)
  516.    
  517.     for i, v in pairs(Battle.Characters) do
  518.         if (i > iv)
  519.         and ((include_dead and v.Health > 0) or not include_dead) then
  520.             return i
  521.         end
  522.     end
  523.     return iv
  524. end
  525.  
  526. function Battle:getCharacterOnLeft(iv, include_dead)
  527.    
  528.     for i, v in pairs(Battle.Characters) do
  529.         if (i < iv) and ((include_dead and v.Health > 0) or not include_dead) then
  530.             return i
  531.         end
  532.     end
  533.     return iv
  534. end
  535.  
  536. function Battle:GetEnemy(mode, iv)
  537.     mode = mode:lower()
  538.     for i, v in pairs(self.Enemies) do
  539.         local compL = i < iv --I sincerely have no idea why this happens.
  540.         local compR = i > iv;
  541.         local comp;
  542.        
  543.         if (mode == 'l') then
  544.             for i = iv, 0, -1 do
  545.                
  546.                 if (not self.Enemies[i]) then
  547.                     return iv; --if there is no enemy before one
  548.                 elseif --[[(not checkIncapacitated(self.Enemies[i])) and]] i ~= iv and self.Enemies[i].Health > 0 then
  549.                     return i
  550.                 end
  551.             end
  552.         elseif (mode == 'r') then
  553.             comp = compR;
  554.         end
  555.        
  556.         if (comp) and v.Health > 0 then
  557.             return i;
  558.         end
  559.     end
  560.    
  561.     return iv;
  562. end
  563.  
  564.  
  565. function Battle:GetCharacter(mode, iv, include_dead)
  566.     mode = mode:lower()
  567.     for i, v in pairs(self.Characters) do
  568.         local compL = i > iv;
  569.         local compR = i < iv;
  570.         local comp;
  571.         if (mode == 'l') then
  572.             comp = compL;
  573.         elseif (mode == 'r') then
  574.             comp = compR;
  575.         end
  576.         if (not include_dead and v.Health > 0) or include_dead then
  577.             if (comp) then
  578.                 return i;
  579.             end
  580.         end
  581.     end
  582.    
  583.     return iv;
  584. end
  585. --animation functon for humanoid objects
  586.  
  587. function LoadAnimation(AnimationObject, Target)
  588.     if (BattleInfo.MemberAnimations[Target]) then --if the humanoid was already used as a target
  589.         if (BattleInfo.MemberAnimations[Target][tostring(AnimationObject.AnimationId)]) then --check if the humanoid already loaded the animation object
  590.             return BattleInfo.MemberAnimations[Target][tostring(AnimationObject.AnimationId)] --return the animation track if so
  591.         else --otherwise
  592.            
  593.             BattleInfo.MemberAnimations[Target][tostring(AnimationObject.AnimationId)] = Target:LoadAnimation(AnimationObject) --make animationobject point to the animationtrack
  594.             return BattleInfo.MemberAnimations[Target][tostring(AnimationObject.AnimationId)] --return the animation track
  595.         end
  596.     else --if the humanoid is fresh
  597.        
  598.         BattleInfo.MemberAnimations[Target] = {}; --set the humanoid to point to an animation storage table
  599.         BattleInfo.MemberAnimations[Target][tostring(AnimationObject.AnimationId)] = Target:LoadAnimation(AnimationObject) --save animation to table
  600.         return BattleInfo.MemberAnimations[Target][tostring(AnimationObject.AnimationId)] --return animation
  601.     end
  602. end
  603. function Battle:LoadAnimation(...)
  604.     return LoadAnimation(...)
  605. end
  606. function StopAnimation(Animation, Target)
  607.     -- MemberAnimations -> [Table (Humanoid Object/Target)] -> AnimationObject Name == AnimationTrack
  608.     --MemberAnimations -> Table -> Animation Object -> Animation Track
  609.    
  610.     Animation = typeof(Animation) == "string" and {Name = Animation} or Animation;
  611.     for i, v in pairs(Target:GetPlayingAnimationTracks()) do
  612.         if (v.Name == Animation.Name) then
  613.             v:Stop();
  614.         end
  615.     end
  616.     return warn('Couldn\'t find animation', Animation.Name)
  617. end
  618.  
  619. function animationStatus(Animation, Humanoid)
  620.     for i, v in pairs(Humanoid:GetPlayingAnimationTracks()) do
  621.         if (v.Name:lower() == Animation.Name:lower()) then
  622.             --impwarn('Found animation track.')
  623.             return v;
  624.         end
  625.     end
  626.     return false
  627. end
  628.  
  629. --personaify function to make text randomly black or white with random rotation
  630. function personaIfy(text)
  631.     local MAX = 3;
  632.     local str='';
  633.     local NONCOUNT = 1;
  634.     local LastPersonaIfied = false;
  635.     for i = 0, #text do
  636.         if (math.random() < 0.5 and MAX ~= 0 and LastPersonaIfied ~= true and NONCOUNT >= 2) then
  637.             NONCOUNT = 0;
  638.             MAX=MAX-1
  639.             LastPersonaIfied = true;
  640.             str = str..'<TextColor3=Black><Rotation='..math.random(-5, 5)..'><BackgroundTransparency=0>'..text:sub(i,i)..'<TextColor3=White><BackgroundTransparency=1><Rotation=0>'
  641.         else
  642.             NONCOUNT = NONCOUNT+1;
  643.             LastPersonaIfied = false;
  644.             str = str..text:sub(i,i)
  645.         end
  646.     end
  647.     return str
  648. end
  649.  
  650. local StageDirections = { --utilize stage directions in order to make going forward and backwards easier
  651.     Main = {}; --we don't include main because that could lead to any direction. the main screen will look messy at the start
  652.     PersonaAttackList = {Back = 'Main', Next = 'PersonaTarget'};
  653.     Shoot = {Back = 'Main'};
  654.     Item = {Back = 'Main', Next = 'ItemSelect'};
  655.     PersonaChange = {Back = 'PersonaAttackList'}
  656. }
  657.  
  658.  
  659. --get character from number ID
  660. function Battle:GetCharacterFromID(id)
  661.     if (id == 1) then return Character end;
  662.    
  663.     if (typeof(id) == 'table') then
  664.         for i, v in pairs(self.Characters) do
  665.             if (v == id) then
  666.                 if (v.Name == self.Characters[1].Name) then
  667.                     return Character, i;
  668.                 else
  669.                     return self.PartyContainer:WaitForChild(v.Name), i
  670.                 end
  671.             end
  672.         end
  673.     elseif (typeof(id) == 'string') then
  674.         for i, v in pairs(self.Characters) do
  675.             if (v.Name == id) then
  676.                 return (i == 1 and Character or self.PartyContainer:WaitForChild(v.Name)), i
  677.             end
  678.         end
  679.     end
  680.     if (self.Characters and self.Characters[id]) then --if the id is valid
  681.         return workspace:WaitForChild('Party Container'):WaitForChild(self.Characters[id].Name)
  682.     end
  683.    
  684.     return 0;
  685. end
  686.  
  687. function Battle:GetEnemyFromName(id)
  688.     if (self.Enemies and self.Enemies[id]) then
  689.         if (typeof(id) == 'number') then
  690.             return workspace:WaitForChild('Enemy Container'):WaitForChild(id)
  691.         elseif (typeof(id) == 'string') then
  692.             for i, v in pairs(workspace:WaitForChild('Enemy Container'):GetChildren()) do
  693.                 if (v:WaitForChild('PersonaName').Value:lower() == id:lower()) then --bad idea because duplicates will be there
  694.                     return v;
  695.                 end
  696.             end
  697.         end
  698.     end
  699. end
  700.  
  701.  
  702. --persona create function
  703.    
  704. function RemoveAllPersonas(Transition)
  705.     CurrentPersonaThing = nil;
  706.     for i, v in pairs(CollectionService:GetTagged('PersonaObject')) do
  707.         local x = v;
  708.         if (Transition) then
  709.             for i, v in pairs(v:GetDescendants()) do
  710.                 spawn(function()
  711.                     if v:IsA('BasePart') or v:IsA('Decal') then
  712.                         for i = v.Transparency, 1, 0.1 do
  713.                             wait();
  714.                             v.Transparency = i;
  715.                         end
  716.                     end
  717.                     x:Destroy()
  718.                 end)
  719.             end
  720.         else
  721.             v:Destroy()
  722.         end
  723.         print'Persona Removed.'
  724.     end
  725. end
  726.  
  727. function Battle:createPersona(rf, summonall, t)
  728.     if (not summonall) then
  729.         RemoveAllPersonas();
  730.     end
  731.     if (not self.Ambush) then
  732.         self:CharacterPositionButWithPersona(nil, nil, rf);
  733.     end
  734.     CurrentPersonaThing = nil;
  735.     local Sona = game:GetService('ReplicatedStorage'):WaitForChild('Personas'):WaitForChild(self.Characters[t or BattleInfo.SelectedMember].Persona.Name):Clone()
  736.    
  737.     local n = self.Characters[t or BattleInfo.SelectedMember].Persona.CustomSize or {};
  738.     local H = Sona:WaitForChild('Humanoid');
  739.     H.BodyDepthScale.Value = (n.Depth or 2);
  740.     H.BodyHeightScale.Value = (n.Height or 2);
  741.     H.BodyProportionScale.Value = (n.Proportions or 1);
  742.     H.BodyTypeScale.Value = (n.Type or 1.75);
  743.     H.BodyWidthScale.Value = (n.Width or 2);
  744.     H.HeadScale.Value = (n.Head or 2);
  745.     local bodyColors = Sona:WaitForChild('Body Colors')
  746.     local bodyColor = Color3.fromRGB(4, 175, 236)
  747.     --2,2, 1, 1.75, 2, 2
  748.     do --BodyProperties
  749.         bodyColors.HeadColor3 = bodyColor
  750.         bodyColors.LeftArmColor3 = bodyColor
  751.         bodyColors.LeftLegColor3 = bodyColor
  752.         bodyColors.RightArmColor3 = bodyColor
  753.         bodyColors.RightLegColor3 = bodyColor
  754.         bodyColors.TorsoColor3 = bodyColor
  755.     end
  756.     local pl = Instance.new('PointLight')
  757.     pl.Brightness = math.abs(math.sin(tick())*10)
  758.     pl.Range = math.abs(math.sin(tick())*16)
  759.     for i, v in pairs(Sona:GetDescendants()) do
  760.         if v:IsA('BasePart') then
  761.             v.Transparency = 0.7;
  762.             if (not v:FindFirstAncestorWhichIsA('Accessory') and not v:FindFirstAncestorWhichIsA('Hat')) then
  763.                 v.Material = Enum.Material.ForceField
  764.             end
  765.         end
  766.         if (v.Name == 'HumanoidRootPart') then--
  767.             v.Transparency = 1;
  768.             pl.Parent = v;
  769.         end
  770.     end
  771.     CollectionService:AddTag(Sona, "PersonaObject");
  772.     Sona.Name = "Persona";
  773.     if ((t or BattleInfo.SelectedMember) == 1) then
  774.         Sona.Parent = workspace;--game.Players.LocalPlayer.Character;
  775.         Sona:WaitForChild('HumanoidRootPart').Anchored = true;
  776.         while Sona.Parent and not Sona.Parent:IsA('Folder') do
  777.             if (Sona.Parent:IsA('Folder')) then break end;
  778.             pl.Brightness = math.abs(math.sin(tick())*10)
  779.             pl.Range = math.abs(math.sin(tick())*16)
  780.             wait()
  781.             if (not CurrentPersonaThing) and Sona:FindFirstChild('Humanoid') then
  782.                 LoadAnimation(game:GetService('ReplicatedStorage').AnimationAssets['Hover Animation']:WaitForChild('HoverAnimation'), Sona.Humanoid):Play()
  783.             end
  784.             local T = Sona.PrimaryPart or Sona:FindFirstChild('HumanoidRootPart') or Sona:FindFirstChild('Torso');
  785.             if (not Sona.Parent) then break end;
  786.             if (Sona.PrimaryPart) then
  787.                 Sona:SetPrimaryPartCFrame(CFrame.new((game.Players.LocalPlayer.Character.UpperTorso.CFrame.lookVector * -3.5) + game.Players.LocalPlayer.Character.UpperTorso.CFrame.p + Vector3.new(0, math.sin(tick()), 0)) * CFrame.Angles(self.PartySpawns:WaitForChild('Spawn'..(t or BattleInfo.SelectedMember)).CFrame:toEulerAnglesXYZ())  + Vector3.new(0, 5, 0))
  788.             end
  789.             if (summonall) then
  790.                 return Sona;
  791.             end
  792.         end
  793.     else
  794.         Sona.Parent = workspace;--workspace:WaitForChild('Party Container'):WaitForChild(self.Characters[t or BattleInfo.SelectedMember].Name);
  795.         local xyz = workspace:WaitForChild('Party Container'):WaitForChild(self.Characters[t or BattleInfo.SelectedMember].Name)
  796.         Sona:WaitForChild('HumanoidRootPart').Anchored = true;
  797.         while Sona.Parent and not Sona.Parent:IsA('Folder') do
  798.             pl.Brightness = math.abs(math.sin(tick())*10)
  799.             pl.Range = math.abs(math.sin(tick())*16)
  800.             if (Sona.Parent:IsA('Folder') or Sona.Parent == nil) then break end;
  801.             wait()
  802.             if (not CurrentPersonaThing) and (Sona:FindFirstChild('Humanoid')) then
  803.                 --
  804.                 --CurrentPersonaThing:Play(game:GetService('ReplicatedStorage').AnimationAssets['Hover Animation']:WaitForChild('HoverAnimation'));
  805.                 LoadAnimation(game:GetService('ReplicatedStorage').AnimationAssets['Hover Animation']:WaitForChild('HoverAnimation'), Sona.Humanoid):Play()
  806.             end
  807.             local T = Sona.PrimaryPart or Sona:FindFirstChild('HumanoidRootPart') or Sona:FindFirstChild('Torso');
  808.             local Torso = xyz.PrimaryPart;
  809.             if (Sona.PrimaryPart) then
  810.                 Sona:SetPrimaryPartCFrame(CFrame.new((xyz.UpperTorso.CFrame.lookVector * -7) + xyz.UpperTorso.CFrame.p + Vector3.new(0, math.sin(tick()), 0)) * CFrame.Angles(self.PartySpawns:WaitForChild('Spawn'..(t or BattleInfo.SelectedMember)).CFrame:toEulerAnglesXYZ()) + Vector3.new(0, 5, 0));
  811.             elseif (T) then
  812.                 T.CFrame = (CFrame.new((Torso.CFrame.lookVector * -7) + Torso.CFrame.p) * CFrame.Angles(Torso.CFrame:toEulerAnglesXYZ()) + Vector3.new(0, math.sin(tick()), 0) + Vector3.new(0, 5, 0))
  813.             end
  814.             if (summonall) then
  815.                 return Sona;
  816.             end
  817.         end
  818.     end
  819. end
  820.  
  821.  
  822. --global tween function
  823. function Tween(obj, ti, goalTable)
  824.    
  825.     if (not obj) then error('invalid object'); end;
  826.     if (not ti) then error('invalid tween info'); end;
  827.     if (not goalTable) then error('invalid goal table'); end;
  828.    
  829.     local TS = game:GetService('TweenService');
  830.    
  831.     return game:GetService('TweenService'):Create(obj, ti, goalTable);
  832. end
  833. --camera functions
  834. function Battle:CharacterPositionButWithPersona(t, lookAt, inst, ofst, vertoffset)
  835.     --impwarn('Started new thread!')
  836.     --impwarn('B1')
  837.     lookAt = typeof(lookAt) == 'CFrame' and {CFrame = lookAt} or (typeof(lookAt) == 'Instance' and {CFrame = lookAt.CFrame})
  838.     if (currentTween) then currentTween:Cancel(); currentTween = nil; end;
  839.     local C = Battle.Characters[t or BattleInfo.SelectedMember];
  840.     local OBJ = nil;
  841.     --impwarn('B2')
  842.     if ((t or BattleInfo.SelectedMember) <=1) then
  843.         OBJ = game.Players.LocalPlayer.Character;
  844.     else
  845.         OBJ = workspace:WaitForChild('Party Container'):WaitForChild(C.Name)
  846.     end
  847.     --impwarn('B3')
  848.     local OBJ2 = OBJ.PrimaryPart or self.BattleArea:WaitForChild(self.Ambush and 'Ambush Spawns' or 'Spawns')['Party Spawns']:WaitForChild('Spawn'..(t or BattleInfo.SelectedMember))
  849.     --impwarn(OBJ2)
  850.     local Equation = CFrame.new(OBJ2.CFrame.lookVector * -(ofst or 20) + --[[workspace.CurrentCamera.CFrame]]OBJ2.CFrame.RightVector*9) * CFrame.Angles(OBJ2.CFrame:toEulerAnglesXYZ()) + OBJ2.Position + Vector3.new(0,10,0);
  851.     --impwarn('B5')
  852.    
  853.    
  854.     local X,Y,Z = CFrame.new(Equation.Position + (not lookAt and OBJ2.CFrame.RightVector*-6.5 or Vector3.new(0,0,0)), OBJ2.Position + Vector3.new(0, (vertoffset or 7.5), 0)):ToEulerAnglesXYZ();
  855.     Equation = CFrame.new(Equation.Position) * (
  856.         not lookAt and CFrame.Angles(X,Y,Z) or
  857.         CFrame.Angles(
  858.             CFrame.new(workspace.CurrentCamera.CFrame.Position, lookAt.CFrame.Position):ToEulerAnglesXYZ())
  859.         )
  860.     --impwarn('B6')
  861.    
  862.     currentTween = Tween(workspace.CurrentCamera, TweenInfo.new(not lookAt and not inst and 1 or 0, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, false, 0), {CFrame = Equation})
  863.     currentTween:Play(); --* CFrame.Angles(workspace.CurrentCamera.CFrame:ToEulerAnglesXYZ());
  864.     --impwarn('B7')
  865.     wait()
  866. end
  867.  
  868. function Battle:CharacterPosition(player, inverse, start)
  869.     if (currentTween) then currentTween:Cancel(); currentTween = nil; end
  870.     player = player or BattleInfo.SelectedMember
  871.     local C = self.Characters[player];
  872.    
  873.    
  874.     local Keyword = self.BattleArea:WaitForChild(self.Ambush and 'Ambush Spawns' or 'Spawns')
  875.    
  876.     local OBJ = nil;
  877.     if (player <=1) then
  878.         OBJ = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait();
  879.     else
  880.         OBJ = workspace:WaitForChild('Party Container'):WaitForChild(C.Name)
  881.     end
  882.     OBJ = OBJ.PrimaryPart;
  883.     local c = inverse and Keyword['Enemy Spawns']:WaitForChild('Spawn1') or OBJ
  884.     local mp = (not inverse) and -9 or 6.25
  885.     local RightVector = (not inverse) and 11.25 or 0;
  886.     if (not start) then
  887.         local CF = CFrame.new((OBJ.CFrame.lookVector * mp) + OBJ.CFrame.rightVector*RightVector)+ OBJ.Position + Vector3.new(0,OBJ.Parent.Humanoid.HipHeight+0.24,0)
  888.         currentTween = Tween(
  889.             workspace.CurrentCamera,
  890.             TweenInfo.new(0.2, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, false, 0),
  891.             {  
  892.                 CFrame =  CF *
  893.                 CFrame.Angles(CFrame.new(CF.Position, OBJ.Position):ToEulerAnglesXYZ())
  894.             }
  895.         )
  896.         currentTween:Play();
  897.     else
  898.     local CF = CFrame.new((OBJ.CFrame.lookVector * mp) + OBJ.CFrame.rightVector*RightVector)+ OBJ.Position + Vector3.new(0,OBJ.Parent.Humanoid.HipHeight+0.24,0)
  899.         workspace.CurrentCamera.CFrame = CF *
  900.                 CFrame.Angles(CFrame.new(CF.Position, OBJ.Position):ToEulerAnglesXYZ())
  901.     end
  902. end
  903.  
  904. function Battle:CharacterAttacked(player)
  905.     player = player or BattleInfo.SelectedMember
  906.     local C = self.Characters[player];
  907.    
  908.    
  909.     local Keyword = self.BattleArea:WaitForChild(self.Ambush and 'Ambush Spawns' or 'Spawns')
  910.    
  911.     local OBJ = nil;
  912.     if (player <=1) then
  913.         OBJ = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait();
  914.     else
  915.         OBJ = workspace:WaitForChild('Party Container'):WaitForChild(C.Name)
  916.     end
  917.     local Increase = 8.5
  918.     OBJ = OBJ.PrimaryPart--Keyword['Party Spawns']:WaitForChild('Spawn'..(player))
  919.     local c =  OBJ
  920.     local mp = 7
  921.    
  922.     workspace.CurrentCamera.CFrame = CFrame.new(OBJ.CFrame.lookVector*-mp + OBJ.CFrame.rightVector*2.5) * CFrame.Angles(c.CFrame:toEulerAnglesXYZ()) + OBJ.Position --+ Vector3.new(0,Increase, 0)
  923.    
  924.     local Formula = workspace.CurrentCamera.CFrame.LookVector * -10 + workspace.CurrentCamera.CFrame.Position;
  925.     Tween(workspace.CurrentCamera, TweenInfo.new(5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {
  926.    
  927.         CFrame = CFrame.new(Formula) * CFrame.Angles(CFrame.new(Formula, OBJ.Position):ToEulerAnglesXYZ())
  928.  
  929.     }):Play();
  930.    
  931.     wait(1.15)
  932. end
  933.  
  934. function Battle:PartyAttacked()
  935.     local Root = Player.Character.PrimaryPart
  936.    
  937.     local Keyword = self.BattleArea:WaitForChild(self.Ambush and 'Ambush Spawns' or 'Spawns')
  938.    
  939.     Keyword = Keyword["Party Spawns"];
  940.     local SpawnOne = Keyword:GetChildren()[1];
  941.     local SpawnTwo = Keyword:GetChildren()[#Keyword:GetChildren()];
  942.     local mp = 11
  943.    
  944.     local Half = SpawnOne.CFrame:Lerp(SpawnTwo.CFrame, .5)
  945.     Half = {CFrame = Half, Position = Half.Position}
  946.    
  947.     print(typeof(Half))
  948.     workspace.CurrentCamera.CFrame =
  949.         (CFrame.new(
  950.                 Half.CFrame.LookVector*-mp
  951.                 +
  952.                 Half.CFrame.rightVector*
  953.                 2.5
  954.         ) + Vector3.new(0, Root.Parent.Humanoid.HipHeight + 4.5, 0)) *
  955.         CFrame.Angles(
  956.             Half.CFrame:toEulerAnglesXYZ()
  957.         ) +
  958.         Half.Position --+ Vector3.new(0,Increase, 0)
  959.  
  960.     local Formula = workspace.CurrentCamera.CFrame.LookVector * -10 + workspace.CurrentCamera.CFrame.Position;
  961.     Tween(workspace.CurrentCamera, TweenInfo.new(5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {
  962.    
  963.         CFrame = CFrame.new(Formula) * CFrame.Angles(CFrame.new(Formula, Half.Position):ToEulerAnglesXYZ())
  964.  
  965.     }):Play();
  966. end
  967.  
  968. function isCloserToPosition(p, op, modulofactor, clamp)
  969.     p = p.CFrame;
  970.     local p1 = math.abs(((-p.RightVector + p.Position) - op.Position).Magnitude);
  971.     local p2 = math.abs(((p.RightVector + p.Position) - op.Position).Magnitude);
  972.    
  973.     if (math.floor(p1) > math.floor(p2)) then --if the other part is closer to the right side
  974.         return 'Right', math.clamp(p2/(modulofactor or 1), -clamp, clamp);
  975.     else --if the other part is closer to the left side
  976.         return 'Left',  math.clamp(p1/(modulofactor or 1), -clamp, clamp);
  977.     end
  978. end
  979.  
  980. function Battle:CharacterAttacking(player, target, crit, mhit)
  981.     player = player or BattleInfo.SelectedMember
  982.     local C = self.Characters[player];
  983.    
  984.    
  985.     local Keyword = self.BattleArea:WaitForChild(self.Ambush and 'Ambush Spawns' or 'Spawns')
  986.    
  987.     local OBJ = nil;
  988.     if (player <=1) then
  989.         OBJ = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait();
  990.     else
  991.         OBJ = workspace:WaitForChild('Party Container'):WaitForChild(C.Name)
  992.     end
  993.     local Increase = 8.5
  994.     OBJ = OBJ.PrimaryPart--Keyword['Party Spawns']:WaitForChild('Spawn'..(player))
  995.     local ClosestTo, shiftFactor = isCloserToPosition(OBJ, target, 10, 2)
  996.     if (mhit) then
  997.         local Keyword = Keyword['Enemy Spawns']
  998.         local CF = Keyword:GetChildren()[1].CFrame:Lerp(Keyword:GetChildren()[#Keyword:GetChildren()].CFrame, 0.5)
  999.         target = {CFrame = CF, Position = CF.Position}
  1000.     end
  1001.     local c =  OBJ
  1002.     local mp = 5--(ClosestTo == 'Right' and 1 or 5)
  1003.     local RV = (ClosestTo == 'Right' and -shiftFactor-5 or 5+shiftFactor)--move closer to the left if the attacked person is too far to the right
  1004.    
  1005.  
  1006.    
  1007.     workspace.CurrentCamera.CFrame = CFrame.new(Vector3.new(0,6.5,0)+OBJ.CFrame.lookVector*-mp + OBJ.CFrame.rightVector*(crit and 0 or RV)) * CFrame.Angles(CFrame.new(c.CFrame--[[:toEulerAnglesXYZ()]].Position, target.CFrame.Position):ToEulerAnglesXYZ()) + OBJ.Position --+ Vector3.new(0,Increase, 0)
  1008.     wait();
  1009.     local Formula = workspace.CurrentCamera.CFrame.LookVector * -(crit and -5 or 5) + workspace.CurrentCamera.CFrame.Position;
  1010.     Tween(workspace.CurrentCamera, TweenInfo.new(2, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {
  1011.    
  1012.         CFrame = CFrame.new(Formula) * CFrame.Angles(CFrame.new(Formula, target.CFrame.Position):ToEulerAnglesXYZ())
  1013.  
  1014.     }):Play();
  1015.    
  1016.     wait(1.25)
  1017. end
  1018.  
  1019. --functions for battle
  1020. function getNextStage()
  1021.     for i, v in pairs(StageDirections) do
  1022.         if (i == BattleInfo.BattleStage) then
  1023.             return v.Next;
  1024.         end
  1025.     end
  1026.    
  1027.     return nil;
  1028. end
  1029.  
  1030. function getPreviousStage()
  1031.     for i, v in pairs(StageDirections) do
  1032.         if (i == BattleInfo.BattleStage) then
  1033.             return v.Next;
  1034.         end
  1035.     end
  1036.    
  1037.     return nil;
  1038. end
  1039. w = warn;
  1040.  
  1041. function Battle:selectViableMember(RefillMembers)
  1042.     if (self.BattleFinished) then return 1 end;
  1043.     if (not self.AvailableUsers) then
  1044.         self.AvailableUsers = {};
  1045.     end
  1046.     local AvailableUsers = self.AvailableUsers;
  1047.     if (not BattleInfo.TotalTurn) then
  1048.        
  1049.         BattleInfo.TotalTurn = 0;
  1050.     end
  1051.    
  1052.     print('Baton Count:', self.BatonCount or 0);
  1053.    
  1054.     if (self.BatonPass) then
  1055.         self.BatonCount = self.BatonCount + 1;
  1056.        
  1057.         if (self.BatonCount == 1) then
  1058.             showLabel('Attack and Recovery increased!')
  1059.         elseif (self.BatonCount == 2) then
  1060.             showLabel('Attack and Recovery greatly increased!')
  1061.         elseif (self.BatonCount == 3) then
  1062.             showLabel('Attack and Recovery massively increased!')
  1063.         elseif (self.BatonCount == 4) then
  1064.             showLabel('Attack and Recovery tremendously increased!')
  1065.         end
  1066.        
  1067.         local OBT = self.BatonPass;
  1068.         self.BatonPass = nil;
  1069.         return OBT
  1070.     end
  1071.    
  1072.    
  1073.    
  1074.     if (self.OneMore) then
  1075.        
  1076.         Battle:showOneMore()
  1077.         return BattleInfo.SelectedMember;
  1078.     end
  1079.    
  1080.     for i, v in pairs(self.Characters) do
  1081.         v.BatonPassed = false;
  1082.     end
  1083.    
  1084.     self.BatonCount = 0;
  1085.    
  1086.     --use X prefix to describe enemies
  1087.    
  1088.     --Add all ids to one table so we can determine their agility for turn order
  1089.    
  1090.     if (not self.Ambush) then
  1091.        
  1092.         if (BattleInfo.TotalTurn == 0) then
  1093.            
  1094.             spawn(function()
  1095.                 local RandomAppraisals = {"Awesome, Joker! We have the first strike! Make it good!", "Alright Joker, we have the upper hand! Don't mess it up!", "Alright team, you know what to do!", "Slay them all!", "Cut down their family tree!"}
  1096.                 if (self.Boss) then
  1097.                     RandomAppraisals = {'Alright team, stay calm! I know this one\'s strong, but think your actions through!'}
  1098.                 end;
  1099.                 local WeakAppraisals = {}
  1100.                 local lv = 0;
  1101.                 for i, v in pairs(self.Enemies) do
  1102.                     lv = lv + (v.Level or 0);
  1103.                 end
  1104.                 lv = (lv/#self.Enemies) --get average of enemies
  1105.                 local clv = 0;
  1106.                 for i, v in pairs(self.Characters) do
  1107.                     clv = clv + (v.Level or 0);
  1108.                 end
  1109.                
  1110.                 clv = (clv/#self.Characters);
  1111.                
  1112.                 if (clv - lv > 5) then
  1113.                     for i, v in pairs(not self.Boss and WeakAppraisals or {}) do
  1114.                         RandomAppraisals[#RandomAppraisals+1] = v;
  1115.                     end
  1116.                 elseif (clv - lv < -5) then
  1117.                     RandomAppraisals = not self.Boss and {
  1118.                         string.format("Joker, be cautious! %s very strong!", #self.Enemies > 1 and "These guys are" or "This guy is");
  1119.                         string.format("Joker, be careful! %s tough..", #self.Enemies > 1 and "These ones're" or "This one's");
  1120.                         string.format("Joker, be careful! We may have the upper hand, but %s tough!", #self.Enemies > 1 and "These ones're" or "This one's");
  1121.                         string.format("Be cautious, everyone! %s tough!", #self.Enemies > 1 and "These ones're" or "This one's")
  1122.                     } or RandomAppraisals;
  1123.                 end
  1124.            
  1125.                 _G.BattleAnnouncement(RandomAppraisals[math.random(1, #RandomAppraisals)], ReplicatedStorage:WaitForChild('Party Members'):WaitForChild('Yuki'))
  1126.             end)
  1127.            
  1128. --          for i, v in pairs(self.Characters) do
  1129. --             
  1130. --              AvailableUsers[#AvailableUsers+1] = {i, 7000-(math.random(1, 500))}
  1131. --          end
  1132.         end
  1133.     elseif (BattleInfo.TotalTurn == 0) then
  1134.            
  1135.         for i, v in pairs(self.Enemies) do
  1136.            
  1137.             AvailableUsers[#AvailableUsers+1] = {"X"..v.ID, 7000-(math.random(1, 500))}
  1138.         end
  1139.     end
  1140.    
  1141.     if (RefillMembers) then
  1142.         self.knockedChar = false;
  1143.         --impwarn("Refilling...")
  1144.         BattleInfo.EnemyActions = {};
  1145.         BattleInfo.MemberActions = {};
  1146.         for i, v in pairs(self.Characters) do --character personas dont have an agility stat yet SIKE THEY DO NOW
  1147.            
  1148.             BattleInfo.PlayerTurns[i] = BattleInfo.PlayerTurns[i] or 1
  1149.            
  1150.             local Incapacitated = checkIncapacitated(v, nil, BattleInfo.PlayerTurns[i] or 1);
  1151.            
  1152.             if (not BattleInfo.MemberActions[i]) --[[and (not checkIncapacitated(v, nil, BattleInfo.PlayerTurns[i]))]] then
  1153.                 AvailableUsers[#AvailableUsers+1] = {i, v.Persona.Stats.Agility};
  1154.                
  1155.             elseif Incapacitated then
  1156.                
  1157.                 impprint('Player was incapacitated. Skipping turn and adding one.')
  1158.                 BattleInfo.PlayerTurns[i] = BattleInfo.PlayerTurns[i] and (BattleInfo.PlayerTurns[i]+1)or 1
  1159.             end
  1160.         end
  1161.        
  1162.         for i, v in pairs(self.Enemies) do
  1163.             if (v.TurnCount) then
  1164.                
  1165.                 v.CTC = v.CTC or 1;
  1166.             end
  1167.            
  1168.             BattleInfo.EnemyTurns[v.ID] = BattleInfo.EnemyTurns[v.ID] or 1
  1169.            
  1170.             local Incapacitated = checkIncapacitated(v, nil, BattleInfo.EnemyTurns[v.ID] or 1);
  1171.            
  1172.             if (not BattleInfo.EnemyActions[i]) and (not Incapacitated) then
  1173.                
  1174.                 if (v.TurnCount and v.CTC <= v.TurnCount) then
  1175.                    
  1176.                     for i = 0, v.TurnCount do
  1177.                         --NO WONDER IT DIDNT WORK, IT ONLY DID IT FOR TURN COUNTS ONLY WHAT
  1178.                         AvailableUsers[#AvailableUsers+1] = {'X'..v.ID, (v.EnemyStats or v.Stats).Agility};                    
  1179.                     end
  1180.                 elseif (not v.TurnCount) and (not BattleInfo.EnemyActions[v.ID]) and (not Incapacitated) then
  1181.                     AvailableUsers[#AvailableUsers+1] = {'X'..v.ID, (v.EnemyStats or v.Stats).Agility};
  1182.                 end
  1183.             elseif Incapacitated then
  1184.                
  1185.                 impprint('Enemy was incapacitated. Skipping turn and adding one.', "Name:", v.Name, "ID", v.ID or 0)
  1186.                
  1187.                 local oa = BattleInfo.EnemyTurns[i] or 1;
  1188.                
  1189.                 BattleInfo.EnemyTurns[i] = BattleInfo.EnemyTurns[i] and (BattleInfo.EnemyTurns[i]+1) or 1
  1190.                
  1191.                 impwarn('Previously:', oa, 'Now:', BattleInfo.EnemyTurns[i])
  1192.             end
  1193.         end
  1194.        
  1195.     end
  1196.    
  1197.     --sort the table based on their agility. convert all strings to numbers and then place in the table if the string's numbers are valid
  1198.     for i, v in pairs(AvailableUsers) do
  1199.        
  1200.         impprint('Before Turn Order:', table.concat(v, ', '))
  1201.     end        
  1202.    
  1203.     table.sort(AvailableUsers, function(a, b)
  1204.        
  1205.        
  1206.         local newA = a[2];
  1207.         local newB = b[2];
  1208.        
  1209.         return newA > newB
  1210.     end)
  1211.     for i, v in pairs(AvailableUsers) do
  1212.        
  1213.         impprint('After Turn Order:', table.concat(v, ', '))
  1214.        
  1215.     end
  1216.    
  1217.     local CharacterCount = 0;
  1218.    
  1219.     local y = tostring(AvailableUsers[1][1]);
  1220.         --hehe
  1221.     BattleInfo.TotalTurn = BattleInfo.TotalTurn + 1;
  1222.    
  1223.     for i, v in pairs(self.Enemies) do
  1224.         v.Debuffs = v.Debuffs or {};
  1225.         local Enemy = v;
  1226.         for i, v in pairs(v.Debuffs) do
  1227.             if (v.TurnAdded and v.TurnAdded + v.Length < (BattleInfo.EnemyTurns[Enemy.ID] or 0)) then
  1228.                 Battle:MoveCameraToEnemy(Enemy.ID)
  1229.                 if (v.Name ~= 'Down') then
  1230.                     showLabel(v.Name..'has worn off!', 2.5)
  1231.                 else
  1232.                     Battle.HoldUpped = false;
  1233.                 end
  1234.                 v.Debuffs[i] = nil;
  1235.             else
  1236.                 impwarn("");
  1237.                 impwarn("Debuff Data:");
  1238.                 impwarn("Receiver Name:", Enemy.Name, "Debuff Name:", v.Name, "::", "TurnAdded:", v.TurnAdded, "Length:", v.Length, "Finishing Turn:", v.TurnAdded + v.Length, "Current Turn:", BattleInfo.TotalTurn, "\n")
  1239.                
  1240.             end
  1241.         end
  1242.     end
  1243.     for i, v in pairs(self.Characters) do
  1244.         v.Debuffs = v.Debuffs or {};
  1245.         local Character = v;
  1246.         for i, v in pairs(v.Debuffs) do
  1247.             if (v.TurnAdded and v.TurnAdded + v.Length < (BattleInfo.PlayerTurns[i] or 0)) then
  1248.                 Battle:MoveCameraToCharacter(i)
  1249.                 if (v.Name ~= 'Down') then
  1250.                     showLabel(v.Name..'has worn off!', 2.5)
  1251.                 end
  1252.                 v.Debuffs[i] = nil;
  1253.             else
  1254.                 impwarn("");
  1255.                 impwarn("Debuff Data (Player):")
  1256.                 impwarn("Receiver Name:", Character.Name, "Debuff Name:", v.Name, "::", "TurnAdded:", v.TurnAdded, "Length:", v.Length, "Finishing Turn:", v.TurnAdded + v.Length, "Current Turn:", BattleInfo.TotalTurn, "\n")
  1257.             end
  1258.         end
  1259.     end
  1260.     if (tostring(AvailableUsers[1][1]):match('X')) then
  1261.         warn("X Found!");
  1262.         return self.Enemies[tonumber(AvailableUsers[1][1]:match('(%d+)'))]
  1263.     else
  1264.         warn("X Not Found!");
  1265.         return tonumber(AvailableUsers[1][1])
  1266.     end
  1267.    
  1268. end
  1269.        
  1270.        
  1271.  
  1272. local Technicals = {
  1273.     wind = {burn = true};
  1274.     physical = {frozen = true, shock = true};
  1275.     nuclear = {frozen = true, burning = true, shock = true};
  1276.     psychic = {confuse = true, fear = true, despair = true, rage = true, brainwash = true};
  1277.    
  1278. } --Technicals
  1279. local CMS = require(game:GetService('Players').LocalPlayer:WaitForChild('PlayerScripts'):WaitForChild('PlayerModule'):WaitForChild('ControlModule'));
  1280.  
  1281.  
  1282. local KeypadTranslations = { --translate alternative inputs to base inputs for easier coding within the UserInputService InputBegan
  1283.     Y = 'Z';
  1284.     X = 'X';
  1285.     A = 'V';
  1286. }
  1287.  
  1288. function Battle:RemoveHealthbars()
  1289.     for i, v in pairs(CollectionService:GetTagged('TemporaryAdornee')) do
  1290.         v:Destroy();
  1291.     end
  1292. end
  1293.  
  1294. function Battle:AdorneeHealth(type)
  1295. --  if ((BattleInfo.SelectedPersonaAttack.Type == 'Kaja' or BattleInfo.SelectedPersonaAttack.Type == 'Buff') and BattleInfo.SelectedPersonaAttack.Type2 ~= 'Debuff') or BattleInfo.BattleStage == 'BatonPass' then
  1296. --      local Guy = self.Characters[BattleInfo.SelectedEnemyGuy];
  1297. --      PlayerGui:WaitForChild('HealthBar').Adornee = self:GetCharacterFromID(BattleInfo.SelectedEnemyGuy).PrimaryPart;
  1298. --      PlayerGui.HealthBar.Frame.Frame.Frame.Size = UDim2.new(math.clamp(Guy.Health/Guy.MaxHealth-0.05, 0, math.huge), 0, 0.6, 0)
  1299. --      PlayerGui.HealthBar.HealthLabel.Text = tostring(Guy.Health)
  1300. --  else
  1301. --      local Guy = self.Enemies[BattleInfo.SelectedEnemyGuy];
  1302. --     
  1303. --      PlayerGui:WaitForChild('HealthBar').Adornee = self:GetEnemyFromName(BattleInfo.SelectedEnemyGuy, true).PrimaryPart;
  1304. --      PlayerGui.HealthBar.Frame.Frame.Frame.Size = UDim2.new(math.clamp(Guy.Health/Guy.MaxHealth-0.05, 0, math.huge), 0, 0.6, 0)
  1305. --      PlayerGui.HealthBar.WeakLabel.Visible = Guy.Weak and Guy.Weak[BattleInfo.SelectedPersonaAttack.Type] or false
  1306. --      PlayerGui.HealthBar.HealthLabel.Text = tostring(Guy.Health)
  1307. --  end
  1308.  
  1309.    
  1310.    
  1311.     if (BattleInfo.SelectedPersonaAttack) then
  1312.         if (BattleInfo.SelectedPersonaAttack.Heals) then
  1313.             for i, v in pairs(self.Characters) do
  1314.                 local newHealthBar = PlayerGui:WaitForChild('HealthBar'):Clone();
  1315.                 if (v.ID) then
  1316.                     local IDValue = Instance.new('StringValue', newHealthBar);
  1317.                     IDValue.Name = "Enemy";
  1318.                     IDValue.Value = tostring(v.ID);
  1319.                 end
  1320.                 newHealthBar.Parent = self:GetCharacterFromID(i).PrimaryPart;
  1321.                 newHealthBar.Adornee = newHealthBar.Parent;
  1322.                 newHealthBar.HealthLabel.Text = v.Health;
  1323.                 newHealthBar.Frame.Frame.Frame.Size = UDim2.new(math.clamp(v.Health/v.MaxHealth-0.05, 0, math.huge),  0, 0.6, 0)
  1324.                 newHealthBar.WeakLabel.Visible = (not not v.Persona.Weak[BattleInfo.SelectedPersonaAttack.Type])
  1325.                 CollectionService:AddTag(newHealthBar, 'TemporaryAdornee')
  1326.             end
  1327.         elseif (BattleInfo.SelectedPersonaAttack.Damages) then
  1328.             for i, v in pairs(self.Enemies) do
  1329.                 if (v.Health > 0) then
  1330.                     local newHealthBar = PlayerGui:WaitForChild('HealthBar'):Clone();
  1331.                     if (v.ID) then
  1332.                         local IDValue = Instance.new('StringValue', newHealthBar);
  1333.                         IDValue.Name = "Enemy";
  1334.                         IDValue.Value = tostring(v.ID);
  1335.                     end
  1336.                    
  1337.                     newHealthBar.Parent = self:GetEnemyFromName(v.ID, true).PrimaryPart;
  1338.                     newHealthBar.Adornee = newHealthBar.Parent;
  1339.                     newHealthBar.HealthLabel.Text = v.Health;
  1340.                     newHealthBar.Frame.Frame.Frame.Size = UDim2.new(math.clamp(v.Health/v.MaxHealth-0.05, 0, math.huge),  0, 0.6, 0)
  1341.                     if (v.Weak) then
  1342.                         newHealthBar.WeakLabel.Visible = (not not v.Weak[BattleInfo.SelectedPersonaAttack.Type])
  1343.                     end
  1344.                     CollectionService:AddTag(newHealthBar, 'TemporaryAdornee')
  1345.                 end
  1346.             end
  1347.         elseif (BattleInfo.SelectedPersonaAttack.Type2 ~= 'Debuff') and (tonumber(BattleInfo.SelectedEnemyGuy)) and  (BattleInfo.SelectedPersonaAttack.Type == 'Kaja' or BattleInfo.SelectedPersonaAttack.Type == 'Buff') then
  1348.             local C = self:GetCharacterFromID(BattleInfo.SelectedEnemyGuy)
  1349.             if (C.PrimaryPart) then
  1350.                 print("Yes Primary Part");
  1351.                 local newHealthBar = PlayerGui:WaitForChild('HealthBar'):Clone();
  1352.                 local IDValue = Instance.new('StringValue', newHealthBar);
  1353.                 IDValue.Name = "Player";
  1354.                 IDValue.Value = tostring(BattleInfo.SelectedEnemyGuy);
  1355.                 newHealthBar.Parent = C.PrimaryPart;
  1356.                 newHealthBar.Adornee = newHealthBar.Parent;
  1357.                 newHealthBar.HealthLabel.Text = self.Characters[BattleInfo.SelectedEnemyGuy].Health
  1358.                 newHealthBar.Frame.Frame.Frame.Size = UDim2.new(math.clamp(self.Characters[BattleInfo.SelectedEnemyGuy].Health/self.Characters[BattleInfo.SelectedEnemyGuy].MaxHealth-0.05, 0, math.huge),  0, 0.6, 0)
  1359.                 CollectionService:AddTag(newHealthBar, 'TemporaryAdornee')
  1360.             end
  1361.         else
  1362.             local Guy = self.Enemies[BattleInfo.SelectedEnemyGuy];
  1363.             if (self:GetEnemyFromName(BattleInfo.SelectedEnemyGuy, true).PrimaryPart) and Guy.Health > 0 then
  1364.                 print("Yes Primary Part");
  1365.                 local newHealthBar = PlayerGui:WaitForChild('HealthBar'):Clone();
  1366.                 local IDValue = Instance.new('StringValue', newHealthBar);
  1367.                 IDValue.Name = "Enemy";
  1368.                 IDValue.Value = tostring(BattleInfo.SelectedEnemyGuy);
  1369.                 newHealthBar.Parent = self:GetEnemyFromName(BattleInfo.SelectedEnemyGuy, true).PrimaryPart;
  1370.                 newHealthBar.Adornee = newHealthBar.Parent;
  1371.                 newHealthBar.HealthLabel.Text = Guy.Health
  1372.                 newHealthBar.Frame.Frame.Frame.Size = UDim2.new(math.clamp(Guy.Health/Guy.MaxHealth-0.05, 0, math.huge),  0, 0.6, 0)
  1373.                 newHealthBar.WeakLabel.Visible = (not not Guy.Weak[BattleInfo.SelectedPersonaAttack.Type])
  1374.                 CollectionService:AddTag(newHealthBar, 'TemporaryAdornee')
  1375.             end
  1376.         end
  1377.     end
  1378.     return true;
  1379. end
  1380.  
  1381.  
  1382.  
  1383. function Battle:TweenHealth(t)
  1384.     local ty = tonumber(PlayerGui.HealthBar.HealthLabel.Text);
  1385.    
  1386.     local waitTime = t--(ty - Guy.Health) * 1/60
  1387.  
  1388.    
  1389.     for i, v in pairs(CollectionService:GetTagged('TemporaryAdornee')) do
  1390.         local Guy;
  1391.         if (v:FindFirstChild("Enemy")) then
  1392.             Guy = self.Enemies[tonumber(v.Enemy.Value)];
  1393.         elseif (v:FindFirstChild("Player")) then
  1394.             Guy = self.Characters[tonumber(v.Player.Value)]
  1395.         end
  1396.         v.Frame.Frame.Frame:TweenSize(UDim2.new(math.clamp(Guy.Health/Guy.MaxHealth-0.05, 0, math.huge),  0, 0.6, 0), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, waitTime, true)
  1397.         v.HealthLabel.Text = Guy.Health;
  1398.     end
  1399.        
  1400. --  for i = ty, Guy.Health, -1 do
  1401. --     
  1402. --      if (i < Guy.Health) then
  1403. --         
  1404. --          break; --so no infinite loops
  1405. --      end
  1406. --      wait(1/60)
  1407. --      PlayerGui.HealthBar.HealthLabel.Text = i;
  1408. --  end
  1409.  
  1410.  
  1411.     wait(waitTime)
  1412. end
  1413.  
  1414. function Battle:AmbushPosition(t)
  1415.     workspace.CurrentCamera.CFrame = self.BattleArea.Cameras.AmbushCamera.CFrame;
  1416.     --return Tween(workspace.CurrentCamera, TweenInfo.new(tonumber(t) or 0.25, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, false, 0), {CFrame = self.BattleArea.Cameras.AmbushCamera.CFrame}):Play();
  1417. end
  1418.  
  1419. function checkIncapacitated(t, isdown, abc)
  1420.     if (t) then
  1421.         if (t.Debuffs) then
  1422.             local y = t; --             if (v.Health > 0) and (not v.Debuffs.Down) and (not v.Debuffs.Sleep) and (not v.Debuffs.Shock) and (not v.Debuffs.Confused) and (not v.Debuffs.Dizzy) and (not v.Debuffs.Fear) then
  1423.             local t = t.Debuffs;
  1424.            
  1425.             if ((not isdown and t.Down) or t.Sleep or t.Shock or t.Confused or t.Fear or y.Health <= 0) then
  1426.                 if (not t.Down) and (y.Health > 0) then
  1427.                     return (math.random() < 0.25) and false or true -- 25% chance to be able to act even when debuffed (but not downed)
  1428.                 end
  1429.                 if abc and (t.Down and t.Down.Length + t.Down.TurnAdded <= abc+1) then
  1430.                    
  1431.                     return false --so they can have a turn, they get up, then they attack. epic!!
  1432.                 end
  1433.                 return true;
  1434.             end
  1435.         else
  1436.             t.Debuffs = {};
  1437.         end
  1438.            
  1439.         if (t.Health <= 0) then
  1440.             return true;
  1441.         end
  1442.     else
  1443.         warn('error in checkIncapacitated')
  1444.     end
  1445.     return false
  1446. end
  1447.  
  1448. function Battle:NewTurn()
  1449.     local DC = 0;
  1450.     local LivingEnemies = 0;
  1451.     for i, v in pairs(self.Enemies) do
  1452.         if (v.Health > 0) then
  1453.             if (v.Debuffs and v.Debuffs.Down) then
  1454.                 DC = DC+1;
  1455.             end
  1456.             LivingEnemies = LivingEnemies + 1;
  1457.         end
  1458.     end
  1459.     impwarn(DC, LivingEnemies, 'downcount & living enemies')
  1460.     if (DC == LivingEnemies) and DC > 0 and not Battle.HoldUpped then
  1461.         self.OneMore = false;
  1462.     end
  1463.     for i, v in pairs(ReplicatedStorage:WaitForChild('AnimationAssets'):WaitForChild('CritAnim'):GetChildren()) do
  1464.         if (tonumber(BattleInfo.SelectedMember) and tonumber(BattleInfo.SelectedMember) ~= 0) then
  1465.             --impwarn('mem:', BattleInfo.SelectedMember);
  1466.             local Z = Battle:GetCharacterFromID(BattleInfo.SelectedMember):FindFirstChild('Humanoid', true);
  1467.             local Y = animationStatus(v, Z);
  1468.             if (Y) then
  1469.                 Y:AdjustWeight(1, 2)
  1470.                 StopAnimation(v, Z)
  1471.             end
  1472.         end
  1473.     end
  1474.     CurrentCameraShake.RotationInfluence = Vector3.new(0.1, 0.1, 0)
  1475.     coroutine.wrap(function()
  1476.         wait();
  1477.         self:RemoveHealthbars();
  1478.     end)();
  1479.     if (self.BattleFinished) then return nil end;
  1480.     CMS:Disable()
  1481.     if (not (self.Characters[1].Debuffs.Down or self.Characters[1].Health == 0)) and (DC == LivingEnemies) and DC > 0 and not Battle.HoldUpped then
  1482.         --Hold Up
  1483.         CurrentCameraShake.RotationInfluence = Vector3.new(0.05, 0.05, 0)
  1484.         RemoveAllPersonas(true);
  1485.         local stateType = Enum.HumanoidStateType
  1486.         print('HOLD UP!')
  1487.         local CFrames = {};
  1488.         for i, v in pairs(self.Characters) do
  1489.             if (i ~= 1) then
  1490.    
  1491.  
  1492.                 v = Battle:GetCharacterFromID(i)
  1493.                 for i, v in pairs(v:GetDescendants()) do
  1494.                     if v:IsA('BasePart') then
  1495.                         v.Velocity = Vector3.new(0,0,0)
  1496.                         v.RotVelocity = Vector3.new(0,0,0)
  1497.                     end
  1498.                 end
  1499.                 CFrames[i] = v and v:GetPrimaryPartCFrame() or error ("improper coding idiot")
  1500.                 v.Humanoid:SetStateEnabled(stateType.FallingDown, false)
  1501.                 v.Humanoid:SetStateEnabled(stateType.Ragdoll, false)
  1502.                 --impwarn(v);
  1503.                 local PrimaryPart = v.PrimaryPart;
  1504.                 PrimaryPart.Anchored = false;
  1505.                 wait(.1)
  1506.                 v.Humanoid:MoveTo(PrimaryPart.CFrame.LookVector*7 + PrimaryPart.Position)
  1507.             end
  1508.         end --movecameratoenemy
  1509.        
  1510.         for i, v in pairs(Character:GetDescendants()) do
  1511.             if v:IsA('BasePart') then
  1512.                 v.Velocity = Vector3.new(0,0,0)
  1513.                 v.RotVelocity = Vector3.new(0,0,0)
  1514.             end
  1515.         end
  1516.         CFrames[1] = Character:GetPrimaryPartCFrame();
  1517.         Character.Humanoid:SetStateEnabled(stateType.FallingDown, false)
  1518.         Character.Humanoid:SetStateEnabled(stateType.Ragdoll, false)
  1519.         wait(.1);
  1520.         Character.PrimaryPart.Anchored = false;
  1521.         Character.Humanoid:MoveTo(Character.PrimaryPart.CFrame.LookVector*7 + Character.PrimaryPart.CFrame.Position)
  1522.        
  1523.         Character.Humanoid.MoveToFinished:Wait()
  1524.         local ColorCorrection = Instance.new('ColorCorrectionEffect', game:GetService('Lighting'));
  1525.         ColorCorrection.Name = "BattleEffect";
  1526.         local Length = 1;
  1527.         Tween(ColorCorrection, TweenInfo.new(Length), {Brightness = -0.45}):Play();
  1528.         Battle.OtherMusic = game:GetService('ReplicatedStorage').Music['Negotiation']:Clone();
  1529.         Battle.OtherMusic.Volume = 0;
  1530.         Battle.OtherMusic.Parent = Player.PlayerGui;
  1531.         Battle.OtherMusic:Play();
  1532.         local Vol = self.Music.Volume;
  1533.         for i = self.Music.Volume, 0, -0.075 do
  1534.             self.Music.Volume = i;
  1535.             Battle.OtherMusic.Volume = Battle.OtherMusic.Volume + (Vol - i)
  1536.             wait();
  1537.         end
  1538.         self.Music:Pause();
  1539.         local Input;
  1540.        
  1541.         BattleInfo.SelectedEnemyGuy = Battle:GetFirstLivingEnemy();
  1542.         local SEG = BattleInfo.SelectedEnemyGuy;
  1543.         local Char = self:GetEnemyFromName(BattleInfo.SelectedEnemyGuy, true);
  1544.         Battle:CharacterPositionButWithPersona(1, Char.PrimaryPart, true, 11, 3.5) --(t, lookAt, inst, ofst)
  1545.        
  1546.  
  1547.         local Part;
  1548.         Part = not (Part and Part:Destroy()) and Instance.new('Part')
  1549.         Part.Anchored = true;
  1550.         Part.Transparency = 1;
  1551.         Part.CFrame = Char:GetPrimaryPartCFrame() + Vector3.new(0,5,0);
  1552.         Part.CanCollide = false;
  1553.         Part.Parent = workspace;
  1554.         do --create new scope so other scopes cannot access these current local scopes.
  1555.             for i, v in pairs(self.PartyContainer:GetChildren()) do
  1556.                 local Part = Instance.new('Part')
  1557.                 Part.Anchored = true;
  1558.                 Part.Transparency = 1;
  1559.                 Part.CFrame = v:GetPrimaryPartCFrame() + Vector3.new(0,5,0);
  1560.                 Part.CanCollide = false;
  1561.                 Part.Parent = workspace;
  1562.                
  1563.                 local PointLight = Instance.new('PointLight')
  1564.                 PointLight.Color = Color3.fromRGB(206, 200, 131)
  1565.                 PointLight.Range = 4;
  1566.                 PointLight.Brightness = 32.25;
  1567.                 PointLight.Parent = Part;      
  1568.             end
  1569.            
  1570.             local Part = Instance.new('Part')
  1571.             Part.Anchored = true;
  1572.             Part.Transparency = 1;
  1573.             Part.CFrame = Character:GetPrimaryPartCFrame() + Vector3.new(0,5,0);
  1574.             Part.CanCollide = false;
  1575.             Part.Parent = workspace;
  1576.            
  1577.             local PointLight = Instance.new('PointLight')
  1578.             PointLight.Color = Color3.fromRGB(206, 200, 131)
  1579.             PointLight.Range = 4;
  1580.             PointLight.Brightness = 32.25;
  1581.             PointLight.Parent = Part;      
  1582.         end
  1583.         local PointLight = Instance.new('PointLight')
  1584.         PointLight.Color = Color3.fromRGB(206, 200, 131)
  1585.         PointLight.Range = 4;
  1586.         PointLight.Brightness = 32.25;
  1587.         PointLight.Parent = Part;      
  1588.         local lastInput;
  1589.         self.OtherMusic = Battle.OtherMusic;
  1590.         repeat
  1591.             Input = (typeof(lastInput or true) ~= 'boolean' and lastInput) or UIS.InputBegan:Wait()
  1592.             if (Input == 'MessedUp') then
  1593.                 for i, v in pairs(self.Characters) do
  1594.                     v = Battle:GetCharacterFromID(i);
  1595.                     v:SetPrimaryPartCFrame(CFrames[i]);
  1596.                 end
  1597.                 local Index = PlayerGui:FindFirstChild('BattleChoices', true) and PlayerGui:FindFirstChild('BattleChoices', true):Destroy() or nil;
  1598.                 local OtherIndex = PlayerGui:FindFirstChild('BattleBox', true) and PlayerGui:FindFirstChild('BattleBox', true):Destroy() or nil;
  1599.                 Part = Part and Part:Destroy();
  1600.                 local Length = 0.25;
  1601.                 Tween(ColorCorrection, TweenInfo.new(Length), {Brightness = 0}):Play();
  1602.                 Input = true; Battle.HoldUpped = true; break;
  1603.             end
  1604.             if (Input.KeyCode == Enum.KeyCode.Z) then
  1605.                 local Index = PlayerGui:FindFirstChild('BattleChoices', true) and PlayerGui:FindFirstChild('BattleChoices', true):Destroy() or nil;
  1606.                 local OtherIndex = PlayerGui:FindFirstChild('BattleBox', true) and PlayerGui:FindFirstChild('BattleBox', true):Destroy() or nil;
  1607.                
  1608.                 for i, v in pairs(self.Characters) do
  1609.                     v = Battle:GetCharacterFromID(i);
  1610.                     v:SetPrimaryPartCFrame(CFrames[i]);
  1611.                 end
  1612.                 Part = Part and Part:Destroy();
  1613.                 local Length = 0.25;
  1614.                 Tween(ColorCorrection, TweenInfo.new(Length), {Brightness = 0}):Play();
  1615.                 Input = true; Battle.HoldUpped = true; break;
  1616.             elseif (Enum.KeyCode.X == Input.KeyCode) then --cursed
  1617.                 Tween(workspace.CurrentCamera, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, false, 0), {CFrame = self.BattleArea.Cameras.AmbushCamera.CFrame}):Play();
  1618.                 local Index = PlayerGui:FindFirstChild('BattleChoices', true) and PlayerGui:FindFirstChild('BattleChoices', true):Destroy() or nil;
  1619.                 local OtherIndex = PlayerGui:FindFirstChild('BattleBox', true) and PlayerGui:FindFirstChild('BattleBox', true):Destroy() or nil;
  1620.                 self.Music:Resume();
  1621.                 for i = 0, Vol, 0.075 do
  1622.                     self.Music.Volume = i;
  1623.                     Battle.OtherMusic.Volume = Battle.OtherMusic.Volume - i;
  1624.                     wait();
  1625.                 end
  1626.                 for i, v in pairs(self.Characters) do
  1627.                     v = Battle:GetCharacterFromID(i);
  1628.                     v:SetPrimaryPartCFrame(CFrames[i]);
  1629.                 end
  1630.                 Part = Part and Part:Destroy();
  1631.                 local Length = 0.25;
  1632.                 Tween(ColorCorrection, TweenInfo.new(Length), {Brightness = 0}):Play()
  1633.                 local Personas = {};
  1634.                 local what = game:GetService('ReplicatedStorage'):WaitForChild('EffectStorage'):WaitForChild('DustPart'):Clone();
  1635.                 local MiddleCF = self.EnemySpawns:GetChildren()[1].CFrame:Lerp(self.EnemySpawns:GetChildren()[#self.EnemySpawns:GetChildren()].CFrame, 0.5);
  1636.                 local ChosenEffects = {};
  1637.                 local ACF=0;
  1638.                 local CompletedEffects = {};
  1639.                 local Passed;
  1640. --              spawn(function()
  1641. --                  repeat wait(.5) what.ParticleEmitter:Emit(1500) until Passed
  1642. --              end)
  1643.                 what.CFrame = MiddleCF;
  1644.                 what.Parent = Instance.new('Model', workspace)
  1645.                 what.Parent.PrimaryPart = what;
  1646.                 local a = Instance.new('Humanoid', what.Parent);
  1647.                 what.ParticleEmitter.Enabled = true;
  1648.                 a.HipHeight = game.Players.LocalPlayer.Character.Humanoid.HipHeight
  1649.                 for i, v in pairs(self.Characters) do
  1650.                     local N = v;
  1651.                     if (i ~= BattleInfo.SelectedMember) then
  1652.                         v = Battle:GetCharacterFromID(i);
  1653.                         for i, v in pairs(v:GetDescendants()) do
  1654.                             if (v:IsA("BasePart") or v:IsA('Decal')) and (v.Name ~= 'HumanoidRootPart') then
  1655.                                 local Transparency = Instance.new'NumberValue';
  1656.                                 Transparency.Name = 'Opacity'
  1657.                                 Transparency.Value = v.Transparency;
  1658.                                 Transparency.Parent = v
  1659.                                 spawn(function(a)
  1660.                                     wait(0.5)
  1661.                                     for i = v.Transparency, 1, 0.1 do
  1662.                                         wait();
  1663.                                         v.Transparency = i;
  1664.                                     end
  1665.                                 end)
  1666.                             end
  1667.                         end
  1668.                     end
  1669.                     ChosenEffects[N.Persona.Name] = N.Persona.Attacks[math.random(1, #N.Persona.Attacks)]
  1670.                     ACF=ACF+1;
  1671.                 end
  1672.                 for i, v in pairs(self.Characters) do --todo // change all _G.Characters to self.Characters unless in initialization function
  1673.                     Personas[v.Persona.Name]=Battle:createPersona(nil, true, i)
  1674.                     Personas[v.Persona.Name].Name = v.Name;
  1675.                 end
  1676.                 wait();
  1677.                 for i, v in pairs(self.Characters) do
  1678.                     local N = v;
  1679.                     if (i ~= BattleInfo.SelectedMember) then
  1680.                         v = Battle:GetCharacterFromID(i);
  1681.                         v:WaitForChild('Humanoid'):MoveTo(MiddleCF.Position);
  1682.                     end
  1683.                 end
  1684.                 wait(3.5);
  1685.                 spawn(function()
  1686.                     local Next = 0.1+math.random()/2
  1687.                     while wait(Next) do
  1688.                         if (Passed) then
  1689.                             local HeavyHit = ReplicatedStorage.Music:WaitForChild('HeavyHit')
  1690.                             HeavyHit = HeavyHit:Clone()
  1691.                             HeavyHit.Parent = game.Players.LocalPlayer.PlayerGui;
  1692.                             HeavyHit.PlayOnRemove = true;
  1693.                             HeavyHit:Destroy();
  1694.                             break;
  1695.                         end;
  1696.                         local HeavyHit = ReplicatedStorage.Music:WaitForChild('NormalHit')
  1697.                         HeavyHit = HeavyHit:Clone()
  1698.                         HeavyHit.Parent = game.Players.LocalPlayer.PlayerGui;
  1699.                         HeavyHit.PlayOnRemove = true;
  1700.                         HeavyHit:Destroy();
  1701.                         Next = 0.1+math.random()/2
  1702.                     end
  1703.                 end)
  1704.                 for i, v in pairs(ChosenEffects) do
  1705.                     local Effect = Effects[getAttack(v).Effect] or function() end;
  1706.                     coroutine.wrap(function()  
  1707.                         Effect({
  1708.                             PrimaryPart = what;
  1709.                             TargetPart = Personas[i].PrimaryPart;
  1710.                             IgnoreAnimation = false;
  1711.                             TargetFolder = self.EnemyContainer;
  1712.                         });
  1713.                         CompletedEffects[#CompletedEffects+1] = v;
  1714.                     end)() 
  1715.                 end
  1716.                 repeat wait() --[[impwarn(#CompletedEffects, ACF, ACF==#CompletedEffects)]] until #CompletedEffects == ACF
  1717.                 Passed = true;
  1718.                 for i, v in pairs(self.Characters) do
  1719.                     v = Battle:GetCharacterFromID(i);
  1720.                     v.Humanoid:MoveTo(v.PrimaryPart.Position);
  1721.                     wait();
  1722.                     v:SetPrimaryPartCFrame(CFrames[i]);
  1723.                     for i, v in pairs(v:GetDescendants()) do
  1724.                         spawn(function(a)
  1725.                             if (v:IsA('BasePart') or v:IsA('Decal')) and (v:FindFirstChild'Opacity') then
  1726.                                 --impwarn(v.Transparency, v.Opacity.Value)
  1727.                                 for i = v.Transparency, v.Opacity.Value, -0.1 do
  1728.                                     wait();
  1729.                                     v.Transparency = i;
  1730.                                 end
  1731.                             end
  1732.                         end)
  1733.                     end
  1734.                 end
  1735. --                      Effects[attack.Effect]({PrimaryPart = Char.PrimaryPart,  --enemy's part
  1736. --                          IgnoreAnimation = ia, --ignore animation?
  1737. --                          TargetPart = Me.PrimaryPart, --my primary part
  1738. --                          TargetFolder = self.EnemyContainer --enemy's folder? WHAT
  1739. --                      })
  1740.  
  1741.                 what.ParticleEmitter.Enabled = false;
  1742.                 local Damage = 0;
  1743.                 for i, v in pairs(self.Characters) do
  1744.                     local EquippedMelee = v.Equipped.Melee
  1745.                     local Item = Items[EquippedMelee];
  1746.                     if (Item) then
  1747.                         Damage = Damage+(Item.Damage or 0);
  1748.                     end
  1749.                 end
  1750.                 --[[
  1751.                     attacks.Lunge = {
  1752.                         Name = 'Lunge';
  1753.                         Type = 'Physical',
  1754.                         Damage = 35;
  1755.                         HPRequired = 5;
  1756.                         Description = 'Slight Physical damage to one foe.';
  1757.                         JPDesc = '???????????????' --//??
  1758.                     }
  1759.                 --]]
  1760.                 wait(1);
  1761.                 Battle:AdorneeHealth();
  1762.                 Battle:Damage(self.Characters[1], self.Enemies[1], {
  1763.                     Name = "All Out Attack",
  1764.                     Type = "Almighty",
  1765.                     Damages = "All";
  1766.                     Damage = Damage;
  1767.                     HPRequired = 0;
  1768.                     Description = "No time for apologies!";
  1769.                 }, true)
  1770.                 Battle:TweenHealth();
  1771.                 for i, v in pairs(self.Enemies) do
  1772.                     v.Debuffs = {};
  1773.                 end
  1774.                 RemoveAllPersonas(true)
  1775.                 Input = true;
  1776.             elseif (Input.KeyCode == Enum.KeyCode.Left or Input.KeyCode == Enum.KeyCode.Right or Input.KeyCode == Enum.KeyCode.DPadLeft or lastInput == "Left" or lastInput == "Right") then
  1777.                 --print(Input.Name:match('Left') or Input.Name:match('Right'));
  1778.                 Input = lastInput and {Name = lastInput} or Input.KeyCode;
  1779.                 Input = {Name = Input.Name:match('Left') or Input.Name:match('Right')};
  1780.                 BattleInfo.SelectedEnemyGuy = self:GetEnemy(Input.Name:sub(1,1):lower(), BattleInfo.SelectedEnemyGuy)
  1781.                 local Char = self:GetEnemyFromName(BattleInfo.SelectedEnemyGuy, true);
  1782.                 Battle:CharacterPositionButWithPersona(1, Char.PrimaryPart, nil, 11, 3.5)
  1783.                 Part = not (Part and Part:Destroy()) and Instance.new('Part')
  1784.                 Part.Anchored = true;
  1785.                 Part.Transparency = 1;
  1786.                 Part.CFrame = Char:GetPrimaryPartCFrame() + Vector3.new(0,5,0);
  1787.                 Part.CanCollide = false;
  1788.                 Part.Parent = workspace;
  1789.                
  1790.                 local PointLight = Instance.new('PointLight')
  1791.                 PointLight.Color = Color3.fromRGB(206, 200, 131)
  1792.                 PointLight.Range = 4;
  1793.                 PointLight.Brightness = 32.25;
  1794.                 PointLight.Parent = Part;
  1795.                
  1796.                 lastInput = nil;
  1797.                 lastInput = _G.ShowIntroSpeech(game:GetService('ReplicatedStorage').ModuleScripts.Dialogue.Timid, self.Enemies[SEG].Name, Battle, self.Enemies[SEG], BattleInfo.SelectedEnemyGuy);
  1798.             end  
  1799.         until Input == true;
  1800.         self.Music:Resume();
  1801.         for i = 0, Vol, 0.075 do
  1802.             self.Music.Volume = i;
  1803.             Battle.OtherMusic.Volume = Battle.OtherMusic.Volume - i;
  1804.             wait();
  1805.         end
  1806.         Battle.OtherMusic:Stop();
  1807.         Battle.OtherMusic:Destroy();
  1808.         self.OneMore = false;
  1809.     end
  1810.    
  1811.  
  1812.    
  1813.    
  1814.  
  1815.    
  1816.    
  1817.    
  1818.     if (self.OneMore == 'W') then
  1819.         self.OneMore = true
  1820.     end
  1821.    
  1822.     --PlayerGui.Reticle.Enabled = false;
  1823.     local NoHealth = 0;
  1824.     for i, v in pairs(self.Enemies) do
  1825.         if (v.Health <= 0) then
  1826.             NoHealth = NoHealth + 1;
  1827.         end
  1828.     end
  1829.  
  1830.     local NHealth = 0
  1831.     for i, v in pairs(self.Characters) do
  1832.         if (v.Health <= 0) then
  1833.             NHealth = NHealth + 1;
  1834.         end;
  1835.     end
  1836.     RemoveAllPersonas(true)
  1837.    
  1838.     self:EndBattleProtocol(NoHealth, NHealth, false)
  1839. --  if (NoHealth == #self.Enemies or NHealth == #self.Characters) then
  1840. --      self:EndBattle();
  1841. --     
  1842. --      for i, v in pairs(Character.Humanoid:GetPlayingAnimationTracks()) do
  1843. --          v:Stop(); --stop all playing animations, the default animator will replay animations again so it doesn't matter'
  1844. --      end
  1845. --      local PLighting = ReplicatedStorage:FindFirstChild('Previous Lighting');
  1846. --      if (PLighting) then
  1847. --          for i, v in pairs(PLighting:GetChildren()) do
  1848. --              pcall(function()
  1849. --                  game:GetService('Lighting')[v.Name] = v.Value;
  1850. --              end)
  1851. --          end
  1852. --      end
  1853. --      self.BattleArea:Destroy();
  1854. --      for i, v in pairs(game:GetService'Lighting':GetChildren()) do
  1855. --          if (v.ClassName:match('Effect') and v.Name ~= 'e') then
  1856. --              v.Enabled = true
  1857. --          end
  1858. --      end
  1859. --      Character:SetPrimaryPartCFrame(self.PositionBeforeBattle)
  1860. --      Character:WaitForChild('HumanoidRootPart').Anchored = false;
  1861. --      StopAnimation(nil, Character:WaitForChild('Humanoid'))
  1862. --      _G.Music:Play();
  1863. --      return true, script:Destroy(); --self destruct script just to be safe
  1864. --  end
  1865.     BattleInfo.BattleStage = 'Main'; --reset BattleStage so the battle can basically refresh itself upon a new turn
  1866.     BattleInfo.SelectedEnemyGuy = 1 --workspace['Enemy Container']:GetChildren()[1] --set the selectedenemyguy to the first person
  1867.     if (BattleInfo.SelectedMember == 0) then
  1868.         --reset all tables in case a goof happened
  1869.         BattleInfo.EnemyTurns = {};
  1870.         BattleInfo.PlayerTurns = {};
  1871.         BattleInfo.MemberActions = {};
  1872.     elseif (BattleInfo.SelectedMember == 'Enemy') then
  1873.         BattleInfo.MemberActions = {}; --reset member actions if the player has already done stuff
  1874.     end
  1875.    
  1876.     local ChosenMember;
  1877.     if (not self.AvailableUsers) or (#self.AvailableUsers == 0) then
  1878.         impwarn("Refilling now.")
  1879.         ChosenMember = self:selectViableMember(true); --modify selectViableMember to provide enemy turns so debuffs wear off individually
  1880.     else
  1881.         impwarn("Not refilling, choosing a chracter now.")
  1882.         ChosenMember = self:selectViableMember() --true variable means that it just needs to choose a character and thats it, no reselecting
  1883.     end
  1884.     repeat game:GetService('RunService').RenderStepped:Wait();
  1885.         if not (typeof(ChosenMember) == "table") then
  1886.             if (not self.AvailableUsers) or (#self.AvailableUsers == 0) then
  1887.                 impwarn("No chosen member. Refilling now.")
  1888.                 ChosenMember = self:selectViableMember(true); --modify selectViableMember to provide enemy turns so debuffs wear off individually
  1889.             else
  1890.                 impwarn("No chosen member. Not refilling.")
  1891.                 ChosenMember = self:selectViableMember() --true variable means that it just needs to choose a character and thats it, no reselecting
  1892.             end
  1893.         end
  1894.     until (typeof(ChosenMember) == "table")
  1895.     impwarn("PASSED.")
  1896.     table.remove(self.AvailableUsers, 1)
  1897.     ChosenMember.Guard = false;
  1898.     BattleInfo.SelectedMember = ChosenMember;
  1899.  
  1900.     for x, v in pairs(self.Characters) do
  1901.         local n = v;
  1902.         BattleInfo.PlayerTurns[x] = BattleInfo.PlayerTurns[x] or 0;
  1903.         --warn('lope')
  1904.         if (v.Debuffs) then
  1905.             --warn('fat')
  1906.             for i, v in pairs(v.Debuffs) do
  1907.                 --warn('worn')
  1908.                 if (v.TurnAdded and v.Length and v.TurnAdded + v.Length <=  BattleInfo.PlayerTurns[x]) then
  1909.                     --warn('hi lol ecksdee')
  1910.                     self:MoveCameraToCharacter(x)
  1911.                     if (v.Name ~= 'Down') then
  1912.                         local DebuffTitle = (v.Name or '???')..' has worn off!';
  1913.                         DebuffTitle = v.WearOff or DebuffTitle;
  1914.                         showLabel(DebuffTitle, 1.5);
  1915.                     end
  1916.                     if (v.Name == 'Down') then
  1917.                         self.Characters[x].Debuffs.Down = nil;
  1918.                     end
  1919.                     spawn(function()
  1920.                         print(n.Debuffs[i])
  1921.                     end)
  1922.                     impwarn('Debuff data:', v.Name, v.Length, v.TurnAdded, 'Turn:', BattleInfo.EnemyTurns[x], 'Holder:', n.Name)
  1923.                 end
  1924.             end
  1925.         end
  1926.         if (v.Health == 0) then
  1927.             v.Debuffs = {};
  1928.         end
  1929.     end
  1930.    
  1931.     if (self.Characters[BattleInfo.SelectedMember] and self.Characters[BattleInfo.SelectedMember].Health > 0) then
  1932.         if (animationStatus(game.ReplicatedStorage.AnimationAssets.Death.Stay, Battle:GetCharacterFromID(BattleInfo.SelectedMember).Humanoid) and animationStatus(game.ReplicatedStorage.AnimationAssets.Death.Stay, Battle:GetCharacterFromID(BattleInfo.SelectedMember).Humanoid).IsPlaying) then
  1933.             impwarn('Character was alive but down! Recovering...')
  1934.             local Humanoid = Battle:GetCharacterFromID(BattleInfo.SelectedMember).Humanoid;
  1935.             --stop animation b
  1936.             self:InvisibleEnemies()
  1937.             StopAnimation(game.ReplicatedStorage.AnimationAssets.Death.Stay, Humanoid)
  1938.             StopAnimation(game.ReplicatedStorage.AnimationAssets.Death.Fall, Humanoid)
  1939.             self:MoveCameraToCharacter(BattleInfo.SelectedMember)
  1940.             local Anim = LoadAnimation(game.ReplicatedStorage.AnimationAssets.Rise.Rise, Humanoid)
  1941.             Anim:Play()
  1942.             Anim.Stopped:Wait()
  1943.             self:InvisibleEnemies()
  1944.         end
  1945.     end
  1946.     if (typeof(ChosenMember) ~= 'table') and not self.OneMore then
  1947.         BattleInfo.PlayerTurns[ChosenMember] = BattleInfo.PlayerTurns[ChosenMember] and BattleInfo.PlayerTurns[ChosenMember] + 1 or 1;
  1948.         warn(_G.Characters[ChosenMember].Name.."'s Turn:", BattleInfo.PlayerTurns[ChosenMember])
  1949.         if (checkIncapacitated(self.Characters[ChosenMember], nil)) then
  1950.             warn'incapazitated'
  1951.             return Battle:NewTurn()
  1952.         end
  1953.     end
  1954. --  Battle:ResetCharacters()
  1955.     if (checkIncapacitated(self.Characters[ChosenMember])) then
  1956.         warn('Member is incapacitated! Skipping turn..')
  1957.         BattleInfo.MemberActions[ChosenMember] = "Incapacitated"
  1958.         return Battle:NewTurn();
  1959.     end
  1960.        
  1961.     for x, v in pairs(self.Enemies) do
  1962.         local n = v;
  1963.         --warn('lope2')
  1964.         if (v.Debuffs) then
  1965.             --warn('fat2')
  1966.             for i, v in pairs(v.Debuffs) do
  1967.                 --warn('lorn2')
  1968.                 BattleInfo.EnemyTurns[n.ID] = BattleInfo.EnemyTurns[n.ID] or 1;
  1969.                 if (v.TurnAdded and v.Length and v.TurnAdded + v.Length <=  BattleInfo.EnemyTurns[n.ID]) then
  1970.                     --warn('enemy lolecksdee')
  1971.                     Battle:MoveCameraToEnemy(n.ID)
  1972.                     if (v.Name ~= 'Down') then
  1973.                         showLabel((v.Name or '???')..' has worn off!', 1.5);
  1974.                     end
  1975.                    
  1976.                     if (v.Name == 'Down') then
  1977.                         n.Debuffs.Down = nil;
  1978.                         warn("DOWN DATA:", n.Debuffs.Down)
  1979.                         --stop animation a
  1980.                         self:InvisibleParty()
  1981.                         local Humanoid = Battle:GetEnemyFromID(n.ID, true).Humanoid;
  1982.                         StopAnimation(game.ReplicatedStorage.AnimationAssets.Death.Stay, Humanoid)
  1983.                         StopAnimation(game.ReplicatedStorage.AnimationAssets.Death.Fall, Humanoid)
  1984.                         local Anim = LoadAnimation(game.ReplicatedStorage.AnimationAssets.Rise.Rise, Humanoid)
  1985.                         Anim:Play()
  1986.                         Anim.Stopped:Wait()
  1987.                         self:InvisibleParty()
  1988.                     end
  1989.                 else
  1990.                     warn('Debuff data:', v.Name, v.Length, v.TurnAdded, 'Turn:', BattleInfo.EnemyTurns[n.ID], 'Holder:', n.Name)
  1991.                 end
  1992.             end
  1993.         end
  1994.         if (v.Health == 0) then
  1995.             v.Debuffs = {};
  1996.         end
  1997.     end
  1998.    
  1999.     if (not self.Ambush) and tonumber(ChosenMember) then
  2000.         Battle:CharacterPosition() --reset camera position to the player's back
  2001.     elseif (self.Ambush) then
  2002.         Battle:AmbushPosition()
  2003.     end
  2004.     if (typeof(ChosenMember) == 'table') then
  2005.         BattleInfo.EnemyTurns[ChosenMember.ID] = BattleInfo.EnemyTurns[ChosenMember.ID] and BattleInfo.EnemyTurns[ChosenMember.ID] + 1 or 1;
  2006.         PlayerGui.PersonaListR.Adornee = nil;
  2007.         PlayerGui.HealthBar.Adornee = nil;
  2008.         if (checkIncapacitated(ChosenMember)) then
  2009.             warn('Enemy is incapacitated! Skipping turn..')
  2010.             BattleInfo.EnemyActions[ChosenMember.ID] = "Incapacitated";
  2011.             return Battle:NewTurn();
  2012.         end
  2013.         --Battle:PointCameraToEnemy(ChosenMember.ID, true)
  2014.         if (ChosenMember.CTC and ChosenMember.TurnCount and ChosenMember.CTC >= ChosenMember.TurnCount) then
  2015.             --impwarn("First")
  2016.             BattleInfo.EnemyActions[ChosenMember.ID] = true;
  2017.         elseif (ChosenMember.CTC and ChosenMember.TurnCount and ChosenMember.CTC < ChosenMember.TurnCount) then
  2018.             --impwarn("Second")
  2019.             ChosenMember.CTC = ChosenMember.CTC+1;
  2020.         else
  2021.             --impwarn("Third");
  2022.             BattleInfo.EnemyActions[ChosenMember.ID] = true;
  2023.         end
  2024.         EnemyAPI:EnemyFunction(self.Characters[math.random(1, #self.Characters)], ChosenMember, Battle)
  2025.        
  2026.         wait(1.5)
  2027.        
  2028.         return Battle:NewTurn(); --make the function recursive
  2029.     end --enemy ai
  2030.     PlayerGui.PersonaListR.Adornee = ChosenMember == 1 and Character.PrimaryPart or workspace:WaitForChild('Party Container'):WaitForChild(self.Characters[ChosenMember].Name).PrimaryPart
  2031.     --^ set the adornee to the localplayer's primary part if the chosenmember is one otherwise it sets it to the other's primaryparts.
  2032.  
  2033.     --using a stage system to determine where we are at
  2034.    
  2035.     --connect to UserInputService for epicness
  2036.     local InputBegan; --define InputBegan as a dummy variable
  2037.     local KeyPressed;
  2038.     pcall(function()
  2039.         self.Characters[BattleInfo.SelectedEnemyGuy].Guard = false;
  2040.     end)
  2041.     InputBegan = UIS.InputBegan:Connect(function(Key, Process)
  2042.         if (KeyPressed or Process) then return nil end
  2043.         BattleInfo.MemberActions[BattleInfo.SelectedMember] = true; --remove this
  2044.         ReplicatedStorage.Music.Blip:Play();
  2045.        
  2046.         --redefine InputBegan as the signal so we can keep the signal local whilst being able to disconnect it in the signal
  2047.         Key = Key.KeyCode;
  2048.         local Stage = BattleInfo.BattleStage
  2049.        
  2050.        
  2051.         if (Stage == 'Main' or Stage == 'BatonPass') then
  2052.            
  2053.                
  2054.        
  2055.             if (Key == K.Z or Key == K.ButtonY) then
  2056.                
  2057.                                
  2058.                 local Humanoid = self:GetCharacterFromID(BattleInfo.SelectedMember):WaitForChild('Humanoid')
  2059.                 BattleInfo.BattleStage = 'PersonaAttackList'
  2060.                 PlayerGui['Persona Attacks List'].Enabled = true
  2061.                 BattleInfo.MemberActions[BattleInfo.SelectedMember] = true;
  2062.                 game:GetService('RunService').RenderStepped:Wait()
  2063. --              for i, v in pairs(PlayerGui['Persona Attacks List'].Table:GetChildren()) do
  2064. --                  if (v:IsA('Frame')) then
  2065. --                      v.Button.Selected = true;
  2066. --                      game:GetService('GuiService').SelectedObject = v.Button;
  2067. --                      break;
  2068. --                  end
  2069. --              end
  2070.                 return true;
  2071.             elseif (Key == K.Q or Key == K.ButtonR2) and (self.OneMore) then
  2072.                
  2073.                 BattleInfo.BattleStage = 'BatonPass'
  2074.                 BattleInfo.SelectedEnemyGuy = BattleInfo.SelectedMember; --set btn pass to passer guy
  2075.                 self:MoveCameraToCharacter(BattleInfo.SelectedMember)
  2076.                 return true;
  2077.             end
  2078.         end
  2079.        
  2080.         if (Key == K.Backspace or Key == K.ButtonB) and Stage ~= 'Main' then
  2081.             Battle:RemoveHealthbars();
  2082.             if (Stage == 'AwaitGuard') then
  2083.                 if (not self.Ambush) then
  2084.                     Battle:CharacterPosition() --reset camera position to the player's back
  2085.                 else
  2086.                     Battle:AmbushPosition()
  2087.                 end            
  2088.                 RemoveAllPersonas()
  2089.                 PlayerGui['Guard'].Enabled = false;
  2090.                 BattleInfo.BattleStage = 'Main'
  2091.                 return nil;
  2092.             elseif (Stage == 'PersonaTarget' or Stage == 'PersonaChange') then
  2093.                 BattleInfo.Waffle = "AnimAndSound";
  2094.                 BattleInfo.BattleStage = 'PersonaAttackList'
  2095.                 self.PersonaSelect = nil;
  2096.                 return nil;
  2097.             elseif (Stage == 'Analysis') then
  2098.            
  2099.                 BattleInfo.SelectedPersonaAttack = {Name = 'Analysis'}; --KOWALSKI
  2100.                 BattleInfo.BattleStage = 'PersonaTarget'
  2101.                 return nil;
  2102.            
  2103.             else
  2104.                 if (not self.Ambush) then
  2105.                     Battle:CharacterPosition() --reset camera position to the player's back
  2106.                 else
  2107.                     Battle:AmbushPosition()
  2108.                 end            
  2109.                 RemoveAllPersonas()
  2110.                 BattleInfo.BattleStage = 'Main'
  2111.                 BattleInfo.SelectedPersonaAttack = {};
  2112.                 return nil;
  2113.             end;
  2114.         elseif (Key == K.LeftBracket or Key == K.RightBracket or Key == K.ButtonL1 or Key == K.ButtonR1) and (Stage == 'PersonaChange' or Stage == 'PersonaAttackList') and (BattleInfo.SelectedMember == 1) then
  2115.             Key = (Key == K.LeftBracket or Key == K.ButtonL1) and 'Left' or 'Right'
  2116.             local OrigTable = {}
  2117.             local x = 0;
  2118.             local targetI = nil;
  2119.             for i, v in pairs(Personas) do
  2120.                 if ((not self.PersonaSelect) and (v.Name == self.Characters[1].Persona.Name)) or self.PersonaSelect == x then
  2121.                     --warn('Not Self.PersonaSelect, and v.Name is self.Characters[1].Persona.Name, or self.PersonaSelect is equal to X.')
  2122.                     targetI = x;
  2123.                 else
  2124.                     --warn('?????')
  2125.                 end
  2126.                 if (not v.Unspawnable) and (v.Name) then
  2127.                     x=x+1; --put the x in the Unspawnable area so it only increments if the persona is indeed spawnable, so we dont spawn a boss persona.
  2128.                    
  2129.                     OrigTable[x] = v
  2130.                    
  2131.                 end --so we don't use big boss personas by accident
  2132.             end            
  2133.            
  2134.             self.CurrentPersona = nil
  2135.                 --obtain player
  2136.             for i, v in pairs(OrigTable) do
  2137.                
  2138.                 if (i == targetI) and (Stage ~= 'PersonaChange') then --v-1
  2139.                    
  2140.                     self.PersonaSelect = targetI;
  2141.                     self.CurrentPersona = v[2] --set thing to the table so we can use it's first iterator value to determine what place we are in'
  2142.                 elseif (i == self.PersonaSelect or i == 1) then
  2143.                     if (Key == 'Left') then
  2144.                         if (OrigTable[(self.PersonaSelect or 0)-1]) then
  2145.                             self.PersonaSelect = self.PersonaSelect and self.PersonaSelect-1 or #OrigTable;
  2146.                         else
  2147.                             self.PersonaSelect = #OrigTable;
  2148.                         end
  2149.                     elseif (Key == 'Right') then
  2150.                         if (OrigTable[(self.PersonaSelect or 0)+1]) then
  2151.                             self.PersonaSelect = self.PersonaSelect and self.PersonaSelect+1 or 1;
  2152.                         else
  2153.                             self.PersonaSelect = 1;
  2154.                         end
  2155.                     end
  2156.                     self.CurrentPersona = OrigTable[self.PersonaSelect];
  2157.                     break;
  2158.                 end
  2159.             end
  2160.            
  2161.             if (not self.CurrentPersona) then
  2162.                 self.CurrentPersona = OrigTable[1];
  2163.                 self.PersonaSelect = 1;
  2164.             end
  2165.            
  2166.             _G.RequestPersona(self.CurrentPersona or OrigTable[1]);
  2167.             BattleInfo.BattleStage = 'PersonaChange';
  2168.         elseif (Key == K.R or Key == K.ButtonL1) and (BattleInfo.BattleStage == 'Main') then
  2169.             BattleInfo.SelectedPersonaAttack = {Name = 'Analysis'}; --KOWALSKI
  2170.             BattleInfo.BattleStage = 'PersonaTarget'
  2171.         elseif (Key == K.Return or Key == K.ButtonA) then
  2172.        
  2173.             if (UIS:IsKeyDown(K.R)) then
  2174.                 KeyPressed = true;
  2175.                 return true;
  2176.             end
  2177.            
  2178.             if (BattleInfo.BattleStage == 'PersonaTarget' and BattleInfo.SelectedPersonaAttack and BattleInfo.SelectedPersonaAttack.Name == 'Analysis') then
  2179.                
  2180.                 _G.RequestPersona(self.Enemies[BattleInfo.SelectedEnemyGuy] or self.Enemies[#self.Enemies], true)
  2181.                 BattleInfo.BattleStage = 'Analysis'
  2182.                 return true;
  2183.             end
  2184.            
  2185.             if (self.CurrentPersona and Stage == 'PersonaChange') then
  2186.                 local Persona = self.CurrentPersona or Personas.Widgeon;
  2187.                 local NeverSwappedPersona = self.CurrentPersona.Name == self.Characters[1].Persona.Name
  2188.                 self.Characters[1].Persona = self.CurrentPersona or Personas.Widgeon;
  2189.                 RefreshPersonaList(not NeverSwappedPersona)
  2190.                 BattleInfo.BattleStage = 'PersonaAttackList'
  2191.                 return true;
  2192.             end
  2193.            
  2194.             if (Stage == 'AwaitGuard') then
  2195.                 self.Characters[BattleInfo.SelectedMember].Guard = true;
  2196.                 KeyPressed = true;
  2197.                 PlayerGui['Guard'].Enabled = false;
  2198.                 BattleInfo.MemberActions[BattleInfo.SelectedMember] = true;
  2199.                 wait(.25)
  2200.                 return true;
  2201.             end
  2202.            
  2203.             if (Stage == 'BatonPass') then
  2204.                 if (BattleInfo.SelectedEnemyGuy == BattleInfo.SelectedMember) then
  2205.                     spawn(function(a) showLabel('Cannot baton pass to yourself.', 0.25) end)
  2206.                     ReplicatedStorage.Music.Error:Play();
  2207.                     return true;
  2208.                 end
  2209.                 if (self.Characters[BattleInfo.SelectedEnemyGuy].BatonPassed) then
  2210.                     showLabel('Cannot baton pass to someone twice.', 0.25)
  2211.                     return true;
  2212.                 end
  2213.                 self.Characters[BattleInfo.SelectedEnemyGuy].BatonPassed = true;
  2214.                 self.BatonPass = BattleInfo.SelectedEnemyGuy;
  2215.                 KeyPressed = true;
  2216.                 return true;
  2217.             end
  2218.            
  2219.             if (Stage == 'PersonaAttackList') then
  2220.                 KeyPressed = 'Waiting'
  2221.                 if (not game:GetService('GuiService').SelectedObject) then KeyPressed = false; return nil end;
  2222.                
  2223.                 local Attack = getAttack(game:GetService('GuiService').SelectedObject.Parent.AttackTitle.Text);
  2224.                
  2225.                 if Attack.HPRequired and (modifyDamage(Attack.HPRequired, self.Characters[BattleInfo.SelectedMember].MaxHealth) > self.Characters[BattleInfo.SelectedMember].Health) then
  2226.                     KeyPressed = false;
  2227.                     ReplicatedStorage.Music['Error']:Play();
  2228.                     return true, showLabel('Not enough HP!');
  2229.                 elseif (Attack.SPRequired and self.Characters[BattleInfo.SelectedMember].SP < Attack.SPRequired) then
  2230.                     KeyPressed = false;
  2231.                     ReplicatedStorage.Music['Error']:Play();
  2232.                     return true, showLabel('Not enough SP!');
  2233.                 elseif Attack.Type == 'Buff' then
  2234.                     if (Attack.Type2 == 'Revive') then
  2235.                         local NobodyDead = true
  2236.                         for i, v in pairs(self.Characters) do
  2237.                             if (v.Health == 0) then
  2238.                                 NobodyDead = false
  2239.                             end
  2240.                         end
  2241.                         if (NobodyDead) then
  2242.                             KeyPressed = false;
  2243.                             ReplicatedStorage.Music['Error']:Play();
  2244.                             return true, showLabel('There are no fallen party members.');
  2245.                         end
  2246.                     elseif (Attack.Type2 == 'Cure') then
  2247.                         local HasDebuff = false;   
  2248.                         for i, v in pairs(self.Characters) do
  2249.                             for i, v in pairs(v.Debuffs) do
  2250.                                 if (Attack.Debuffs[v.Name]) then
  2251.                                     HasDebuff = true;
  2252.                                 end
  2253.                             end
  2254.                         end
  2255.                         if (not HasDebuff) then
  2256.                             KeyPressed = false;
  2257.                             ReplicatedStorage.Music['Error']:Play();
  2258.                             return true, showLabel('There are no party members with debuffs.');
  2259.                         end
  2260.                     else
  2261.                         local FullHealth = 0;
  2262.                         for i, v in pairs(self.Characters) do
  2263.                             if (v.Health == v.MaxHealth) then
  2264.                                 FullHealth = FullHealth+1
  2265.                             end
  2266.                         end
  2267.                        
  2268.                         if (FullHealth == #self.Characters) then
  2269.                             KeyPressed = false;
  2270.                             ReplicatedStorage.Music['Error']:Play();
  2271.                             return true, showLabel('All party members are fully healed.');
  2272.                         end
  2273.                     end
  2274.                 end
  2275.                 BattleInfo.BattleStage = 'PersonaTarget'
  2276.                 BattleInfo.SelectedEnemyGuy = (not (Attack.Type == 'Buff' or (Attack.Type == 'Kaja' and Attack.Type2 ~= 'Debuff'))) and self:GetFirstLivingEnemy() or BattleInfo.SelectedMember;
  2277.                 BattleInfo.SelectedPersonaAttack = Attack
  2278.                 self:RemoveHealthbars()
  2279.                 self:AdorneeHealth();
  2280.                 KeyPressed = false;
  2281.                 --local x = not self.Ambush and ((Attack.Type == 'Buff' or Attack.Type == 'Kaja') and
  2282.                     --self:MoveCameraToCharacter(BattleInfo.SelectedMember) or self:MoveCameraToEnemy(self:GetEnemyFromID(BattleInfo.SelectedEnemyGuy)))
  2283.                
  2284.                 --get attack from selected object name^
  2285.                 if (self.Ambush) and ((Attack.Type == 'Kaja' and Attack.Type2 ~= 'Debuff') or Attack.Type == 'Buff') then
  2286.                     --PlayerGui.Reticle.Enabled = true;
  2287.                     PlayerGui.Reticle.Adornee = self:GetCharacterFromID(BattleInfo.SelectedMember)
  2288.                 end
  2289.                
  2290.                 local Char = self:GetEnemyFromName(BattleInfo.SelectedEnemyGuy, true);
  2291.                
  2292.                 --move camera seamelessly
  2293.                
  2294.                 local Factor = (Attack.Heals and "Heals") or (Attack.Damages and "Damages") or nil;
  2295.                 if (Factor and not self.Ambush) then
  2296.                     local y = (Factor == "Heals" and self.PartySpawns:GetChildren()) or (Factor == "Damages" and self.EnemySpawns:GetChildren());
  2297.                     local First, Last;
  2298.                     local LivingEnemies = 0;
  2299.                     for i, v in pairs(self.Enemies) do
  2300.                         if (v.Health > 0) then
  2301.                             LivingEnemies=LivingEnemies+1;
  2302.                         end
  2303.                     end
  2304.                     First = y[1]; --get the first spawn
  2305.                     Last = y[LivingEnemies]; --get the last spawn
  2306.                    
  2307.                     local PositionToCirculateAround = First.CFrame:Lerp(Last.CFrame, 0.5) --get their distance from the leftmost cframe
  2308.                     local thing = CFrame.new(PositionToCirculateAround.LookVector*(#(Factor == "Damages" and (function()local a={};for i=0,LivingEnemies do a[#a+1]=i return a end end)() or self.Characters)*3.5) + PositionToCirculateAround.Position);
  2309.                     --local newThing = thing + Vector3.new(0,LivingEnemies*4,0)
  2310.                     local EC = 0;
  2311.                     local D
  2312.                     for i, v in pairs(self.Enemies) do
  2313.                         if (v.Health > 0) then
  2314.                             EC = EC+1;
  2315.                             D = not D and v.ID or D;
  2316.                         end
  2317.                     end
  2318.                     workspace.CurrentCamera.CFrame = CFrame.new(workspace.CurrentCamera.CFrame.Position, (EC == 1 and self:GetCharacterFromID(D).PrimaryPart.CFrame.Position) or thing.Position+Vector3.new(0,(Character.Humanoid.HipHeight+2 or 6.5),0))
  2319.                     return 0;
  2320.                 end
  2321.                
  2322.                 if (not self.Ambush) and (not Factor) then
  2323.                     Battle:CharacterPositionButWithPersona(nil, Char.PrimaryPart.CFrame)
  2324.                 else
  2325.                     PlayerGui.Reticle.Adornee = Char.PrimaryPart;
  2326.                     --PlayerGui.Reticle.Enabled = true;
  2327.                 end
  2328.                
  2329.                 if (self.Ambush) and not (Attack.Type == 'Kaja' or Attack.Type == 'Buff') then --woo spaghetti
  2330.                     PlayerGui.Reticle.Adornee = Char.PrimaryPart;
  2331.                     --PlayerGui.Reticle.Enabled = true;
  2332.                 elseif (not self.Ambush) then
  2333.                     --PlayerGui.Reticle.Enabled = false;
  2334.                 end
  2335.             elseif (BattleInfo.BattleStage == 'PersonaTarget' and Battle.FinishedAttacking) then
  2336.                 local Attack = BattleInfo.SelectedPersonaAttack;
  2337.                 Battle.FinishedAttacking = false;
  2338.                 if (Attack.Damage) then
  2339.                     pcall(function()
  2340.                         local SelectedShouts = Shouts.AttackShouts[tostring(BattleInfo.SelectedMember or 1)]
  2341.                         local newShout = SelectedShouts:GetChildren()[math.random(1, #SelectedShouts:GetChildren())]:Clone();
  2342.                         newShout.Parent = PlayerGui;
  2343.                         newShout.PlayOnRemove = true;
  2344.                         wait();
  2345.                         newShout:Destroy();
  2346.                     end)
  2347.                 end
  2348.                 Battle:Damage(self.Characters[BattleInfo.SelectedMember], (not Attack.Heals) and self.Enemies[BattleInfo.SelectedEnemyGuy] or self.Characters[1], Attack);
  2349.                 KeyPressed = true;
  2350.             end
  2351.         elseif (Key == K.C or Key == K.ButtonB) then
  2352.             if (BattleInfo.BattleStage == 'Main') then
  2353.                 BattleInfo.BattleStage = 'AwaitGuard'
  2354.                 PlayerGui['Guard'].Enabled = true;
  2355.                 return nil;
  2356.             elseif (BattleInfo.BattleStage == 'AwaitGuard') then
  2357.                 PlayerGui['Guard'].Enabled = false;
  2358.                 BattleInfo.BattleStage = 'Main'
  2359.                 return nil;
  2360.             end
  2361.         elseif (Key == K.Left or Key == K.Right or Key == K.DPadLeft or Key == K.DPadRight) and (BattleInfo.SelectedPersonaAttack and (BattleInfo.BattleStage == 'PersonaTarget' or BattleInfo.BattleStage == 'BatonPass')) and (not BattleInfo.SelectedPersonaAttack.Damages) and not BattleInfo.SelectedPersonaAttack.Heals then
  2362.             local Attack = BattleInfo.SelectedPersonaAttack;
  2363.             Key = {Name = Key.Name:match('Left') or Key.Name:match('Right')};
  2364.             local Factor = (Attack.Heals and "Heals") or (Attack.Damages and "Damages") or nil;
  2365.            
  2366.             if (Attack.Type2 ~= "Debuff") and (BattleInfo.BattleStage == 'BatonPass' or Attack.Type == 'Kaja' or Attack.Type == 'Buff') then
  2367.                 print(Attack.Name, Attack.Type, Attack.Type2, "Facing toward character.")
  2368.                 BattleInfo.SelectedEnemyGuy = self:GetCharacter(Key.Name:sub(1,1):lower(), BattleInfo.SelectedEnemyGuy, (BattleInfo.SelectedPersonaAttack.Type2 == 'Revive' or nil)) or BattleInfo.SelectedEnemyGuy
  2369.                 local Char = self:GetCharacterFromID(BattleInfo.SelectedEnemyGuy);
  2370.                 Battle:MoveCameraToCharacter(BattleInfo.SelectedEnemyGuy);
  2371.                 --PlayerGui.Reticle.Adornee = Char.PrimaryPart;
  2372.                 ----PlayerGui.Reticle.Enabled = true;
  2373.             else
  2374.                 print(Attack.Name, Attack.Type, Attack.Type2, "Facing toward enemy.")
  2375.                 BattleInfo.SelectedEnemyGuy = self:GetEnemy(Key.Name:sub(1,1):lower(), BattleInfo.SelectedEnemyGuy)
  2376.                 local Char = self:GetEnemyFromName(BattleInfo.SelectedEnemyGuy, true);
  2377.                 if (not self.Ambush) then
  2378.                     Battle:CharacterPositionButWithPersona(nil, Char.PrimaryPart.CFrame)
  2379.                 else
  2380.                     --PlayerGui.Reticle.Adornee = Char.PrimaryPart;
  2381.                     ----PlayerGui.Reticle.Enabled = true;
  2382.                 end
  2383.             end
  2384.             self:RemoveHealthbars()
  2385.             self:AdorneeHealth();      
  2386.             end
  2387.         return true;
  2388.     end)
  2389.    
  2390.     repeat wait() until KeyPressed == true; --strict comparison because keypressed is also assigned to strings
  2391.     if (InputBegan) then
  2392.         InputBegan:Disconnect();
  2393.     end
  2394.     Battle.FinishedAttacking = true;
  2395.     if (self.OneMore == true) then
  2396.         self.OneMore = false;
  2397.     end
  2398.     return Battle:NewTurn();
  2399. end
  2400. function RefreshPersonaList(sound)
  2401.     --impwarn("Sound:", sound)
  2402.     for i,v in pairs(PlayerGui["Persona Attacks List"].List.Frame:GetChildren()) do
  2403.         if (v.Name ~= "Grid") then v:Destroy() end;
  2404.     end
  2405.    
  2406.     if (PlayerGui:WaitForChild("Persona Attacks List").Enabled) then
  2407.        
  2408.  
  2409.         local y = RichText:New(PlayerGui:WaitForChild('Persona Attacks List')['ID Background']:WaitForChild('PersonaName'), '<TextScale=1><TextScaled=true>'..personaIfy(Battle.Characters[BattleInfo.SelectedMember].Persona.Nickname or Battle.Characters[BattleInfo.SelectedMember].Persona.Name or '???'));
  2410.         y:Show()
  2411.         spawn(function()
  2412.             if (not sound) then
  2413.                 pcall(function()
  2414.                     if (BattleInfo.Waffle == 'AnimAndSound') then                      
  2415.                         local SFX = ReplicatedStorage.SFX.SummonPersona:Clone();
  2416.                         SFX.Parent = PlayerGui;
  2417.                         SFX.PlayOnRemove = true;
  2418.                         SFX:Destroy();
  2419.                     elseif (not BattleInfo.Waffle) then
  2420.                         local Humanoid = Battle:GetCharacterFromID(BattleInfo.SelectedMember):WaitForChild('Humanoid')
  2421.                         BattleInfo.BattleStage = 'PersonaAttackList'
  2422.                         LoadAnimation(ReplicatedStorage.AnimationAssets.Spin.Spin, Humanoid):Play();
  2423.                         local SFX = ReplicatedStorage.SFX.SummonPersona:Clone();
  2424.                         SFX.Parent = PlayerGui;
  2425.                         SFX.PlayOnRemove = true;
  2426.                         SFX:Destroy();
  2427.                         if (math.random(1, 15) < 10) then
  2428.                             local SelectedShouts = Shouts.PersonaShout[tostring(BattleInfo.SelectedMember or 1)]
  2429.                             local newShout = SelectedShouts:GetChildren()[math.random(1, #SelectedShouts:GetChildren())]:Clone();
  2430.                             newShout.Parent = PlayerGui;
  2431.                             newShout.PlayOnRemove = true;
  2432.                             newShout:Destroy();
  2433.                         end
  2434.                     end
  2435.                     BattleInfo.Waffle = false;
  2436.                     wait();
  2437.                 end)
  2438.             end
  2439.             Battle:createPersona(BattleInfo.Waffle == true)
  2440.         end)
  2441.         ----
  2442.         for i, v in pairs(Battle.Characters[BattleInfo.SelectedMember].Persona.Attacks) do
  2443.             v = getAttack(v)
  2444.             if (v) then
  2445.             if (tostring(i):match('%a')) then
  2446.                 --where the heck was I going with this?
  2447.             else           
  2448.             local C = PlayerGui["Persona Attacks List"].ExampleObject:Clone();
  2449.             C.Name = i;
  2450.             C.BorderSizePixel = 0;
  2451.             if (C.Frame:FindFirstChild(v.Type)) then
  2452.                 C.Frame[v.Type].Visible = true
  2453.             end
  2454.             C.AttackTitle.Text = v.Name;
  2455.             if (v.HPRequired) then
  2456.                 C.HP.Visible = true;
  2457.                 C.SP.Visible = false;
  2458.                 C.HP.Text = tostring(modifyDamage(v.HPRequired, Battle.Characters[BattleInfo.SelectedMember].MaxHealth)).. 'HP'
  2459.             elseif (v.SPRequired) then
  2460.                 C.HP.Visible = false;
  2461.                 C.SP.Visible = true;
  2462.                 C.SP.Text = tostring(v.SPRequired).. 'SP'
  2463.             end
  2464.            
  2465.             for i, x in pairs(Battle.Enemies) do
  2466.                 if (x.Weak) and x.Weak[v.Type] and x.Health > 0 then
  2467.                     C.WeakBack.Visible = true;
  2468.                     C.WeakFront.Visible = true
  2469.                 end
  2470.             end
  2471.             C.Parent = PlayerGui["Persona Attacks List"].List.Frame;
  2472.             C.Button.Text = ''
  2473.            
  2474.             C.Visible = true; end
  2475.             end
  2476.         end
  2477.         for i, v in pairs(PlayerGui['Persona Attacks List'].List.Frame:GetChildren()) do
  2478.             if (v:IsA('Frame')) then
  2479.                 v.Button.Selected = true;
  2480.                 game:GetService('GuiService').SelectedObject = v.Button;
  2481.                 break;
  2482.             end
  2483.         end
  2484.     else
  2485.        
  2486.     end
  2487. end
  2488.  
  2489. --function Battle:EndBattle()
  2490. --  self.Music:Stop();
  2491. --  self.Music = ReplicatedStorage.Music['Persona 5 - Victory (Victory)'];
  2492. --  self.Music.Looped = true;
  2493. --  self.Music:Play();
  2494. --  PlayerGui.YouWinAnimation.Enabled = true;
  2495. --  local stuff = {};
  2496. --  for i, v in pairs(PlayerGui.YouWinAnimation:GetChildren()) do
  2497. --      stuff[v] = v.Position;
  2498. --  end
  2499. --  local e = 0;
  2500. --  for i,v in pairs(self.Enemies) do
  2501. --      e = e + v.Level;
  2502. --  end
  2503. --  e = math.ceil(e/#self.Enemies);
  2504. --  local c = 1;
  2505. ----    for i, v in pairs(self.Characters) do
  2506. ----        c = c + v.Level;
  2507. ----    end
  2508. --  c = math.ceil(e/#self.Characters)
  2509. --  local EXPGained = math.ceil((e/c)*3.5*((e+c)*math.random(2, 3)));--*math.clamp(math.random(), 1, 1.3)));
  2510. --  EXPGained = EXPGained*DifficultyModifiers[self.Difficulty].Experience
  2511. --  local SP = {}--script.Parent:WaitForChild('YouWinAnimation');
  2512. --  local XYZ = PlayerGui.YouWinAnimation
  2513. --  for i, v in pairs(PlayerGui.YouWinAnimation:GetChildren()) do
  2514. --      SP[v.Name] = setmetatable({}, {__index = v;});
  2515. --      local x = SP[v.Name]
  2516. --      function x:TweenPosition(a,b,c,d, dir, style, num, override)
  2517. --          return v:TweenPosition(UDim2.new(a,b,c,d), dir, style, num or 1, override)
  2518. --      end
  2519. --      SP[v.Name].__newindex = function(self, i, y) v[i] = y; end;
  2520. --  end
  2521. --  --[[
  2522. --          Merciless={
  2523. --      DamageRecieved=1.6;
  2524. --      DamageDealt=0.8;
  2525. --      Experience=0.4;
  2526. --      Money=0.4;
  2527. --          };
  2528. --  --]]
  2529. --  SP.XPLabel:TweenPosition(-0.09, 0, 0.114, -3, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2530. --  SP.XPFrame:TweenPosition(-0.048, 0, 0.099, -0, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2531. --  SP.XPNumber:TweenPosition(0.127,0,0.124,-8, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true);
  2532. --  XYZ.XPNumber.Text = safetyZero(0, EXPGained)
  2533. --  spawn(function(y)
  2534. --      wait(1)
  2535. --      for i = 0, EXPGained, EXPGained/10 do
  2536. --          wait()
  2537. --          XYZ.XPNumber.Text = safetyZero(math.ceil(i), EXPGained);
  2538. --      end;
  2539. --  end)
  2540. -- 
  2541. --  game:GetService('UserInputService').InputBegan:Wait();
  2542. --  SP.MoneyFrame:TweenPosition(-0.012, 0, 0.297, 0, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2543. --  SP.YenSign:TweenPosition(-0.848, 0, 0.279, -3, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2544. --  SP.MoneyLabel:TweenPosition(0.058, 0, 0.334, 3, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true);
  2545. --  SP.MoneyNumber:TweenPosition(0.303, 0, 0.307, -8, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2546. --  --
  2547. --  local Money = 0;
  2548. --  Money = math.ceil(((EXPGained/math.random(3, 5))*DifficultyModifiers[self.Difficulty].Money)*math.clamp(math.random(), 0.5, 1)) + (Battle.MoneyNet or 0)
  2549. --  --MoneyPlaceholder = MoneyPlaceholder + Money;
  2550. -- 
  2551. -- 
  2552. --  XYZ.MoneyNumber.Text = safetyZero(0, Money)
  2553. --  spawn(function(x)
  2554. --      wait(1)
  2555. --      for i = 0, Money, Money/10 do
  2556. --          wait()
  2557. --          XYZ.MoneyNumber.Text = safetyZero(math.ceil(i), Money);
  2558. --      end;
  2559. --  end)
  2560. --  game:GetService('UserInputService').InputBegan:Wait();
  2561. --  if (self.ItemsGained) then
  2562. --      SP.ItemFrame:TweenPosition(-0.012, 0, 0.496, 0, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2563. --      SP.ItemLabel:TweenPosition(0.092, 0, 0.507, -3, Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2564. --  end
  2565. --  local al = false;
  2566. --  local level = false;
  2567. --  for i, v in pairs(self.Characters) do
  2568. --      local EXPToLevelUp = v.Level^2*3;
  2569. --      local NowExperience = v.EXP + (EXPGained/#self.Characters);
  2570. --      v.EXP = NowExperience;
  2571. --      local levelUp = false;
  2572. --      for i = v.Level, math.huge, 1 do
  2573. --          game:GetService('RunService').RenderStepped:Wait();
  2574. --          if (v.EXP >= EXPToLevelUp) then
  2575. --              --
  2576. --              level = true;
  2577. --              levelUp = true;
  2578. --              v.Level = v.Level+1;
  2579. --              EXPToLevelUp = v.Level^2*5;
  2580. --              local MXH = v.MaxHealth;
  2581. --              local L = (v.Level^1.35)
  2582. --              v.MaxHealth = math.ceil(100+L);
  2583. --              v.MaxSP = math.ceil(v.Level*2.5 + 77.5 + 4)
  2584. --          else
  2585. --              v.EXP = v.EXP
  2586. --              break;
  2587. --          end
  2588. --      end
  2589. --      local newLevel = v.Level;
  2590. --      if (levelUp) then
  2591. --          if (level and not al) then
  2592. --              al = true;
  2593. --              PlayerGui.YouWinAnimation.RankUpFrame:TweenPosition(UDim2.new(0.665,0,0.115,0), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 1, true)
  2594. --          end
  2595. --          local ecks = PlayerGui.YouWinAnimation.RankUpFrame.ScrollingFrame.itemObjectThing:Clone();
  2596. --          ecks.Parent = PlayerGui.YouWinAnimation.RankUpFrame.ScrollingFrame;
  2597. --          ecks.Name = 'LevelUp'
  2598. --          ecks.Visible = true;
  2599. --          ecks.TextLabel.Text = (v.LastName or '')..' '..(v.Name or 'Akira')..' '..' ('..v.Level..')';
  2600. --          game:GetService('UserInputService').InputBegan:Wait();
  2601. --      end
  2602. --  end
  2603. -- 
  2604. --  al = false;
  2605. --  local y = PlayerGui.YouWinAnimation.RankUpFrame.ScrollingFrame.UIListLayout:Clone();
  2606. --  wait();
  2607. --  PlayerGui.YouWinAnimation.RankUpFrame.ScrollingFrame.CanvasPosition = Vector2.new(0,0)
  2608. --  y.Parent = PlayerGui.YouWinAnimation.RankUpFrame.ScrollingFrame;
  2609. -- 
  2610. --  for i, v in pairs(PlayerGui.YouWinAnimation:GetChildren()) do
  2611. --      if (v.Name ~= 'Background') then
  2612. --          if (v.Name ~= 'RankUpFrame') then
  2613. --              v.Position = UDim2.new(v.Position.X.Scale-1, v.Position.X.Offset, v.Position.Y.Scale, v.Position.Y.Offset)
  2614. --          else
  2615. --              v.Position = UDim2.new(v.Position.X.Scale+1, v.Position.X.Offset, v.Position.Y.Scale, v.Position.Y.Offset)
  2616. --          end
  2617. --      end
  2618. --  end
  2619. --  workspace["Enemy Container"]:Destroy();
  2620. --  workspace["Party Container"]:Destroy();
  2621. --  for i, v in pairs(stuff) do
  2622. --      i.Position = v;
  2623. --  end
  2624. -- 
  2625. --  for i, v in pairs(PlayerGui.YouWinAnimation.RankUpFrame.ScrollingFrame:GetChildren()) do
  2626. --      if v:IsA('Frame') and v.Name ~= "itemObjectThing" then
  2627. --          v:Destroy();
  2628. --      end
  2629. --  end
  2630. -- 
  2631. --  for i, v in pairs(PlayerGui.YouWinAnimation.ItemFrame.ScrollingFrame:GetChildren()) do
  2632. --      if v:IsA('Frame') and v.Name ~= "itemObjectThing" then
  2633. --          v:Destroy();
  2634. --      end
  2635. --  end
  2636. -- 
  2637. --  for i, v in pairs(game.Lighting:GetChildren()) do
  2638. --      if v.ClassName:match('Effect') then
  2639. --          v.Enabled = false
  2640. --      end
  2641. --  end
  2642. -- 
  2643. --  PlayerGui.YouWinAnimation.Enabled = false;
  2644. -- 
  2645. -- 
  2646. --  --reset camerae by deleting it
  2647. --  workspace.CurrentCamera:Destroy();
  2648. --  wait(.1)
  2649. --  workspace.CurrentCamera.CameraType = Enum.CameraType.Custom;
  2650. --  workspace.CurrentCamera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid;
  2651. --  --
  2652. --  workspace.CurrentCamera.CameraType = Enum.CameraType.Custom;
  2653. --  self.Music:Stop();
  2654. --  _G.Occupied = false;
  2655. --  self.BattleFinished = true;
  2656. --  BattleInfo.BattleStage = nil;
  2657. --  _G.Stage = nil;
  2658. --  local Sky = game:GetService('ReplicatedStorage'):FindFirstChild('TempSky');
  2659. --  local OSky = game:GetService('Lighting'):FindFirstChildWhichIsA('Sky');
  2660. -- 
  2661. --  if (Sky) then
  2662. --      if (OSky) then
  2663. --          OSky:Destroy();
  2664. --      end
  2665. --      Sky.Name = 'Sky';
  2666. --      Sky.Parent = game:GetService('Lighting');
  2667. --  end
  2668. --  for i, v in pairs(game:GetService('Lighting'):GetChildren()) do
  2669. --      if (v.Name == 'Palace' and v:IsA('PostEffect')) then
  2670. --          v.Enabled = true
  2671. --      end
  2672. --  end
  2673. --  return true;
  2674. --end
  2675.  
  2676. function Battle:EndBattle()
  2677.     self.Music:Stop();
  2678.     self.Music = ReplicatedStorage.Music['Persona 5 - Victory (Victory)'];
  2679.     self.Music.Looped = true;
  2680.     self.Music:Play();
  2681.     local function Shorten(group)
  2682.         local Things = {};
  2683.         for i, v in pairs(group:GetChildren()) do
  2684.             if (tonumber(v.Name)) then
  2685.                 Things[tonumber(v.Name)] = {v, v.Size};
  2686.                 wait();
  2687.                 v.Size = UDim2.new(0,0,v.Size.Y.Scale,v.Size.Y.Offset)
  2688.             end
  2689.         end
  2690.         return Things;
  2691.     end
  2692.     local newWinAnimationObject = PlayerGui:WaitForChild('YouWinAnimation')
  2693.     newWinAnimationObject = newWinAnimationObject:Clone();
  2694.     newWinAnimationObject.Parent = PlayerGui;
  2695.     local GuiOne = newWinAnimationObject:WaitForChild'PhaseOne';
  2696.     local GuiTwo = newWinAnimationObject:WaitForChild'PhaseTwo';
  2697.     local SetOne = Shorten(GuiOne);
  2698.     local SetTwo = Shorten(GuiTwo);
  2699.     for i, v in pairs(GuiOne:GetChildren()) do
  2700.         pcall(function()
  2701.             if (not tonumber(v.Name)) then
  2702.                 v.Position = v.Position + UDim2.new(1)
  2703.             end
  2704.         end)
  2705.     end
  2706.     for i, v in pairs(GuiTwo:GetChildren()) do
  2707.         pcall(function()
  2708.             if (not tonumber(v.Name)) then
  2709.                 v.Position = v.Position + UDim2.new(-1)
  2710.             end
  2711.         end)
  2712.     end
  2713.     newWinAnimationObject.Enabled = true;
  2714.     local UserInputService = game:GetService('UserInputService');
  2715.     local e = 0;
  2716.     for i,v in pairs(self.Enemies) do
  2717.         e = e + v.Level;
  2718.     end
  2719.     e = math.ceil(e/#self.Enemies);
  2720.     local c = 1;
  2721.     for i, v in pairs(self.Characters) do
  2722.         c = c + v.Level;
  2723.     end
  2724.     c = math.ceil(e/#self.Characters)
  2725.     local EXPGained = math.ceil((e/c)*3.5*((e+c)*math.random(2, 3)));--*math.clamp(math.random(), 1, 1.3)));
  2726.     EXPGained = EXPGained*DifficultyModifiers[self.Difficulty].Experience
  2727.     local Money = math.ceil(((EXPGained/math.random(3, 5))*DifficultyModifiers[self.Difficulty].Money)*math.clamp(math.random(), 0.5, 1)) + (Battle.MoneyNet or 0)
  2728.  
  2729.     local function numWithCommas(amount)
  2730.         local formatted = amount
  2731.         while true do
  2732.             game:GetService('RunService').RenderStepped:Wait();
  2733.             formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
  2734.             if (k==0) then
  2735.                 break
  2736.             end
  2737.             k=nil;
  2738.         end
  2739.         return formatted
  2740.     end
  2741.     local function Odometize(stringObject, value, addend)
  2742.         local stringValue = tostring(stringObject.Text):gsub('%D', '');
  2743.         local oldValue = tonumber(stringValue) or 0;
  2744.         --stringObject = numWithCommas(tonumber(stringObject))
  2745.         local currentValue = oldValue;
  2746.         --      script.Parent.Money.Value = script.Parent.Money.Value + (math.sign(Difference) == 1 and math.ceil or math.floor)(math.sign(Difference) * (math.sign(Difference)*Difference/20))
  2747.         while game:GetService('RunService').RenderStepped:Wait() do
  2748.             local Difference = value - oldValue;
  2749.             oldValue = oldValue + (math.sign(Difference) == 1 and math.ceil or math.floor)(math.sign(Difference) * (math.sign(Difference)*Difference/10))--20
  2750.             if (math.floor(oldValue) == math.floor(value)) then
  2751.                 print'Broken!';
  2752.                 break;
  2753.             end
  2754.             stringObject.Text = (addend or '')..numWithCommas(oldValue);
  2755.         end
  2756.     end
  2757.     for i, v in pairs(SetOne) do
  2758.         v[1]:TweenSize(v[2], Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, 0.05);
  2759.         wait(0.025)
  2760.     end
  2761.     for i, v in pairs(GuiOne:GetChildren()) do
  2762.         pcall(function()
  2763.             if (not tonumber(v.Name)) then
  2764.                 v:TweenPosition(v.Position - UDim2.new(1), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 0.25)
  2765.                 wait(0.15)
  2766.             end
  2767.         end)
  2768.     end
  2769.     GuiOne:TweenPosition(GuiOne.Position+UDim2.new(0.025,0,0,0), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 5, false)
  2770.     spawn(function()--{0.23, 0},{0, 0}
  2771.         Odometize(newWinAnimationObject.PhaseOne.ExpCount, EXPGained)
  2772.     end)
  2773.     repeat until UserInputService.InputBegan:Wait().KeyCode == Enum.KeyCode.Return;
  2774.     GuiTwo:TweenPosition(UDim2.new(0,0,0,0), Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, 1, false)
  2775.     GuiOne:TweenPosition(UDim2.new(1,0,0,0), Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, 1, true)
  2776.     wait(0.9)
  2777.     for i, v in pairs(SetTwo) do
  2778.         v[1]:TweenSize(v[2], Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, 0.05);
  2779.         wait(0.025)
  2780.     end
  2781.     for i, v in pairs(GuiTwo:GetChildren()) do
  2782.         pcall(function()
  2783.             if (not tonumber(v.Name)) then
  2784.                 v:TweenPosition(v.Position + UDim2.new(1), Enum.EasingDirection.Out, Enum.EasingStyle.Back, 0.25)
  2785.                 wait(0.15);
  2786.             end
  2787.         end)--{0.018, 0},{0.003, 0}
  2788.     end
  2789.     GuiTwo:TweenPosition(GuiTwo.Position+UDim2.new(0.05,0,0,0), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 5, true)
  2790.     GuiOne:TweenPosition(GuiOne.Position+UDim2.new(0.05,0,0,0), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 5, true)
  2791.     spawn(function()
  2792.         Odometize(GuiTwo.MoneyCounter, Money, '¥')
  2793.     end)
  2794.     repeat until UserInputService.InputBegan:Wait().KeyCode == Enum.KeyCode.Return;
  2795.     workspace["Enemy Container"]:Destroy();
  2796.     workspace["Party Container"]:Destroy();
  2797.    
  2798.     newWinAnimationObject:Destroy();
  2799.    
  2800.     --reset camerae by deleting it
  2801.     workspace.CurrentCamera:Destroy();
  2802.     wait(.1)
  2803.     workspace.CurrentCamera.CameraType = Enum.CameraType.Custom;
  2804.     workspace.CurrentCamera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid;
  2805.     --
  2806.     workspace.CurrentCamera.CameraType = Enum.CameraType.Custom;
  2807.     self.Music:Stop();
  2808.     _G.Occupied = false;
  2809.     self.BattleFinished = true;
  2810.     BattleInfo.BattleStage = nil;
  2811.     _G.Stage = nil;
  2812.     self.OneMore = false;
  2813.     local Sky = game:GetService('ReplicatedStorage'):FindFirstChild('TempSky');
  2814.     local OSky = game:GetService('Lighting'):FindFirstChildWhichIsA('Sky');
  2815.    
  2816.     if (Sky) then
  2817.         if (OSky) then
  2818.             OSky:Destroy();
  2819.         end
  2820.         Sky.Name = 'Sky';
  2821.         Sky.Parent = game:GetService('Lighting');
  2822.     end
  2823.     for i, v in pairs(game:GetService('Lighting'):GetChildren()) do
  2824.         if (v.Name == 'Scene' and v:IsA('PostEffect')) then
  2825.             v.Enabled = true
  2826.         end
  2827.         if (v.Name == 'BattleEffect') then
  2828.             v:Destroy();
  2829.         end
  2830.     end
  2831.     --PlayerGui.Reticle.Enabled = false;
  2832.     PlayerGui.Reticle.Adornee = nil
  2833.     return true;
  2834. end
  2835.  
  2836.  
  2837. function showLabel(text, duration)
  2838.     text = text or '???'
  2839.     duration = duration or 1
  2840.     local Label = PlayerGui.Statuses.Frame:Clone();
  2841.     Label.Name = "CopiedStatusEffect"
  2842.     Label.Parent = PlayerGui.Statuses;
  2843.     Label.Frame.TextLabel.Text = text
  2844.     for i = 1, 0, -0.1 do
  2845.         Label.BackgroundTransparency = i;
  2846.         game:GetService('RunService').RenderStepped:Wait();
  2847.     end
  2848.     wait(duration)
  2849.     for i = 0, 1, 0.1 do
  2850.         Label.BackgroundTransparency = i;
  2851.         game:GetService('RunService').RenderStepped:Wait();
  2852.     end
  2853. end
  2854. function Battle:showLabel(text, duration)
  2855.     showLabel(text, duration)
  2856. end
  2857. function Battle.new(party, enemies, ambush, difficulty, ba, music, boss)
  2858.     _G.Occupied = true;
  2859.     CurrentCameraShake = CameraShaker.new(Enum.RenderPriority.Camera.Value+1, function(shakeOffset)
  2860.         workspace.CurrentCamera.CFrame = workspace.CurrentCamera.CFrame * shakeOffset;
  2861.     end)
  2862.     wait();
  2863.     coroutine.wrap(function()
  2864.         CurrentCameraShake:Start();
  2865.         CurrentCameraShake:ShakeSustain(CameraShaker.Presets.HandheldCamera);
  2866.     end)();
  2867.     _G.StartLoad(true)
  2868.     CMS:Disable()
  2869.     game.Players.LocalPlayer.Character.PrimaryPart.Anchored = true;
  2870.     EnemyAPI:Initialize() --start the enemy api
  2871.     for i, v in pairs(Battle) do
  2872.         print(i, v)
  2873.     end
  2874.    
  2875.     local battleArea = ba:Clone()
  2876.     battleArea.Name = "Arena";
  2877.     battleArea:SetPrimaryPartCFrame(CFrame.new(0,2500,0))
  2878.     for i, v in pairs(game:GetService('Lighting'):GetChildren()) do
  2879.         if (v.Name ~= 'e' and v:IsA('PostEffect')) then
  2880.             v.Enabled = false
  2881.         end
  2882.     end
  2883.     if (battleArea:FindFirstChild('Lighting')) then
  2884.        
  2885.         --preserve old lighting properties
  2886.        
  2887.         local PreLighting = Instance.new('Folder', game:GetService'ReplicatedStorage');
  2888.         PreLighting.Name = "Previous Lighting";
  2889.         for i, v in pairs(battleArea.Lighting:GetChildren()) do
  2890.             if (v:IsA('PostEffect') and v.Name ~= 'e') then
  2891.                 v.Enabled = false;
  2892.             end
  2893.             local NewValue = Instance.new(v.ClassName, PreLighting);
  2894.             local success, info = pcall(function() --put it in a protected call so any invalid properties won't break the script
  2895.                 NewValue.Name = v.Name;
  2896.                 NewValue.Value = game:GetService('Lighting')[v.Name];
  2897.             end)
  2898.             if (not success) then --remove the lingering variable and continue
  2899.                 NewValue:Destroy();
  2900.             else
  2901.                 warn('Setting Lighting value of', v.Name, 'to', v.Value);
  2902.                 game:GetService('Lighting')[v.Name] = v.Value;
  2903.             end
  2904.         end
  2905.        
  2906.        
  2907.         --begin tweening properties
  2908.        
  2909.        
  2910.     end
  2911.     battleArea.Parent = workspace;
  2912.  
  2913.    
  2914.     local self = Battle;
  2915.     self.OneMore = false;
  2916.     BattleInfo = { --Independant turns for every character.
  2917.         EnemyTurns = {}; --one for the enemies
  2918.         PlayerTurns = {}; --one for the player. this allows for rakukaja to turn on/off not when it's Akira's turn
  2919.         EnemyActions = {};
  2920.        
  2921.         MemberActions = {};
  2922.         MemberAnimations = {};
  2923.         SelectedPersonaAttack = nil;
  2924.        
  2925.         BattleStage = 'Main'; --using general identifiers for battlestage
  2926.         SelectedMember = 0; --Default to 0 so we can know this is the start of the battle.
  2927.     }
  2928.    
  2929.     self.BattleFinished = false;
  2930.     self.PositionBeforeBattle = Character:GetPrimaryPartCFrame();
  2931.     --set camera type to scriptable so we can manipulate the camera with ease
  2932.     workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable;
  2933.    
  2934.     --defining self properties for easier access
  2935.     self.Difficulty = difficulty;
  2936.     self.Characters = party;
  2937.     for i, v in pairs(self.Characters) do
  2938.         v.Debuffs = {};
  2939.         v.Guard = false;
  2940.     end
  2941.     Metatable(self.Characters) --give party memberds a metatable
  2942.     self.Ambush = ambush;
  2943.     self.Enemies = {};
  2944.     self.EnemiesString = enemies;
  2945.  
  2946.     local Keyword = ambush and 'Ambush Spawns' or 'Spawns'
  2947.     local Spawns = battleArea:WaitForChild(Keyword)
  2948.     for i, v in pairs(enemies) do
  2949.         if (not boss and i > #Spawns['Enemy Spawns']:GetChildren()) then
  2950.             break; --so overloading doesnt happen
  2951.         end
  2952.         self.Enemies[i] = getPersonaFromString(v) --convert all personas to actual tables so we can use them in battle
  2953.        
  2954.        
  2955.         self.Enemies[i].MaxHealth = v.Health; --set maxhealth property before they even spawn for ezpz work
  2956.        
  2957.         wait()
  2958.     end
  2959.    
  2960.     Metatable(self.Enemies) --give enemy members a metatable;
  2961.     for i, v in pairs(self.Characters) do
  2962.         v.Enemies = {};
  2963.     end
  2964.     self.BattleArea = battleArea;
  2965.     if (self.Ambush) then
  2966.         self:AmbushPosition();
  2967.     end
  2968.     if (self.BattleArea:FindFirstChild('Ambush Spawns')) then
  2969.         for i, v in next, self.BattleArea:FindFirstChild('Ambush Spawns'):GetDescendants() do
  2970.             if (v:IsA('BasePart')) then
  2971.                 v.Transparency = 1;
  2972.             end
  2973.         end
  2974.     end
  2975.     if (self.BattleArea:FindFirstChild('Spawns')) then
  2976.         for i, v in next, self.BattleArea:FindFirstChild('Spawns'):GetDescendants() do
  2977.             if (v:IsA('BasePart')) then
  2978.                 v.Transparency = 1;
  2979.             end
  2980.         end
  2981.     end
  2982.     if (self.BattleArea:FindFirstChildWhichIsA('Sky')) then
  2983.         local Sky = game:GetService('Lighting'):FindFirstChildWhichIsA("Sky");
  2984.         if (Sky) then
  2985.             Sky.Parent = game:GetService('ReplicatedStorage');
  2986.             Sky.Name = 'TempSky';
  2987.         end
  2988.         self.BattleArea:FindFirstChildWhichIsA('Sky'):Clone().Parent = game:GetService('Lighting');
  2989.     end
  2990.     self.BattleFolder = Spawns;
  2991.     self.PartySpawns = Spawns['Party Spawns']
  2992.     self.EnemySpawns = Spawns['Enemy Spawns']
  2993.     self.PartyContainer = workspace:FindFirstChild('Party Container') and workspace['Party Container']:ClearAllChildren() and workspace['Party Container'] or Instance.new('Folder')
  2994.     self.PartyContainer.Name = 'Party Container'
  2995.     self.PartyContainer.Parent = workspace;
  2996.    
  2997.     --Begin moving the entire party to the battle area
  2998.    
  2999.     for index, x in pairs(party) do
  3000.  
  3001.         for i, v in pairs(ReplicatedStorage["Party Members"]:GetChildren()) do
  3002.             if (v.Name:lower():match(x.Name:lower())) and (x.InParty or index == 1) then --Allow case-insensitivity just to make sure I can cover my mistakes.
  3003.                 local PartyMemberClone = v:Clone()
  3004.                 PartyMemberClone:WaitForChild('Humanoid').HipHeight = recalculateHipHeight(PartyMemberClone);
  3005.                 local SpawnCFrame = Spawns:WaitForChild('Party Spawns'):WaitForChild('Spawn'..index).CFrame + Vector3.new(0, math.abs(PartyMemberClone:WaitForChild("Humanoid").HipHeight), 0)
  3006.                 PartyMemberClone.Parent = self.PartyContainer;
  3007.                 PartyMemberClone.Humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
  3008.                 PartyMemberClone.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
  3009.                 PartyMemberClone.Humanoid.WalkSpeed = Character.Humanoid.WalkSpeed;
  3010.                 PartyMemberClone.PrimaryPart.Anchored = false;
  3011.                 if (v:FindFirstChild('Animations')) then
  3012. --                  for i, x in pairs(v.Animations:getChildren()) do
  3013. --                      LoadAnimation(x, PartyMemberClone:WaitForChild('Humanoid')):Play();
  3014. --                  end
  3015.  
  3016.                     if v.Animations:FindFirstChild("Idle") then
  3017.                         LoadAnimation(v.Animations.Idle, PartyMemberClone:WaitForChild("Humanoid")):Play();
  3018.                     end
  3019.                 end
  3020.                 PartyMemberClone:SetPrimaryPartCFrame(SpawnCFrame)
  3021.             end
  3022.         end
  3023.     end
  3024.    
  3025.  
  3026.     game.Players.LocalPlayer.Character.PrimaryPart.Velocity = Vector3.new();
  3027.     game.Players.LocalPlayer.Character:SetPrimaryPartCFrame(Spawns:WaitForChild('Party Spawns')['Spawn1'].CFrame + Vector3.new(0,game.Players.LocalPlayer.Character.Humanoid.HipHeight+.5,0)) --teleport the character to the first spawn
  3028.    
  3029.    
  3030.     if _G.Music then _G.Music:Pause() end;
  3031.     if (not music) then
  3032.         if (Keyword == 'Ambush Spawns') then
  3033.             self.Music = ReplicatedStorage.Music['Persona 5 - Willpower (Awakening)']          
  3034.         else
  3035.             self.Music = ReplicatedStorage.Music["Persona 5 - Last Surprise (Ambush)"]
  3036.         end
  3037.     else
  3038.         self.Music = music;
  3039.     end;
  3040.    
  3041.     --local sign = math.sign(self.Music.Volume - 0); local cond1 =  (sign == 1 and 0 or self.Music.Volume); local cond2 =  (sign == 1 and self.Music.Volume or 0); local cond3 =  (sign == 1 and 0.1 or -0.1)
  3042.     local ms13 = 0.5;
  3043.     self.Music.Looped = true;
  3044.     self.Music.Volume = 0;
  3045.     self.Music:Play();
  3046.    
  3047.     coroutine.wrap(function()
  3048.         for i = 0, ms13, ms13/10 do
  3049.             wait();
  3050.             --game:GetService('RunService').RenderStepped:Wait();
  3051.             print(i);
  3052.             self.Music.Volume = i;
  3053.         end
  3054.     end)();
  3055.     for i, v in pairs(game:GetService'Lighting':GetChildren()) do
  3056.         if v.Name:lower():match('dungeon') or v.Name:match('ambush') then
  3057.             if (self.Ambush and v.Name:lower():match('ambush')) then
  3058.                 v.Enabled = true;
  3059.             elseif (not self.Ambush) and (not v.Name:lower():match('ambush') and v.Name:lower():match('dungeon')) then
  3060.                 v.Enabled = true;
  3061.             else
  3062.                 v.Enabled = false;
  3063.             end
  3064.         end
  3065.     end
  3066.    
  3067.    
  3068.     Signal = PlayerGui:WaitForChild("Persona Attacks List"):GetPropertyChangedSignal('Enabled'):Connect(function()
  3069.         RefreshPersonaList();
  3070.     end)
  3071.    
  3072.     spawn(function()
  3073.         Battle:Failsafe()
  3074.     end)
  3075.     spawn(function(a)
  3076.         wait(2)
  3077.         game.Players.LocalPlayer.Character.PrimaryPart.Anchored = true;
  3078.     end)
  3079.     local EnemySpawns = Spawns:WaitForChild('Enemy Spawns')
  3080.     local EnemyContainer = workspace:FindFirstChild('Enemy Container') and workspace['Enemy Container']:ClearAllChildren() and workspace['Enemy Container'] or Instance.new('Folder')
  3081.     EnemyContainer.Name = 'Enemy Container'
  3082.     EnemyContainer.Parent = workspace;
  3083.     self.EnemyContainer = EnemyContainer;
  3084.     self.Boss = boss;
  3085.     local ChosenMember = Battle:selectViableMember(true);
  3086.     if (tonumber(ChosenMember)) then
  3087.         Battle:CharacterPosition(ChosenMember, nil, true);
  3088.     end
  3089.     for index, x in pairs(enemies) do
  3090.         if (not boss and index > #EnemySpawns:GetChildren()) then
  3091.             break; --prevent any infinite yields / errors
  3092.         end
  3093.         for i, v in pairs(ReplicatedStorage["Personas"]:GetChildren()) do
  3094.             if (v.Name:lower():match(x:lower())) then --enemies will be string values. their models will be taken from Persona List
  3095.                 v = v:Clone();
  3096.                 for i, v in pairs(v:GetDescendants()) do
  3097.                     if v:IsA("BasePart")  then
  3098.                         local Trans = Instance.new('NumberValue', v);
  3099.                         Trans.Value = v.Value;
  3100.                         Trans.Name = 'OriginalTransparency';
  3101.                        
  3102.                         v.Transparency = 1;
  3103.                     end
  3104.                 end
  3105.                 local n = self.Enemies[index] and self.Enemies[index].CustomSize or {};
  3106.                 local H = v:WaitForChild('Humanoid')
  3107.                 H.BodyDepthScale.Value = n.Depth or 1.25;
  3108.                 H.BodyHeightScale.Value = n.Height or 1.35;
  3109.                 H.BodyProportionScale.Value = n.Proportions or 1.2;
  3110.                 H.BodyTypeScale.Value = n.Type or 1.75;
  3111.                 H.BodyWidthScale.Value = n.Width or 1.2;
  3112.                 H.HeadScale.Value = n.Head or 1.3;
  3113.                 wait()
  3114.                 H.HipHeight = recalculateHipHeight(H.Parent);
  3115.                 spawn(function(a)
  3116.                     wait(1.5)
  3117.                     v.PrimaryPart.Anchored = true;
  3118.                 end)
  3119.                 local Indicator = Instance.new('StringValue', v)
  3120.                 Indicator.Name = 'PersonaName'
  3121.                 Indicator.Value = v.Name;
  3122.                 v.Name = index
  3123.                 v.Parent = EnemyContainer;
  3124.                 --v:WaitForChild('Humanoid').HipHeight = 2.462;
  3125.                 local Selector = not boss and Spawns:WaitForChild('Enemy Spawns'):WaitForChild('Spawn'..index) or battleArea:WaitForChild('BossSpawn')
  3126.                 v:SetPrimaryPartCFrame(Selector.CFrame + Vector3.new(0,v.Humanoid.HipHeight + Selector.Size.Y/2, 0))
  3127.                 spawn(function()
  3128.                     local Sp = ReplicatedStorage.EffectStorage.Spawn:Clone();
  3129.                     Sp.Parent = workspace;
  3130.                     Sp:SetPrimaryPartCFrame(v:GetPrimaryPartCFrame() + Vector3.new(0,0,2.5));
  3131.                     for i, v in pairs(Sp:GetDescendants()) do
  3132.                        
  3133.                         if (v:IsA('ParticleEmitter')) then
  3134.                             v:Emit(150)
  3135.                                    
  3136.                         end
  3137.                     end
  3138.                     ReplicatedStorage.EffectStorage.Sounds.EnemySpawn:Play();
  3139.                     wait(.4);
  3140.                     for i, v in pairs(v:GetDescendants()) do
  3141.                         if v:IsA("BasePart") and v.Name:lower() ~= 'humanoidrootpart' then
  3142.                             if v:findFirstChild('OriginalTransparency') then
  3143.                                 Tween(v, TweenInfo.new(.1), {Transparency = v.OriginalTransparency.Value}):Play();
  3144.                             end
  3145.                         end
  3146.                     end
  3147.                 end)
  3148.                 game:GetService('RunService').RenderStepped:Wait() --prevent any bad things
  3149.                 wait(1/#enemies)
  3150.             end
  3151.         end
  3152.     end
  3153.     _G.EndLoad()
  3154.     return Battle:NewTurn() --call the battle's new turn function
  3155. end
  3156. ospawn = spawn;
  3157. spawn = function(f, ...)
  3158.     local a = {...};
  3159.     return ospawn(function()
  3160.         f(unpack(a))
  3161.     end)
  3162. end
  3163. function Effect(e, t, attack, targetIsEnemy, isEnemy, why, self, ia)
  3164.     --target, attack used, is target enemy?, (if t is enemy) target character's id, Battle (self), IgnoreAnimation
  3165.     --if (targetIsEnemy) then
  3166.         print(e, t)
  3167.         for i, v in pairs(attack) do
  3168.             print(i, v)
  3169.         end
  3170.         if (attack.Effect) then
  3171.             --badeffect
  3172.            
  3173.             if (isEnemy) then
  3174.                 --local Char = self:GetCharacterFromID(BattleInfo.SelectedEnemyGuy);
  3175.                 if (why) then
  3176.                    
  3177.                     local Char = self:GetCharacterFromID(why);
  3178.                     if (typeof(attack.Effect) == 'function') then
  3179.                         --Accepts a table with the following args: {PrimaryPart, IgnoreAnimation, TargetPart};
  3180.                         Effects[attack.Effect]({PrimaryPart = Char.PrimaryPart,
  3181.                             IgnoreAnimation = ia,
  3182.                             TargetPart = Battle:GetEnemyFromName(e.ID).PrimaryPart,
  3183.                             TargetFolder = self.PartyContainer,
  3184.                             EnemySpawn = self.PartySpawns}, Battle)
  3185.                     elseif Effects[attack.Effect] then
  3186.                         Effects[attack.Effect]({PrimaryPart = Char.PrimaryPart,
  3187.                             IgnoreAnimation = ia,
  3188.                             TargetPart = Battle:GetEnemyFromName(e.ID).PrimaryPart,
  3189.                             EnemySpawn = self.PartySpawns,
  3190.                             TargetFolder = self.PartyContainer
  3191.                         }, Battle)
  3192.                     end
  3193.                 end
  3194.             else
  3195.                 local Char = self.EnemyContainer:FindFirstChild(t.ID)
  3196.                 local Me = Battle:GetCharacterFromID(e.Name)
  3197.                 if (Char and Me) then
  3198.                    
  3199.                     if (typeof(attack.Effect) == 'function') then
  3200.                         Attacks[attack.Effect]({PrimaryPart = Char.PrimaryPart,
  3201.                             IgnoreAnimation = ia,
  3202.                             TargetPart = Me.PrimaryPart,
  3203.                             EnemySpawn = self.EnemySpawns
  3204.                             }, Battle)
  3205.                     elseif Effects[attack.Effect] then
  3206.                         Effects[attack.Effect]({PrimaryPart = Char.PrimaryPart,  --enemy's part
  3207.                             IgnoreAnimation = ia, --ignore animation?
  3208.                             TargetPart = Me.PrimaryPart, --my primary part
  3209.                             TargetFolder = self.EnemyContainer, --enemy's folder? WHAT
  3210.                             EnemySpawn = self.EnemySpawns
  3211.                         }, Battle)
  3212.                     end
  3213.                 else
  3214.                     warn('Me: ', Me);
  3215.                 end
  3216.             end
  3217.         elseif (Effects[attack.Type..'Effect']) then
  3218.            
  3219.             if (isEnemy) then
  3220.                 if (why) then
  3221.                    
  3222.                     local Char = self:GetCharacterFromID(why);
  3223.                     Effects[attack.Type..'Effect'](
  3224.                         {PrimaryPart = Char.PrimaryPart,
  3225.                         IgnoreAnimation = ia, TargetPart =
  3226.                         Battle:GetEnemyFromName(e.ID).PrimaryPart,
  3227.                         TargetFolder = self.PartyContainer,
  3228.                         EnemySpawn = self.PartySpawns
  3229.                         }, Battle)
  3230.                 end
  3231.             else
  3232.                 local Char = self.EnemyContainer:WaitForChild(t.ID)
  3233.                 local Me = Battle:GetCharacterFromID(e.Name)
  3234.                 if (Char and Me) then
  3235.                     Effects[attack.Type..'Effect']({
  3236.                         PrimaryPart = Char.PrimaryPart,
  3237.                         IgnoreAnimation = ia,
  3238.                         TargetPart = Me.PrimaryPart,
  3239.                         TargetFolder = self.PartyContainer,
  3240.                         EnemySpawn = self.EnemySpawns
  3241.                     }, Battle)
  3242.                 else
  3243.                     warn('Char:', Char, 'Me:', Me)
  3244.                 end
  3245.             end
  3246.         end
  3247.     --end
  3248. end
  3249. local BigAttackHappening = false;
  3250.  
  3251. function Battle:Damage(attacker, target, attack, silent)
  3252.     local DownExclusionBecauseScrewThisStupidCodebase = nil;
  3253.     local Yield = attack.Yield
  3254.     local isEnemy = (not attacker.Persona and true) or false;
  3255.     local targetIsEnemy = (not target.Persona) or false
  3256.     local isHeal = attack.Type:lower() == "buff" or attack.Type:lower() == "kaja"
  3257.     local isMultiHit = attack.Damages or attack.Heals;
  3258.     local PositionOfCharacterAttacked;
  3259.     for i, v in pairs(self.Characters) do
  3260.         if (v.Name == (isEnemy and target.Name or attacker.Name)) then
  3261.             PositionOfCharacterAttacked = i;
  3262.         end
  3263.     end
  3264.    
  3265.     if (not silent) then
  3266.         coroutine.wrap(function()
  3267.             showLabel(attack.Name, 1.5)
  3268.         end)();
  3269.     end
  3270.     target.Debuffs = target.Debuffs or {};
  3271.     attacker.Debuffs = attacker.Debuffs or {};
  3272.     local AttackerDebuffTable = attacker and attacker.Debuffs;
  3273.     local TargetDebuffTable = target and target.Debuffs;
  3274.     if (attack.SPRequired) then
  3275.         attacker:SubtractSP(attack.SPRequired)
  3276.     elseif (attack.HPRequired) then
  3277.         attacker:SubtractHealth(modifyDamage(attack.HPRequired, attacker.MaxHealth))
  3278.     end
  3279.     local toggleOneMore;
  3280.     local HealingTarget = isEnemy and self.Enemies or self.Characters;
  3281.     if (isHeal) then
  3282.         if (attack.CustomMessage) then
  3283.             coroutine.wrap(showLabel)(attack.CustomMessage, 2.5);
  3284.         end
  3285.         if (isMultiHit) then
  3286.             for i, target in pairs(HealingTarget) do
  3287.                 if (isEnemy) then
  3288.                     Battle:MoveCameraToEnemy(i, {yield = true})
  3289.                 else
  3290.                     Battle:MoveCameraToCharacter(i, {yield = true})
  3291.                 end
  3292. --              for i, v in pairs(attack.Debuffs or {}) do
  3293. --                  local x = {};
  3294. --                  for i, v in pairs(v) do
  3295. --                      x[i] = v;
  3296. --                  end
  3297. --                  BattleInfo.PlayerTurns[PositionOfCharacterAttacked] = BattleInfo.PlayerTurns[PositionOfCharacterAttacked] or 1;
  3298. --                  x.TurnAdded = isEnemy and BattleInfo.PlayerTurns[PositionOfCharacterAttacked] or BattleInfo.EnemyTurns[target.ID];
  3299. --                  target:AddDebuff(x)
  3300. --              end
  3301.                 if (attack.Type2 == 'Revive' or target.Health > 0) then target:Heal(attack.Heal) end
  3302.             end
  3303.         else
  3304.             if (attack.CustomMessage) then
  3305.                 coroutine.wrap(showLabel)(attack.CustomMessage, 2.5);
  3306.             end
  3307. --          for i, v in pairs(attack.Debuffs or {}) do
  3308. --              local x = {};
  3309. --              for i, v in pairs(v) do
  3310. --                  x[i] = v;
  3311. --              end
  3312. --              BattleInfo.PlayerTurns[PositionOfCharacterAttacked] = BattleInfo.PlayerTurns[PositionOfCharacterAttacked] or 1;
  3313. --              x.TurnAdded = isEnemy and BattleInfo.PlayerTurns[PositionOfCharacterAttacked] or BattleInfo.EnemyTurns[target.ID];
  3314. --              target:AddDebuff(x)
  3315. --          end
  3316.             if (isEnemy) then
  3317.                 Battle:MoveCameraToEnemy(target.ID, {yield = true})
  3318.                 if (attack.Type2 == 'Revive' or target.Health > 0) then target:Heal(attack.Heal) end
  3319.             else
  3320.                 Battle:MoveCameraToCharacter(PositionOfCharacterAttacked, {yield = true})
  3321.                 if (attack.Type2 == 'Revive' or target.Health > 0) then self.Characters[BattleInfo.SelectedEnemyGuy]:Heal(attack.Heal) end
  3322.             end
  3323.         end
  3324.         return 0; --finish the turn and healing.
  3325.     end
  3326.     if (attack.SelfHeal) then
  3327.         attacker:Heal(attack.SelfHeal);
  3328.     end
  3329.     if (attack.SPRecovered or attack.AddSP) then
  3330.         attacker:AddSP(attack.SPRecovered or attack.AddSP)
  3331.     end
  3332.    
  3333.     --Temporary Stats and Flags for Attacking
  3334.    
  3335.     local Evasion = 0;
  3336.     local Technical = false;
  3337.     local Hunger = false;
  3338.     local Def = 1;
  3339.     local Atk = 1;
  3340.    
  3341.     local a;
  3342.     --local d = (e.Equipped and not isEnemy) and (t.Equipped.Accessory.Defense or 0) or t.Defense or 85;
  3343.    
  3344.    
  3345.     local d = 0;
  3346.    
  3347.     if (target.Equipped and target.Equipped.Defense) then
  3348.         local EquippedDefense = Items[target.Equipped.Defense];
  3349.         d = EquippedDefense.Defense or 0;
  3350.     end
  3351.    
  3352.     d = d+ ((isEnemy and target.Persona.Stats.Endurance or target.EnemyStats.Endurance or 0)*1.25)
  3353.     d = d * Def
  3354.    
  3355.    
  3356.    
  3357.     local l = attacker.Level; --note: later down the line, we will be relying on persona stats and not level-based damage.
  3358.    
  3359.     if (not attack.Type:lower() == "physical") then
  3360.        
  3361.         if (isEnemy) then
  3362.             a = (attacker.EnemyStats or attacker.Stats).Magic+(attack.Damage)
  3363.         else
  3364.             a = attacker.Persona.Stats.Magic*1.25+attack.Damage*1.45
  3365.             a = a+(attack.Damage or 0)
  3366.         end
  3367.        
  3368.     else --if it IS physical
  3369.         --note: don't use a strict system, rely on strings so modifying data post-release will be easier (FINISHED)
  3370.         local AttackerEquipped = attacker.Equipped and Items[attacker.Equipped.Melee]
  3371.         if isEnemy == false and (AttackerEquipped and AttackerEquipped.Damage) then
  3372.             a =  attacker.Persona.Stats.Strength*1.25+(AttackerEquipped.Damage)
  3373.         elseif (isEnemy) then
  3374.             a = (attacker.EnemyStats or attacker.Stats).Strength*1.25+(attacker.EnemyStats or attacker.Stats).Strength*1.45
  3375.         else
  3376.             a = attacker.Persona.Stats.Strength*1.25 + attack.Damage*1.25
  3377.         end
  3378.     end
  3379.  
  3380.  
  3381.     local Weak = target.Weak or (target.Persona and target.Persona.Weak or nil) or {}
  3382.     local Strong = target.Strong or (target.Persona and target.Persona.Strong or nil) or {}
  3383.     local WeakVar = Weak[attack.Type];
  3384.     local StrongVar = Strong[attack.Type];
  3385.    
  3386.     --
  3387.     if (target and target.Equipped and Items[target.Equipped.Defense]) then
  3388.         local ec = Items[target.Equipped.Defense]
  3389.         if ec.Evasion then
  3390.             Evasion = Evasion - ec.Evasion; --subtract the evasion from the thing --45
  3391.         end
  3392.     end
  3393.    
  3394.     if (attacker and attacker.Equipped and Items[attacker.Equipped.Defense]) then
  3395.         local ec = Items[attacker.Equipped.Defense] --incase brainwash is in effect
  3396.         if (ec.Evasion) then
  3397.             Evasion = Evasion + ec.Evasion
  3398.         end
  3399.     end
  3400.    
  3401.     if (attacker and attacker.Debuffs and attacker.Debuffs.EvasionUp) then
  3402.         Evasion = Evasion + 30;
  3403.     elseif (attacker and attacker.Debuffs and attacker.Debuffs.EvasionDown) then
  3404.         Evasion = Evasion - 30; --70
  3405.     end --get the attacker's evasion
  3406.    
  3407.    
  3408.     --add or subtract evasion points for attacker/defender benefit
  3409.     Evasion = Evasion - ((not target.Persona and target.EnemyStats) or target.Persona.Stats or {}).Agility or 0;
  3410.     Evasion = Evasion + ((not attacker.Persona and attacker.EnemyStats) or attacker.Persona.Stats or {}).Agility or 0;
  3411.     Evasion = math.abs(Evasion);
  3412.    
  3413.     local Divisor = 300; --divide the Evasion value by Divisor.
  3414.    
  3415.     local GroupToAttack, Type = (targetIsEnemy and self.Enemies) or self.Characters, (targetIsEnemy and "Enemies") or "Characters"
  3416.    
  3417.     --Stat Modification
  3418.     if (attacker and attacker.Debuffs and attacker.Debuffs.Hunger) then
  3419.         Hunger = true;
  3420.         --
  3421.     end
  3422.     if (target and target.Debuffs and target.Debuffs.DefenseDown) then
  3423.         Def = 0.7
  3424.         --
  3425.     end
  3426.     if (target and target.Debuffs and target.Debuffs.DefenseUp) then
  3427.         Def = 1.5
  3428.         --
  3429.     end
  3430.     if (attacker and attacker.Debuffs and attacker.Debuffs.AttackUp) then
  3431.         Atk = 1.2
  3432.         --
  3433.     end
  3434.     if (attacker and attacker.Debuffs and attacker.Debuffs.AttackDown) then
  3435.         Atk = 0.7
  3436.         --
  3437.     end
  3438.    
  3439.    
  3440.  
  3441. --              if (attack.Type2 == 'Revive' or value.Health > 0) then
  3442. --                  value:Heal(attack.Heal)
  3443. --              end
  3444. --              if (attack.Debuffs) then
  3445. --                  for i, v in pairs(attack.Debuff) do
  3446. --                      value:AddDebuff(v)
  3447. --                  end
  3448. --              end
  3449.  
  3450.  
  3451.     if (typeof(attack.Damage) == 'string') then
  3452.         target:SubtractHealth(target.Health / 2);
  3453.         return true;
  3454.     end
  3455.  
  3456.     local constant = .6969
  3457.    
  3458.     local dif = DifficultyModifiers[self.Difficulty];
  3459.     local DamageMod = 1;
  3460.     if (isEnemy) then
  3461.         DamageMod = dif.DamageRecieved
  3462.     else
  3463.         DamageMod = dif.DamageDealt
  3464.     end
  3465.    
  3466.     local Guard = target.Guard and 0.45 or 1;
  3467.     if Difficulty == 'Satanic' then
  3468.         Guard = Guard==0.45 and 0.1 or Guard;
  3469.     end
  3470.    
  3471.     local BTNCount = not isEnemy and (1 + (self.BatonCount and self.BatonCount/1.75 or 0)) or 1;
  3472.    
  3473.     print('BATON PASS!', BTNCount)
  3474.    
  3475.  
  3476.     a = a*Atk
  3477.     local AlreadyAttacked;
  3478.     local AlreadyCritNotif;
  3479.     local AlreadyAnimated;
  3480.     local CameraMoved;
  3481.     local CritStorage = {}; --Store criticals beforehand so we only show the animation once at the start of the animation;
  3482.     local CritCounter = 0;
  3483.     if (not isEnemy) then
  3484.         for i, v in pairs(self.Enemies) do
  3485.             if (attack.Damages) or v.ID == target.ID then
  3486.                 local Luck = isEnemy and attacker.EnemyStats.Luck or attacker.Persona.Stats.Luck
  3487.                 local Formula = math.clamp((Luck/100+(Luck and Luck/100 or 0)+(Luck/1000)+(attack.CritChance and attack.CritChance/1000 or 0/1000))/1.5, 0, 1000)/(math.pi);
  3488.                 local crit = (tonumber(v.ID) == 2) or ((not v.Uncritable) and math.random() < Formula)
  3489.                 if (v.Weak and v.Weak[attack.Type] or crit) and (not (v.Null and v.Null[attack.Type])) then
  3490.                     CritCounter = CritCounter+1;
  3491.                     CritStorage[tonumber(v.ID or i)] = {v.ID, i};
  3492.                     --impwarn('CritStorage Length:', #CritStorage)
  3493.                 end
  3494.             end
  3495.         end
  3496.     end
  3497.     if (not AlreadyAnimated) and (not isEnemy) and (CritCounter > 0) and (not self.OneMore) then
  3498.         AlreadyAnimated=true;
  3499.         local Audio = ReplicatedStorage:WaitForChild('SFX'):WaitForChild('Weak');
  3500.         Audio = Audio:Clone();
  3501.         Audio.Parent = PlayerGui;
  3502.         Audio.PlayOnRemove = true;
  3503.         Audio:Destroy();
  3504.         self:CharacterPosition(nil, true, true)
  3505.         local Animations = ReplicatedStorage:WaitForChild('AnimationAssets'):WaitForChild('CritAnim'):GetChildren()
  3506.         local Animation = LoadAnimation(Animations[math.random(1, #Animations)], Battle:GetCharacterFromID(BattleInfo.SelectedMember):FindFirstChild('Humanoid', true))
  3507.         Animation:AdjustWeight(1, 2)
  3508.         Animation:Play();
  3509.         wait(2);
  3510.         if (self.Ambush) then
  3511.             self:AmbushPosition()
  3512.         end
  3513.     end
  3514.     local attackFunction = function(target, attack, Iterator)
  3515.             local randomValue = math.random();
  3516.             if (not game:GetService'RunService':IsStudio()) and Evasion ~= 0 and (randomValue < math.abs(Evasion/Divisor)*0.9) and attack.Type ~= 'Buff' and attack.Type ~= 'Kaja' and attack.Type2 ~= 'Debuff' then
  3517.                 impwarn('Missed! Raw Evasion Chance:', Evasion, 'Modified Evasion Change:', Evasion/Divisor, "Random value:", randomValue);
  3518.                 ReplicatedStorage.Music:WaitForChild('Miss'):Play();
  3519.             else
  3520.                 local crit;
  3521.                 if (isEnemy) then
  3522.                     local Luck = isEnemy and attacker.EnemyStats.Luck or attacker.Persona.Stats.Luck
  3523.                     local Formula = math.clamp((Luck/100+(Luck and Luck/100 or 0)+(Luck/1000)+(attack.CritChance and attack.CritChance/1000 or 0/1000))/1.5, 0, 1000)/(math.pi);
  3524.                     warn('Formula:', Formula)
  3525.                     crit = ((not target.Uncritable) and math.random() < Formula)
  3526.                 else
  3527.                     crit = CritStorage[tonumber(target.ID)] ~= nil
  3528.                     impwarn('Critical Status:', crit)
  3529.                 end
  3530.                 if (TargetDebuffTable) then
  3531.                     for i, v in pairs(TargetDebuffTable) do
  3532.                         local affinity = tostring(attack.Type):lower()
  3533.                         if (Technicals[affinity] and Technicals[affinity][v.Name:lower()]) or (v.Name:lower() == 'dizzy' or v.Name:lower() == 'sleep') then
  3534.                             Technical = true;
  3535.                             if (v.Name ~= 'sleep' and v.Name ~= 'dizzy') then
  3536.                                 TargetDebuffTable[i] = nil;
  3537.                             end
  3538.                         end
  3539.                     end
  3540.                 end
  3541.                 if (not CameraMoved) and (not silent) and (not isHeal) and (not self.Ambush) then
  3542.                     CameraMoved=true;
  3543.                     if (isEnemy) then
  3544.                         if (isMultiHit and not isHeal) then
  3545.                             Battle:PartyAttacked()
  3546.                         else
  3547.                             Battle:CharacterAttacked(PositionOfCharacterAttacked)
  3548.                         end
  3549.                     elseif (not isEnemy) then
  3550.                         local Char = self.EnemyContainer:WaitForChild(target.ID)
  3551.                         Battle:CharacterAttacking(BattleInfo.SelectedMember, Char.PrimaryPart, CritCounter>0, attack.Damages or attack.Heals)
  3552.                         wait(0.25)
  3553.                     end
  3554.                 end
  3555.                 if (target.Health > 0) then
  3556.                     if (attack.Yield and not AlreadyAttacked) or (((not attack.Damages) and (not attack.Heals))) then
  3557.                         AlreadyAttacked = true;
  3558.                         Effect(attacker, target, attack, targetIsEnemy, isEnemy, PositionOfCharacterAttacked, Battle);
  3559.                     elseif (not attack.Yield) then
  3560.                         coroutine.wrap(Effect)(attacker, target, attack, targetIsEnemy, isEnemy, PositionOfCharacterAttacked, Battle);
  3561.                     end
  3562.                 end
  3563.                 print('damage guy called', target)
  3564.                 if (crit or WeakVar) and not (target.Null and target.Null[attack.Type]) then
  3565.                     local HeavyHit = ReplicatedStorage.Music:WaitForChild('HeavyHit')
  3566.                     HeavyHit = HeavyHit:Clone()
  3567.                     HeavyHit.Parent = game.Players.LocalPlayer.PlayerGui;
  3568.                     HeavyHit.PlayOnRemove = true;
  3569.                     HeavyHit:Destroy();
  3570.                     if (not AlreadyCritNotif) and (not target.Guard) then
  3571.                         if ((WeakVar or crit) and not isEnemy) then --so morgana doesn't shout HAHA LOOKING COOL JOKER when i get murdered'
  3572.                             if (target.Debuffs) then
  3573.                                 if (not target.Debuffs.Down) and (not self.OneMore) and (not target.Guard) then --check for self.onemore so i don't play the stupid sound over and over and over and over and over again'
  3574.                                     AlreadyCritNotif = true;
  3575.                                     local HeavyHit = ReplicatedStorage.Music:WaitForChild('Looking Cool Joker!') --what have i done
  3576.                                     HeavyHit = HeavyHit:Clone()
  3577.                                     HeavyHit.Parent = game.Players.LocalPlayer.PlayerGui;
  3578.                                     HeavyHit.PlayOnRemove = true;
  3579.                                     HeavyHit:Destroy();
  3580.                                    
  3581.                                     local Name = attacker.Name:lower();
  3582.                                     local RandomDownAwareness = {};
  3583.                                    
  3584.                                     if (Name == "ryuji") then
  3585.                                         RandomDownAwareness = {
  3586.                                        
  3587.                                             "Wow, Skull. You really showed me..",
  3588.                                             "Nice one, Skull!",
  3589.                                             "Wow, Skull! You're actually good at something for once!",
  3590.                                             "Great, Skull! Pass the baton and follow up!",
  3591.                                             "Awesome, Skull! You wiped a few enemies off their feet!"
  3592.                                        
  3593.                                         };
  3594.                                     elseif (Name == "Yuki") then
  3595.                                         RandomDownAwareness = {
  3596.                                            
  3597.                                             "Wow, Blizzard! You got them!",
  3598.                                             "Huh, for a shut-in chick, you have some skills! Good job, Blizzard!",
  3599.                                             "Great job, Blizzard! You knocked a few enemies off their feet!",
  3600.                                             "Nice exhibition of those \"magical powers\", Blizzard!",
  3601.                                             "Exemplary job, Blizzard! Pass the baton and follow up!"
  3602.                                            
  3603.                                         }
  3604.                                    
  3605.                                     elseif (Name == "akira") then
  3606.                                         RandomDownAwareness = {
  3607.                                            
  3608.                                             "Woah, Joker! You did it!",
  3609.                                             "Woaaah, looking cool Joker!",
  3610.                                             "For a quite uncharming messy-haired troublemaker, you're good at fighting! Good job, Joker!",
  3611.                                             "Nice job, Joker! You knocked a few enemies off their feet!",
  3612.                                             "Your powers are incredible, Joker!",
  3613.                                         }
  3614.                                     elseif (Name == "ann") then
  3615.                                         RandomDownAwareness = {
  3616.                                            
  3617.                                             "Panther knocked them down with style and grace!",
  3618.                                             "Great job, Panther! Keep it up!",
  3619.                                             "From one female to another, you're beautiful, Panther!",
  3620.                                             "Nice one, Panther! Pass the baton and follow up!",
  3621.                                             "A beautiful rose has thorns!",
  3622.                                             "Nice one, Panther!"
  3623.                                            
  3624.                                         }
  3625.                                     end
  3626.                                    
  3627.                                     local availableSpeakers = {}; --get a random list of the characters
  3628.                                     for i, v in pairs(self.Characters) do
  3629.                                         if (v.Name:lower() ~= Name) and i ~= 1 then --so 1. the downer can't congratulate themselves (downer lol)
  3630.                                             availableSpeakers[#availableSpeakers+1] = v.Name;
  3631.                                         else
  3632.                                             print(v.Name:lower(), Name, self.Characters[1].Name:lower(), #availableSpeakers);
  3633.                                         end
  3634.                                     end
  3635.                                     local Member = availableSpeakers[math.random(1, #availableSpeakers)];
  3636.                                     Member = Member:sub(1,1):upper()..Member:sub(2); --capitalize first letter of names
  3637.                                     Member = ReplicatedStorage:WaitForChild('Party Members'):WaitForChild(Member);
  3638.                                     local Chosen = RandomDownAwareness[math.random(1, #RandomDownAwareness)];
  3639.                                     warn'hrmm'
  3640.                                     toggleOneMore = "W"
  3641.                                     _G.BattleAnnouncement(Chosen, Member, true);
  3642.                                 end
  3643.                             end
  3644.                         elseif ((WeakVar or crit) and isEnemy) then --so morgana doesn't shout HAHA LOOKING COOL JOKER when i get murdered'
  3645.                             if (target.Debuffs) then
  3646.                                 if (not target.Debuffs.Down) and (not self.knockedChar) and (not target.Guard) then --check for self.onemore so i don't play the stupid sound over and over and over and over and over again'
  3647.                                     self.knockedChar = true;
  3648.                                    
  3649.                                     local Name = target.Name:lower();
  3650.                                    
  3651.                                     local RandomDownAwareness = {};
  3652.                                    
  3653.                                     if (Name == "ryuji") then
  3654.                                         RandomDownAwareness = {
  3655.                                             "Skull, you're biting off more than what you can chew! Stay calm!",
  3656.                                             "Everyone, Skull is down! Be careful!",
  3657.                                             "One of the strongest in our team is knocked out! Watch out, everyone!",
  3658.                                             "If they can take down Skull, they can take down Joker! Protect them both at all costs!",
  3659.                                             "Come on, Skull! Get up!"
  3660.                                         }
  3661.                                     elseif (Name == "yuki") then
  3662.                                         RandomDownAwareness = {
  3663.                                             "Everyone, the most u- I mean, a party member is down! Take care of them!",
  3664.                                             "King's been knocked off their feet! Protect her at all costs!",
  3665.                                             "Guys, Ice-Girl has been knocked off her last leg! Watch out, everyone!",
  3666.                                             "They took down Ice-Girl! Everyone, be careful!",
  3667.                                             "King, get up! We need you!"
  3668.                                         }
  3669.                                     elseif (Name == "akira") then
  3670.                                         RandomDownAwareness = {
  3671.                                             "Joker? Hey, stop playing games! Get up!",
  3672.                                             "Joker! This isn't the time to be playing around!",
  3673.                                             "Everyone, Joker's been knocked off his feet! Take some time to tend to his wounds!",
  3674.                                             "Uh, guys! Joker's not doing too well!",
  3675.                                             "Joker, hurry and rise like a phoenix!",
  3676.                                         }
  3677.                                     elseif (Name == "ann") then
  3678.                                         RandomDownAwareness = {
  3679.                     --                      "Alright, Panther! Strike them down with style and grace!",
  3680.                     --                      "Alright, Panther! Time to start the counter-attack!"
  3681.                                             "Everyone, Panther has been downed! Watch her carefully!",
  3682.                                             "Discount K- I mean, Panther has been knocked off of her feet! Stay cautious, everyone!",
  3683.                                             "Guys, keep your guard up! Panther is down!",
  3684.                                             "Everyone, protect Panther until she gets up!",
  3685.                                             "Panther, now is definitely not the time! Get back up!",
  3686.                                         }
  3687.                                     end
  3688.                                     local Chosen = RandomDownAwareness[math.random(1, #RandomDownAwareness)] or "undefined";
  3689.                                     _G.BattleAnnouncement(Chosen, nil, true);
  3690.                                 end
  3691.                             end
  3692.                         end
  3693.                     end
  3694.                     --impwarn('Pass One:', target.Guard, target.Debuffs.Down, target.Health)
  3695.                 elseif CritCounter < 1 then
  3696.                     local HeavyHit = ReplicatedStorage.Music:WaitForChild('NormalHit')
  3697.                     HeavyHit = HeavyHit:Clone()
  3698.                     HeavyHit.Parent = game.Players.LocalPlayer.PlayerGui;
  3699.                     HeavyHit.PlayOnRemove = true;
  3700.                     HeavyHit:Destroy();
  3701.                     toggleOneMore=false;
  3702.                     self.OneMore = false;
  3703.                 end
  3704.                 local damage = math.floor(attack.Damage*constant^(d/a))
  3705.                 --impwarn(damage, WeakVar, StrongVar, crit, d, a)
  3706.                 damage = math.ceil(damage * (WeakVar and 1.35 or 1) * (StrongVar and 0.45 or 1) * (crit and 1.25 or 1))--l*math.floor(attack.Damage*constant^(d/a) * (WeakVar and 1.15 or 1) * (StrongVar and 0.55 or 1) * (crit and 1.15 or 1))
  3707.                 local Formula = ((damage * DamageMod)*Atk)*(Hunger and 0.4 or 1)*(Technical and 1.25 or 1)*Guard*BTNCount;
  3708.                
  3709.                 if (isEnemy) and (target.Persona.Drain and target.Persona.Drain[attack.Type]) then
  3710.                     local SFX = ReplicatedStorage.SFX.Drain:Clone();
  3711.                     SFX.Parent = PlayerGui;
  3712.                     SFX.PlayOnRemove = true;
  3713.                     SFX:Destroy();
  3714.                     target:Heal(Formula, true)
  3715.                 elseif (target.Drain and target.Drain[attack.Type]) then
  3716.                     local SFX = ReplicatedStorage.SFX.Drain:Clone();
  3717.                     SFX.Parent = PlayerGui;
  3718.                     SFX.PlayOnRemove = true;
  3719.                     SFX:Destroy();
  3720.                     target:Heal(Formula, true)
  3721.                 elseif (isEnemy) and (target.Null and target.Null[attack.Type]) then
  3722.                     target:SubtractHealth(0)
  3723.                     return 'NULL'
  3724.                 elseif (target.Null and target.Null[attack.Type]) then
  3725.                     target:SubtractHealth(0)
  3726.                     return 'NULL'
  3727.                 else
  3728.                     target:SubtractHealth(Formula);--(object, shakeFactor, magnitude, dampeningFactor)
  3729.                     if (target.Health <= 0) then
  3730.                         target.Debuffs = {};
  3731.                         local Humanoid = isEnemy and Battle:GetCharacterFromID(PositionOfCharacterAttacked).Humanoid or Battle:GetEnemyFromName(target.ID).Humanoid;
  3732.                         local Anim = LoadAnimation(ReplicatedStorage.AnimationAssets.Death.Fall, Humanoid)
  3733.                         local Anim2 = LoadAnimation(ReplicatedStorage.AnimationAssets.Death.Stay, Humanoid);
  3734.                         spawn(function(a)
  3735.                             Anim:Play();
  3736.                             Anim.Stopped:Wait()
  3737.                             Anim2:Play()
  3738.                         end)
  3739.                     else
  3740.                         target.Debuffs = target.Debuffs or {};
  3741.                         for i, v in pairs(attack.Debuffs or {}) do
  3742.                             if (((not Strong) or ((not Weak[attack.Type]) and (not crit) and Strong and (not Strong[attack.Type]) and (not Strong[attack.Type:lower()])) and (not target.Guard) and  (not target.Debuffs[v.Name])) and target.Health > 0) or game:GetService('RunService'):IsStudio() then --do thing
  3743.                                 if (v.Chance/100 >= math.random()) then
  3744.                                    
  3745.                                     local zyrf = v.Name == "Down" and impprint'downed... added'
  3746.                                     local x = {};
  3747.                                     for i, v in pairs(v) do
  3748.                                         x[i] = v;
  3749.                                     end
  3750.                                     if (target.ID) then
  3751.                                         BattleInfo.EnemyTurns[target.ID] = BattleInfo.EnemyTurns[target.ID] or 1
  3752.                                     end
  3753.                                     BattleInfo.PlayerTurns[PositionOfCharacterAttacked] = BattleInfo.PlayerTurns[PositionOfCharacterAttacked] or 1;
  3754.                                     x.TurnAdded = isEnemy and BattleInfo.PlayerTurns[PositionOfCharacterAttacked] or BattleInfo.EnemyTurns[target.ID];
  3755.                                     target:AddDebuff(x)
  3756.                                     coroutine.wrap(showLabel)(('%s has been inflicted with %s'):format(target.Name or '???', x.Name and x.Name..'!' or 'Unknown Debuff..?'), 2);
  3757.                                 end
  3758.                             end
  3759.                         end
  3760.                         if not (DownExclusionBecauseScrewThisStupidCodebase == target) then
  3761.                             impwarn("WTJASFJNASF??")
  3762.                             if ((not target.Guard) and (not target.Debuffs.Down)) or (math.floor(target.Health) <= 0) then
  3763.                                 impwarn("WHAT????")
  3764.                                 if (( (not isEnemy) and ( not (target.Null and target.Null[attack.Type] ))) or ( (isEnemy) and not (target.Persona.Null and target.Persona.Null[attack.Type]))) then
  3765.                                     impwarn("WHY???")
  3766.                                     toggleOneMore = 'W';
  3767.                                     local Humanoid = isEnemy and Battle:GetCharacterFromID(PositionOfCharacterAttacked).Humanoid or Battle:GetEnemyFromName(target.ID).Humanoid;
  3768.                                     local Anim = LoadAnimation(ReplicatedStorage.AnimationAssets.Death.Fall, Humanoid)
  3769.                                     local Anim2 = LoadAnimation(ReplicatedStorage.AnimationAssets.Death.Stay, Humanoid);
  3770.                                     DownExclusionBecauseScrewThisStupidCodebase = target;
  3771.                                     spawn(function(a)
  3772.                                         Anim:Play();
  3773.                                         impwarn("Down.");
  3774.                                         Anim.Stopped:Wait()
  3775.                                         Anim2:Play()
  3776.                                     end)
  3777.                                     local x = math.floor(target.Health) > 0 and target:AddDebuff({Name = "Down", TurnAdded = (not isEnemy and BattleInfo.EnemyTurns[target.ID] or BattleInfo.PlayerTurns[PositionOfCharacterAttacked] or 1), Length = math.random(1, 2)+(target.TurnCount and target.TurnCount/2 or 0), Chance = 100});
  3778.                                 elseif CritCounter  < 1 then
  3779.                                     toggleOneMore = false;
  3780.                                     self.OneMore=false;
  3781.                                 end
  3782.                             elseif (target.Guard) then
  3783.                                 imppwarn("wat du hek", target.Name)
  3784.                             end
  3785.                         else
  3786.                             impprint(DownExclusionBecauseScrewThisStupidCodebase, target, DownExclusionBecauseScrewThisStupidCodebase == target)
  3787.                         end
  3788.                     end
  3789.                     if (PositionOfCharacterAttacked) then
  3790.                         local newShake = Shake.new():setShake(PlayerGui:WaitForChild('Statuses').PartyIndicator:WaitForChild(tostring(PositionOfCharacterAttacked)), 0.5, 0):initShake(1);
  3791.                     end
  3792.                 end
  3793.                
  3794.  
  3795.                
  3796.                 --print('Dealt', Formula,'damage.', target.Name.."'s health is now", tostring(target.Health)..'.')
  3797.                 --print("Damage:", damage, "\nDamageMod:", DamageMod, "\nDamage*DamageMod:", damage*DamageMod, "\nAtk:", Atk, "\nDamage*DamageMod*Atk:", damage*DamageMod*Atk, "\nHunger:", Hunger, "\nGuard:", Guard, "\nBTNCount:", BTNCount, "\na:", a, "\nd:", d, "\nattack.Damage:", attack.Damage)
  3798.                 Battle:TweenHealth(0.25)
  3799.             end
  3800.         end
  3801.     if (isMultiHit) then
  3802.         if (attack.AttackCount) then
  3803.             --impwarn('Has several hits.')
  3804.             local tab = typeof(attack.AttackCount) == "number" and {0, attack.AttackCount} or {attack.AttackCount[1], math.random(attack.AttackCount[1]+1, attack.AttackCount[2])};
  3805.             for i = tab[1], tab[2] do
  3806.                 for i, v in pairs(GroupToAttack) do
  3807.                     if (v.Health > 0) then
  3808.                         if (attack.Yield and not AlreadyAttacked) then
  3809.                             (attackFunction)(v, attack, nil)
  3810.                         end
  3811.                         coroutine.wrap(attackFunction)(v, attack, nil)
  3812.                         wait(0.25)
  3813.                     end
  3814.                 end
  3815.                 wait(0.175)
  3816.             end
  3817.         else
  3818.             for i, v in pairs(GroupToAttack) do
  3819.                 if (v.Health > 0) then
  3820.                     if (attack.Yield and not AlreadyAttacked) then
  3821.                         (attackFunction)(v, attack, nil)
  3822.                     end
  3823.                     coroutine.wrap(attackFunction)(v, attack, nil)
  3824.                     wait(0.25)
  3825.                 end
  3826.             end
  3827.         end
  3828.     else
  3829.         if (attack.AttackCount) then
  3830.             --impwarn('Has several hits. (singular attack)')
  3831.             local tab = typeof(attack.AttackCount) == "number" and {0, attack.AttackCount[2]} or {attack.AttackCount[1], math.random(attack.AttackCount[1]+1, attack.AttackCount[2])};
  3832.             for i = tab[1], tab[2] do
  3833.                 (attackFunction)(target, attack, PositionOfCharacterAttacked or target.ID)
  3834.                 wait(0.175)
  3835.             end
  3836.         else
  3837.             (attackFunction)(target, attack, PositionOfCharacterAttacked or target.ID)
  3838.         end
  3839.     end
  3840.     self.OneMore = toggleOneMore;
  3841.     wait(1.25);
  3842. end
  3843.  
  3844.  
  3845.  
  3846.  
  3847.  
  3848. --battle input functionfd
  3849.  
  3850.  
  3851.  
  3852. function Battle:Failsafe()
  3853.     Player.Chatted:Connect(function(c)
  3854.         c = c:match('giveattack:%s?(.*)');
  3855.        
  3856.         local C = _G.Characters[1].Persona.Attacks;
  3857.         for i, v in pairs(C) do
  3858.             if (v:lower() == c:lower()) then
  3859.                 return false;
  3860.             end
  3861.         end
  3862.        
  3863.         for i, v in pairs(Attacks) do
  3864.             if (i:lower() == c:lower()) then
  3865.                 C[#C+1] = i;
  3866.                 print("Given attack:", i);
  3867.                 return true;
  3868.             end
  3869.         end
  3870.         return false;
  3871.     end)
  3872.     print('Failsafe Started!')
  3873.     local DebugAndUi
  3874.     DebugAndUi = game:GetService('RunService').RenderStepped:Connect(function(DebugAndUI)
  3875.         --partyspawns, enemyspawns, partycontainer, enemycontainer
  3876.         --impwarn(self.Characters[1].Guard, self.Characters[2].Guard, self.Characters[3].Guard, self.Characters[4].Guard);
  3877.         pcall(function()
  3878.             PlayerGui:WaitForChild('Persona Attacks List').List.Description.Text = getAttack(game:GetService('GuiService').SelectedObject.Parent.AttackTitle.Text).Description
  3879.         end)
  3880.         --Used to make debug functions and for UI progression.
  3881.         if (self.BattleFinished) then
  3882.             if (Signal) then
  3883.                 print'disconnected signal'
  3884.                 Signal:Disconnect();
  3885.                 Signal = nil;
  3886.             end
  3887.             DebugAndUi:Disconnect();
  3888.             DebugAndUi = nil;
  3889.             PlayerGui:WaitForChild('Persona Attacks List').Enabled = false;
  3890.             PlayerGui:WaitForChild('PersonaListR').Enabled = false;
  3891.             PlayerGui:WaitForChild('Change Persona').Enabled = false;
  3892.             BattleInfo.BattleStage = nil;
  3893.             _G.Stage = nil;
  3894.             CMS:Enable();
  3895.             script:Destroy();
  3896.             warn('Finished failsafe.')
  3897.             return nil;
  3898.         else
  3899.             _G.Occupied = true;
  3900.             _G.Stage = BattleInfo.BattleStage
  3901.         end
  3902.         _G.Occupied = true;
  3903.         if (tonumber(BattleInfo.SelectedMember) and not self.BattleFinished) then
  3904.         --  print(BattleInfo.BattleStage);
  3905.        
  3906.         PlayerGui:WaitForChild('Persona Attacks List').Enabled = BattleInfo.BattleStage == 'PersonaAttackList'
  3907.         PlayerGui:WaitForChild('PersonaListR').Enabled = BattleInfo.BattleStage == 'Main'
  3908.         PlayerGui.PersonaListR['BATON PASS'].Visible = self.OneMore
  3909.         PlayerGui:WaitForChild('Change Persona').Enabled = BattleInfo.BattleStage == 'PersonaChange' or BattleInfo.BattleStage == 'Analysis'
  3910.         pcall(function()
  3911.         PlayerGui.PersonaListR.StudsOffset = Vector3.new(
  3912.             self:
  3913.             GetCharacterFromID(BattleInfo.SelectedMember)
  3914.             .PrimaryPart.Size.X + 0.75,
  3915.             self:
  3916.             GetCharacterFromID(BattleInfo.SelectedMember)
  3917.             .PrimaryPart.Size.X/1.75,
  3918.             0
  3919.             )
  3920.            
  3921.         end)
  3922.                
  3923.         local MovementStatus = (not self.BattleFinished) and CMS:Disable() or CMS:Enable()
  3924.         end
  3925.  
  3926.        
  3927.        
  3928.     end)
  3929.    
  3930.     if (self.Ambush) then
  3931.         while wait(2.5) do
  3932.             if (self.BattleFinished) then
  3933.                 game:GetService('Lighting').ambusheffectpulse.Enabled = false;
  3934.                
  3935.                 break;
  3936.             end
  3937.             --pulse if ambush
  3938.             Tween(game:GetService('Lighting').ambusheffectpulse, TweenInfo.new(0.35, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, true, 0.5), {TintColor = Color3.fromRGB(255,114,114)}):Play()
  3939.             local CMFOV = workspace.CurrentCamera.FieldOfView;
  3940.             wait(0.65)
  3941.             Tween(workspace.CurrentCamera, TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = CMFOV-15}):Play();
  3942.             wait()
  3943.             Tween(workspace.CurrentCamera, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = CMFOV}):Play();
  3944.             wait(0.5);
  3945.         end
  3946.     end
  3947. end
  3948.  
  3949.  
  3950.  
  3951. --debug
  3952.  
  3953. local function getCharFromPartName(s)
  3954.     for i, v in pairs(Battle.Characters) do
  3955.         if (v.Name:lower():match(s:lower())) then
  3956.             return v;
  3957.         end
  3958.     end
  3959. end
  3960. local function getSonaFromPartName(s)
  3961.     for i, v in pairs(game:GetService'ReplicatedStorage':WaitForChild('Personas'):GetChildren()) do
  3962.         if (v.Name:lower():match(s:lower())) then
  3963.             return v;
  3964.         end
  3965.     end
  3966. end
  3967.  
  3968. return Battle;
Advertisement
Add Comment
Please, Sign In to add comment