Guest User

DS1 Bugged Soft Humanity Explanation

a guest
Nov 10th, 2019
2,010
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.64 KB | None | 0 0
  1. DS1 Bugged Soft Humanity Explanation
  2.  
  3. First, when the game needs to store integer values for use in event scripts, etc., it always uses an "event value", which means that a certain number of event flags are read as the binary representation of the number. This is stored big-endian, so the smallest flag gets the most significant bit. FROM represents an event value by the first event flag and the number of bits (i.e. the number of flags to use).
  4.  
  5. For example, if the first event flag is 5000 and the value has 4 bits, then to store 3 (which is 0011 in 4-bit binary), we need to set 5000 off, 5001 off, 5002 on, and 5003 on. 5000 is the 8's place, 5001 is the 4's place, 5002 is the 2's place, and 5003 is the 1's place.
  6.  
  7. The game stores each area's humanityPoint and humanityCount this way. The HumanityPointCountFlagIdTop field indicates where the two values are stored: a 16-bit value starting at that flag, and a 4-bit value starting at that flag+16. For example, the flag for Gwyn is 8940, so m18_00's humanityPoint is the 16-bit event value starting at 8940, and humanityCount is the 4-bit event value starting at 8956. This means the maximum of humanityPoint is 131071, and the maximum for humanityCount is 15.
  8.  
  9. In order for this system to work, the game *cannot* use these event flags for other purposes, since if we imagine that 8940 was used for something else, if it ever got flipped on when it was off, the humanityPoint value would increase by 2^16 = 65536. FROM is usually good about ensuring this type of thing never happens, although there's a slip-up in the DLC shop flags that messes with how many Gold Pine Resin are in Elizabeth's shop; the number of items remaining to purchase of a finitely-sold shop lot is stored in an event value.
  10.  
  11. As you can probably guess, something *is* interfering with these flags. Namely, the NPC soft humanity system. NPCs need to store how much soft humanity they have remaining in an event value so the game can keep track of it for use with the Dark Hand. When the "Register NPC Humanity Event Value" event script command is used, the game looks up the target entity's ChrInitParam entry to find their soft humanity and stores the result in an 8-bit event value starting at a specified flag. For example, the game registers Solaire's soft humanity at flag 8310, so his event value makes use of the flags 8310-8317.
  12. One quirk of this system is that the 128's bit is always set on, so even though Solaire has 5 soft humanity at the start of the game, the command sets the flags 8310, 8315, and 8317 (to make the binary value 10000101 = 133 = 128+5). This is probably because the 128's bit is being used as the sign bit, i.e. the value is actually representing -5 and increments toward 0 as the player steals soft humanity from Solaire.
  13.  
  14. Since these soft humanity registration commands are almost always run as soon as the area loads, it immediately clobbers the 8 flags and replaces them with the soft humanity value. The command runs every time the area is loaded, but from testing, it will only bother to update the flags if the sign bit is 0, i.e. the value is non-negative.
  15.  
  16. So, what is happening in, say, the Kiln?
  17.  
  18. The Kiln uses flag 8940 (16-bit) for humanityPoint and 8956 (4-bit) for humanityCount. There are a few NPCs that use a registration flag that overlap with these flag ranges:
  19.  
  20. Mildred (8 soft humanity) in m14_00, based at flag 8940,
  21. Leeroy (3 soft humanity) in m13_00 and m13_01, based at flag 8948, and
  22. Kirk (0 soft humanity) in m10_00 and m14_01, based at flag 8956.
  23.  
  24. Mildred sets the flags 8940-8947 to 10001000 (-8), which clobbers the Kiln humanityPoint value to read 10001000xxxxxxxx, which, if the previous value was below 256, has the effect of adding 34816.
  25. Leeroy sets the flags 8948-8956 to 10000011 (-3), which clobbers the Kiln humanityPoint value to read yyyyyyyy10000011,
  26. which, if the previous value was below 256, has the effect of setting it to 133.
  27. Kirk sets the flags 8956-8963 to 10000000 (-0), which clobbers the Kiln humanityCount value to read 1000, and also the four bits in flags 8960-8963 to be 0000, which isn't used for any area humanity things. This has the effect of setting the humanityCount value to 8.
  28.  
  29. Of course, these only occur if the sign bit of the NPC's flag is not 1. So if the player has 9 humanityCount, the value will *not* get set to 8 when Kirk is loaded, since Kirk's flag will read 10010000, which has the sign bit set. This also means that the player will suddenly be able to extract 16 soft humanity from Kirk once they reach 9 humanityCount in the Kiln. Unfortunately, there are no enemies that give soft humanity points in the Kiln.
  30.  
  31. How about Duke's?
  32.  
  33. Duke's uses flag 8920 (16-bit) for humanityPoint and 8936 (4-bit) for humanityCount. Again, there are a few NPCs whose humanity flags overlap:
  34.  
  35. Lautrec's Mage Summon (0 soft humanity) in m15_01, based at flag 8916,
  36. Tarkus (0 soft humanity) in m15_00, based at flag 8924, and
  37. Beatrice (0 soft humanity) in m12_00 and m16_00, based at flag 8932.
  38.  
  39. Lautrec's Mage Summon sets flags 8916-8923 to 10000000 (-0), which clobbers Duke's humanityPoint value to read 0000xxxxxxxxxxxx.
  40. Tarkus sets flags 8924-8931 to 10000000 (-0), which clobbers Duke's humanityPoint value to read yyyy10000000yyyy.
  41. Beatrice sets flags 8932-8939 to 10000000 (-0), which clobbers Duke's humanityPoint value to read zzzzzzzzzzzz1000 and the humanityCount to read 0000.
  42.  
  43. Loading the Undead Parish bonfire causes Tarkus and Beatrice to get loaded, which under most normal circumstances will write 2056 to the humanityPoint value and 0 to the humanityCount value. Notably, if the humanityPoint value has the 8's bit set before doing this, Beatrice's registration will not occur and the humanityCount value will not be set to 0.
  44.  
  45. Unfortunately, a cursory search of the registration commands reveals that no other NPC humanity values overlap with any other area humanity values, so it is unlikely other examples exist.
  46.  
  47. (In debug, use GAME > Event > NewEventFlag to see real-time event flag data. Set UseBitNum to the number of flags used by an event value, and the number next to the flag input line will compute the event value of that many bits starting at the flag that's been selected. Use DPadL and DPadR to select the digits of the flag on the first line, X to increment the digit, Triangle to decrement the digit. You can also place the cursor on the second line (<- ->) and use the standard debug scroll controls to scroll through the flags using DPadL and DPadR (+ L1 to move by 10s, + Square to move by 100s, + L1+Square to move by 1000s). If you want to quickly input an event value, set it in SetEventValue and press X to set all the flags at once. FlagReset resets every event flag in the game to 0.)
Add Comment
Please, Sign In to add comment