<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="26">
  <CheatEntries>
    <CheatEntry>
      <ID>1</ID>
      <Description>"Activate Trainer"</Description>
      <Options moHideChildren="1"/>
	  <VariableType>Auto Assembler Script</VariableType>
	  <AssemblerScript>[ENABLE]
{$lua}
tCheckBattleHPPtr = createTimer(nil, false)
tCheckBattleHPPtr.OnTimer = function(fCheckBattleHPPtr)

	local AllyBattlePtr = getAddressSafe("AllyBattlePtr")
	local iNumAllyBattlePtr = getAddressSafe("iNumAllyBattlePtr")
	local AllyBattlePtr2 = getAddressSafe("AllyBattlePtr2")
	local iNumAllyBattlePtr2 = getAddressSafe("iNumAllyBattlePtr2")
	
	local EnemyBattlePtr = getAddressSafe("EnemyBattlePtr")
	local iNumEnemyBattlePtr = getAddressSafe("iNumEnemyBattlePtr")
	local EnemyBattlePtr2 = getAddressSafe("EnemyBattlePtr2")
	local iNumEnemyBattlePtr2 = getAddressSafe("iNumEnemyBattlePtr2")
	
	local bEnemiesAreDead = getAddressSafe("bEnemiesAreDead")
	
	if (iNumAllyBattlePtr ~= nil) then
		if (iNumAllyBattlePtr ~= 0) then
			if (iNumEnemyBattlePtr ~= nil) then
				if (iNumEnemyBattlePtr ~= 0) then
					local iNumAllyBattlePtr1 = ReadInteger(iNumAllyBattlePtr)
					local iNumEnemyBattlePtr1 = ReadInteger(iNumEnemyBattlePtr)
					local iNumAllyBattlePtr21 = ReadInteger(iNumAllyBattlePtr2)
					local iNumEnemyBattlePtr21 = ReadInteger(iNumEnemyBattlePtr2)
					
					-- Recaculate Ally List Count
					if (iNumAllyBattlePtr1 &gt; 0) then
						local index5 = 0
						local new_count = 0
						
						while (index5 &lt; 16) do
							local CurrentAllyHPPtr = ReadPointer(AllyBattlePtr + (index5*8))
							
							if (CurrentAllyHPPtr ~= nil) then
								if(CurrentAllyHPPtr ~= 0) then
									new_count = new_count + 1
								end
							end
							
							index5 = index5 + 1
						end
						
						WriteInteger(iNumAllyBattlePtr,new_count)
					end

					-- Recaculate Ally List Count 2
					if (iNumAllyBattlePtr21 &gt; 0) then
						local index7 = 0
						local new_count7 = 0
						
						while (index7 &lt; 128) do
							local CurrentAllyHPPtr = ReadPointer(AllyBattlePtr2 + (index7*8))
							
							if (CurrentAllyHPPtr ~= nil) then
								if(CurrentAllyHPPtr ~= 0) then
									new_count7 = new_count7 + 1
								end
							end
							
							index7 = index7 + 1
						end
						
						WriteInteger(iNumAllyBattlePtr2,new_count7)
					end

					-- Recaculate Enemy List Count
					if (iNumEnemyBattlePtr1 &gt; 0) then
						local index6 = 0
						local new_count2 = 0
						
						while (index6 &lt; 256) do
							local CurrentEnemyHPPtr = ReadPointer(EnemyBattlePtr + (index6*8))
							
							if (CurrentEnemyHPPtr ~= nil) then
								if(CurrentEnemyHPPtr ~= 0) then
									new_count2 = new_count2 + 1
								end
							end
							
							index6 = index6 + 1
						end
						
						WriteInteger(iNumEnemyBattlePtr,new_count2)
					end

					-- Recaculate Enemy List Count 2
					if (iNumEnemyBattlePtr21 &gt; 0) then
						local index8 = 0
						local new_count8 = 0
						
						while (index8 &lt; 512) do
							local CurrentEnemyHPPtr = ReadPointer(EnemyBattlePtr2 + (index8*8))
							
							if (CurrentEnemyHPPtr ~= nil) then
								if(CurrentEnemyHPPtr ~= 0) then
									new_count8 = new_count8 + 1
								end
							end
							
							index8 = index8 + 1
						end
						
						WriteInteger(iNumEnemyBattlePtr2,new_count8)
					end
					
					local bEnemiesAlive = 0
					if (iNumEnemyBattlePtr1 &gt; 0) then
						local index = 0
						
						while (index &lt; 256) do
							local CurrentEnemyPtr = ReadPointer(EnemyBattlePtr + (index*8))
							
							if (CurrentEnemyPtr ~= nil) then
								if (CurrentEnemyPtr ~= 0) then
									local CurrentEnemyPtr1 = ReadPointer(CurrentEnemyPtr + 0x20)
									local ValidEnemyCheck = 0
									
									if (CurrentEnemyPtr1 ~= nil) then
										if (CurrentEnemyPtr1 ~= 0) then
											ValidEnemyCheck = ReadInteger(CurrentEnemyPtr1 + 0x128)
										end
									end
									
									if not ((ValidEnemyCheck == 0) or (ReadFloat(CurrentEnemyPtr + 0x2AC) == 0)) then
										bEnemiesAlive = 1
										break
									else
										-- Enemy Is Invalid, Remove Them From List
										WritePointer(EnemyBattlePtr + (index*8),0)
										WriteInteger(iNumEnemyBattlePtr,iNumEnemyBattlePtr1 - 1)

										--WritePointer(EnemyBattlePtr2 + (index*8),0)
										--WriteInteger(iNumEnemyBattlePtr2,iNumEnemyBattlePtr21 - 1)
									end
								end
							end
							
							index = index + 1							
						end

						-- Check If Any Enemies Still Alive
						if (bEnemiesAlive == 0) then
							WriteInteger(bEnemiesAreDead,1)
							
							-- Reset Just Enemies
							local index2 = 0
							
							WriteInteger(iNumEnemyBattlePtr,0)
							
							while (index2 &lt; 256) do
								WritePointer(EnemyBattlePtr + (index2*8),0)					
								index2 = index2 + 1
							end						

							-- Reset Just Enemies 2
							index2 = 0
							
							WriteInteger(iNumEnemyBattlePtr2,0)
							
							while (index2 &lt; 512) do
								WritePointer(EnemyBattlePtr2 + (index2*8),0)
								index2 = index2 + 1
							end						
						else
							WriteInteger(bEnemiesAreDead,0)
						end						
					else
						if (iNumAllyBattlePtr1 &gt; 0) then
							bEnemiesAlive = 0
							WriteInteger(bEnemiesAreDead,1)
						else
							bEnemiesAlive = 1
							WriteInteger(bEnemiesAreDead,0)
						end
					end	
				end
			end
		end
	end
  
end
tCheckBattleHPPtr.Interval = 200
tCheckBattleHPPtr.Enabled = true

-- Enemies Are Dead Timer (Check If Enemies Are Dead for 20 Seconds)
tCheckEnemiesAreDead = createTimer(nil, false)
tCheckEnemiesAreDead.OnTimer = function(fCheckEnemiesAreDead)

	local AllyBattlePtr = getAddressSafe("AllyBattlePtr")
	local iNumAllyBattlePtr = getAddressSafe("iNumAllyBattlePtr")
	local AllyBattlePtr2 = getAddressSafe("AllyBattlePtr2")
	local iNumAllyBattlePtr2 = getAddressSafe("iNumAllyBattlePtr2")
	
	local EnemyBattlePtr = getAddressSafe("EnemyBattlePtr")
	local iNumEnemyBattlePtr = getAddressSafe("iNumEnemyBattlePtr")
	local EnemyBattlePtr2 = getAddressSafe("EnemyBattlePtr2")
	local iNumEnemyBattlePtr2 = getAddressSafe("iNumEnemyBattlePtr2")
	
	local bEnemiesAreDead = getAddressSafe("bEnemiesAreDead")
	local iTimeSinceEnemiesDied = getAddressSafe("iTimeSinceEnemiesDied")

	if (bEnemiesAreDead ~= nil) then
		if (bEnemiesAreDead ~= 0) then
			local iNumAllyBattlePtr1 = ReadInteger(iNumAllyBattlePtr)
			local iNumAllyBattlePtr21 = ReadInteger(iNumAllyBattlePtr2)
			
			if (iNumAllyBattlePtr1 &gt; 0) then
				local bEnemiesAreDead1 = ReadInteger(bEnemiesAreDead)
				local iTimeSinceEnemiesDied1 = ReadInteger(iTimeSinceEnemiesDied)
								
				if (bEnemiesAreDead1 == 1) then
					WriteInteger(iTimeSinceEnemiesDied,iTimeSinceEnemiesDied1+1)
										
					if ((iTimeSinceEnemiesDied1 &gt; 120)) then
						local index2 = 0
						
						WriteInteger(iNumAllyBattlePtr,0)
						WriteInteger(iNumAllyBattlePtr2,0)
						
						while (index2 &lt; 16) do
							WritePointer(AllyBattlePtr + (index2*8),0)
							WritePointer(AllyBattlePtr2 + (index2*8),0)
							index2 = index2 + 1
						end
						
						index2 = 0

						while (index2 &lt; 128) do
							WritePointer(AllyBattlePtr2 + (index2*8),0)
							index2 = index2 + 1
						end
												
						WriteInteger(bEnemiesAreDead,0)
						WriteInteger(iTimeSinceEnemiesDied,0)
					end					
				else
					WriteInteger(iTimeSinceEnemiesDied,0)
				end	
			end
		end
	end
  
end
tCheckEnemiesAreDead.Interval = 250
tCheckEnemiesAreDead.Enabled = true

tValidateEnemyList = createTimer(nil, false)
tValidateEnemyList.OnTimer = function(fValidateEnemyList)

	local AllyBattlePtr = getAddressSafe("AllyBattlePtr")
	local iNumAllyBattlePtr = getAddressSafe("iNumAllyBattlePtr")
	local AllyBattlePtr2 = getAddressSafe("AllyBattlePtr2")
	local iNumAllyBattlePtr2 = getAddressSafe("iNumAllyBattlePtr2")
	
	local EnemyBattlePtr = getAddressSafe("EnemyBattlePtr")
	local iNumEnemyBattlePtr = getAddressSafe("iNumEnemyBattlePtr")
	local EnemyBattlePtr2 = getAddressSafe("EnemyBattlePtr2")
	local iNumEnemyBattlePtr2 = getAddressSafe("iNumEnemyBattlePtr2")
		
	if (iNumEnemyBattlePtr ~= nil) then
		if (iNumEnemyBattlePtr ~= 0) then
			local iNumEnemyBattlePtr1 = ReadInteger(iNumEnemyBattlePtr)
			local iNumAllyBattlePtr1 = ReadInteger(iNumAllyBattlePtr)
			local iNumEnemyBattlePtr21 = ReadInteger(iNumEnemyBattlePtr2)
			local iNumAllyBattlePtr21 = ReadInteger(iNumAllyBattlePtr2)
			
			local index = 0
			
			while (index &lt; 256) do
				local CurrentBattleHPPtr = ReadPointer(EnemyBattlePtr + (index*8))
				local CurrentBattleHPPtr2 = ReadPointer(EnemyBattlePtr2 + (index*8))
				
				if (CurrentBattleHPPtr ~= nil) then
					if (CurrentBattleHPPtr ~= 0) then
						local CurrentHPValue = ReadFloat(CurrentBattleHPPtr + 0x2AC)
						local CurrentMaxHPValue = ReadFloat(CurrentBattleHPPtr + 0x2A8)
						local CurrentBattleHPPtr1 = ReadPointer(CurrentBattleHPPtr + 0x20)
						
						if (CurrentHPValue ~= nil) then
							if (CurrentHPValue ~= 0) then
								if (CurrentBattleHPPtr1 ~= nil) then
									if (CurrentBattleHPPtr1 ~= 0) then
										local ValidEnemyCheck = ReadInteger(CurrentBattleHPPtr1 + 0x128)
										
										if (ValidEnemyCheck == 0) then
											-- We Have To Check Max HP The Same Between Ally Lists
											local index99 = 0
											
											while (index99 &lt; 512) do
												local CurrentBattleHPPtr2 = ReadPointer(EnemyBattlePtr2 + (index99*8))
												
												if (CurrentBattleHPPtr2 ~= nil) then
													if (CurrentBattleHPPtr2 ~= 0) then
														local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
														
														if (CurrentBattleHPPtr21 ~= nil) then
															if (CurrentBattleHPPtr21 ~= 0) then
																local MyMaxHP = ReadFloat(CurrentBattleHPPtr21 + 0x0C)
																
																if (MyMaxHP == CurrentMaxHPValue) then
																	WritePointer(EnemyBattlePtr2 + (index99*8),0)
																	WriteInteger(iNumEnemyBattlePtr2,iNumEnemyBattlePtr21 - 1)
																end
															end
														end
													end
												end
												
												index99 = index99 + 1
											end

											-- Enemy Is Invalid, Remove Them From List
											WritePointer(EnemyBattlePtr + (index*8),0)
											WriteInteger(iNumEnemyBattlePtr,iNumEnemyBattlePtr1 - 1)
										end
										
										if ((ValidEnemyCheck ~= 1) and (CurrentMaxHPValue ~= 1)) then
											-- Move This To Ally
											if (AllyBattlePtr ~= nil) then
												if (AllyBattlePtr ~= 0) then
													local index2 = 0
													local bAlreadyInAllyList = 0
													
													while (index2 &lt; 16) do
														local CurrentAllyHPPtr = ReadPointer(AllyBattlePtr + (index2*8))
														
														if (CurrentAllyHPPtr ~= nil) then
															if (CurrentAllyHPPtr == CurrentBattleHPPtr) then
																bAlreadyInAllyList = 1
																break
															end
														end
														
														index2 = index2 + 1
													end

													if (bAlreadyInAllyList == 0) then
														-- Find Spot To Put It In
														local index3 = 0
														local bFoundASpot = 0
														
														while (index3 &lt; 16) do
															local CurrentAllyHPPtr = ReadPointer(AllyBattlePtr + (index3*8))
															
															if (CurrentAllyHPPtr == nil) then
																bFoundASpot = 1
															else
																if (CurrentAllyHPPtr == 0) then
																	bFoundASpot = 1
																end
															end
															
															index3 = index3 + 1
														end
														
														if (bFoundASpot == 1) then
															-- Set HP To Full Just In Case
															local CurrentMaxHP = ReadFloat(CurrentBattleHPPtr + 0x2A8)
															WriteFloat(CurrentBattleHPPtr + 0x2AC,CurrentMaxHP)
															
															WritePointer(AllyBattlePtr + (index3*8),CurrentBattleHPPtr)
															WriteInteger(iNumAllyBattlePtr,iNumAllyBattlePtr1 + 1)
															
															WritePointer(EnemyBattlePtr + (index*8),0)
															WriteInteger(iNumEnemyBattlePtr,iNumEnemyBattlePtr1 - 1)
														end
													end
													
													local index100 = 0
													
													while (index100 &lt; 512) do
														local CurrentBattleHPPtr2 = ReadPointer(EnemyBattlePtr2 + (index100*8))
														
														if (CurrentBattleHPPtr2 ~= nil) then
															if (CurrentBattleHPPtr2 ~= 0) then
																local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
																
																if (CurrentBattleHPPtr21 ~= nil) then
																	if (CurrentBattleHPPtr21 ~= 0) then
																		local MyMaxHP = ReadFloat(CurrentBattleHPPtr21 + 0x0C)
																		
																		if (MyMaxHP == CurrentMaxHPValue) then
																			local index3 = 0
																			local bAlreadyInAllyList2 = 0
																			
																			while (index3 &lt; 128) do
																				local CurrentAllyHPPtr = ReadPointer(AllyBattlePtr2 + (index3*8))
																				
																				if (CurrentAllyHPPtr ~= nil) then
																					if (CurrentAllyHPPtr == CurrentBattleHPPtr2) then
																						bAlreadyInAllyList2 = 1
																						break
																					end
																				end
																				
																				index3 = index3 + 1
																			end

																			if (bAlreadyInAllyList2 == 0) then
																				-- Find Spot To Put It In
																				local index3 = 0
																				local bFoundASpot2 = 0
																				
																				while (index3 &lt; 128) do
																					local CurrentAllyHPPtr = ReadPointer(AllyBattlePtr2 + (index3*8))
																					
																					if (CurrentAllyHPPtr == nil) then
																						bFoundASpot2 = 1
																					else
																						if (CurrentAllyHPPtr == 0) then
																							bFoundASpot2 = 1
																						end
																					end
																					
																					index3 = index3 + 1
																				end
																				
																				if (bFoundASpot2 == 1) then
																					-- Set HP To Full Just In Case
																					local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
																					
																					if (CurrentBattleHPPtr21 ~= nil) then
																						if (CurrentBattleHPPtr21 ~= 0) then
																							local CurrentMaxHP = ReadFloat(CurrentBattleHPPtr21 + 0x0C)
																							WriteFloat(CurrentBattleHPPtr21 + 0x08,CurrentMaxHP)
																						end
																					end
																					
																					WritePointer(AllyBattlePtr2 + (index3*8),CurrentBattleHPPtr2)
																					WriteInteger(iNumAllyBattlePtr2,iNumAllyBattlePtr21 + 1)
																					
																					WritePointer(EnemyBattlePtr2 + (index*8),0)
																					WriteInteger(iNumEnemyBattlePtr2,iNumEnemyBattlePtr21 - 1)
																				end
																			end	
																		end
																	end
																end
															end
														end
															
														index100 = index100 + 1
													end													
													
												end
											end
										end
									end
								end
							else
								if (CurrentBattleHPPtr1 ~= nil) then
									if (CurrentBattleHPPtr1 ~= 0) then
										local ValidEnemyCheck = ReadInteger(CurrentBattleHPPtr1 + 0x128)
										
										if (ValidEnemyCheck == 0) then
											-- We Have To Check Max HP The Same Between Ally Lists
											local index99 = 0
											
											while (index99 &lt; 512) do
												local CurrentBattleHPPtr2 = ReadPointer(EnemyBattlePtr2 + (index99*8))
												
												if (CurrentBattleHPPtr2 ~= nil) then
													if (CurrentBattleHPPtr2 ~= 0) then
														local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
														
														if (CurrentBattleHPPtr21 ~= nil) then
															if (CurrentBattleHPPtr21 ~= 0) then
																local MyMaxHP = ReadFloat(CurrentBattleHPPtr21 + 0x0C)
																
																if (MyMaxHP == CurrentMaxHPValue) then
																	WritePointer(EnemyBattlePtr2 + (index99*8),0)
																	WriteInteger(iNumEnemyBattlePtr2,iNumEnemyBattlePtr21 - 1)
																end
															end
														end
													end
												end
												
												index99 = index99 + 1
											end

											-- Enemy Is Invalid, Remove Them From List
											WritePointer(EnemyBattlePtr + (index*8),0)
											WriteInteger(iNumEnemyBattlePtr,iNumEnemyBattlePtr1 - 1)
										end
									end
								end							
							end
						end
					end
				end
				
				index = index + 1
			end
		end
	end

end
tValidateEnemyList.Interval = 200
tValidateEnemyList.Enabled = true

