Jump to content

Open Community  ·  25 members

Far Cry

How to make rain more/less frequent [Tutorial]


aleeque

Recommended Posts

Allright, so basically JRavens (user JVarnes on the forums, the guy behind www.FarCryMods.com) figured out how to do it and apparently it's not at all hard to do if you are willing to spend some time.

 

You will need these three tools:

 

- HxD hex editor

- Notepad++

- Gibbed Dunia tools v1.79

 

We'll be assuming that you are playing Ziggy's mod. If not, scroll to the end of the tutorial.

 

Starty by extracting the Dunia tools to your desktop. Then go to your Far Cry 3 installation folder and locate the /data_win32/ subfolder. Drag and drop the patch.fat file onto the Dunia unpack tool. Then go to /patch_unpack/worlds/fc3_main/generated. There will be a file called fc3_main.managers.fcb. This is the file that controls rain frequency. Open it with the HxD hex editor.

 

Then download my (already edited) version of the file here: https://drive.google.com/file/d/1kbA5gQAEsfb07pJl5mZURp5xjPT8OfDA/view?usp=sharing
Open it in HxD as well. You now have these two files side by side so that you can compare the content. Like this: http://i.imgur.com/jwI9W0d.jpgPress ctrl-f and search for "Default:StormIntensity.Default" in both of these files. Now, tab between them a few times. Notice how these lines of code are slightly different in a few places? Those are the bytes that control weather.

 

