I would like an event to occur every turn, and also having occurred when a game starts, since it may add region modifiers (hence my question on that and its icons).
The wiki on Empires modding says, under Adding Events:
If you copied an existing scenario as above, your scenario should already contain a DATA\SCRIPTS\Events_Plugin.BSF containing one function, Event_EntryPoint(). Standard Empires events are found the Data\scripts\Events.BSF in the game installation folder. You may refer to the events in this file as a reference when creating events. At the bottom of Events_Plugin, create a new function for your event, this function will be called at the end of each turn and will determine if the event should occur, what factions are affected, and apply the gameplay effects of the event.
Does this mean that the first time that these functions are called are at the end of the first turn, or will they also be called when the game starts?
If the latter, how can I ensure that it is also called before the game starts?
Events occurring every turn and at game start?
Moderator: Pocus
-
kronenblatt
- General - Carrier

- Posts: 4772
- Joined: Mon Jun 03, 2019 4:17 pm
- Location: Stockholm, SWEDEN
Events occurring every turn and at game start?
kronenblatt's campaign and tournament thread hub:
https://www.slitherine.com/forum/viewtopic.php?t=108643
https://www.slitherine.com/forum/viewtopic.php?t=108643
Re: Events occurring every turn and at game start?
Looking at the code, it seems in the current version you can't do what you ask in the ideal way. Ideally the system should be expanded so you could have code triggering at scenario start...
For now so, you will have to edit directly the common file Events.bsf
I would suggest you create custom functions at the end of this file, bearing your name, like Event_KB_BlahBlah
Then you can add these functions here:
Events_TriggerAtStart(scenarioID)
See that for TriggerAtStart, there are 3 sections depending of the scenario. For CheckEachTurn, the test on how relevant the event is, is done in the function itself (no particular reason!), so be sure your event is either working in all scenarios, or exclude the ones that don't fit (including Pyrrhus).
For now so, you will have to edit directly the common file Events.bsf
I would suggest you create custom functions at the end of this file, bearing your name, like Event_KB_BlahBlah
Then you can add these functions here:
Events_TriggerAtStart(scenarioID)
See that for TriggerAtStart, there are 3 sections depending of the scenario. For CheckEachTurn, the test on how relevant the event is, is done in the function itself (no particular reason!), so be sure your event is either working in all scenarios, or exclude the ones that don't fit (including Pyrrhus).
AGEOD Team - Makers of Kingdoms, Empires, ACW2, WON, EAW, PON, AJE, RUS, ROP, WIA.
-
kronenblatt
- General - Carrier

