Is there a way to mod, or hack, or something to disable the automatic fail/success of rolling a 1 and 20? I know you can disable 1s for just saving throws, but I want this to apply to everything.
this is built in to the game engineâs standard combat behaviour, and there is no config option, such as with saving throws. you could conceivably hook the attack event using nwnx or otherwise handle parts of the attack round manually. afaik thereâs currently no nwnx function set that can change this aspect of combat, so youâd end up re-inventing the wheel. so unless this is very important to you and youâre willing to put in a lot of effort, i think the short answer to your question would be ânoâ.
Ah, too bad.
This wouldnât be too hard to do with nwnx. nwnx2 (for 1.69) development is mostly dead, though, so if you lack the skills to do it yourself, youâll need to motivate someone, likely from the nwnx:ee group. If anyone wants this for EE, they can just file a request at github.com/nwnxee/unified/issues
While is it already possible disable the 1 (auto fail) through nwnplayer.ini
isnât possible doing so with 20.
#Sherincall
I would really like a function that would allow to disable the automatic success (20).
A friend of mine already proposed this during a livestream, Trent Oster replied that it was possible to do so but did not say whether such work would be done in the future. So I think the only possibility is to do it through nwnx.
Beamdog simply does not have enough resources to implement and test all these requests. There has been a lot of âun-hardcodingâ going on lately, but whether any particular thing will be opened or not depends on low level state of the code that implements it.
Hereâs an example of things that have recently been opened up to customization:
https://gist.githubusercontent.com/Daztek/7e30bbe841e3c80ac1e416eacd2b3d07/raw/f183ea056a3c9dad1837c6afd581ccf3668b8171/ruleset.2da
Any more niche features that require such deep level changes are exactly why nwnx exists. Unfortunately for some, nwnx only works for dedicated servers, so it is not really usable in singleplayer
thx
Of course this is not a request from a person that is planning to create a SP module, quite the contrary it is needed to improve my old pw.
Oh, I wanted this to be used in singleplayer modules.
Also, the one at nwnplayer.ini only affects saving throws, doesnât work for other stuff.
I checked out the NWNX thing but it seemed fairly confusing, not sure if I can do it or even know where to start.
Maybe if you can tell us the âwhyâ of your request, we can figure out other options.
I just donât like getting hit with 50+ AC against mobs that only have 20 attack chance.
Whatât the point of fighting them then? There always needs to be a way for things to be at least a little bit dangerous. Seems boring.
If you have to ask that question, then whatever I say wonât satisfy you.
It could be very useful in a pvp server where critical failure (1) is already turned off,so in order to rebalance the game the admin may also need to disable the automatic success (20) .
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, probably not my guess.
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.
I have no idea if this will work in multiplayer, it may use a different function for that, not sure. Keep in mind everyone involved in the server should have it on, otherwise some unpredictable stuff will happen.
<?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>
Sorry for being off-topic, but I wished somebody determined enough would find a way (either via in-memory patch or by finding the right bytes in the binary) to make <StartHighlight>
change text color to yellow instead of that damn blue. Yes, I know it can be made green or red through stringtokens.2da
, but that doesnât help much.