Modding Civilization I - Grassland Pattern

Gowron

Chieftain
Joined
May 21, 2007
Messages
62
The Grassland pattern is far simpler than the Special Resources pattern.
To determine if a Grassland/River square provides a shield, the following steps are executed:

1. The shield output if Grassland/River is 1 by default.
2. Multiply the x-coordinate of the square by 7.
3. Multiply the y-coordinate of the square by 11.
4. Add the results from step 1 and step 2 together.
5. Treat the result of step 3 as a binary number. Check if the "2" bit is equal to 1. If yes, set the shield output to zero.

If you are not familiar with binary numbers, you can also determine the outcome of step 5 this way:
Reduce the result of step 3 modulo 4 (i.e. keep subtracting 4 from the result until it is between 0 and 3). If the resulting number is 2 or 3, then set the shield output to zero.


This results in the well-known shield pattern:
ooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxx
oxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxo
xxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxoo
xooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxoox
ooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxx
oxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxo
xxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxoo
xooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxoox
(and so on...)
For a more sophistic image, check the attached image here or any other ingame map picture.


Modifying the Pattern

This requires a unpacked .exe file, as described here. It would also be wise to rename the unpacked file to "Civ1.exe" and keep the original executable in the civ folder, since this should prevent the "Overlay not found" error from occuring.

There are actually two instances of the Grassland pattern. The first instance determines the shield output and is used for both Grassland and River squares. The second instance is just graphical and only used for Grassland squares. It decides if the square looks like "Grassland with shield" or "Grassland without shield".
This means some variables appear at two different positions.

multiplier for x-coordinate
default value: 0x07
first position: 0x161E1
second position: 0x1E0F4

multiplier for y-coordinate
default value: 0x0B (= 11)
first position: 0x161E9
second position: 0x1E0FC

shield output of Grassland/River "without shield"
default value: 0
position: 0x161F8
note: This value will only affect the shield output, not the graphics.

bit pattern for the bitwise comparison (bitwise "OR")
default value: 0x02
first position: 0x161F2
second position: 0x1E105
notes: This is probably the most important variable. Setting this to 0 will give you Grassland/River with shield everywhere. Setting it to 1 will create a chessboard pattern. Setting it to 0xFF (= 255) will give you Grassland/River without shield everywhere.
 
Thanks to Dack, Gowron, darkpanda, et al., my interest in Civ 1 has returned (I had been playing Civ 4 previously).

bit pattern for the bitwise comparison (bitwise "OR")
default value: 0x02
first position: 0x161F2
second position: 0x1E105
notes: This is probably the most important variable. Setting this to 0 will give you Grassland/River with shield everywhere. Setting it to 1 will create a chessboard pattern. Setting it to 0xFF (= 255) will give you Grassland/River without shield everywhere.

One thing that has bothered me about Civ 1 was that not all of the grasslands had the shields icon, and I had wondered how to change it. I am very grateful that Gowron had figured it out, but it looks like the offsets in his post are for the unpacked exe of version 475.01.

I think I found the corresponding locations for the packed exe (the original state), version 474.05. Luckily, the multipliers for the coordinates did not change between versions 1 and 5, so it was only a question of finding a hex string containing
"07 xx xx xx xx xx xx xx 0B xx xx xx xx xx xx xx xx 02",
where "xx" were unknown hex values. So, here are the locations for 474.05, packed:

multiplier for x-coordinate
default value: 0x07
first position: 0x13CCC
second position: 0x1B7BC

multiplier for y-coordinate
default value: 0x0B (= 11)
first position: 0x13CD4
second position: 0x1B7C4

bit pattern for the bitwise comparison (bitwise "OR")
default value: 0x02
first position: 0x13CDD
second position: 0x1B7CD

shield output of Grassland/River "without shield"
default value: 0
position: 0x13CE3

So, to change it so that the grassland with shield appears everywhere, change the "02" at 0x13CDD and 0x1B7CD to a "00":
Code:
Before:
offset 13CCC: [COLOR="Green"]07[/COLOR] 00 F7 6E  06 8B C8 B8  [COLOR="Green"]0B[/COLOR] 00 F7 6E  08 02 C8 F6  C1 [COLOR="Red"]02[/COLOR]
offset 1B7BC: [COLOR="Green"]07[/COLOR] 00 F7 6E  06 8B CB B8  [COLOR="Green"]0B[/COLOR] 00 F7 6E  08 02 C8 F6  C1 [COLOR="Red"]02[/COLOR]

After:
offset 13CCC: [COLOR="Green"]07[/COLOR] 00 F7 6E  06 8B C8 B8  [COLOR="Green"]0B[/COLOR] 00 F7 6E  08 02 C8 F6  C1 [COLOR="Blue"]00[/COLOR]
offset 1B7BC: [COLOR="Green"]07[/COLOR] 00 F7 6E  06 8B CB B8  [COLOR="Green"]0B[/COLOR] 00 F7 6E  08 02 C8 F6  C1 [COLOR="Blue"]00[/COLOR]
(The green bytes are the multipliers for the coordinates explained above.)

If you look at the attached city screen, it looks like it works. :)
 

Attachments

  • Civ1-City_View-0640x0400.png
    Civ1-City_View-0640x0400.png
    56.7 KB · Views: 276
Good job :)

It should be noted that, contrary to special resources, there isn't a dedicated routine to detect whether a map square should have a shield or not, but throughout CIV code, whenever necessary, the piece of code illustrated in previous posts is repeated.

One case not covered by Gowron and eumyang is the calculation of Land value, although for sure it does not affect the game as much as shield output.
 
Back
Top Bottom