Mod Tool/Scripting: Difference between revisions
< Mod Tool
Jump to navigation
Jump to search
Paradox-01 (talk | contribs) (there's a problem with reading some registry keys on a 64-bit OS with an 32-bit program) |
Paradox-01 (talk | contribs) (not a fan of VbsEdit (especially since testing the code is delayed to force annoyance onto the user to buy the god damn license) but it can compile scripts to a program) |
||
Line 1: | Line 1: | ||
===build an vbs executable=== | |||
[[Image:VbsEdit_for_scripting_and_compiling.png|thumb]] | |||
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=== | ===OS bit version=== | ||
if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then | if GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth = 64 then | ||
Line 27: | Line 38: | ||
wText.WriteLine AE_path | wText.WriteLine AE_path | ||
wText.Close | wText.Close | ||
===read file=== | |||
====as 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 | |||
Line 203: | Line 311: | ||
'qW = ... * -1 | 'qW = ... * -1 | ||
'set qRotation = XSIMath.CreateQuaternion (qW, qX, qY, qZ) | 'set qRotation = XSIMath.CreateQuaternion (qW, qX, qY, qZ) | ||
[[Category:Windows-only modding tools]] | [[Category:Windows-only modding tools]] |
Revision as of 21:09, 8 September 2014
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
as 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
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)