tValidateAllyList = createTimer(nil, false)
tValidateAllyList.OnTimer = function(fValidateAllyList)

	local AllyBattlePtr = getAddressSafe("AllyBattlePtr")
	local iNumAllyBattlePtr = getAddressSafe("iNumAllyBattlePtr")
	local AllyBattlePtr2 = getAddressSafe("AllyBattlePtr2")
	local iNumAllyBattlePtr2 = getAddressSafe("iNumAllyBattlePtr2")
	
	local EnemyBattlePtr = getAddressSafe("EnemyBattlePtr")
	local iNumEnemyBattlePtr = getAddressSafe("iNumEnemyBattlePtr")
	local EnemyBattlePtr2 = getAddressSafe("EnemyBattlePtr2")
	local iNumEnemyBattlePtr2 = getAddressSafe("iNumEnemyBattlePtr2")
		
	if (iNumAllyBattlePtr ~= nil) then
		if (iNumAllyBattlePtr ~= 0) then
			local iNumAllyBattlePtr1 = ReadInteger(iNumAllyBattlePtr)
			local iNumEnemyBattlePtr1 = ReadInteger(iNumEnemyBattlePtr)
			local iNumAllyBattlePtr21 = ReadInteger(iNumAllyBattlePtr2)
			local iNumEnemyBattlePtr21 = ReadInteger(iNumEnemyBattlePtr2)
			
			local index = 0
			
			while (index &lt; 16) do
				local CurrentBattleHPPtr = ReadPointer(AllyBattlePtr + (index*8))
				
				if (CurrentBattleHPPtr ~= nil) then
					if (CurrentBattleHPPtr ~= 0) then
						local CurrentHPValue = ReadFloat(CurrentBattleHPPtr + 0x2AC)
						local CurrentMaxHPValue = ReadFloat(CurrentBattleHPPtr + 0x2A8)
						local CurrentBattleHPPtr1 = ReadPointer(CurrentBattleHPPtr + 0x20)
						
						if (CurrentHPValue ~= nil) then
							if (CurrentHPValue ~= 0) then
								if (CurrentBattleHPPtr1 ~= nil) then
									if (CurrentBattleHPPtr1 ~= 0) then
										local ValidEnemyCheck = ReadInteger(CurrentBattleHPPtr1 + 0x128)
										
										if (ValidEnemyCheck == 0) then
											-- Ally Is Invalid, Remove Them From List
											-- We Have To Check Max HP The Same Between Ally Lists
											local index99 = 0
											
											while (index99 &lt; 128) do
												local CurrentBattleHPPtr2 = ReadPointer(AllyBattlePtr2 + (index99*8))
												
												if (CurrentBattleHPPtr2 ~= nil) then
													if (CurrentBattleHPPtr2 ~= 0) then
														local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
														
														if (CurrentBattleHPPtr21 ~= nil) then
															if (CurrentBattleHPPtr21 ~= 0) then
																local MyMaxHP = ReadFloat(CurrentBattleHPPtr21 + 0x0C)
																
																if (MyMaxHP == CurrentMaxHPValue) then
																	WritePointer(AllyBattlePtr2 + (index99*8),0)
																	WriteInteger(iNumAllyBattlePtr2,iNumAllyBattlePtr21 - 1)
																end
															end
														end
													end
												end
												
												index99 = index99 + 1
											end
																						
											WritePointer(AllyBattlePtr + (index*8),0)
											WriteInteger(iNumAllyBattlePtr,iNumAllyBattlePtr1 - 1)
										end
										
										if (ValidEnemyCheck == 1) then
											-- Move This To Enemy
											if (EnemyBattlePtr ~= nil) then
												if (EnemyBattlePtr ~= 0) then
													local index2 = 0
													local bAlreadyInEnemyList = 0
													
													while (index2 &lt; 256) do
														local CurrentEnemyHPPtr = ReadPointer(EnemyBattlePtr + (index2*8))
														
														if (CurrentEnemyHPPtr ~= nil) then
															if (CurrentEnemyHPPtr == CurrentBattleHPPtr) then
																bAlreadyInEnemyList = 1
																break
															end
														end
														
														index2 = index2 + 1
													end

													if (bAlreadyInEnemyList == 0) then
														-- Find Spot To Put It In
														local index3 = 0
														local bFoundASpot = 0
														
														while (index3 &lt; 256) do
															local CurrentEnemyHPPtr = ReadPointer(EnemyBattlePtr + (index3*8))
															
															if (CurrentEnemyHPPtr == nil) then
																bFoundASpot = 1
															else
																if (CurrentEnemyHPPtr == 0) then
																	bFoundASpot = 1
																end
															end
															
															index3 = index3 + 1
														end
														
														if (bFoundASpot == 1) then
															WritePointer(EnemyBattlePtr + (index3*8),CurrentBattleHPPtr)
															WriteInteger(iNumEnemyBattlePtr,iNumEnemyBattlePtr1 + 1)
															
															WritePointer(AllyBattlePtr + (index*8),0)
															WriteInteger(iNumAllyBattlePtr,iNumAllyBattlePtr1 - 1)
														end
													end

													local index100 = 0
													
													while (index100 &lt; 512) do
														local CurrentBattleHPPtr2 = ReadPointer(EnemyBattlePtr2 + (index100*8))
														
														if (CurrentBattleHPPtr2 ~= nil) then
															if (CurrentBattleHPPtr2 ~= 0) then
																local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
																
																if (CurrentBattleHPPtr21 ~= nil) then
																	if (CurrentBattleHPPtr21 ~= 0) then
																		local MyMaxHP = ReadFloat(CurrentBattleHPPtr21 + 0x0C)
																		
																		if (MyMaxHP == CurrentMaxHPValue) then
																			local index4 = 0
																			local bAlreadyInEnemyList2 = 0
																			
																			while (index4 &lt; 512) do
																				local CurrentEnemyHPPtr2 = ReadPointer(EnemyBattlePtr2 + (index4*8))
																				
																				if (CurrentEnemyHPPtr2 ~= nil) then
																					if (CurrentEnemyHPPtr2 == CurrentBattleHPPtr2) then
																						bAlreadyInEnemyList2 = 1
																						break
																					end
																				end
																				
																				index4 = index4 + 1
																			end

																			if (bAlreadyInEnemyList2 == 0) then
																				-- Find Spot To Put It In
																				local index5 = 0
																				local bFoundASpot2 = 0
																				
																				while (index5 &lt; 512) do
																					local CurrentEnemyHPPtr2 = ReadPointer(EnemyBattlePtr2 + (index5*8))
																					
																					if (CurrentEnemyHPPtr2 == nil) then
																						bFoundASpot2 = 1
																					else
																						if (CurrentEnemyHPPtr2 == 0) then
																							bFoundASpot2 = 1
																						end
																					end
																					
																					index5 = index5 + 1
																				end
																				
																				if (bFoundASpot2 == 1) then
																					WritePointer(EnemyBattlePtr2 + (index5*8),CurrentBattleHPPtr2)
																					WriteInteger(iNumEnemyBattlePtr2,iNumEnemyBattlePtr21 + 1)
																					
																					WritePointer(AllyBattlePtr2 + (index*8),0)
																					WriteInteger(iNumAllyBattlePtr2,iNumAllyBattlePtr21 - 1)
																				end
																			end
																		
																		end
																	end
																end
															end
														end
															
														index100 = index100 + 1
													end													
												end
											end
										end
									end
								end
							else
								if (CurrentBattleHPPtr1 ~= nil) then
									if (CurrentBattleHPPtr1 ~= 0) then
										local ValidEnemyCheck = ReadInteger(CurrentBattleHPPtr1 + 0x128)
										
										if (ValidEnemyCheck == 0) then
											-- We Have To Check Max HP The Same Between Ally Lists
											local index99 = 0
											
											while (index99 &lt; 128) do
												local CurrentBattleHPPtr2 = ReadPointer(AllyBattlePtr2 + (index99*8))
												
												if (CurrentBattleHPPtr2 ~= nil) then
													if (CurrentBattleHPPtr2 ~= 0) then
														local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
														
														if (CurrentBattleHPPtr21 ~= nil) then
															if (CurrentBattleHPPtr21 ~= 0) then
																local MyMaxHP = ReadFloat(CurrentBattleHPPtr21 + 0x0C)
																
																if (MyMaxHP == CurrentMaxHPValue) then
																	WritePointer(AllyBattlePtr2 + (index99*8),0)
																	WriteInteger(iNumAllyBattlePtr2,iNumAllyBattlePtr21 - 1)
																end
															end
														end
													end
												end
												
												index99 = index99 + 1
											end

											-- Ally Is Invalid, Remove Them From List
											WritePointer(AllyBattlePtr + (index*8),0)
											WriteInteger(iNumAllyBattlePtr,iNumAllyBattlePtr1 - 1)
										end
									end
								end							
							end
						end
					end
				end
				
				index = index + 1
			end
		end
	end

end
tValidateAllyList.Interval = 200
tValidateAllyList.Enabled = true

tDoGodMode = createTimer(nil, false)
tDoGodMode.OnTimer = function(fDoGodMode)

	local AllyBattlePtr = getAddressSafe("AllyBattlePtr")
	local iNumAllyBattlePtr = getAddressSafe("iNumAllyBattlePtr")
	local AllyBattlePtr2 = getAddressSafe("AllyBattlePtr2")
	local iNumAllyBattlePtr2 = getAddressSafe("iNumAllyBattlePtr2")
	
	local GodMode = getAddressSafe("GodMode")

	if (AllyBattlePtr ~= nil) then
		if (AllyBattlePtr ~= 0) then
			local index = 0
			
			while (index &lt; 16) do
				local CurrentBattleHPPtr = ReadPointer(AllyBattlePtr + (index*8))
				
				if (CurrentBattleHPPtr ~= nil) then
					if (CurrentBattleHPPtr ~= 0) then
						if (ReadInteger(GodMode) == 1) then
							local CurrentMaxHP = ReadFloat(CurrentBattleHPPtr +0x2A8)
							WriteFloat(CurrentBattleHPPtr + 0x2AC,CurrentMaxHP)
						end
					end
				end
				
				index = index + 1
			end

			index = 0
			
			while (index &lt; 128) do
				local CurrentBattleHPPtr2 = ReadPointer(AllyBattlePtr2 + (index*8))
				
				if (CurrentBattleHPPtr2 ~= nil) then
					if (CurrentBattleHPPtr2 ~= 0) then
						local CurrentBattleHPPtr21 = ReadPointer(CurrentBattleHPPtr2 + 0x4F8)
						
						if (CurrentBattleHPPtr21 ~= nil) then
							if (CurrentBattleHPPtr21 ~= 0) then						
								if (ReadInteger(GodMode) == 1) then
									local CurrentMaxHP = ReadFloat(CurrentBattleHPPtr21 +0x0C)
									WriteFloat(CurrentBattleHPPtr21 + 0x08,CurrentMaxHP)
								end
							end
						end
					end
				end

				index = index + 1
			end
		end
	end
  
