Mod Tool/Scripting
< Mod Tool
Jump to navigation
Jump to search
build an vbs executable
Executable, app(lication), program. Whatever you call it, sometimes it might be necessary to compile the script into an actual program.
Even though vbs is a script language and not a programming language, it can be done.
VbsEdit is an editor to fulfill such task with ease.
- Just goto File > Convert into Executable. Choose output path, 32/64-bit version and hit OK.
OS bit version
if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then logmessage "64" else logmessage "32" end if
faster
Set WshShell = CreateObject("WScript.Shell") if instr(WshShell.RegRead("HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0\Identifier"), "x86") = 1 then logmessage "32" else logmessage "64" end if
read registry
Mod Tool (because 32-bit) fails to execute following code properly on 64-bit operation systems. So the code must be build as 64-bit and 32-bit application.
Set WshShell = CreateObject("WScript.Shell") AE_path = WshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{B67333BB-1CF9-4EFD-A40B-E25B5CB4C8A7}}_is1\InstallLocation") MsgBox AE_path Dim fso Set fso = CreateObject ("Scripting.FileSystemObject") txt_location = fso.GetAbsolutePathName(".") & "\AE_path.txt" Set wText = fso.CreateTextFile (txt_location, 1) wText.WriteLine AE_path wText.Close
read file
binary
scan_AKEV_file_table sub scan_AKEV_file_table ' ############################################## OniInputFile = "H:\Oni\AE\GameDataFolder\level1_Final\AKEVEnvWarehouse.oni" ' ############################################## Set OniInputFileStream = CreateObject("ADODB.Stream") OniInputFileStream.Type = 1 OniInputFileStream.Open OniInputFileStream.LoadFromFile OniInputFile ' ### read AKEV textures table offset and size ByteNum = 4 ' ############################################## TOffset = cLng("&H" & "28") ' ############################################## OniInputFileStream.Position = TOffset BArr1 = OniInputFileStream.Read(ByteNum) ByteNum = 4 ' ############################################## TSize = cLng ("&H" & "2C") ' ############################################## OniInputFileStream.Position = TSize BArr2 = OniInputFileStream.Read(ByteNum) ' ### get AKEV textures table offset and size TOffsetHex = SimpleBinaryToString(BArr1) for i = ubound(TOffsetHex ) - 1 to 0 step -1 newhex = newhex & hex(Asc(TOffsetHex(i))) next logmessage newhex logmessage "name table offset: " & cLng("&H" & newhex) TOffsetInt = cLng("&H" & newhex) newhex = "" TSizeHex = SimpleBinaryToString(BArr2) for i = ubound(TSizeHex) - 1 to 0 step -1 newhex = newhex & hex(Asc(TSizeHex(i))) next logmessage newhex logmessage "name table size: " & cLng("&H" & newhex) TSizeInt = cLng("&H" & newhex) logmessage "------------------------------" ' ### read table content ByteNum = TSizeInt OniInputFileStream.Position = TOffsetInt BArr3 = OniInputFileStream.Read(ByteNum) TContent = SimpleBinaryToString(BArr3) ' ### name grapper NG = "" for each n in TContent if not Asc(n) = 0 then NG = NG & n else 'if instr(NG, "TXMP") = 1 then ' write TXMP to array ? logmessage NG 'end if NG = "" end if next end sub Function SimpleBinaryToString(Binary) ReDim tmpArr(LenB(Binary) - 1) For I = 1 To LenB(Binary) S = Chr(AscB(MidB(Binary, I, 1))) tmpArr(I - 1) = S Next SimpleBinaryToString = tmpArr End Function
Output:
' INFO : 0E40 ' INFO : name table offset: 3648 ' INFO : 0A4A ' INFO : name table size: 2634 ' INFO : ------------------------------ ' INFO : AKEVEnvWarehouse ' INFO : AGDBEnvWarehouse ' INFO : TXMP_DOOR_FRAME ' INFO : TXMPNONE ' INFO : TXMPSUMI_1 ' INFO : TXMPTC_CONTROL_01 ' [...] ' INFO : TXMPWH_DCTRBND
modify file
binary
Change FilePath and in case of binary patching use function "StringToByteArray".
FilePath = "C:\path_to\AKEVEnvWarehouse.oni" ' ### create stream objects Set InputStream = CreateObject("ADODB.Stream") InputStream.Type = 1 InputStream.Open Set OutputStream = CreateObject("ADODB.Stream") OutputStream.Type = 1 OutputStream.Open ' ### load input stream from file InputStream.LoadFromFile FilePath ' ### copy first 16 signs of input stream to output stream OutputStream.Write InputStream.Read(16) ' ### apply patch ' # ASCII patching patch_data = "ABCD" patch_data_length = len(patch_data) ' patch_data_length = 4 InputStream.Position = InputStream.Position + patch_data_length OutputStream.Write CreateObject("System.Text.ASCIIEncoding").GetBytes_4(patch_data) ' # binary patching 'OutputStream.Write StringToByteArray("41424344") ' ### re-add data that was cut off OutputStream.Write InputStream.Read ' ### unloader InputStream.Close Set InputStream = Nothing ' ### modes: 2 = overwrite; 1 = dontoverwrite ' test: save to new file ' FilePath2 = "C:\path_to\AKEVEnvWarehouseB.oni" OutputStream.SaveToFile FilePath, 2 OutputStream.Close Set OutputStream = Nothing
Math
Euler rotation -> matrix
function cosn (n) cosn = cos(XSIMath.DegreesToRadians(n)) end function function sinn (n) sinn = sin(XSIMath.DegreesToRadians(n)) end function ' ################ logmessage "input" x = 60 : logmessage x y = 60 : logmessage y z = 60 : logmessage z logmessage "##################" logmessage "converted" set RotMatX = XSIMath.CreateMatrix3(1, 0, 0, 0, cosn(x), sinn(x), 0, -sinn(x), cosn(x)) set RotMatY = XSIMath.CreateMatrix3(cosn(y), 0, -sinn(y), 0, 1, 0, sinn(y), 0, cosn(y)) set RotMatZ = XSIMath.CreateMatrix3(cosn(z), sinn(z), 0, -sinn(z), cosn(z), 0, 0, 0, 1) RotMatZ.MulInPlace RotMatY RotMatZ.MulInPlace RotMatX for i=0 to 2 for j=0 to 2 logmessage RotMatZ (i, j) next next ' INFO : input ' INFO : 60 ' INFO : 60 ' INFO : 60 ' INFO : ################## ' INFO : converted ' INFO : 0,25 ' INFO : 0,808012701892219 ' INFO : 0,53349364905389 ' INFO : -0,433012701892219 ' INFO : -0,399519052838329 ' INFO : 0,808012701892219 ' INFO : 0,866025403784439 ' INFO : -0,433012701892219 ' INFO : 0,25
Matrix -> Euler rotation
Function Atan2(y, x) If x > 0 Then Atan2 = Atn(y / x) ElseIf x < 0 Then Atan2 = Sgn(y) * (XSIMath.PI - Atn(Abs(y / x))) ElseIf y = 0 Then Atan2 = 0 Else Atan2 = Sgn(y) * XSIMath.PI / 2 End If End Function function ToEuler(M00, M10, M20, M21, M22) a = M00 b = M10 dim c, s, r if b = 0 then c = Sgn(a) s = 0 r = Abs(a) elseif a = 0 then c = 0 s = Sgn(b) r = Abs(b) elseif Abs(b) > Abs(a) then t = a / b u = Sgn(b) * Sqr(1 + t * t) s = 1 / u c = s * t r = b * u else t = b / a u = Sgn(a) * Sqr(1 + t * t) c = 1 / u s = c * t r = a * u end if Z = -Atan2(s, c) Y = Atan2(M20, r) X = -Atan2(M21, M22) X = XSIMath.RadiansToDegrees(X) Y = XSIMath.RadiansToDegrees(Y) Z = XSIMath.RadiansToDegrees(Z) ToEuler = array(X, Y, Z) end function ' ################################ set RotMat = XSIMath.CreateMatrix3( _ 0.25, 0.808012701892219, 0.53349364905389, _ -0.433012701892219, -0.399519052838329, 0.808012701892219, _ 0.866025403784439, -0.433012701892219, 0.25 ) ' convert matrix to euler rotation and store values to array ReXYZ = ToEuler(RotMat(0,0), RotMat(1,0), RotMat(2,0), RotMat(2,1), RotMat(2,2)) logmessage "reconverted" logmessage ReXYZ(0) logmessage ReXYZ(1) logmessage ReXYZ(2) ' INFO : 60 ' INFO : 60 ' INFO : 60
Euler rotation -> quaternion
dim x, y, z, dRotation, qRotation x = 90 y = 0 z = 0 set dRotation = XSIMath.CreateRotation(XSIMath.DegreesToRadians(x), XSIMath.DegreesToRadians(y), XSIMath.DegreesToRadians(z)) set qRotation = XSIMath.CreateQuaternion() dRotation.GetQuaternion (qRotation) LogMessage qRotation.W LogMessage qRotation.X LogMessage qRotation.Y LogMessage qRotation.Z ' INFO : 0,707106781186548 ' INFO : 0,707106781186547 ' INFO : 0 ' INFO : 0 ' to calculate oni quaternions from euler rotations use this setup: ' LogMessage qRotation.X ' LogMessage qRotation.Y ' LogMessage qRotation.Z ' LogMessage qRotation.W * -1
Quaternion -> Euler rotation
dim qW, qX, qY, qZ, qRotation, x, y, z qW = 0.707106781186548 qX = 0.707106781186547 qY = 0 qZ = 0 set qRotation = XSIMath.CreateQuaternion (qW, qX , qY, qZ) qRotation.GetXYZAngleValues x, y, z logmessage XSIMath.RadiansToDegrees(x) logmessage XSIMath.RadiansToDegrees(y) logmessage XSIMath.RadiansToDegrees(z) ' INFO : 89,9999999999999 ' INFO : 0 ' INFO : 0 ' to calculate euler rotations from oni quaternions use this setup: 'qX = ... 'qY = ... 'qZ = ... 'qW = ... * -1 'set qRotation = XSIMath.CreateQuaternion (qW, qX, qY, qZ)
Conversions
String -> byte array
function StringToByteArray(ThisString) for i = 1 To Len(ThisString) Step 2 str = str & Chr("&h" & Mid(ThisString, i, 2)) next Set stream = CreateObject("ADODB.Stream") With stream .Open .CharSet = "Windows-1252" .Type = 2 ' ### 2 = text .WriteText str .Position = 0 .Type = 1 ' ### 1 = binary StringToByteArray = .Read .Close End With end function ' ### usage ByteArray = StringToByteArray(ThisString)
Byte array -> string
Function ByteArrayToString(Binary) 'Antonin Foller, http://www.motobit.com 'Optimized version of a simple BinaryToString algorithm. Dim cl1, cl2, cl3, pl1, pl2, pl3 Dim L cl1 = 1 cl2 = 1 cl3 = 1 L = LenB(Binary) Do While cl1<=L pl3 = pl3 & Chr(AscB(MidB(Binary,cl1,1))) cl1 = cl1 + 1 cl3 = cl3 + 1 If cl3>300 Then pl2 = pl2 & pl3 pl3 = "" cl3 = 1 cl2 = cl2 + 1 If cl2>200 Then pl1 = pl1 & pl2 pl2 = "" cl2 = 1 End If End If Loop BinaryToString = pl1 & pl2 & pl3 End Function ' ### usage MyString = ByteArrayToString(ByteArray)