Naval blockades are possible in Rome Remastered. Now I found a way to implement a script to
+ Generate money for player each round per each blockade he does (100 denarii in this example per blockade per round)
+ Make player lose money each round per each blockaded port of his faction (100 denarii in this example per blockade per round)
That way, the player gets an incentive to fight pirates and enemy fleets and also we can build a kind of pirate empire where your income is based on raiding foreign ports.
To implement this script, you will need to work with a program language like Python to generate the script for you. This tutorial will be for Python (it is simple and easy to learn). You have to write a Python program which generates the campaign script code for you. In this example, I use the tool Atlas which is a Python program which also already has the faction data implemented. If you do not, you have to implement a class for Faction and a class for Region and define the following important attributes: Faction.Id (e.g. romans_julii), Faction.UID (e.g. F001) and Region.UI and Region.PositionPort.X and Region.PositionPort.Y - in my example, I am using Atlas* so I do not have to worry about that.
You can however use at least the logic to implement it in any programming language and templating tool you want. You will have to rewrite the syntax of course.
* https://www.twcenter.net/forums/show...er-and-cleaner
We need to use a Python Templating tool to bring our data into a game script template. First, you need to define variables (counters) for specific situations
-> Does a Region currently have a port building?
-> Does a Region currently belong to the player?
-> Does a Region currently belong to an enemy of the player?
This we do here:
Here we define the counter HasPort{REGIONUID} to hold information on whether the region has a port building currently (0 = no 1 = yes)
Quick remark #1: The lowest level of port in my mod is port_0 - in vanilla Rome, it is port. You have to insert the lowest level of port building here.Code:#for @Region in @Get.AllRegions(): monitor_event SettlementTurnEnd SettlementName @{Region.IdCity} if SettlementBuildingExists >= port_0 set_counter HasPort@{Region.UID} 1 end_if if not SettlementBuildingExists >= port_0 set_counter HasPort@{Region.UID} 0 end_if end_monitor #end
Quick remark #2: Why do I use UID instead of the factions ID or something more readable? Because I want my counter names to be as short as possible. These heavy scripts tend to be quite big so we want to save as much RAM space as possible otherwise we get longer loading times. The UID in case of Atlas looks like for example for factions: F1, F2, F3, F4, ... and for regions R1, R2, R3, R4, ... - so we have counters for example like HasPortR1, HasPortR2, IsEnemyF1, IsEnemyF2, ...
Here we define the counter IsPlayer{REGIONUID} to hold information on whether the region currently belongs to the player (0 = no 1 = yes) and simultaneously if it does belong to a players enemy IsEnemy{REGIONUID}
To be able to know if a region belongs to an enemy of the player, we need to implement logic to set that, we do it here:Code:monitor_event FactionTurnEnd FactionType slave #for @Region in @Get.AllRegions(): #for @Faction in @Get.AllFactions(): if I_SettlementOwner @{Region.IdCity} = @{Faction.Id} and I_CompareCounter IsEnemy@{Faction.UID} = 1 set_counter IsEnemy@{Region.UID} 1 end_if if I_SettlementOwner @{Region.IdCity} = @{Faction.Id} and I_CompareCounter IsEnemy@{Faction.UID} = 0 set_counter IsEnemy@{Region.UID} 0 end_if if I_SettlementOwner @{Region.IdCity} = @{Faction.Id} and I_LocalFaction @{Faction.Id} set_counter IsPlayer@{Region.UID} 1 set_counter IsEnemy@{Region.UID} 0 end_if if not I_SettlementOwner @{Region.IdCity} = @{Faction.Id} and I_LocalFaction @{Faction.Id} set_counter IsPlayer@{Region.UID} 0 end_if #end #end end_monitor
Nice effect: we also have a Variable now to hold information of whether any faction is at war with another faction IsWar{FACTION1UID}{FACTION2UID}Code:#for @Faction in @Get.AllFactions(): monitor_event FactionTurnEnd FactionType @Faction.Id #for @OtherFaction in @Get.AllFactionsExceptFaction(@{Faction}): if DiplomaticStanceFromFaction @OtherFaction.Id AtWar set_counter IsWar@{Faction.UID}@{OtherFaction.UID} 1 set_counter IsWar@{OtherFaction.UID}@{Faction.UID} 1 if I_LocalFaction @{Faction.Id} set_counter IsEnemy@{OtherFaction.UID} 1 end_if if I_LocalFaction @{OtherFaction.Id} set_counter IsEnemy@{Faction.UID} 1 end_if end_if if not DiplomaticStanceFromFaction @OtherFaction.Id AtWar set_counter IsWar@{Faction.UID}@{OtherFaction.UID} 0 set_counter IsWar@{OtherFaction.UID}@{Faction.UID} 0 if I_LocalFaction @{Faction.Id} set_counter IsEnemy@{OtherFaction.UID} 0 end_if if I_LocalFaction @{OtherFaction.Id} set_counter IsEnemy@{Faction.UID} 0 end_if end_if #end end_monitor #end
Now we are ready to implement the logic which costs player money or gives player money depending on naval blockades:
The first part is implementing a blockade counter which counts up for each blockade the player does and another counter which counts up for each blockade the AI does to the player:
The second part is at the end of each turn we check these two counters and pay out the money/take the money away to/from the player:Code:monitor_event FactionTurnEnd FactionType slave #for @BlockingFaction in @Get.AllFactions(): #for @Region in @Get.AllRegionsWithPorts(): if I_CharacterTypeNearTile @BlockingFaction.Id admiral, 2 @{Region.PositionPort.X},@{Region.PositionPort.Y} and I_CompareCounter HasPort@{Region.UID} = 1 if I_CompareCounter IsPlayer@{Region.UID} = 1 and I_CompareCounter IsEnemy@{BlockingFaction.UID} = 1 inc_counter blockadeMinus 1 end_if if I_CompareCounter IsEnemy@{Region.UID} = 1 and I_LocalFaction @BlockingFaction.Id inc_counter blockadePlus 1 end_if end_if #end #end end_monitor
Of course dont forget to reset the counter to 0 again. Note that in this case, the max. amount of ports blockaded at one time is 10. We can of course raise that limit higher by adding more numbers to the numbers list.Code:monitor_event FactionTurnEnd FactionType slave #for @i in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]: if I_CompareCounter blockadePlus = @{i} console_command add_money @{i}00 @Scripter.MessageInfo("@{i}00 denarii looted from port blockade", "x") end_if if I_CompareCounter blockadeMinus = @{i} console_command add_money -@{i}00 @Scripter.MessageInfo("@{i}00 denarii lost from port blockade", "x") end_if #end set_counter blockadePlus 0 set_counter blockadeMinus 0 end_monitor
We should also implement a message which informs the player how much money he got or lost due to naval blockades. I use the function @Scripter.MessageInfo() from Atlas which generates the message_prompt for me. For further info, how to generate a message look here: https://github.com/FeralInteractive/...pts/Scripts.md
And we are done! Here a screenshot where we blockade an enemys port and get money:
Keep in mind that the scripts size can get quite big and depends on how many factions you have and how many regions with ports you have. I for example have 150 factions in my mod and around 100 cities with ports. My script gets around 30 MB big, which is OK, but if you have more regions for example, you will get bigger script size.
This script can be further improved by for example introducing a random element to the amount of loot you or the AI make from blockading. Just use the RandomPercent condition.