end
tDoGodMode.Interval = 300
tDoGodMode.Enabled = true

local CurrentSaveSymbolList = {
"fEnemyDamageMultiplier",
"fHeroDamageMultiplier",
"fHeroHealingMultiplier",
"fEnemyHealingMultiplier",
"GodMode",
"TwoHitKill",
"HeroCannotDie",
"fHeroHPMinPercent"
}

-- First, make sure Save Symbol List global variable is empty
for i=#SaveSymbolList,1,-1 do
	table.remove(SaveSymbolList,i)
end

for j=1,#CurrentSaveSymbolList do
	-- Insert our custom symbol list for this trainer into the global variable
	table.insert(SaveSymbolList,CurrentSaveSymbolList[j])
end

{$asm}
alloc(newmem,1024,$process)
alloc(newmem2,4096,$process)

///
alloc(newmem3,1024,$process)
alloc(newmem4,8192,$process)

///
label(AllyBattlePtr)
registersymbol(AllyBattlePtr)
label(iNumAllyBattlePtr)
registersymbol(iNumAllyBattlePtr)
label(bEnemiesAreDead)
registersymbol(bEnemiesAreDead)
label(iTimeSinceEnemiesDied)
registersymbol(iTimeSinceEnemiesDied)

///
label(EnemyBattlePtr)
registersymbol(EnemyBattlePtr)
label(iNumEnemyBattlePtr)
registersymbol(iNumEnemyBattlePtr)

///
label(AllyBattlePtr2)
registersymbol(AllyBattlePtr2)
label(iNumAllyBattlePtr2)
registersymbol(iNumAllyBattlePtr2)

///
label(EnemyBattlePtr2)
registersymbol(EnemyBattlePtr2)
label(iNumEnemyBattlePtr2)
registersymbol(iNumEnemyBattlePtr2)

newmem:
bEnemiesAreDead:
dq 0
iTimeSinceEnemiesDied:
dq 0
iNumAllyBattlePtr:
dq 0
AllyBattlePtr:
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0

newmem2:
iNumEnemyBattlePtr:
dq 0
EnemyBattlePtr:
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0

newmem3:
iNumAllyBattlePtr2:
dq 0
AllyBattlePtr2:
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0

newmem4:
iNumEnemyBattlePtr2:
dq 0
EnemyBattlePtr2:
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0
dq 0

[DISABLE]
{$lua}
tCheckBattleHPPtr.Destroy()
tCheckEnemiesAreDead.Destroy()
tValidateEnemyList.Destroy()
tValidateAllyList.Destroy()
tDoGodMode.Destroy()

{$asm}

///
unregistersymbol(AllyBattlePtr)
unregistersymbol(iNumAllyBattlePtr)
unregistersymbol(bEnemiesAreDead)
unregistersymbol(iTimeSinceEnemiesDied)

///
unregistersymbol(EnemyBattlePtr)
unregistersymbol(iNumEnemyBattlePtr)

///
unregistersymbol(AllyBattlePtr2)
unregistersymbol(iNumAllyBattlePtr2)

///
unregistersymbol(EnemyBattlePtr2)
unregistersymbol(iNumEnemyBattlePtr2)

dealloc(newmem)
dealloc(newmem2)
dealloc(newmem3)
dealloc(newmem4)
</AssemblerScript>
	  <Hotkeys>
		<Hotkey>
		  <Action>Activate</Action>
		  <Keys>
			<Key>112</Key>
		  </Keys>
		  <ID>0</ID>
		</Hotkey>
	  </Hotkeys>
	</CheatEntry>
    <CheatEntry>
      <ID>10</ID>
      <Description>"Save Current Trainer Values"</Description>
      <Options moHideChildren="1"/>
	  <VariableType>Auto Assembler Script</VariableType>
	  <AssemblerScript>[ENABLE]
{$lua}

--- Call Function To Save Trainer Values
SaveTrainerValues()

{$asm}

[DISABLE]
{$lua}
tCheckBattleHPPtr.Destroy()

{$asm}

</AssemblerScript>
	  <Hotkeys>
		<Hotkey>
		  <Action>Toggle Activation</Action>
		  <Keys>
			<Key>113</Key>
		  </Keys>
		  <ID>0</ID>
		</Hotkey>
	  </Hotkeys>
	</CheatEntry>
    <CheatEntry>
      <ID>11</ID>
      <Description>"Load Current Trainer Values"</Description>
      <Options moHideChildren="1"/>
	  <VariableType>Auto Assembler Script</VariableType>
	  <AssemblerScript>[ENABLE]
{$lua}

--- Call Function To Load Trainer Values
LoadTrainerValues()

{$asm}

[DISABLE]

</AssemblerScript>
	  <Hotkeys>
		<Hotkey>
		  <Action>Toggle Activation</Action>
		  <Keys>
			<Key>114</Key>
		  </Keys>
		  <ID>0</ID>
		</Hotkey>
	  </Hotkeys>
	</CheatEntry>
    <CheatEntry>
      <ID>12</ID>
      <Description>"Change Slot Config Description"</Description>
      <Options moHideChildren="1"/>
	  <VariableType>Auto Assembler Script</VariableType>
	  <AssemblerScript>[ENABLE]
{$lua}

--- Call Function To Change Slot Description
ChangeSlotDescription()

{$asm}

[DISABLE]

</AssemblerScript>
	  <Hotkeys>
		<Hotkey>
		  <Action>Toggle Activation</Action>
		  <Keys>
			<Key>115</Key>
		  </Keys>
		  <ID>0</ID>
		</Hotkey>
	  </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>200</ID>
	  <Description>"Enable Damage Modifier Options (God Mode, One Hit Kill, etc)"</Description>
	  <Options moHideChildren="1"/>
	  <VariableType>Auto Assembler Script</VariableType>
	  <AssemblerScript>[ENABLE]
{$lua}

-- This is the function call at [rbp+8F]
lua_aobscan("AllyFunctionCall",process,"48 8D 4D 07 E8 ?? ?? ?? ?? 48 8B 4D 07 48 85 C9 75 DF",1)

-- This is the function call at [rbp+8F]
lua_aobscan("EnemyFunctionCall",process,"66 48 0F 7E C8 FF D0 B0 01 48 8B 5C 24 30 48 83 C4 20 5F C3",9)

-- This is the function call at [rbp-41]
lua_aobscan("AllyFunctionCall2",process,"EB B0 33 C0 48 8B B4 24 A0 00 00 00",1)

-- This is the function call at [rbp+1CF] for enemy list
lua_aobscan("EnemyFunctionCall2",process,"48 85 C0 74 65 48 8B D3 48 81 E2 00 00 FF FF",1)

{$asm}
aobscanmodule(DamageModAOB,$process,48 89 5C 24 10 57 48 83 EC 20 83 79 20 00 48 89 D3) // should be unique
registersymbol(DamageModAOB)
alloc(newmem,8192)

///
label(return)
label(DamageModAOBSave)
registersymbol(DamageModAOBSave)
label(GodMode)
registersymbol(GodMode)
label(TwoHitKill)
registersymbol(TwoHitKill)
label(fHeroDamageMultiplier)
registersymbol(fHeroDamageMultiplier)
label(fEnemyDamageMultiplier)
registersymbol(fEnemyDamageMultiplier)
label(fHeroHealingMultiplier)
registersymbol(fHeroHealingMultiplier)
label(fEnemyHealingMultiplier)
registersymbol(fEnemyHealingMultiplier)
label(HeroCannotDie)
registersymbol(HeroCannotDie)
label(fHeroHPMinPercent)
registersymbol(fHeroHPMinPercent)

newmem:
  mov qword ptr [bEnemy],0
  mov [R10Save],r10
  mov [R11Save],r11
  mov [R12Save],r12
  mov [R13Save],r13
  mov [R14Save],r14
  mov [R15Save],r15
  movss [XMM7SSSave],xmm7
  movss [XMM8SSSave],xmm8
  movss [XMM9SSSave],xmm9
  movss [XMM10SSSave],xmm10
  movss [XMM11SSSave],xmm11
  movss [XMM12SSSave],xmm12
  movss [XMM13SSSave],xmm13
  movss [XMM14SSSave],xmm14
  movss [XMM15SSSave],xmm15
  xor r14,r14
  xorps xmm10,xmm10
  movss xmm13,[fOne]
  // Determine What Setting HP To
  mov r15,rdx 
  test r15,r15
  je PutThingsBack  
  mov r15,[r15+000004F8]
  movss xmm9,[r15+00000008]
  movss xmm14,[r15+00000008]
  movss xmm8,[r15+0000000C]
  mulss xmm8,[fHeroHPMinPercent]
  cvttss2si r14d,xmm8
  cvtsi2ss xmm8,r14d
  // Get Current HP from structure further down
  mov r15,rcx
  mov r15,[r15+00000028]
  test r15,r15
  je PutThingsBack
  mov r15,[r15+00000000]
  test r15,r15
  je PutThingsBack
  mov r15,[r15+00000008]
  test r15,r15
  je PutThingsBack
  mov r15,[r15+00000018]
  test r15,r15
  je PutThingsBack
  mov r15,[r15+00000000]
  test r15,r15
  je PutThingsBack
  mov r15,[r15+00000018]
  test r15,r15
  je PutThingsBack
  movss xmm12,[r15+0000002AC]
  movss xmm11,[r15+0000002A8]
  comiss xmm12,xmm10
  je PutThingsBack
  // Determine Ally vs Enemy
  mov r14,AllyFunctionCall
  cmp [rbp+8F],r14
  je FoundAlly
  mov r14,AllyFunctionCall2
  cmp [rbp-41],r14
  jne CheckOtherEnemy
  mov r13,[r15+00000020]
  test r13,r13
  je CheckOtherEnemy
  cmp dword ptr [r13+00000128],1
  jne FoundAlly
  cmp dword ptr [r15+00000140],1
  jne FoundAlly
  jmp CheckOtherEnemy