- Posts: 4772
- Joined: Mon Jun 03, 2019 4:17 pm
- Location: Stockholm, SWEDEN
Re: Events occurring every turn and at game start?
I actually put it in the SCENARIO.BSF file, calling upon my event under FUNCTION StartTurn(). This worked!
So now the event is run at the beginning of every turn. Only question is: will the modifiers make a difference, given that duration is 1 and hence the modifers only last that one turn? I.e., may the modifers disappear before manpower, gold, etc is calculated and changed?
kronenblatt's campaign and tournament thread hub:
https://www.slitherine.com/forum/viewtopic.php?t=108643
https://www.slitherine.com/forum/viewtopic.php?t=108643
Re: Events occurring every turn and at game start?
I don't put events in StartTurn, because all events trigger at end of turn, so they factor what happened during the turn. Admittedly, The StartTurn of n+1 happens just after the end turn of turn n, but a few things will have changed in-between nonetheless. For example Aging and Progress is done after all events are processed, to take into account what happened during events. Turn number is incremented after events. So your StartTurn is shifted one turn.
For what you do I don't think it matters much, but that's not a practice I like a lot.
Now, checking again, I see that in SCENARIO.BSF, which is a file custom to each scenario, you can add also stuff in InitScenario, so you can trigger the initial check here, given this function is calling
Events_TriggerAtStart(gTurnInfos.scenarioID);
This will amount to the same.
As for the recurring call, you can call it in Event_EntryPoint (file Events_Plugin.BSF)
Doing it this way will emulate the closest as possible what I do / when I do it.
I checked your mod, it is working fine, nice job.
I see one issue and one optimization though in EventCustom_RemoteRegionModifiers
The first issue is that if you happen to have no capital, then you get no penalties whereas I guess you should get some (perhaps not the max one, or you are adding insult to injury and it will be very difficult to recover from the loss of your capital).
The optimization (tied to the issue) is that you can call once Faction_Politic_CountCapitals(factionID) outside the region loop, if there is none, no need to iterate over all regions and calc each time the closest capital, just give to them all the penalty for capital missing.
I think it would be phrased better if the wording was 'is located remotely' and not 'is located remote', but minor point.
For what you do I don't think it matters much, but that's not a practice I like a lot.
Now, checking again, I see that in SCENARIO.BSF, which is a file custom to each scenario, you can add also stuff in InitScenario, so you can trigger the initial check here, given this function is calling
Events_TriggerAtStart(gTurnInfos.scenarioID);
This will amount to the same.
As for the recurring call, you can call it in Event_EntryPoint (file Events_Plugin.BSF)
Doing it this way will emulate the closest as possible what I do / when I do it.
I checked your mod, it is working fine, nice job.
I see one issue and one optimization though in EventCustom_RemoteRegionModifiers
The first issue is that if you happen to have no capital, then you get no penalties whereas I guess you should get some (perhaps not the max one, or you are adding insult to injury and it will be very difficult to recover from the loss of your capital).
The optimization (tied to the issue) is that you can call once Faction_Politic_CountCapitals(factionID) outside the region loop, if there is none, no need to iterate over all regions and calc each time the closest capital, just give to them all the penalty for capital missing.
I think it would be phrased better if the wording was 'is located remotely' and not 'is located remote', but minor point.
AGEOD Team - Makers of Kingdoms, Empires, ACW2, WON, EAW, PON, AJE, RUS, ROP, WIA.
-
kronenblatt
- General - Carrier

