Results 1 to 2 of 2

Thread: How to make naval blockades of ports generate money for you/cost you money

  1. #1

    Default How to make naval blockades of ports generate money for you/cost you money

    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)

    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 #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.

    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}

    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
    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:
    #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
    Nice effect: we also have a Variable now to hold information of whether any faction is at war with another faction IsWar{FACTION1UID}{FACTION2UID}

    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:

    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
    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 @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
    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.

    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.
    Last edited by Ocyalos; January 28, 2022 at 12:28 AM.

  2. #2

    Default Re: How to make naval blockades of ports generate money for you/cost you money

    Ok, as a bonus, I found an easy way to implement a randomized amount of port blockade loot.

    Previously, we incremented the blockadecounter by 1 each time we block an enemy port or the ai blocks our port.

    Now, we say with 20% chance we increment it another 1, 20% chance anouter 1 and 20% another one. So with one blockade we or the AI can get the counter incremented by 1 - 4 times.

    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
                    if RandomPercent < 25
                        inc_counter blockadeMinus 1
                        console_command reseed_random
                    end_if
                    if RandomPercent < 25
                        inc_counter blockadeMinus 1
                        console_command reseed_random
                    end_if
                end_if
                if I_CompareCounter IsEnemy@{Region.UID} = 1
                and I_LocalFaction @BlockingFaction.Id
                    inc_counter blockadePlus 1
                    if RandomPercent < 20
                        inc_counter blockadePlus 1
                        console_command reseed_random
                    end_if
                    if RandomPercent < 20
                        inc_counter blockadePlus 1
                        console_command reseed_random
                    end_if
                    if RandomPercent < 20
                        inc_counter blockadePlus 1
                        console_command reseed_random
                    end_if
                end_if
            end_if
            #end
        #end
    end_monitor
    This makes it necessary to increate the amount of max counter for the port blockades from 10 to 40, so in worst case, we can get maximum 10 blockades per round to give us money or take money from us.

    Code:
    monitor_event FactionTurnEnd FactionType slave
        #for @i in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40"]:
            if I_CompareCounter blockadePlus = @{i}
                console_command add_money @{Scripter.Multiply(@{i}, 100)}
                @Scripter.MessageInfo("Denarii looted from port blockade", "Our navies blockaded enemy ports and looted @{Scripter.Multiply(@{i}, 100)} denarii in total.")
            end_if
            if I_CompareCounter blockadeMinus = @{i}
                console_command add_money -@{Scripter.Multiply(@{i}, 100)}
                @Scripter.MessageInfo("Denarii lost from port blockade", "Our enemies blockaded our ports and we lost @{Scripter.Multiply(@{i}, 100)} denarii because of that.")
            end_if
        #end
        set_counter blockadePlus 0
        set_counter blockadeMinus 0
    end_monitor
    In this example we block the port of Athens with our Spartan navy here for 2 rounds, see the different amount of loot we get from that:




    Last edited by Ocyalos; January 27, 2022 at 02:43 PM.
    CPU: AMD Ryzen 5 5600X 4,6 Ghz AM4 | GPU: 2x NVIDIA GeForce RTX 3060Ti Gainward Ghost OC 8GB GDRR6 | RAM: Corsair Vengeance RGB PRO DDR4 3600 Mhz C18 16 GB | SSD: PNY XLR8 CS3030 4TB M.2 NVMe 3 GB/s | PSU: be quiet! Straight Power 11 Platinum 550 Watt | MB: Asus ROG Strix B550-F Gaming WiFi | Case: be quiet! Silent Base 801 Silver


    Long: New York Stock Exchange: MO, XOM, AAL, AMZN, FB, MSFT, GOOGL, AMD, CRM | Wiener Börse: POST, BG, ADKO, UBS | London Stock Exchange: BP, BATS | Hong Kong Stock Exchange: 3988, 601318 | Euronext Paris: ORA, FP | Bolsa de Madrid: ELE | Coinbase: BTC
    Short: -

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •