Will try to explain what is needed to add custom options to the random map mode in this guide. As an example let's add new 'additional options' for the diplomatic center: default - no diplomatic center - expensive mercenaries. 3 things are needed : 1) the actual code that makes the options work (scripts) , 2) making the options appear in the interface (gui) and 3) localisation for the languages. Notes: - You can name the new option whatever you want, as long as you use the same name everywhere. I used .limitdiplo in the example, you may as well call it .banana. But one typo and it won't work. - Line numbers below are indicators, these can change as gsc patches files. 1. Let's add entries to make this new option work. 1.1 Let's start by defining the names which we will use in all the files. Go to data\script\dmscript.global and add: Code: Line 1020 + gc_mapsettings_limitdiplo_default = 0; gc_mapsettings_limitdiplo_nodiplo = 1; gc_mapsettings_limitdiplo_expensivemercs = 2; Add a new value aswell for the price modifier for mercenaries which we'll use later on in the player.script Code: gc_gameplay_expensivemercskoef = 3; 1.2 Next, add the new limitdiplo to data\scripts\lib\classes.script Line 46 + Code: limitdiplo: Integer; 1.3 Next, go to data\scripts\lib\player.script : Find the cannons options somewhere around line 2664+ . Make sure the following matches the column of the option above (cannons). This states that if the diplo option isn't default then, 2 cases: no diplo or expensive mercs. In the case of no diplo, if the object usage is dipcenter then bproduceenabled is false, and in the case of expensive mercs, if the object is a bmercenary then multiply the price by the given value we put in dmscript.global above. Code: if (gMap.settings.additional.limitdiplo<>gc_mapsettings_limitdiplo_default) then begin for pl:=0 to gc_MaxPlayerCount-1 do begin for cid:=0 to gc_MaxCountryCount-1 do for id:=0 to gc_country_maxmembers-1 do begin pobjbase := gPlayer[pl].objbase[cid][id]; pobjprop := gObjProp[cid][id]; case gMap.settings.additional.limitdiplo of gc_mapsettings_limitdiplo_nodiplo : begin if (TObjProp(pobjprop).usage=gc_obj_usage_dipcenter) then begin TObjBase(pobjbase).bproduceenabled := False; var csid : String; _country_GetSIDByID(cid, csid); end; end; gc_mapsettings_limitdiplo_expensivemercs : begin if (TObjProp(pobjprop).bmercenary) then begin var res : Integer; for res:=0 to gc_ResCount-1 do TObjBase(pobjbase).price[res] := TObjBase(pobjbase).price[res]*gc_gameplay_expensivemercskoef; end; end; end; end; end; end; 2. We'll make the necessary entries now to make it appear in the GUI. 2.1 Go to data\gui\menu.inc\showcustomgame.inc : Adjust this value to however many new options are added. In our case of the no diplo +1 Line 557: Code: [*] = ;const cAdditionalSettingsCount = 7; // 6+1 Next, make sure to adjust the number in front if you stick it in the middle somewhere and the numbers below. Line 566: Code: [*] = ; 3 : textid := 'randommap.settings.limitdiplo'; Again adjust numbers below this option to match: Line 601: Code: [*] = ; 3 : begin [*] = ; case gMap.settings.additional.limitdiplo of [*] = ; gc_mapsettings_limitdiplo_default : s2 := 'default'; [*] = ; gc_mapsettings_limitdiplo_nodiplo : s2 := 'nodiplo'; [*] = ; gc_mapsettings_limitdiplo_expensivemercs : s2 := 'expensivemercs'; [*] = ; end; [*] = ; end; If you dont add expensive mercenaries and no diplo is the last option, then add this one here, if your last option is something else, add this here. Line 683 Code: [*] = ; 3 : begin [*] = ; textid := 'randommap.settings.limitdiplo'; [*] = ; count := gc_mapsettings_limitdiplo_expensivemercs+1; [*] = ; end; Line 745 Code: [*] = ; 3 : begin [*] = ; for i:=0 to gc_mapsettings_limitdiplo_expensivemercs do [*] = ; begin [*] = ; case i of [*] = ; gc_mapsettings_limitdiplo_default : s2 := 'default'; [*] = ; gc_mapsettings_limitdiplo_nodiplo : s2 := 'nodiplo'; [*] = ; gc_mapsettings_limitdiplo_expensivemercs : s2 := 'expensivemercs'; [*] = ; end; [*] = ; var text : String = GetLocaleTableListItemByID('gui', textid+'.'+s2); [*] = ; GUIListBoxAddItem(elmHnd, text, i); [*] = ; end; [*] = ; SetGUIListBoxItemIndexSilent(elmHnd, gMap.settings.additional.limitdiplo); [*] = ; end; 2.2 Next file, data\gui\menu.inc\eventcustomgame.inc Again, make sure to adjust the numbers of the options below this line if you put it at nr3. If you add it last, do so everywhere. Line 50: (ish) Code: [*] = ; 3 : gMap.settings.additional.limitdiplo := tag; 2.3 Next file to adjust: data\gui\menu.inc\initmapsettings.inc Line 20: Code: [*] = ; gMap.settings.additional.limitdiplo := 0; 2.4 Last file to get it to work: data\scripts\lib\miscext2.script Line 2075: Code: roomdata := roomdata+IntToStr(gMap.settings.additional.limitdiplo)+gc_gui_delimitercharstr; Line 2293: Code: 18 : map.settings.additional.limitdiplo := istr; // again adjust the numbers below. 3) Localisation: without it , the text won't show up in game. There are 3 versions of the language editor: An unofficial one which you can find on the c3 forums here ( it displays cyrillic, but you can't add new strings with it, so don't bother with this one for this example) , a standalone official language editor by gsc (get it here) and an inbuilt one in the editor.exe (which has slightly more options, but not required for this). The standalone version (editorlang.exe) will do just fine for this. You'll want to open it, and 'load' data/locale/en/gui.lng. Press the 'add' button and fill out the keys i posted below (or whichever names you used for your entries, eg randommap.settings.limitdiplo ) Press ok and fill out the 'translation' in english in the field. Do so for every line of options. Don't bother moving them up with the rest. Then go to File - save, and save as gui.lng and again go to File- and this time select the option 'save as .txt'. Code: randommap.settings.limitdiplo Diplomatic Center randommap.settings.limitdiplo.default Default randommap.settings.limitdiplo.nodiplo No Diplomatic Center randommap.settings.limitdiplo.expensivemercs Expensive Mercenaries If you did everything right you should have your new no diplo options in game: Questions? Ask!
4) Some extra information: 4.1 A bit more information about player.script: Spoiler Assuming you want to do something differently, perhaps disable another building/unit, you can find gc_obj_usages in data\scripts\lib\unit.script or data\scripts\lib\dmscript.global Code: gc_obj_usage_none = 0; // Default gc_obj_usage_mill = 1; gc_obj_usage_farm = 2; // Housing gc_obj_usage_center = 3; gc_obj_usage_storage = 4; gc_obj_usage_tower = 5; gc_obj_usage_field = 6; gc_obj_usage_mine = 7; gc_obj_usage_fasthorse = 8; gc_obj_usage_mortar = 9; // Howitzer gc_obj_usage_cannon = 10; gc_obj_usage_grenadier = 11; gc_obj_usage_hardwall = 12; // Stone Wall gc_obj_usage_weakwall = 13; // Wooden wall gc_obj_usage_battleship = 14; gc_obj_usage_weak = 15; gc_obj_usage_fisher = 16; gc_obj_usage_artdepo = 17; gc_obj_usage_supermortar = 18; // Mortar gc_obj_usage_port = 19; gc_obj_usage_lightinfantry = 20; gc_obj_usage_shooter = 21; gc_obj_usage_hardhorse = 22; gc_obj_usage_peasant = 23; gc_obj_usage_horseshooter = 24; gc_obj_usage_frigate = 25; gc_obj_usage_galley = 26; gc_obj_usage_yacht = 27; gc_obj_usage_xebec = 28; gc_obj_usage_transport = 29; gc_obj_usage_archer = 30; gc_obj_usage_mcannon = 31; // Multibarrel cannon gc_obj_usage_dipcenter = 32; Not every building/unit has a defined gc_obj_usage. For example mercenary units don't, as you can see above I've used .bmercenary which you can find back in units.script, or if for example you want to disable the market, use bmarket as in the code below: Code: if (gMap.settings.additional.limitmarket<>gc_mapsettings_limitmarket_default) then begin for pl:=0 to gc_MaxPlayerCount-1 do begin for cid:=0 to gc_MaxCountryCount-1 do for id:=0 to gc_country_maxmembers-1 do begin pobjbase := gPlayer[pl].objbase[cid][id]; pobjprop := gObjProp[cid][id]; case gMap.settings.additional.limitmarket of gc_mapsettings_limitmarket_nomarket : begin if (TObjProp(pobjprop).bmarket) then begin TObjBase(pobjbase).bproduceenabled := False; var csid : String; _country_GetSIDByID(cid, csid); end; end; end; end; end; end; Assuming you also want to disable some upgrades along with some units. Look at the following lines which disables every artillery piece and some of it's related artillery upgrades in the academy: Code: if (gMap.settings.additional.cannons<>gc_mapsettings_cannons_default) then begin for pl:=0 to gc_MaxPlayerCount-1 do begin for cid:=0 to gc_MaxCountryCount-1 do for id:=0 to gc_country_maxmembers-1 do begin pobjbase := gPlayer[pl].objbase[cid][id]; pobjprop := gObjProp[cid][id]; case gMap.settings.additional.cannons of gc_mapsettings_cannons_noartillery : begin if (TObjProp(pobjprop).usage=gc_obj_usage_cannon) or (TObjProp(pobjprop).usage=gc_obj_usage_mortar) or (TObjProp(pobjprop).usage=gc_obj_usage_supermortar) or (TObjProp(pobjprop).usage=gc_obj_usage_mcannon) then begin TObjBase(pobjbase).bproduceenabled := False; var csid : String; _country_GetSIDByID(cid, csid); var upgind : Integer = _country_GetUpgradeIndexByUpgradeID(cid, csid+'art.cannon.1.1', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'art.cannon.2.1', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'art.howitzer.1.1', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'art.howitzer.2.1', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'aca.18', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'aca.19', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'aca.20', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'aca.21', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; upgind := _country_GetUpgradeIndexByUpgradeID(cid, csid+'aca.27', False); if (upgind>-1) then gPlayer[pl].upgstate[cid, upgind].enabled := False; end; end; gc_mapsettings_cannons_expensivecannons : begin if (TObjProp(pobjprop).bartillery) then begin var res : Integer; for res:=0 to gc_ResCount-1 do TObjBase(pobjbase).price[res] := TObjBase(pobjbase).price[res]*gc_gameplay_expensivecannonskoef; end; end; end; end; end; end; Finding the id's for the academy upgrades is easy: look in data\scripts\dmglobal.script or in data\scripts\lib\country.script The unit upgrades are a bit more tricky. They aren't written in full anywhere, but the format is "upgradeplace.member.id" So 'art.howitzer.1.1' is in the artillery depot for the howitzer and is the first top upgrade, while 2.1 is the bottom upgrade. Since these upgrades are linked, you only need to disable the first one. 4.2 Language editor and cyrillic (non latin languages) Spoiler The official language editor doesn't display cyrillic and the unofficial language editor doesnt allow to add new entries, only edit them. So, here's how to get around it and make adjustments to the russian/ukrainian language files: Go to Editor.exe -> Modules -> Locale table -> Choose table -> Edit selected table -> File -> Save as TXT Next open the text file you just saved in your preferred text editor (I use sublime text ), go to File -> Reopen with encoding -> Cyrillic (Windows 1251). It will now display cyrillic properly. Edit the text file with your new entries. File -> Save with encoding -> Cyrillic (Windows 1251) Back to the editor.exe -> Modules -> Locale table -> Load as .txt -> Select your edited file -> Save as .lng 4.3 Some pointers on files involved in other random map options: Spoiler - Map Shape : data\game\var\generator.cfg, data\gen\terrainmasks\, data\gen\terrainmasks.src\, data\script\dmscript.global, data\scripts\common.inc\dogenerate.inc - Peace Time: data\scripts\lib\misc.script, data\gui\menu.inc\showcustomgame.inc, - Start Options : data\game\var\startingsettings.cfg , data\script\dmscript.global, data\gui\menu.inc\showcustomgame.inc - Resource options: data\scripts\lib\serial.script, data\scripts\common.inc\initmapgen.inc, - Map Size : see post below in this thread.
There are 2 or 3 separate size "options" in the dmscript.global file but I'm not sure if they really do anything.
I have tried to modify that file but it looks like it freezes when generating the new map. Specifically at the generating hills and mountains stage. I know that there are other files that need to be edited but I dont know what files.
Assuming you want to increase the mapsize, doubt anyone would want to make it smaller than it already is. We'll go with an increase in the example ( 640 -> 720 ) and calling it "Carlos Size" 1. data\scripts\dmscript.global Line 48 : Adjust following values Code: gc_idlegrid_mapwidth = 720; gc_idlegrid_mapheight = 720; gc_idlegrid_countx = 900;//gc_idlegrid_mapwidth*1.25; gc_idlegrid_county = 900;//gc_idlegrid_mapheight*1.25; gc_scangrid_mapwidth = 720; gc_scangrid_mapheight = 720; gc_resgrid_mapwidth = 720; gc_resgrid_mapheight = 720; gc_soundgrid_mapwidth = 720; gc_soundgrid_mapheight = 720; gc_terraindata_mapwidth = 720; gc_terraindata_mapheight = 720; Line 125 Code: gc_MaxMapWidth = 720; gc_MaxMapHeight = 720; 2. data\scripts\common.inc\dogenerate.inc Code: Line 430 [*] = ; const cMapSize = 720; Line 1298 Code: [*] = ;if (mapW<>720) or (mapH<>720) then [*] = ; var modifier : Float = (720/((mapW+mapH)/2)); 3. data\scripts\common.inc\generatemap.inc Line 618 Code: [*] = ; const cWaterMapArrSize = (720 div cWaterFieldSize); Line 657 Code: [*] = ; var mapsizemod : Float = (cWaterMapArrSize/((720/mapheight)*2))*cWaterFieldSize; // var mapsizemod : Float = (cWaterMapArrSize div ((720 div mapheight)*2))*cWaterFieldSize; Line 684 Code: [*] = ; var tmpPatternMask : array [0..720-1] of array [0..720-1] of Boolean; 4. data\scripts\common.inc\postprocess.inc Line 35 Code: [*] = ;var mask : array [0..720-1] of array [0..720-1] of TColor; [*] = ;var maskTmp : array [0..720-1] of array [0..720-1] of TColor; 5. data\scripts\common.inc\smoothtiles.inc Line 27 Code: [*] = ;var atilemap : array [0..720] of array [0..720] of Integer; 6. data\scripts\lib\misc.script Line 3260 Code: procedure _misc_StandPatternPlaceMask(patName : String; standX, standZ, angle : Float; var tmpPatternMask : array [0..719] of array [0..719] of Boolean); 7. gui\menu.inc\donewgame.inc Line 6 Code: [*] = ;const cMapSize = 720; Line 36 Code: [*] = ;case gMap.settings.gen.mapsize of [*] = ; 0 : genMapSize := 320; [*] = ; 1 : genMapSize := 480; [*] = ; 2 : genMapSize := 640; [*] = ; 3 : genMapSize := 720; [*] = ; else [*] = ; genMapSize := 320; [*] = ;end; 8. gui\menu.inc\showcustomgame.inc Line 124 Code: [*] = ;procedure FillComboBoxMapSize(elmHnd : Integer); [*] = ;begin [*] = ; var cTextSizeNormal, cTextSizeLarge, cTextSizeHuge, CTextSizeCarlosSized : String; [*] = ; _misc_GetNewTextLocale('map.size.normal', cTextSizeNormal); [*] = ; _misc_GetNewTextLocale('map.size.large', cTextSizeLarge); [*] = ; _misc_GetNewTextLocale('map.size.huge', cTextSizeHuge); [*] = ; _misc_GetNewTextLocale('map.size.carlossize', cTextSizeCarlosSized); [*] = ; var i : Integer; [*] = ; if (GetGUIListBoxItemsCount(elmHnd)=0) then [*] = ; begin [*] = ; GUIListBoxAddItem(elmHnd, cTextSizeNormal, 0); [*] = ; GUIListBoxAddItem(elmHnd, cTextSizeLarge, 1); [*] = ; GUIListBoxAddItem(elmHnd, cTextSizeHuge, 2); [*] = ; GUIListBoxAddItem(elmHnd, cTextSizeCarlosSized, 3); [*] = ; SetGUIListBoxItemIndexSilent(elmHnd, 0); [*] = ; end; [*] = ;end; 9. Localisation. Mapsize strings for english are in /data/locale/needloc/new.lng Other languages in /data/locale/xx/new.lng See to guide in first post how to use Language editor. Add string: Code: map.size.carlossize Carlos Size Note: Scrollbar or not. 10. gui\menu.inc\showcustomgame.inc Line 552 No scroll bar : Code: [*] = ;elmHnd := _gui_CreateComboBox('mapsize', elmMain, 4, 0, gc_halParentLeft, gc_valParentTop, 805+cAddOffsetL, 103+ind*cOffY, 145, gc_halLeft, gc_valMiddle, 5, 0, gc_font_serif_12, bAllowChange, eventstate, bupdate, True); Scrollbar : Code: [*] = ;elmHnd := _gui_CreateComboBox('mapsize', elmMain, 3, 0, gc_halParentLeft, gc_valParentTop, 805+cAddOffsetL, 103+ind*cOffY, 145, gc_halLeft, gc_valMiddle, 5, 0, gc_font_serif_12, bAllowChange, eventstate, bupdate, True); Without scroll bar for this option is better I think. Took a long time to generate the map, because of the size. Especially the forest stage. I hope you have a good computer. I didn't thoroughly test this, it's very well possible I forgot to change something somewhere, but it works on first glance.
Thank you for that information I appreciate it. I made the changes and It is weird. When I change the values to 645 it takes very long time to create. When I change it back to normal (640) everything is ok. There is not big difference.
Yeah, 640->645 isn't a big increase, hardly noticeable. About the slow creating time. I remember reading in a patch note they optimized something in regards to terrain generation. It's very well possible I read over it in the files and didn't include it in my changes above.