- Posts: 4772
- Joined: Mon Jun 03, 2019 4:17 pm
- Location: Stockholm, SWEDEN
Re: Events occurring every turn and at game start?
The InitScenario worked perfectly: thanks!Pocus wrote: ↑Tue Jun 09, 2020 7:36 am I don't put events in StartTurn, because all events trigger at end of turn, so they factor what happened during the turn. Admittedly, The StartTurn of n+1 happens just after the end turn of turn n, but a few things will have changed in-between nonetheless. For example Aging and Progress is done after all events are processed, to take into account what happened during events. Turn number is incremented after events. So your StartTurn is shifted one turn.
For what you do I don't think it matters much, but that's not a practice I like a lot.
Now, checking again, I see that in SCENARIO.BSF, which is a file custom to each scenario, you can add also stuff in InitScenario, so you can trigger the initial check here, given this function is calling
Events_TriggerAtStart(gTurnInfos.scenarioID);
This will amount to the same.
As for the recurring call, you can call it in Event_EntryPoint (file Events_Plugin.BSF)
Doing it this way will emulate the closest as possible what I do / when I do it.
However, the recurring trigger of the event from Event_EntryPoint (i.e., at end of turn) seems to run into a problem when a modifier with a duration of 1 turn is added: they simply disappear when the turn shifts to the next turn and are no longer visible unfortunately.
So with triggering the event in InitScenario and then Event_EntryPoint will result in that the modifiers are in place just during the first turn and then never again (given a duration of 1 turn).
Maybe should go for the 999 duration after all?
Thanks. Something like this maybe, please see below (but if I use 999 duration, I'll have to remove modifiers actively as well of course.)Pocus wrote: ↑Tue Jun 09, 2020 7:36 am I checked your mod, it is working fine, nice job.
I see one issue and one optimization though in EventCustom_RemoteRegionModifiers
The first issue is that if you happen to have no capital, then you get no penalties whereas I guess you should get some (perhaps not the max one, or you are adding insult to injury and it will be very difficult to recover from the loss of your capital).
The optimization (tied to the issue) is that you can call once Faction_Politic_CountCapitals(factionID) outside the region loop, if there is none, no need to iterate over all regions and calc each time the closest capital, just give to them all the penalty for capital missing.
I think it would be phrased better if the wording was 'is located remotely' and not 'is located remote', but minor point.
Code: Select all
FUNCTION EventCustom_RemoteRegionModifiers()
{
int facCount;
int facIndex;
int factionID;
int regCount;
int regIndex;
int regionID;
int capitalID;
int capCount;
// Iterate over all factions
facCount = GetNumFactions();
for (facIndex = 0; facIndex < facCount; facIndex++)
{
factionID = GetFactionID(facIndex);
capCount = Faction_Politic_CountCapitals(factionID); // COUNTING NUMBER OF CAPITALS AND THUS CHECKING WHETHER THERE ARE ANY CAPITALS AT ALL
// Iterate over all regions of a faction
regCount = GetNumOwnedRegions(factionID);
for (regIndex = 0; regIndex < regCount; regIndex++)
{
regionID = GetOwnedRegionID(factionID, regIndex);
if ( capCount > 0 )
{
if ( Region_HasNationalCapitol(factionID, regionID) == FALSE) // Checking so that the region is not a capital, because otherwise there is no meaning to check distance
{
capitalID = Faction_Politic_NearestCapitalID(factionID, regionID);
if ( gResult >= EVTCUSTOM_REMOTEREGION_DISTANCE_I && gResult < EVTCUSTOM_REMOTEREGION_DISTANCE_II )
{
Region_AddModifier(regionID, $ID_MOD_REGION_CUSTOM_REMOTEREGION_I);
}
else if ( gResult >= EVTCUSTOM_REMOTEREGION_DISTANCE_II && gResult < EVTCUSTOM_REMOTEREGION_DISTANCE_III )
{
Region_AddModifier(regionID, $ID_MOD_REGION_CUSTOM_REMOTEREGION_II);
}
else if ( gResult >= EVTCUSTOM_REMOTEREGION_DISTANCE_III && gResult < EVTCUSTOM_REMOTEREGION_DISTANCE_IV )
{
Region_AddModifier(regionID, $ID_MOD_REGION_CUSTOM_REMOTEREGION_III);
}
else if ( gResult >= EVTCUSTOM_REMOTEREGION_DISTANCE_IV && gResult < EVTCUSTOM_REMOTEREGION_DISTANCE_V )
{
Region_AddModifier(regionID, $ID_MOD_REGION_CUSTOM_REMOTEREGION_IV);
}
else if ( gResult >= EVTCUSTOM_REMOTEREGION_DISTANCE_V )
{
Region_AddModifier(regionID, $ID_MOD_REGION_CUSTOM_REMOTEREGION_V);
}
}
}
else if (capCount == 0) // Then ALL a faction's regions will get modest penalties
{
Region_AddModifier(regionID, $ID_MOD_REGION_CUSTOM_REMOTEREGION_X);
}
}
}
}
Also: I'd like to exclude the independent Germanics, Celtics, etc., from this so that their regions don't get . What's the proper trigger for that?
EDIT: Is it Faction_IsWorldFaction (and thus to be used: Faction_IsWorldFaction(factionID) == TRUE )?
kronenblatt's campaign and tournament thread hub:
https://www.slitherine.com/forum/viewtopic.php?t=108643
https://www.slitherine.com/forum/viewtopic.php?t=108643
Re: Events occurring every turn and at game start?
Correct for IsWorldFaction
You are right, the events are triggered (including the ones in EntryPoint) and then just after that in hosting there is Region_Modifiers_EndTurnUpdate_All
Which will remove one turn, then create back the necessary one-turn event handled by the code (so not yours
)
Given you anyway iterate over all regions each turn, you can start, once you have the regionID, remove the 5 possible modifiers you are giving with Region_RemoveModifier(regionID, modTplID). It won't do anything if the modifier is not there, so call systematically the function with all variants.
And then add back one with a 999 duration.
You are right, the events are triggered (including the ones in EntryPoint) and then just after that in hosting there is Region_Modifiers_EndTurnUpdate_All
Which will remove one turn, then create back the necessary one-turn event handled by the code (so not yours
Given you anyway iterate over all regions each turn, you can start, once you have the regionID, remove the 5 possible modifiers you are giving with Region_RemoveModifier(regionID, modTplID). It won't do anything if the modifier is not there, so call systematically the function with all variants.
And then add back one with a 999 duration.
AGEOD Team - Makers of Kingdoms, Empires, ACW2, WON, EAW, PON, AJE, RUS, ROP, WIA.
