One of the main problems with events is that they tend to be very rigidly scripted things, this is okay for clearly time based events ( e.g. the appearence of the Hussites ) but tends to get trickier for more random events like e.g. "Noble grants military aid" or "Merchants ask for additional investments"
Depending on the time that these events are triggered they might have very different effects
you can hardly have a Noble sending you levy spearmen and peasant archers in 1740
or be expected to pay 10.000 florins to invest in trade on turn 3
and you don't want events to be identical every time either!
Now a first step I took in dealing with this is by using some sort of division over the different ages via "if" statements. Wich is a most logical step as each historic period had it's own problems and advancements. However it still left a lot to be desired since I wanted the development of the region and of the nation to affect the outcome of the events.
A nation that invested heavily in it's merchants should reap the benefits of this when a merchant event came along. And a very Feudal oriented nation should get other units that a nation that is constantly working on the professionalism of it's armies. All in all I wanted to shift more power to the players choices.
Also last but not least I want to be able to tweak my events rather easily should they appear to be too expensive or cheap or produce toomuch men etc.
To do this without adding like 80-100 lines of if statements per event x 50 ish events per county x 106 counties was my goal and this is what I came up with.
I decided for a more centralised approach wich allowed me to do achieve everything I wanted. it all revolves around a serie of while loops wich get incorperated into the monitor aswel.
How does it work?
Up until now I've used a direct way to include the event effects by putting them straight into the monitor like so.
Code:
monitor_event EventCounter EventCounterType RandomMerchantEvent1
set_event_counter RandomMerchantEvent1_accepted 0
set_counter LocalRandomMerchantEvent 0
console_command add_money 3000
if RandomPercent < 30
console_command add_money 1500
end_if
end_monitor
Typing out everything for every event, now this is going to change as I'm introducing a new counter "ExtraIncomeMerchants" and replace all the entries like so:
Code:
monitor_event EventCounter EventCounterType RandomMerchantEvent1
set_event_counter RandomMerchantEvent1_accepted 0
set_counter LocalRandomMerchantEvent 0
inc_counter ExtraIncomeMerchants 6
end_monitor
I do this for all the events so essentially there isn't a single "strict" number in there anymore. Then I add this piece of script:
Code:
while I_CompareCounter ExtraIncomeMerchant > 0
if I_TurnNumber =< 150
generate_random_counter RandomNumber 1-8
end_if
if I_TurnNumber > 150
generate_random_counter RandomNumber 5-12
end_if
so this gives me a random number based on what turn it is wich allows me to make things more expensive later in the game. All kinds of other things can be included here aswel. Now lets include the mercantile power of our nation into the equation by doing this:
-Note that <1 is the worst outcome and >12 is the best-
Code:
if I_CompareCounter LocalMerchants < 5
inc_counter RandomNumber -1
end_if
if I_CompareCounter LocalMerchants < 12
inc_counter RandomNumber -1
end_if
if I_CompareCounter LocalMerchants > 28
inc_counter RandomNumber 1
end_if
if I_CompareCounter LocalMerchants > 35
inc_counter RandomNumber 1
end_if
if I_CompareCounter LocalMerchants > 50
inc_counter RandomNumber 1
end_if
Really anything you want you can put it in there, kept track of howmany fairs a nation has? why not put it in there, merchant charters etc etc it's up to you!
Now next up is the actual earning of money all I still have to do is this:
Code:
if I_CompareCounter RandomNumber = 1
console_command add_money 237
end_if
if I_CompareCounter RandomNumber = 2
console_command add_money 346
end_if
...
if I_CompareCounter RandomNumber > 12
console_command add_money 1278
end_if
inc_counter ExtraIncomeMerchant -1
end_while
By doing this the script will just keep repeating these steps until you run out of your acumulated extra income counters and then move on ( this really shouldn't take more than a fraction of a second).
These same steps can be used for practically anything, from creating units based on your timeline to unforseen extra expenses.
Choosing a city script
Say you want a player to be able to choose in wich city he wants to build a certain event based building or you want to rally all the nobles from a region in a given province etc. This script will be what you need basically. It lets you pick the city you want on the map. It consists of 2 things, the first gives you some time to decide, the second logs your decision.
The decider works as follows:
Code:
historic_event Decide_Drydock_Antwerp_Bruges_London
while I_EventCounter Decide_Drydock_Antwerp_Bruges_London_accepted = 0
and I_EventCounter Decide_Drydock_Antwerp_Bruges_London_declined = 0
end_while
it's basically a pauser, it tells you what you can decide between and as long as you don't close the scroll you can look around. As soon as you do you move on to the second part. you can incorperate the event text in her too.
"Commissioning of a Royal drydock
My lord our navies are falling behind we must increase the size of our fleet our naval engineers have already determined 3 suitable sites for it. do you wish to build it? take some time to look at the possible locations Antwerp, Bruges and London if you decide to build it you will have to decide wich of these cities it will be in.
Followed by the unit specifications.
Accept/Decline"
Code:
if I_EventCounter Decide_Drydock_Antwerp_Bruges_London_accepted = 1
while I_EventCounter Decide_Drydock_Antwerp_Bruges_London_accepted = 1
if I_SettlementSelected = Antwerp
-effects for Antwerp-
set_event_counter Decide_Drydock_Antwerp_Bruges_London_accepted = 0
end_if
if I_SettlementSelected = Bruges
-effects for Bruges-
set_event_counter Decide_Drydock_Antwerp_Bruges_London_accepted = 0
end_if
if I_SettlementSelected = London
-effects for London-
set_event_counter Decide_Drydock_Antwerp_Bruges_London_accepted = 0
end_if
end_while
end_if
if I_EventCounter Decide_Drydock_Antwerp_Bruges_London_declined = 1
-declined effects-
end_if
It might be wise to add some sort of notification to show that the city has been picked to start. Also you should make sure that the 3 regions actually belong to the local player ( I just collect the data anyway I'll include how in the Data collection section )
That's how easy it is, I've been experimenting with the "flash settlement" command but it doesn't seem to be functioning if anyone has got this to work let me know as it would make a great addition to this script. As it would allow additional criteria to be added.
Random pick with extra criteria
We have used the "generate_random_counter" several times now and it's a great kingdoms addition to our event scripting toolbox and only has one minor drawback. The lack of a possibility to add extra conditionals to your choice this is however very easily fixed with the following script:
Example:
We want some sort of advanced trade building to be offered in a random position. What we don't want however is it being placed in some backwater province in the middle of nowhere. let's assume that we only have 4 provinces in the entire world to show the principle.
data already collected for the example: Merchant power in the various cities
-note this is just to show how the general idea of this script works to actually use this event it will need more development-
Code:
generate_ random_counter RandomNumber 1 4
while I_CompareCounter RandomNumber != 0
Another while loop, these things are godsends really. It will need one entry for every city you wish it to pick from. They should look like this:
Code:
if I_CompareCounter RandomNumber = 1
if I_CompareCounter AntwerpMerchants < 20
inc_counter RandomNumber 1
end_if
if I_CompareCounter AntwerpMerchants > 20
-effects for Antwerp-
set_counter RandomNumber 0
end_if
end_if
Principle is easy enough if the city corresponding with the random number doesn't have an adequate merchant base the script will move on to the next one. Now the last entry in the list should be slightly different:
Code:
if I_CompareCounter RandomNumber = 4
if I_CompareCounter ChampagneMerchants < 20
set_counter RandomNumber 1
end_if
if I_CompareCounter ChampagneMerchants > 20
-effects for Champagne-
set_counter RandomNumber 0
end_if
end_if
end_while
This all is followed by the obvious end while. So if you get to the last city ( either by it being picked randomly or because the previous one wasn't elegible)
There are 2 options
a) The last city is elegible and RandomNumber is set to 0, the end_while is reached and the script moves on
b) The last city is not elegible and RandomNumber is set to 1, the end_while is reached and the script starts reading at the beginning of the while loop again.
Additional comments
Now the more perceptive modder will have already spotted a flaw in this little script:
what happens if none of the cities are elegible? Well the way it is written now it will loop around until the sun explodes ( or you stop playing M2TW wichever comes first).
I'll discuss 2 options to solve this problem, there are others ways but they are basically all variations of these 2.
Option 1:
Probably the easiest one is to just have atleast 1 city that is always elegible, perhaps your capital or something. Some examples:
I want my home province to be able to be picked, just add this lines to the appropriate entry in the loop
Code:
if I_CompareCounter RandomNumber = 1
if I_CompareCounter LondonMerchants < 20
inc_counter RandomNumber 1
end_if
if I_CompareCounter LondonMerchants > 20
and I_LocalFaction != england
-effects for London-
set_counter RandomNumber 0
end_if
if I_LocalFaction == england
-effects for London-
set_counter RandomNumber 0
end_if
end_if
You could also add an extra option for "lesser" home provinces wich gives them a procentual chance to be picked despite not meeting the criteria. Favoritism all the way!
Be careful with the positioning though the "set_counter RandomNumber 0" has to be below the "inc_counter RandomNumber 1" otherwise the script will pick 2 places!!
Code:
if I_CompareCounter RandomNumber = 1
if I_CompareCounter NottinghamMerchants < 20
inc_counter RandomNumber 1
if I_LocalFaction == england
and RandomPercent < 51
-effects for Nottingham-
set_counter RandomNumber 0
end_if
end_if
if I_CompareCounter NottinghamMerchants > 20
-effects for Nottingham-
set_counter RandomNumber 0
end_if
end_if
Option 2:
The lack of a suitable city means the effect is just not run. This might not be very convenient for an event but could be when using this script to trigger things. What will you need to do ? Firstly we'll need a new counter, I'll call it "RandomTracker".
It should always be set to 0 before a loop using it starts! Now every time we go over a city and it's not elegible this tracker should be increased by 1.
Code:
set_counter RandomTracker 0
while I_CompareCounter RandomNumber != 0
Code:
if I_CompareCounter RandomNumber = 1
if I_CompareCounter AntwerpMerchants < 20
inc_counter RandomNumber 1
inc_counter RandomTracker 1
end_if
if I_CompareCounter AntwerpMerchants > 20
-effects for Antwerp-
set_counter RandomNumber 0
end_if
end_if
Then we'll need to add this piece of script under the final entry. Where "
n" is the number of entries.
This will end the loop once every entry has been found inelegible atleast once.
Code:
if I_CompareCounter RandomTracker > n
set_counter RandomNumber 0
end_if