CheckOtherEnemy:
  mov r14,EnemyFunctionCall
  add r14,07
  cmp [rbp+8F],r14
  jne SkipToNextEnemyCheck
  mov r13,[r15+00000020]
  test r13,r13
  je SkipToNextEnemyCheck
  cmp dword ptr [r13+00000128],1
  jne FoundAlly
  jmp FoundEnemy
SkipToNextEnemyCheck:
  cmp dword ptr [r15+00000140],1
  je FoundEnemy
  cmp dword ptr [r15+00000130],FFFFFFFF
  je FoundEnemy
  jmp PossibleAlly
PossibleAlly:
  jmp SkipEnemyPut
FoundAlly:
  mov r10,EnemyBattlePtr
  mov r12,iNumEnemyBattlePtr
  xor r11,r11
  xor r14,r14
CheckIfAllyAnEnemyLoop:
  cmp r11d,#16
  jge AllyIsNotEnemyAlso
  cmp [r10+r11*8],r15
  je AllyIsEnemyAlso
  inc r11
  jmp CheckIfAllyAnEnemyLoop
AllyIsEnemyAlso:
  jmp SkipEnemyPut
AllyIsNotEnemyAlso:
  // Put This Address In Our Ally List
  mov r10,AllyBattlePtr
  mov r12,iNumAllyBattlePtr
  xor r11,r11
  xor r14,r14
StartPutAllyLoop:
  cmp r11,#16
  jge OutofAllySpace
  cmp [r10+r11*8],r15
  je FoundAllyAddress
  cmp [r10+r11*8],r14
  je NotFoundAllyAddress
  inc r11
  jmp StartPutAllyLoop
NotFoundAllyAddress:
  mov [r10+r11*8],r15
  inc [r12]
FoundAllyAddress:
OutofAllySpace:
  // Put This Address In Our Ally List 2
  mov r10,AllyBattlePtr2
  mov r12,iNumAllyBattlePtr2
  xor r11,r11
  xor r14,r14
StartPutAllyLoop2:
  cmp r11,#128
  jge OutofAllySpace2
  cmp [r10+r11*8],rdx
  je FoundAllyAddress2
  cmp [r10+r11*8],r14
  je NotFoundAllyAddress2
  inc r11
  jmp StartPutAllyLoop2
NotFoundAllyAddress2:
  mov [r10+r11*8],rdx
  inc [r12]
FoundAllyAddress2:
OutofAllySpace2:
  jmp SkipEnemyPut
FoundEnemy:
  // First, Check If In Ally List
  mov r10,AllyBattlePtr
  mov r12,iNumAllyBattlePtr
  xor r11,r11
  xor r14,r14
CheckIfEnemyAnAllyLoop:
  cmp r11d,#16
  jge EnemyIsNotAllyAlso
  cmp [r10+r11*8],r15
  je EnemyIsAllyAlso
  inc r11
  jmp CheckIfEnemyAnAllyLoop
EnemyIsAllyAlso:
  jmp SkipEnemyPut
EnemyIsNotAllyAlso:
  // Put This Address In Our Enemy List
  mov r10,EnemyBattlePtr
  mov r12,iNumEnemyBattlePtr
  xor r11,r11
  xor r14,r14
StartPutEnemyLoop:
  cmp r11,#256
  jge OutofEnemySpace
  cmp [r10+r11*8],r15
  je FoundEnemyAddress
  cmp [r10+r11*8],r14
  je NotFoundEnemyAddress
  inc r11
  jmp StartPutEnemyLoop
NotFoundEnemyAddress:
  mov [r10+r11*8],r15
  inc [r12]
FoundEnemyAddress:
OutofEnemySpace:
  // Put This Address In Our Enemy List 2
  mov r10,EnemyBattlePtr2
  mov r12,iNumEnemyBattlePtr2
  xor r11,r11
  xor r14,r14
StartPutEnemyLoop2:
  cmp r11,#512
  jge OutofEnemySpace2
  cmp [r10+r11*8],rdx
  je FoundEnemyAddress2
  cmp [r10+r11*8],r14
  je NotFoundEnemyAddress2
  inc r11
  jmp StartPutEnemyLoop2
NotFoundEnemyAddress2:
  mov [r10+r11*8],rdx
  inc [r12]
FoundEnemyAddress2:
OutofEnemySpace2:
SkipEnemyPut:
  // Check Our List For Enemy
  mov r10,EnemyBattlePtr
  mov r12,iNumEnemyBattlePtr
  mov r12,[r12]
  xor r11,r11
  xor r14,r14
CheckIfEnemyLoop:
  cmp r11d,r12d
  jge FoundAlly2
  cmp [r10+r11*8],r15
  je FoundEnemy2
  cmp [r10+r11*8],r14
  je FoundAlly2
  inc r11
  jmp CheckIfEnemyLoop
FoundAlly2:  
  mov qword ptr [bEnemy],0
  jmp SkipSetEnemy
FoundEnemy2:
  mov qword ptr [bEnemy],1
SkipSetEnemy:
  // End of Determine Ally vs Enemy
  // Calculate Current Damage
  movss xmm15,xmm12
  subss xmm15,xmm14
  // Check If Ally
  cmp dword ptr [bEnemy],1
  je EnemyHit
  jmp HeroHit
HeroHit:
  mov qword ptr [bSetTwoHitKill],0
  comiss xmm15,xmm10
  ja HeroDamageHit
  jb HeroHealingHit
  jmp PutThingsBack
HeroDamageHit:
  cmp [fHeroDamageMultiplier],(float)0.0
  je CheckGodMode
  mulss xmm15,[fHeroDamageMultiplier]
CheckGodMode:
  cmp [GodMode],1
  jne CheckHeroCannotDie
  xorps xmm15,xmm15
  jmp MyCleanUp1
CheckHeroCannotDie:
  cmp [HeroCannotDie],1
  jne MyCleanUp1
  comiss xmm15,xmm12
  jb @F
  xorps xmm15,xmm15
@@:
  jmp MyCleanUp1
HeroHealingHit:
  cmp [fHeroHealingMultiplier],(float)0.0
  je MyCleanUp1
  mulss xmm15,[fHeroHealingMultiplier]
  jmp MyCleanUp1
EnemyHit:
  mov qword ptr [bSetTwoHitKill],0
  comiss xmm12,xmm13
  jbe PutThingsBack
  comiss xmm15,xmm10
  ja EnemyDamageHit
  jb EnemyHealingHit
  jmp CheckTwoHitKill
EnemyDamageHit:
  comiss xmm12,xmm13
  jbe CheckTwoHitKill
  cmp [fEnemyDamageMultiplier],(float)0.0
  je CheckTwoHitKill
  mulss xmm15,[fEnemyDamageMultiplier]
  comiss xmm15,xmm12
  jb CheckTwoHitKill
  movss xmm15,xmm12
  subss xmm15,xmm13
  jmp CheckTwoHitKill
CheckTwoHitKill:
  cmp [TwoHitKill],1
  jne MyCleanUp1
  comiss xmm12,xmm13
  jbe SkipSettingTwoHitKill
  movss xmm15,xmm12
  subss xmm15,xmm13
  mov qword ptr [bSetTwoHitKill],1
SkipSettingTwoHitKill:
  jmp MyCleanUp1
EnemyHealingHit:
  cmp [fEnemyHealingMultiplier],(float)0.0
  je MyCleanUp1
  mulss xmm15,[fEnemyHealingMultiplier]
  jmp MyCleanUp1
  
MyCleanUp1:
  cvttss2si r14d,xmm15
  cvtsi2ss xmm15,r14d
  mulss xmm15,dword ptr [fNegativeOne]
  addss xmm15,xmm12
  cmp [bEnemy],0
  jne SkipSetHeroMinPercent
  comiss xmm15,xmm8
  jae SkipSetHeroMinPercent
  movss xmm15,xmm8
SkipSetHeroMinPercent:
  comiss xmm15,xmm10
  ja SkipSettingMin
  xorps xmm15,xmm15
SkipSettingMin:
  comiss xmm15,xmm11
  jb SkipSettingMax
  movss xmm15,xmm11
SkipSettingMax:
  mov r15,rdx
  mov r15,[r15+000004F8]
  movss [r15+00000008],xmm15
PutThingsBack:
  mov r10,[R10Save]
  mov r11,[R11Save]
  mov r12,[R12Save]
  mov r13,[R13Save]
  mov r14,[R14Save]
  mov r15,[R15Save]
  movss xmm7,[XMM7SSSave]
  movss xmm8,[XMM8SSSave]
  movss xmm9,[XMM9SSSave]
  movss xmm10,[XMM10SSSave]
  movss xmm11,[XMM11SSSave]
  movss xmm12,[XMM12SSSave]
  movss xmm13,[XMM13SSSave]
  movss xmm14,[XMM14SSSave]
  movss xmm15,[XMM15SSSave]
  jmp originalcode
  