Of course, you need to know what exactly to change. To do that, drag and drop your fc3_main.managers.fcb file (the one in your Ziggy's mod installation, not the one I provided) onto the Dunia ConvertBinaryObject tool. You will get some errors but there will be a file created called fc3_main.managers.fcb.converted. This is an .xml file that you are going to use for reference. You may ask: why not just edit the .xml file and convert it back to .fcb? Well, the answer is that the Dunia converting tool is broken and you'll get all sorts of glitches and bugs in-game if you do it. So the .xml file is just to help you track the values you've changed.

 

Now, open fc3_main.managers.fcb.converted.xml in Notepad++. Press ctrl-f and search for the "Default:StormIntensity.Default" tag. The values responsible for rain frequency are "fclearminimumtime", "fclearmaximumtime", "fstormminimumtime" and "fstormmaximumtime". It should look something like this: http://i.imgur.com/6nPJJl5.jpg

The numbers next to them are the amount of time clear weather / rainy weather can last. So for example, if you want rain to last forever, just edit "fclearminimumtime" and "fclearmaximumtime" to be 4 and 8 or some similar low numbers (again: the editing itself will NOT happen in the .xml file! It's only for reference). There are also some other attributes controlling "transition time" and "lighting intensity" but don't touch those. Only edit the four values above.

 

So now that you have your reference .xml file, go back to HxD. Tab between the two files again and note the bytes that are different in them. Now, change any of those bytes in the old (i.e. not the one you downloaded from me) fc3_main.managers.fcb file (but before that, copy the bit you changed so you can paste it back to revert the changes!) and save it. Now, convert it to .xml again and go back to Notepad++. Notice how it offers you to reload the file? Click "yes" and look at the weather controlling values. As you can see, they changed.

 

Now comes the hardest part: trial and error. Don't worry though, it took me an hour to completely figure out so you should be able to do it as well. The values are encoded in hexadecimal format, so remember that digits go as: 0 1 2 3 4 5 6 7 8 9 A B C D E F. Keep tweaking the numbers until the "fclearminimumtime", "fclearmaximumtime", "fstormminimumtime" and "fstormmaximumtime" in the .xml reference file look right to you.

 

Once you've found the right numbers, remove the .xml file and drag the /patch_unpack/ folder onto the Dunia pack tool. This will create two files in your FC3 /data_win32/ subfolder: "patch_unpack" and "patch_unpack.fat". Rename them to just "patch" and "patch.fat". That' it! Now run the game and play for a while to test the new weather. If you don't like it, go back to HxD and edit the value some more. Personally, I've changed them to be: 32 minimum clear time, 96 maximum clear time, 32 minimum storm time, 64 maximum storm time so this gives me about 60% clear weather and 40% rain. Of course, you are free to edit the values to your liking.

 

That's it. If you have any questions, let me know.

 

P.S. if you are not playing Ziggy's mod, there most likely won't be a fc3_main.managers.fcb file in your patch.fat. Simply copy and paste one there and it should work. And if you are not playing ANY mod at all (i.e.: you're playing Vanilla FC3), you should unpack common.fat instead of patch.fat. I haven't tried it but again, it should work.

Edited by aleeque
Link to comment
Share on other sites

  • 6 months later...
  • 3 months later...
  • 5 weeks later...
  • 6 months later...
  • 1 year later...

Good day (=

 

it´s been a while since this was actial, but any chance you could provide that file one more time? It seems like you have the only solution to change the weather in that game.

 

Thank you so much in advance mate (=

Link to comment
Share on other sites

  • 2 weeks later...
  • 1 month later...

This script for Python 3, you can modify the entire set of parameters:

fClearMinimumTime

fClearMaximumTime

fStormMinimumTime

fStormMaximumTime

fStormTransitionTime

fLightningIntensity

fLightningSpeed

fLightningMinimumTime

fLightningMaximumTime.

 

Help:

python weather_edit.py --help

or

weather_edit.exe --help

 

Sample:

weather_edit.exe -f dunia2-r179_b116\bin\patch_unpack\worlds\fc3_main\generated\ -cmnt 32 -cmxt 96 -smnt 30 -smxt 64

 

console out:

 

+----------------------------+------------------------------+

| tag | value |
+----------------------------+------------------------------+
| fClearMinimumTime | 375.0 -> 32.0 |
+----------------------------+------------------------------+
| fClearMaximumTime | 1875.0 -> 96.0 |
+----------------------------+------------------------------+
| fStormMinimumTime | 90.0 -> 30.0 |
+----------------------------+------------------------------+
| fStormMaximumTime | 270.0 -> 64.0 |
+----------------------------+------------------------------+
| fStormTransitionTime | 5.0 |
+----------------------------+------------------------------+
| fLightningIntensity | 24.0 |
+----------------------------+------------------------------+
| fLightningSpeed | 48.0 |
+----------------------------+------------------------------+
| fLightningMinimumTime | 2.0 |
+----------------------------+------------------------------+
| fLightningMaximumTime | 16.0 |
+----------------------------+------------------------------+
Backup is done
file successfully modified

 

weather_edit.py

import struct
import os
import argparse
import shutil

'''
        <object name="Template">
          <field name="text_NameId" type="String">Default:StormIntensity.Default</field> 
          <field name="NameId" type="Hash32">7BEA2B8D</field>                                           !!! + 0x06
          <field name="text_Template" type="String">{7137F442-9AFE-41C9-B41D-40142804CAF0}</field>
          <field name="Template" type="Hash32">223641C0</field>                                         !!! + 0x18
          <object name="Template">
            <field name="text_hid_DTCTH_ClassName" type="String">CEnvironmentWeather</field>
            <field name="hid_DTCTH_ClassName" type="Hash32">0D8EB6CE</field>                            !!! + 0x30
            <field name="fClearMinimumTime" type="Float32">60</field>                                   !!! + 0x39
            <field name="fClearMaximumTime" type="Float32">300</field>                                  !!! + 0x42
            <field name="fStormMinimumTime" type="Float32">120</field>                                  !!! + 0x4B
            <field name="fStormMaximumTime" type="Float32">270</field>                                  !!! + 0x54
            <field name="fStormTransitionTime" type="Float32">5</field>                                 !!! + 0x5D
            <field name="fLightningIntensity" type="Float32">24</field>                                 !!! + 0x66
            <field name="fLightningSpeed" type="Float32">48</field>                                     !!! + 0X6F
            <field name="fLightningMinimumTime" type="Float32">2</field>                                !!! + 0x78
            <field name="fLightningMaximumTime" type="Float32">16</field>                               !!! + 0x81
          </object>

'''

#Создаём парсер на командную строку скрипта
parser = argparse.ArgumentParser()
parser.add_argument('-f',    '--file', help="path to the file fc3_main.managers.fcb, you can specify a folder")
parser.add_argument('-cmnt', '--fClearMinimumTime',     type=float, help="fClearMinimumTime param")
parser.add_argument('-cmxt', '--fClearMaximumTime',     type=float, help="fClearMaximumTime param")
parser.add_argument('-smnt', '--fStormMinimumTime',     type=float, help="fStormMinimumTime param")
parser.add_argument('-smxt', '--fStormMaximumTime',     type=float, help="fStormMaximumTime param")
parser.add_argument('-stt',  '--fStormTransitionTime',  type=float, help="fStormTransitionTime param")
parser.add_argument('-li',   '--fLightningIntensity',   type=float, help="fLightningIntensity param")
parser.add_argument('-ls',   '--fLightningSpeed',       type=float, help="fLightningSpeed param")
parser.add_argument('-lmnt', '--fLightningMinimumTime', type=float, help="fLightningMinimumTime param")
parser.add_argument('-lmxt', '--fLightningMaximumTime', type=float, help="fLightningMaximumTime param")
parser.add_argument('-b', '--backup', action="store_true", help="no backup fc3_main.managers.fcb")
parser.add_argument('-r', '--reset', action="store_true", help="reset settings  to orginal fc3_main.managers.fcb")
arg = parser.parse_args()

if arg.file:
    fc3_main_managers_fcb =  ''.join(arg.file)  #Путь к файлу
    if "fc3_main.managers.fcb" not in fc3_main_managers_fcb:
        if fc3_main_managers_fcb[-1] != '\\':
            fc3_main_managers_fcb += '\\'
    if(os.path.split(fc3_main_managers_fcb)[1] == ""):
        fc3_main_managers_fcb = os.path.join(fc3_main_managers_fcb,"fc3_main.managers.fcb")
    if not os.path.exists(fc3_main_managers_fcb):
        print("You need to specify the path to the file fc3_main.managers.fcb, --help")
        raise SystemExit(1)
else:
    print("You need to specify the path to the file fc3_main.managers.fcb, --help")
    raise SystemExit(1)

if arg.reset:
    arg.fClearMinimumTime = 375.0
    arg.fClearMaximumTime = 1875.0
    arg.fStormMinimumTime = 90.0
    arg.fStormMaximumTime = 270.0
    arg.fStormTransitionTime = 5.0
    arg.fLightningIntensity = 24.0
    arg.fLightningSpeed = 48.0
    arg.fLightningMinimumTime = 2.0
    arg.fLightningMaximumTime = 16.0

#save data ro list
fields = []
fields.append(arg.fClearMinimumTime)
fields.append(arg.fClearMaximumTime)
fields.append(arg.fStormMinimumTime)
fields.append(arg.fStormMaximumTime)
fields.append(arg.fStormTransitionTime)
fields.append(arg.fLightningIntensity)
fields.append(arg.fLightningSpeed)
fields.append(arg.fLightningMinimumTime)
fields.append(arg.fLightningMaximumTime)

#fc3_main_managers_fcb = r'c:\Users\Tarshikov\Downloads\dunia2-r179_b116_\dunia2-r179_b116\bin\experements\fc3_main.managers.fcb'
namestruct = ['fClearMinimumTime', 'fClearMaximumTime', 'fStormMinimumTime', 'fStormMaximumTime', 'fStormTransitionTime','fLightningIntensity','fLightningSpeed','fLightningMinimumTime','fLightningMaximumTime']

format_struct = '<30s 57s f 5s f 5s f 5s f 5s f 5s f 5s f 5s f 5s f'
format_data = [2,4,6,8,10,12,14,16,18] # Нужные мне индексы

#StormIntensity = namedtuple('StormIntensity', ['fClearMinimumTime', 'fClearMaximumTime', 'fStormMinimumTime', 'fStormMaximumTime', 'fStormTransitionTime','fLightningIntensity','fLightningSpeed','fLightningMinimumTime','fLightningMaximumTime'])
with open(fc3_main_managers_fcb,'rb') as fcb_file:
    for i in range(os.path.getsize(fc3_main_managers_fcb) - struct.calcsize(format_struct)):
        fcb_file.seek(i)
        s = struct.unpack(format_struct,fcb_file.read(struct.calcsize(format_struct)))
        if s[0] == b'Default:StormIntensity.Default':
            break


    table_column1_len = len(max(namestruct)) + 8
    table_column2_len = 30

    #Формируем шапку
    print(f"+{'-'*table_column1_len}+{'-'*table_column2_len}+") 
    print(f"|{'tag'.center(table_column1_len)}|{'value'.center(table_column2_len)}|")
    print(f"+{'-'*table_column1_len}+{'-'*table_column2_len}+")
    
    #заполняем таблицу
    for counter in range(len(namestruct)):       
        if fields[counter] is not None:
            string = f"{str(s[format_data[counter]])} -> {fields[counter]}" if (fields[counter] != s[format_data[counter]]) else f"{str(s[format_data[counter]])}"
            print(f"|{namestruct[counter].center(table_column1_len)}|{string.center(table_column2_len)}|")
            
        else:
            print(f"|{namestruct[counter].center(table_column1_len)}|{str(s[format_data[counter]]).center(table_column2_len)}|")
        print(f"+{'-'*table_column1_len}+{'-'*table_column2_len}+")

    #Формируем файл, ушербно конечно но что поделать =)
    fcb_file.seek(i)
    data = bytearray(fcb_file.read(struct.calcsize(format_struct)))    
    struct.pack_into(format_struct,data,0,
    s[0],
    s[1],
    s[2] if ((fields[0] is None) or (fields[0] == s[2])) else fields[0],
    s[3],
    s[4] if ((fields[1] is None) or (fields[1] == s[4])) else fields[1],
    s[5],
    s[6] if ((fields[2] is None) or (fields[2] == s[6])) else fields[2],
    s[7],
    s[8] if ((fields[3] is None) or (fields[3] == s[8])) else fields[3],
    s[9],
    s[10] if ((fields[4] is None) or (fields[4] == s[10])) else fields[4],
    s[11],
    s[12] if ((fields[5] is None) or (fields[5] == s[12])) else fields[5],
    s[13],
    s[14] if ((fields[6] is None) or (fields[6] == s[14])) else fields[6],
    s[15],
    s[16] if ((fields[7] is None) or (fields[7] == s[16])) else fields[7],
    s[17],
    s[18] if ((fields[8] is None) or (fields[8] == s[18])) else fields[8]
    )

    #Создаём новый модифицированный файл
    with open(fc3_main_managers_fcb + "new",'wb') as fcb_file_new:
        fcb_file.seek(0) # Ставим на начало копируемого файла
        fcb_file_new.write(fcb_file.read(i)) #Копируем начало
        fcb_file_new.write(data)# Вставлям модифицированные данные
        fcb_file.seek(i+struct.calcsize(format_struct)) # Пропускаем данные которые модифицированли
        fcb_file_new.write(fcb_file.read(os.path.getsize(fc3_main_managers_fcb)))

#Делаем backup старого
print("\n\r")
if arg.backup == False:
    shutil.copy2(fc3_main_managers_fcb,fc3_main_managers_fcb[0:fc3_main_managers_fcb.rfind('.')] + '.backup')
    print("\tBackup is done")

os.remove(fc3_main_managers_fcb)
shutil.copy2(fc3_main_managers_fcb + "new",fc3_main_managers_fcb[0:fc3_main_managers_fcb.rfind('.')] + '.fcb')
os.remove(fc3_main_managers_fcb + "new")

print("\tfile successfully modified")
Edited by Dark0711
Link to comment
Share on other sites

  • 3 years later...
  • 11 months later...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...