Skip to content

Made a "mod" to remove natural 20s.

deama2deama2 Member Posts: 4
edited September 2019 in General Modding
So I just don't like the idea of natural 1s and 20s, so is there a way to make it so that when you roll a 1 it turns it into a 2, and if you roll 20 it turns it into a 19? Or maybe just disable the concept of natural 1s and 20s and treat them normally? So it's not an automatic success or fail.

EDIT:
Alright guys, so I worked it out, made a "mod" that removes natural 20s, for everyone. You have to use cheat engine, so just copy the below into a .txt file, rename it to a .ct file and open it with cheat engine. There should be two boxes at the bottom, tick the one that says "no natural 20s", not the other one. This will only work on the diamond edition, I have no idea if it will work in the enhanced one, maybe.

Also, keep in mind, this works by finding out if the roll was a 20, then changing it to a 19 before any checks are done to it. So if you have a weapon that will only crit on 20s, then sorry, you can't crit anymore, though the chance to crit won't be affected if it's 19-20, sorry, couldn't be asked to fix this part.
<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="26">
<CheatEntries>
<CheatEntry>
<ID>0</ID>
<Description>"old, don't touch"</Description>
<LastState/>
<VariableType>Auto Assembler Script</VariableType>
<AssemblerScript>[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
pop edx
pop ebx
pop eax
mov eax,#18
jmp exit

originalcode:
and eax,00007FFF

push eax
push ebx
push edx
mov ebx,#20
div ebx
cmp edx,#19
je newmem
pop edx
pop ebx
pop eax

exit:
jmp returnhere

"nwmain.exe"+44C118:
jmp originalcode
returnhere:


[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"nwmain.exe"+44C118:
and eax,00007FFF
//Alt: db 25 FF 7F 00 00
</AssemblerScript>
</CheatEntry>
<CheatEntry>
<ID>1</ID>
<Description>"no natural 20s"</Description>
<LastState Activated="1"/>
<VariableType>Auto Assembler Script</VariableType>
<AssemblerScript>{ Game : nwmain.exe
Version:
Date : 2019-09-10
Author : deama

This script does blah blah blah
}

[ENABLE]

aobscanmodule(INJECT,nwmain.exe,25 FF 7F 00 00 C3) // should be unique
alloc(newmem,$1000)

label(code)
label(return)

newmem:
pop edx
pop ebx
pop eax
mov eax,#18
jmp return


code:
and eax,00007FFF
///////////////////////////
push eax
push ebx
push edx
mov ebx,#20
div ebx
cmp edx,#19
je newmem
pop edx
pop ebx
pop eax
///////////////////////////
jmp return

INJECT:
jmp code
return:
registersymbol(INJECT)

[DISABLE]

INJECT:
db 25 FF 7F 00 00

unregistersymbol(INJECT)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "nwmain.exe"+44C118

"nwmain.exe"+44C0F4: 8B 4C 24 04 - mov ecx,[esp+04]
"nwmain.exe"+44C0F8: 89 48 14 - mov [eax+14],ecx
"nwmain.exe"+44C0FB: C3 - ret
"nwmain.exe"+44C0FC: E8 B2 3C 00 00 - call nwmain.exe+44FDB3
"nwmain.exe"+44C101: 8B 48 14 - mov ecx,[eax+14]
"nwmain.exe"+44C104: 69 C9 FD 43 03 00 - imul ecx,ecx,000343FD
"nwmain.exe"+44C10A: 81 C1 C3 9E 26 00 - add ecx,00269EC3
"nwmain.exe"+44C110: 89 48 14 - mov [eax+14],ecx
"nwmain.exe"+44C113: 8B C1 - mov eax,ecx
"nwmain.exe"+44C115: C1 E8 10 - shr eax,10
//
INJECTING HERE
"nwmain.exe"+44C118: 25 FF 7F 00 00 - and eax,00007FFF
//
DONE INJECTING
"nwmain.exe"+44C11D: C3 - ret
"nwmain.exe"+44C11E: CC - int 3
"nwmain.exe"+44C11F: CC - int 3
"nwmain.exe"+44C120: 83 EC 08 - sub esp,08
"nwmain.exe"+44C123: DD 14 24 - fst qword ptr [esp]
"nwmain.exe"+44C126: E8 1D 71 00 00 - call nwmain.exe+453248
"nwmain.exe"+44C12B: E8 0D 00 00 00 - call nwmain.exe+44C13D
"nwmain.exe"+44C130: 83 C4 08 - add esp,08
"nwmain.exe"+44C133: C3 - ret
"nwmain.exe"+44C134: 8D 54 24 04 - lea edx,[esp+04]
}
</AssemblerScript>
</CheatEntry>
</CheatEntries>
<CheatCodes>
<CodeEntry>
<Description>Change of test ebp,ebp</Description>
<Address>0064A295</Address>
<ModuleName>nwmain.exe</ModuleName>
<ModuleNameOffset>24A295</ModuleNameOffset>
<Before>
<Byte>6C</Byte>
<Byte>24</Byte>
<Byte>40</Byte>
<Byte>75</Byte>
<Byte>3D</Byte>
</Before>
<Actual>
<Byte>85</Byte>
<Byte>ED</Byte>
</Actual>
<After>
<Byte>74</Byte>
<Byte>39</Byte>
<Byte>66</Byte>
<Byte>8B</Byte>
<Byte>45</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>Change of jne nwmain.exe+24A2B9</Description>
<Address>0064A2AC</Address>
<ModuleName>nwmain.exe</ModuleName>
<ModuleNameOffset>24A2AC</ModuleNameOffset>
<Before>
<Byte>FF</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>3B</Byte>
<Byte>C1</Byte>
</Before>
<Actual>
<Byte>75</Byte>
<Byte>0B</Byte>
</Actual>
<After>
<Byte>BF</Byte>
<Byte>01</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>Change of call dword ptr [edx+7C]</Description>
<Address>006BF170</Address>
<ModuleName>nwmain.exe</ModuleName>
<ModuleNameOffset>2BF170</ModuleNameOffset>
<Before>
<Byte>56</Byte>
<Byte>55</Byte>
<Byte>57</Byte>
<Byte>8B</Byte>
<Byte>C8</Byte>
</Before>
<Actual>
<Byte>FF</Byte>
<Byte>52</Byte>
<Byte>7C</Byte>
</Actual>
<After>
<Byte>E9</Byte>
<Byte>CB</Byte>
<Byte>FE</Byte>
<Byte>FF</Byte>
<Byte>FF</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>Change of mov eax,[esp+10]</Description>
<Address>7754DEC0</Address>
<ModuleName>ntdll.dll</ModuleName>
<ModuleNameOffset>2DEC0</ModuleNameOffset>
<Before>
<Byte>35</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Before>
<Actual>
<Byte>8B</Byte>
<Byte>44</Byte>
<Byte>24</Byte>
<Byte>10</Byte>
</Actual>
<After>
<Byte>89</Byte>
<Byte>6C</Byte>
<Byte>24</Byte>
<Byte>10</Byte>
<Byte>8D</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>Change of call nwmain.exe+44FDB3</Description>
<Address>0084C0FC</Address>
<ModuleName>nwmain.exe</ModuleName>
<ModuleNameOffset>44C0FC</ModuleNameOffset>
<Before>
<Byte>04</Byte>
<Byte>89</Byte>
<Byte>48</Byte>
<Byte>14</Byte>
<Byte>C3</Byte>
</Before>
<Actual>
<Byte>E8</Byte>
<Byte>B2</Byte>
<Byte>3C</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Actual>
<After>
<Byte>8B</Byte>
<Byte>48</Byte>
<Byte>14</Byte>
<Byte>69</Byte>
<Byte>C9</Byte>
</After>
</CodeEntry>
</CheatCodes>
<UserdefinedSymbols/>
<Structures StructVersion="2">
<Structure Name="unnamed structure" AutoFill="0" AutoCreate="1" DefaultHex="0" AutoDestroy="0" DoNotSaveLocal="0" RLECompression="1" AutoCreateStructsize="4096">
<Elements>
<Element Offset="0" Vartype="4 Bytes" Bytesize="4" RLECount="404" DisplayMethod="Unsigned Integer"/>
</Elements>
</Structure>
</Structures>
<Comments>Info about this table:
</Comments>
</CheatTable>
Post edited by deama2 on

Comments

  • ArviaArvia Member Posts: 2,101
    In the nwnplayer.ini file you can go to Server Options and set the value for automatic failure on a rolled 1 to 0.
    I don't think the same option exists for a 20.
    I also don't know if it affects only your own rolls or also those of your opponents.
  • deama2deama2 Member Posts: 4
    edited September 2019
    Arvia wrote: »
    In the nwnplayer.ini file you can go to Server Options and set the value for automatic failure on a rolled 1 to 0.
    I don't think the same option exists for a 20.
    I also don't know if it affects only your own rolls or also those of your opponents.

    Does this work in singleplayer games? Also, there's only "Saving Throw Automatic Failure", so does it only work for saving throws?
    Post edited by deama2 on
  • ArviaArvia Member Posts: 2,101
    edited September 2019
    It works, I don't play multiplayer games.

    But you're right, it only works for saving throws, not attacks or other rolls. I forgot, sorry.

    But it's at least a bit better. It's incredibly frustrating if you have, for example, a paladin's saving throws with Charisma buffed to Torm knows how much, and the beholders still get you, because eventually you *will* roll a 1.

    Edit: I think the natural 20 is okay, by the way. Imagine having an extremely high AC and nobody, except perhaps a dragon, can ever land a lucky hit on you. That would make the game quite boring. But that's just my opinion.
  • deama2deama2 Member Posts: 4
    Idk, I just feel like a lvl 20 monk should only have a 0.1% chance of ever being hit by a lvl 8 fighter for example.
  • deama2deama2 Member Posts: 4
    Alright guys, so I worked it out, made a "mod" that removes natural 20s, for everyone. You have to use cheat engine, so just copy the below into a .txt file, rename it to a .ct file and open it with cheat engine. There should be two boxes at the bottom, tick the one that says "no natural 20s", not the other one. This will only work on the diamond edition, I have no idea if it will work in the enhanced one, maybe.

    Also, keep in mind, this works by finding out if the roll was a 20, then changing it to a 19 before any checks are done to it. So if you have a weapon that will only crit on 20s, then sorry, you can't crit anymore, though the chance to crit won't be affected if it's 19-20, sorry, couldn't be asked to fix this part.
    <?xml version="1.0" encoding="utf-8"?>
    <CheatTable CheatEngineTableVersion="26">
    <CheatEntries>
    <CheatEntry>
    <ID>0</ID>
    <Description>"old, don't touch"</Description>
    <LastState/>
    <VariableType>Auto Assembler Script</VariableType>
    <AssemblerScript>[ENABLE]
    //code from here to '[DISABLE]' will be used to enable the cheat
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)

    newmem: //this is allocated memory, you have read,write,execute access
    pop edx
    pop ebx
    pop eax
    mov eax,#18
    jmp exit

    originalcode:
    and eax,00007FFF

    push eax
    push ebx
    push edx
    mov ebx,#20
    div ebx
    cmp edx,#19
    je newmem
    pop edx
    pop ebx
    pop eax

    exit:
    jmp returnhere

    "nwmain.exe"+44C118:
    jmp originalcode
    returnhere:


    [DISABLE]
    //code from here till the end of the code will be used to disable the cheat
    dealloc(newmem)
    "nwmain.exe"+44C118:
    and eax,00007FFF
    //Alt: db 25 FF 7F 00 00
    </AssemblerScript>
    </CheatEntry>
    <CheatEntry>
    <ID>1</ID>
    <Description>"no natural 20s"</Description>
    <LastState Activated="1"/>
    <VariableType>Auto Assembler Script</VariableType>
    <AssemblerScript>{ Game : nwmain.exe
    Version:
    Date : 2019-09-10
    Author : deama

    This script does blah blah blah
    }

    [ENABLE]

    aobscanmodule(INJECT,nwmain.exe,25 FF 7F 00 00 C3) // should be unique
    alloc(newmem,$1000)

    label(code)
    label(return)

    newmem:
    pop edx
    pop ebx
    pop eax
    mov eax,#18
    jmp return


    code:
    and eax,00007FFF
    ///////////////////////////
    push eax
    push ebx
    push edx
    mov ebx,#20
    div ebx
    cmp edx,#19
    je newmem
    pop edx
    pop ebx
    pop eax
    ///////////////////////////
    jmp return

    INJECT:
    jmp code
    return:
    registersymbol(INJECT)

    [DISABLE]

    INJECT:
    db 25 FF 7F 00 00

    unregistersymbol(INJECT)
    dealloc(newmem)

    {
    // ORIGINAL CODE - INJECTION POINT: "nwmain.exe"+44C118

    "nwmain.exe"+44C0F4: 8B 4C 24 04 - mov ecx,[esp+04]
    "nwmain.exe"+44C0F8: 89 48 14 - mov [eax+14],ecx
    "nwmain.exe"+44C0FB: C3 - ret
    "nwmain.exe"+44C0FC: E8 B2 3C 00 00 - call nwmain.exe+44FDB3
    "nwmain.exe"+44C101: 8B 48 14 - mov ecx,[eax+14]
    "nwmain.exe"+44C104: 69 C9 FD 43 03 00 - imul ecx,ecx,000343FD
    "nwmain.exe"+44C10A: 81 C1 C3 9E 26 00 - add ecx,00269EC3
    "nwmain.exe"+44C110: 89 48 14 - mov [eax+14],ecx
    "nwmain.exe"+44C113: 8B C1 - mov eax,ecx
    "nwmain.exe"+44C115: C1 E8 10 - shr eax,10
    //
    INJECTING HERE
    "nwmain.exe"+44C118: 25 FF 7F 00 00 - and eax,00007FFF
    //
    DONE INJECTING
    "nwmain.exe"+44C11D: C3 - ret
    "nwmain.exe"+44C11E: CC - int 3
    "nwmain.exe"+44C11F: CC - int 3
    "nwmain.exe"+44C120: 83 EC 08 - sub esp,08
    "nwmain.exe"+44C123: DD 14 24 - fst qword ptr [esp]
    "nwmain.exe"+44C126: E8 1D 71 00 00 - call nwmain.exe+453248
    "nwmain.exe"+44C12B: E8 0D 00 00 00 - call nwmain.exe+44C13D
    "nwmain.exe"+44C130: 83 C4 08 - add esp,08
    "nwmain.exe"+44C133: C3 - ret
    "nwmain.exe"+44C134: 8D 54 24 04 - lea edx,[esp+04]
    }
    </AssemblerScript>
    </CheatEntry>
    </CheatEntries>
    <CheatCodes>
    <CodeEntry>
    <Description>Change of test ebp,ebp</Description>
    <Address>0064A295</Address>
    <ModuleName>nwmain.exe</ModuleName>
    <ModuleNameOffset>24A295</ModuleNameOffset>
    <Before>
    <Byte>6C</Byte>
    <Byte>24</Byte>
    <Byte>40</Byte>
    <Byte>75</Byte>
    <Byte>3D</Byte>
    </Before>
    <Actual>
    <Byte>85</Byte>
    <Byte>ED</Byte>
    </Actual>
    <After>
    <Byte>74</Byte>
    <Byte>39</Byte>
    <Byte>66</Byte>
    <Byte>8B</Byte>
    <Byte>45</Byte>
    </After>
    </CodeEntry>
    <CodeEntry>
    <Description>Change of jne nwmain.exe+24A2B9</Description>
    <Address>0064A2AC</Address>
    <ModuleName>nwmain.exe</ModuleName>
    <ModuleNameOffset>24A2AC</ModuleNameOffset>
    <Before>
    <Byte>FF</Byte>
    <Byte>00</Byte>
    <Byte>00</Byte>
    <Byte>3B</Byte>
    <Byte>C1</Byte>
    </Before>
    <Actual>
    <Byte>75</Byte>
    <Byte>0B</Byte>
    </Actual>
    <After>
    <Byte>BF</Byte>
    <Byte>01</Byte>
    <Byte>00</Byte>
    <Byte>00</Byte>
    <Byte>00</Byte>
    </After>
    </CodeEntry>
    <CodeEntry>
    <Description>Change of call dword ptr [edx+7C]</Description>
    <Address>006BF170</Address>
    <ModuleName>nwmain.exe</ModuleName>
    <ModuleNameOffset>2BF170</ModuleNameOffset>
    <Before>
    <Byte>56</Byte>
    <Byte>55</Byte>
    <Byte>57</Byte>
    <Byte>8B</Byte>
    <Byte>C8</Byte>
    </Before>
    <Actual>
    <Byte>FF</Byte>
    <Byte>52</Byte>
    <Byte>7C</Byte>
    </Actual>
    <After>
    <Byte>E9</Byte>
    <Byte>CB</Byte>
    <Byte>FE</Byte>
    <Byte>FF</Byte>
    <Byte>FF</Byte>
    </After>
    </CodeEntry>
    <CodeEntry>
    <Description>Change of mov eax,[esp+10]</Description>
    <Address>7754DEC0</Address>
    <ModuleName>ntdll.dll</ModuleName>
    <ModuleNameOffset>2DEC0</ModuleNameOffset>
    <Before>
    <Byte>35</Byte>
    <Byte>00</Byte>
    <Byte>00</Byte>
    <Byte>00</Byte>
    <Byte>00</Byte>
    </Before>
    <Actual>
    <Byte>8B</Byte>
    <Byte>44</Byte>
    <Byte>24</Byte>
    <Byte>10</Byte>
    </Actual>
    <After>
    <Byte>89</Byte>
    <Byte>6C</Byte>
    <Byte>24</Byte>
    <Byte>10</Byte>
    <Byte>8D</Byte>
    </After>
    </CodeEntry>
    <CodeEntry>
    <Description>Change of call nwmain.exe+44FDB3</Description>
    <Address>0084C0FC</Address>
    <ModuleName>nwmain.exe</ModuleName>
    <ModuleNameOffset>44C0FC</ModuleNameOffset>
    <Before>
    <Byte>04</Byte>
    <Byte>89</Byte>
    <Byte>48</Byte>
    <Byte>14</Byte>
    <Byte>C3</Byte>
    </Before>
    <Actual>
    <Byte>E8</Byte>
    <Byte>B2</Byte>
    <Byte>3C</Byte>
    <Byte>00</Byte>
    <Byte>00</Byte>
    </Actual>
    <After>
    <Byte>8B</Byte>
    <Byte>48</Byte>
    <Byte>14</Byte>
    <Byte>69</Byte>
    <Byte>C9</Byte>
    </After>
    </CodeEntry>
    </CheatCodes>
    <UserdefinedSymbols/>
    <Structures StructVersion="2">
    <Structure Name="unnamed structure" AutoFill="0" AutoCreate="1" DefaultHex="0" AutoDestroy="0" DoNotSaveLocal="0" RLECompression="1" AutoCreateStructsize="4096">
    <Elements>
    <Element Offset="0" Vartype="4 Bytes" Bytesize="4" RLECount="404" DisplayMethod="Unsigned Integer"/>
    </Elements>
    </Structure>
    </Structures>
    <Comments>Info about this table:
    </Comments>
    </CheatTable>
Sign In or Register to comment.