originalcode:
DamageModAOBSave:
  readmem(DamageModAOB,14)
  jmp DamageModAOB+0E
  
bSetTwoHitKill:
dq 0
bEnemy:
dq 0
R10Save:
dq 0
R11Save:
dq 0
R12Save:
dq 0
R13Save:
dq 0
R14Save:
dq 0
R15Save:
dq 0
XMM7SSSave:
dq 0
XMM8SSSave:
dq 0
XMM9SSSave:
dq 0
XMM10SSSave:
dq 0
XMM11SSSave:
dq 0
XMM12SSSave:
dq 0
XMM13SSSave:
dq 0
XMM14SSSave:
dq 0
XMM15SSSave:
dq 0
fZeroFloat:
dq (float)0.0
fNegativeOne:
dq (float)-1.0
fOne:
dq (float)1.0
GodMode:
dq 0
TwoHitKill:
dq 0
fEnemyDamageMultiplier:
dq (float)2.0
fHeroDamageMultiplier:
dq (float)0.25
fEnemyHealingMultiplier:
dq (float)0.25
fHeroHealingMultiplier:
dq (float)2.0
HeroCannotDie:
dq 1
fHeroHPMinPercent:
dq (float)0.33

DamageModAOB:
  jmp newmem
  return:

[DISABLE]

DamageModAOB:
  readmem(DamageModAOBSave,14)

unregistersymbol(DamageModAOB)
unregistersymbol(DamageModAOBSave)
unregistersymbol(GodMode)
unregistersymbol(TwoHitKill)
unregistersymbol(fEnemyDamageMultiplier)
unregistersymbol(fEnemyHealingMultiplier)
unregistersymbol(fHeroDamageMultiplier)
unregistersymbol(fHeroHealingMultiplier)
unregistersymbol(HeroCannotDie)
unregistersymbol(fHeroHPMinPercent)

dealloc(newmem)
</AssemblerScript>
	  <Hotkeys>
		<Hotkey>
		  <Action>Toggle Activation</Action>
		  <Keys>
			<Key>97</Key>
		  </Keys>
		  <ID>0</ID>
		</Hotkey>
	  </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>201</ID>
	  <Description>"God Mode"</Description>
	  <DropDownList DescriptionOnly="1" DisplayValueAsItem="1">0:Off
1:On
</DropDownList>
	  <VariableType>4 Bytes</VariableType>
	  <Address>GodMode</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>1</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>202</ID>
	  <Description>"Hero Cannot Die"</Description>
	  <DropDownList DescriptionOnly="1" DisplayValueAsItem="1">0:Off
1:On
</DropDownList>
	  <VariableType>4 Bytes</VariableType>
	  <Address>HeroCannotDie</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>1</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>203</ID>
	  <Description>"Hero HP Minimum Percent (Hero HP Won't Go Below This Percent)"</Description>
	  <VariableType>Float</VariableType>
	  <Address>fHeroHPMinPercent</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>0.33</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>204</ID>
	  <Description>"Hero Damage Multiplier"</Description>
	  <VariableType>Float</VariableType>
	  <Address>fHeroDamageMultiplier</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>1</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>205</ID>
	  <Description>"Hero Healing Multiplier"</Description>
	  <VariableType>Float</VariableType>
	  <Address>fHeroHealingMultiplier</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>1</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>206</ID>
	  <Description>"Two Hit Kill"</Description>
	  <DropDownList DescriptionOnly="1" DisplayValueAsItem="1">0:Off
1:On
</DropDownList>
	  <VariableType>4 Bytes</VariableType>
	  <Address>TwoHitKill</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>0</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>207</ID>
	  <Description>"Enemy Damage Multiplier"</Description>
	  <VariableType>Float</VariableType>
	  <Address>fEnemyDamageMultiplier</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>1</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
	<CheatEntry>
	  <ID>208</ID>
	  <Description>"Enemy Healing Multiplier"</Description>
	  <VariableType>Float</VariableType>
	  <Address>fEnemyHealingMultiplier</Address>
      <Hotkeys>
        <Hotkey>
          <Action>Set Value</Action>
          <Keys>
            <Key>18</Key>
            <Key>97</Key>
          </Keys>
          <Value>1</Value>
          <ID>0</ID>
        </Hotkey>
      </Hotkeys>
	</CheatEntry>
  </CheatEntries>
<LuaScript>
PROCESS_NAME = 'MidnightSuns-Win64-Shipping.exe'
--------
-------- Auto Attach
--------
local autoAttachTimer = nil ---- variable to hold timer object
local autoAttachTimerInterval = 5 ---- Timer intervals are in milliseconds
local autoAttachTimerTicks = 0 ---- variable to count number of times the timer has run
local autoAttachTimerTickMax = 0 ---- Set to zero to disable ticks max
local function autoAttachTimer_tick(timer) ---- Timer tick call back
        ---- Destroy timer if max ticks is reached
	if autoAttachTimerTickMax > 0 and autoAttachTimerTicks >= autoAttachTimerTickMax then
		timer.destroy()
	end
        ---- Check if process is running
	if getProcessIDFromProcessName(PROCESS_NAME) ~= nil then
		timer.destroy() ---- Destroy timer
		openProcess(PROCESS_NAME) ---- Open the process
		local EnumChildWindowsPtr = getAddressSafe("EnumChildWindows")
		WriteBytes(EnumChildWindowsPtr,0xC3)
	end
	autoAttachTimerTicks = autoAttachTimerTicks + 1 ---- Increase ticks
end
autoAttachTimer = createTimer(getMainForm()) ---- Create timer with the main form as it's parent
autoAttachTimer.Interval = autoAttachTimerInterval ---- Set timer interval
autoAttachTimer.OnTimer = autoAttachTimer_tick ---- Set timer tick call back

function lua_aobscan(name,module,bytes,index)
  index = index - 1
  if(module == "") then
    local resultSet = AOBScan(bytes)
      if(resultSet == nil) then
        unregisterSymbol(name)
        print(name.." not found")
      else
        unregisterSymbol(name)
        registerSymbol(name,resultSet[index])
        resultSet.destroy()
      end
  else
    if(getModuleSize(module) == nil) then
      print("Module "..module.." not found")
    else
      local memScanner = createMemScan()
      local memFoundList = createFoundList(memScanner)
      memScanner.firstScan(
        soExactValue,vtByteArray,rtRounded,bytes,nil,
        getAddress(module),(getAddress(module)+getModuleSize(module)),"",
        fsmNotAligned,"",true,false,false,false)
      memScanner.waitTillDone()
      memFoundList.initialize()
        if(memFoundList.Count == 0) then
          unregisterSymbol(name)
          print(name.." in module "..module.." not found")
        else
          unregisterSymbol(name)
          registerSymbol(name,memFoundList.Address[index])
        end
      memScanner.destroy()
      memFoundList.destroy()
    end
  end
end

function lua_aobscan_last(name,module,bytes)
  if(module == "") then
    local resultSet = AOBScan(bytes)
      if(resultSet == nil) then
        unregisterSymbol(name)
        print(name.." not found")
      else
        unregisterSymbol(name)
        registerSymbol(name,resultSet[#resultSet])
        resultSet.destroy()
      end
  else
    if(getModuleSize(module) == nil) then
      print("Module "..module.." not found")
    else
      local memScanner = createMemScan()
      local memFoundList = createFoundList(memScanner)
      memScanner.firstScan(
        soExactValue,vtByteArray,rtRounded,bytes,nil,
        getAddress(module),(getAddress(module)+getModuleSize(module)),"",
        fsmNotAligned,"",true,false,false,false)
      memScanner.waitTillDone()
      memFoundList.initialize()
        if(memFoundList.Count == 0) then
          unregisterSymbol(name)
          print(name.." in module "..module.." not found")
        else
          unregisterSymbol(name)
          registerSymbol(name,memFoundList.Address[memFoundList.Count-1])
        end
      memScanner.destroy()
      memFoundList.destroy()
    end
  end
end


-- Function By DrummerIX to find the address of an AOB that matches a particular name
-- as there are times when CE shows a name, but you cannot go to that address by using
-- the name by default, so we use this as a workaround
-- It expects a name to register the found address, a module name (can be blank), the bytes to search, and the name to match
function lua_aobscan_find_method(name,module,bytes,method_name)
  if(module == "") then
    local resultSet = AOBScan(bytes)
      if(resultSet == nil) then
        unregisterSymbol(name)
        print(name.." not found")
      else
	    -- Go Through Results Looking For method_name
		for i=0,resultSet.Count-1 do
			local CurrentAddress = resultSet[i]
			local CurrentName = getNameFromAddress(CurrentAddress)
			if CurrentName ~= nil then
				if CurrentName == method_name then
					unregisterSymbol(name)
					registerSymbol(name,CurrentAddress)
				end
			end
		end
		resultSet.destroy()	
      end
  else
    if(getModuleSize(module) == nil) then
      print("Module "..module.." not found")
    else
      local memScanner = createMemScan()
      local memFoundList = createFoundList(memScanner)
      memScanner.firstScan(
        soExactValue,vtByteArray,rtRounded,bytes,nil,
        getAddress(module),(getAddress(module)+getModuleSize(module)),"",
        fsmNotAligned,"",true,false,false,false)
      memScanner.waitTillDone()
      memFoundList.initialize()
        if(memFoundList.Count == 0) then
          unregisterSymbol(name)
          print(name.." in module "..module.." not found")
        else
		  -- Go Through Results Looking For method_name
		  for i=0,memFoundList.Count-1 do
			local CurrentName = getNameFromAddress(memFoundList.Address[i])
			if CurrentName ~= nil then
				if CurrentName == method_name then
				  unregisterSymbol(name)
				  registerSymbol(name,memFoundList.Address[i])
				end
			end
		  end
        end
      memScanner.destroy()
      memFoundList.destroy()
    end
  end
end

-- code by FreeER
function getFields(param)
  -- simplified 'classname' or 'namespace:classname' input
  -- obviously you could just change the code to pass findClass's result
  --local namespace,classname = param:match('(%w+):?(%w*)')
  -- DrummerIX modified the Regex for match to account for periods in classnames (we want everything before : and then everything after :)
  local namespace,classname = param:match('([%w%d%.]*):?([%w%d%.]*)')
  
  if not classname or classname == '' then namespace, classname = '', namespace end
  local class=mono_findClass(namespace, classname)
  local fields=mono_class_enumFields(class)
  local result = {}
  for _, field in ipairs(fields) do
    local keyfieldname = field.name:gsub("&lt;","_"):gsub("&gt;","_")
	--print(namespace,classname,keyfieldname)
    result[keyfieldname] = field.offset
  end
  return result
end

-- Functions By Panraven for mono finding method by signature
function reEscape(s)
  local escPatChars = [[().%+-*?[^]]
  s = s:gsub('.',function(c) if escPatChars:find(c,1,true) then return '%'..c end end)
  return s
end

function findMethodAddrBySignature(namespace,classname,methodname,signature,check)
  local meth = findMethodBySignature(namespace,classname,methodname,signature,check)
  if meth~=nil and meth>0 then
	return mono_compile_method(meth)
  end
end

function findMethodBySignature(namespace,classname,methodname,signature,check)
  assert(type(signature)=='string',"invalid signature")
  signature="^"..reEscape(signature:gsub(";",","))
  local class = mono_findClass(namespace,classname)
  if type(class)~='number' or class==0 then return nil end
  local methods=mono_class_enumMethods(class)
  if type(methods)~='table' or #methods &lt; 1 then return nil end
  if check then  print('check:'..methodname..": &lt;"..signature.."&gt; vs ") end
  for i=1,#methods do
   if methodname == methods[i].name then
     local sign = mono_method_getSignature(methods[i].method)
     if check then  print("  &gt;&gt; &lt;"..sign..'&gt;') end
     if sign:match(signature) then
       return methods[i].method
     end
   end
  end
end

-- Test
function tohex(n)return string.format('%X',n or 0)end 

-- test
--print('--') -- test to show/print all signature of a given function name
--print(tohex(findMethodAddrBySignature('Assembly-CSharp','CommissionFactory','GenerateCommissionsFrequently','?',true)))
--print('--') -- test to match a specific (third) signature of a function name
--print(tohex(findMethodAddrBySignature('Assembly-CSharp','CommissionFactory','GenerateCommissionsFrequently','bool$',true)))
-- the last '$' is lua match end-of-string, wthout this, the match MAY succeed on fourth one.
-- all other character should be compare as is, including upper/lower cases.

-----------------------------------------------------------------------------------------------
--- Things below here deal with the Save and Load of Trainer Values
-----------------------------------------------------------------------------------------------
--- Global List Variables For Use In Save and Load Trainer State
SaveSymbolList = {}

PerformActivateList = {}

CurrentlyActivatingList = {}

CurrentSlotDescriptions = {}

DoNotSaveDescriptions = {
"Save Current Trainer Values",
"Load Current Trainer Values",
"Change Slot Config Description"
}

-- Global Variable For Our SubFolder To Store Configs In
sConfigSubFolder = "\\CheatEvolution\\"

--- Global Variables To Deal With Our Handler Function
bPerformSaveTrainerValues = 0
bPerformLoadTrainerValues = 0
bPerformActivateTrainerCheats = 0
bFinishedActivateTrainerCheats = 1

bUnableToCreateFolder = 0

--- Global Variable Dealing With Save Config Slot #
iSaveConfigSlot = 1
iMaxSaveConfigSlots = 10

function LoadTrainerValues()

	-- First We Ask What Slot They Want To Load
	local mySL = CreateStringList()
	for i,j in ipairs(CurrentSlotDescriptions) do
		mySL.add(j)
	end		

	local result = showSelectionList('Load Trainer Values', 'Which Config Slot', mySL, false)

	mySL.destroy()
	
	if result ~= nil then
		if result ~= -1 then
			iSaveConfigSlot = result + 1
			bPerformLoadTrainerValues = 1
			bPerformActivateTrainerCheats = 1
			bFinishedActivateTrainerCheats = 0
		end
	end

end

function SaveTrainerValues()

	-- First We Ask What Slot They Want To Load
	local mySL = CreateStringList()
	for i,j in ipairs(CurrentSlotDescriptions) do
		mySL.add(j)
	end		
	
	local result = showSelectionList('Save Trainer Values', 'Which Config Slot', mySL, false)
	
	mySL.destroy()
	
	if result ~= nil then
		if result ~= -1 then
			iSaveConfigSlot = result + 1
			bPerformSaveTrainerValues = 1
		end
	end

end
	
function WriteOutCurrentSlotDescriptions()

	local baseFileName = nil

	if (process ~= nil) then
		if (string.find(string.reverse(process),"[.]") ~= nil) then
			baseFileName = string.sub(process,1,string.len(string.reverse(process))-string.find(string.reverse(process),"[.]"))	
		end
	end

	if (baseFileName ~= nil) then
	
		local ourFolder = CheckOurSaveStateFolder()
		local filename = ourFolder .. baseFileName .. '_Slots.txt'
	
		local file = assert(io.open(filename, "w"))
		for i=1,#CurrentSlotDescriptions do
			file:write(CurrentSlotDescriptions[i] .. '\n')
		end
		file:close()
	end

end

function ChangeSlotDescription()

	-- First We Ask What Slot They Want To Load
	local mySL = CreateStringList()
	for i,j in ipairs(CurrentSlotDescriptions) do
		mySL.add(j)
	end		

	local result = showSelectionList('Change Slot Description', 'Which Config Slot', mySL, false)
	
	mySL.destroy()
	
	if result ~= nil then
		if result ~= -1 then
			local myPrompt = 'Current Description for [Slot ' .. string.format("%d",result+1) .. '] is ' .. CurrentSlotDescriptions[result+1]
			myPrompt = myPrompt .. '\n\nWhat do you want to change it to?'
			
			local newDesc = inputQuery('Change Slot Description',myPrompt,CurrentSlotDescriptions[result+1])
			
			if newDesc ~= nil then
				CurrentSlotDescriptions[result+1] = newDesc
				-- Write Out Our Changes
				WriteOutCurrentSlotDescriptions()
			end
		end
	end
	
	-- Deactivate This Memory Record
	ActivateCheatRecord("Change Slot Config Description")
	
end

function InitializeConfigSlotDescriptions()

	local baseFileName = nil

	if (process ~= nil) then
		if (string.find(string.reverse(process),"[.]") ~= nil) then
			baseFileName = string.sub(process,1,string.len(string.reverse(process))-string.find(string.reverse(process),"[.]"))	
		end
	end

	if (baseFileName ~= nil) then
		for i=#CurrentSlotDescriptions,1,-1 do
			table.remove(CurrentSlotDescriptions,i)
		end
		
		local ourFolder = CheckOurSaveStateFolder()
		local filename = ourFolder .. baseFileName .. '_Slots.txt'
		
		if not exists(filename) and (bUnableToCreateFolder == 0) then
			-- Create Default Slot Descriptions
			local file = assert(io.open(filename, "w"))
			for i=1,iMaxSaveConfigSlots do
				if i == 1 then
					file:write("Default\n")
					table.insert(CurrentSlotDescriptions,"Default")
				else
					file:write("Slot " .. string.format("%d",i) .. "\n")
					table.insert(CurrentSlotDescriptions,"Slot " .. string.format("%d",i))
				end
			end
			file:close()
		else
			if (bUnableToCreateFolder == 0) then
				-- Read In Current Slot Descriptions
				local file = assert(io.open(filename, "r"))
				for line in file:lines() do
					table.insert(CurrentSlotDescriptions,line)
				end
			end
		end
	end

end

-- Functions Found On Internet For Dealing With CSV files
function string:split(sSeparator, nMax, bRegexp)
    if sSeparator == '' then
        sSeparator = ','
    end

    if nMax and nMax &lt; 1 then
        nMax = nil
    end

    local aRecord = {}

    if self:len() > 0 then
        local bPlain = not bRegexp
        nMax = nMax or -1

        local nField, nStart = 1, 1
        local nFirst,nLast = self:find(sSeparator, nStart, bPlain)
        while nFirst and nMax ~= 0 do
            aRecord[nField] = self:sub(nStart, nFirst-1)
            nField = nField+1
            nStart = nLast+1
            nFirst,nLast = self:find(sSeparator, nStart, bPlain)
            nMax = nMax-1
        end
        aRecord[nField] = self:sub(nStart)
    end

    return aRecord
end

---------------------------------------------------------------------
function read_csv(path, sep, tonum, null)
    tonum = tonum or true
    sep = sep or ','
    null = null or ''
    local csvFile = {}
    local file = assert(io.open(path, "r"))
    for line in file:lines() do
        fields = line:split(sep)
        if tonum then -- convert numeric fields to numbers
            for i=1,#fields do
                local field = fields[i]
                if field == '' then
                    field = null
                end
                fields[i] = tonumber(field) or field
            end
        end
        table.insert(csvFile, fields)
    end
    file:close()
    return csvFile
end

---------------------------------------------------------------------
function write_csv(path, data, sep)
    sep = sep or ','
    local file = assert(io.open(path, "w"))
    for i=1,#data do
        for j=1,#data[i] do
            if j>1 then file:write(sep) end
            file:write(data[i][j])
        end
        file:write('\n')
    end
    file:close()
end

----- Function Written By DrummerIX for creating our table to write to CSV
--------------------------------------------------------------------------
--- It expects a list of symbols to enumerate and get the current value of as a Qword
function create_symbol_table(list_of_symbols)

  local csvTable = {}
  for k,v in ipairs(list_of_symbols) do
	local SymbolPtr = getAddressSafe(v)
		
	if (SymbolPtr ~= nil) then
		if (SymbolPtr ~= 0) then
           if (ReadBytes(SymbolPtr) ~= nil) then
			  local line = v

			  for i=0,7 do
				  local CurrentByte = ReadBytes(SymbolPtr+i)

				  line = line .. "," .. string.format("%d",CurrentByte)
			  end
			
              local fields = line:split(",")
              for i=1,#fields do
                  local field = fields[i]
                  if field == '' then
                      field = null
                  end
                  fields[i] = tonumber(field) or field
              end
			  table.insert(csvTable, fields)
            end
		end
	end
  end

  return csvTable
end

----- Function Written By DrummerIX for writing our table to current memory
--------------------------------------------------------------------------
--- It expects a table either from reading a CSV or create_symbol_table function
--- to enumerate and write value of as a Qword
function write_symbol_table(table_of_symbols)

	for i=1,#table_of_symbols do
		local SymbolPtr = getAddressSafe(table_of_symbols[i][1])
		
		if (SymbolPtr ~= nil) then
			if (SymbolPtr ~= 0) then
				for j=2,9 do
					WriteBytes(SymbolPtr + (j-2),table_of_symbols[i][j])
				end
			end
		end
	end

end

--- Function by panraven dealing with enumerating current symbols
--- This is helper function because we sometimes don't need every symbol saved and loaded_csv_table
--- So this gets all symbols and you manually remove those you don't need
function printUserDefinedSymbols()
  local mv,sf = getMemoryViewForm()
  if not mv.frmSymbolhandler then
    local mvHidden
    if not mv.Visible then mvHidden=true,mv.Show() end
    mv.miuserdefinedsymbols:OnClick()
    if mvHidden then mv.hide()end
    sf = mv.frmSymbolhandler
    sf.Hide()
  else
    sf = mv.frmSymbolhandler
  end
  if sf ~= nil then
    local symbol
    for i = 0, sf.Listview1.Items.Count - 1 do
      symbol = sf.Listview1.Items.Item[i].Caption
      print('"' .. symbol .. '",')
    end
  end
end 

--- Function Written By DrummerIX for help in activating cheat records in the trainer app
--- It requires that hotkeys be defined for the cheats
--- It expects the name of the record to activate
function ActivateCheatRecord(mr_desc)

	local al = getAddressList()

	local mr = al.getMemoryRecordByDescription(mr_desc)
	
	if (mr ~= nil) then
		for i = 0,mr.HotkeyCount-1 do
			for j = 1,#mr.Hotkey[i].Keys do
				keyDown(mr.Hotkey[i].Keys[j])
			end
		end

		sleep(5)
		
		for i = 0,mr.HotkeyCount-1 do
			for j = 1,#mr.Hotkey[i].Keys do
				keyUp(mr.Hotkey[i].Keys[j])
			end
		end
		
		sleep(5)
	end
	
end

function CheckCheatRecordActive(mr_desc)

	local al = getAddressList()

	local mr = al.getMemoryRecordByDescription(mr_desc)
	
	if (mr ~= nil) then
		return mr.Active
	else
		return false
	end
	
end

function create_active_cheat_list_table()

	local al = getAddressList()
	
	local csvTable = {}

	for i = 0,al.Count-1 do
		if (al.MemoryRecord[i].Active) then
		   if not (string.find(al.MemoryRecord[i].Description,"Activate Trainer")) then
				local SaveThisRecord = true
				for j=1,#DoNotSaveDescriptions do
					if al.MemoryRecord[i].Description == DoNotSaveDescriptions[j] then
						SaveThisRecord = false
					end
				end
				if SaveThisRecord then
					line = al.MemoryRecord[i].Description
					  
					local fields = line:split(",")
					for i=1,#fields do
						local field = fields[i]
						if field == '' then
							field = null
						end
						fields[i] = tonumber(field) or field
					end
					table.insert(csvTable, fields)  
				end
		   end
		end
	end

	return csvTable
end

--- Code from Internet to deal with checking if folder exists
function exists(file)
   local ok, err, code = os.rename(file, file)
   if not ok then
      if code == 13 then
         -- Permission denied, but it exists
         return true
      end
   end
   return ok, err
end

function isdir(path)
   -- "/" works on both Unix and Windows
   return exists(path.."/")
end

-- Our function to create our save state folder
function CheckOurSaveStateFolder()
	local myFolder = os.getenv("USERPROFILE")
	
	local ourPath = myFolder .. sConfigSubFolder
	
	if (bUnableToCreateFolder == 0) then
		if not (isdir(myFolder .. sConfigSubFolder)) then
		   os.execute('mkdir ' .. ourPath)
		end
		
		if not (isdir(myFolder .. sConfigSubFolder)) then
		   bUnableToCreateFolder = 1
		   
		   local MyMessage = string.format("Save and Load Trainer Values will not function\n until you manually create the following folder\n" .. myFolder .. sConfigSubFolder)
		   showMessage(MyMessage)
		end		
	end
	
	return ourPath
end
-----------------------------------------------------------------

function onMemRecPostExecute(memoryrecord, newState, succeeded)

	for i=1,#PerformActivateList do
		if memoryrecord.Description == PerformActivateList[i] then
			table.remove(PerformActivateList,i)
		end
	end
	
	for j=1,#CurrentlyActivatingList do
		if memoryrecord.Description == CurrentlyActivatingList[j] then
			table.remove(CurrentlyActivatingList,j)
		end
	end

end

function StartSaveLoadTrainerValuesHandler()

	if (tTrainerValues ~= nil) then
		tTrainerValues.destroy()
	end
	
	tTrainerValues = createTimer(nil, false)
	tTrainerValues.OnTimer = function(fTrainerValues)
	
		-- Check If CurrentSlotDescriptions Is Empty and Initialize If So
		if #CurrentSlotDescriptions == 0 then
			InitializeConfigSlotDescriptions()
		end
		
		local baseFileName = nil
		
		if (process ~= nil) then
			if (string.find(string.reverse(process),"[.]") ~= nil) then
				baseFileName = string.sub(process,1,string.len(string.reverse(process))-string.find(string.reverse(process),"[.]"))	
			end
		end
		
		if (baseFileName ~= nil) then
			-- First, we check for saving values
			if (bPerformSaveTrainerValues == 1) then
				bPerformSaveTrainerValues = 0
				
				-- First, we save symbols
				local current_csv_table = create_symbol_table(SaveSymbolList)

				local ourFolder = CheckOurSaveStateFolder()
				local filename = ourFolder .. baseFileName .. '_Symbols_' .. string.format("%d",iSaveConfigSlot) .. '.txt'

				write_csv(filename,current_csv_table,",")
				
				-- Finally, we save current active cheat list
				local current_active_csv_table = create_active_cheat_list_table()
				
				local filename2 = ourFolder .. baseFileName .. '_Active_' .. string.format("%d",iSaveConfigSlot) .. '.txt'
				
				write_csv(filename2,current_active_csv_table,",")
			else
				if CheckCheatRecordActive("Save Current Trainer Values") then
					ActivateCheatRecord("Save Current Trainer Values")
				end	
			end

			-- Next, we check for loading symbol values which can only be done after loading and activating cheats
			if (bFinishedActivateTrainerCheats == 1) then
				if (bPerformLoadTrainerValues == 1) then
					bPerformLoadTrainerValues = 0
					
					local ourFolder = CheckOurSaveStateFolder()
					local filename = ourFolder .. baseFileName .. '_Symbols_' .. string.format("%d",iSaveConfigSlot) .. '.txt'
					
					if exists(filename) then
						local loaded_csv_table = read_csv(filename,",",true,null)

						if (loaded_csv_table ~= nil) then
							write_symbol_table(loaded_csv_table)
						end
					end
				end
			end

			-- Next, we check for loading and activating cheats
			if (bFinishedActivateTrainerCheats == 0) then
				if (bPerformActivateTrainerCheats == 1) then
					bPerformActivateTrainerCheats = 0

					local ourFolder = CheckOurSaveStateFolder()
					local filename = ourFolder .. baseFileName .. '_Active_' .. string.format("%d",iSaveConfigSlot) .. '.txt'
					
					if exists(filename) then
						local loaded_csv_table = read_csv(filename,",",true,null)

						if (loaded_csv_table ~= nil) then
							-- First, make sure list is empty
							for i=#PerformActivateList,1,-1 do
								table.remove(PerformActivateList,i)
							end
							
							for i=1,#loaded_csv_table do
								local CurrentDesc = ""
								for j=1,#loaded_csv_table[i] do
									if (j &gt; 1) then
										CurrentDesc = CurrentDesc .. "," .. loaded_csv_table[i][j]
									else
										CurrentDesc = CurrentDesc .. loaded_csv_table[i][j]
									end									
								end
								
								table.insert(PerformActivateList,CurrentDesc)
							end
						end	
					end
				end
			end				

			-- Finally, Loop Through The Current PerformActivateList and attempt to activate the cheat
			if (bFinishedActivateTrainerCheats == 0) then
				if (#PerformActivateList == 0) then
					bFinishedActivateTrainerCheats = 1
				else
					for i=1,#PerformActivateList do				
						if not CheckCheatRecordActive(PerformActivateList[i]) then
							if #CurrentlyActivatingList == 0 then
								ActivateCheatRecord(PerformActivateList[i])
								table.insert(CurrentlyActivatingList,PerformActivateList[i])
							end
						else
							table.remove(PerformActivateList,i)
						end
					end					
				end
			else
				if CheckCheatRecordActive("Load Current Trainer Values") then
					ActivateCheatRecord("Load Current Trainer Values")
				end	
			end
			
		end
		
	end
	tTrainerValues.Interval = 500
	tTrainerValues.Enabled = true

end

-- Actually Call Our Save and Load Handler function to start up the timer
StartSaveLoadTrainerValuesHandler()

------------------------------------------------------------------------------------------
</LuaScript>  
</CheatTable>