Page 1 of 4 1234 LastLast
Results 1 to 20 of 64

Thread: Give a region to another faction via script

  1. #1
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Give a region to another faction via script

    [Kingdoms only]

    WARNING: see "Limitations" below regarding a CTD!

    Post 2 has some useful scripts that can be generated with this tool: TWRegionOwnerSwitch.

    There is no command to give a settlement of Faction A to Faction B, unless Faction B happens to be the player (capture_settlement).

    You could spawn a rebel army to siege...auto_win...attack it and then spawn a Faction B army to do the same. But this has some potentially nasty consequences, including: all characters and units in the settlement are killed.

    Here is another solution...

    It isn't foolproof and it isn't necessarily easy. But it won't kill anybody: everyone currently in the settlement peacefully leaves, as though a diplomacy Give Region was performed.

    You will need a 'hidden' faction. In the example I am using "spawnpool" from this tutorial. Essentially it is just an unplayable faction that not even the AI uses.
    - UPDATE: see the end of the post regarding an alternative that does not require a hidden faction.

    WARNING: Make sure that this 'hidden' faction is not used for any culture/faction tag in descr_regions.txt. If it is then - when the faction_emerge part of the switch happens and that tag region has low public order - the region might also be taken over (emerged into) by the 'hidden' faction and subsequently given to the switch's to-faction.
    - UPDATE: Pretty sure that's incorrect. Normally that would be true but the PO bonus from the building that this technique provides seems to make rioting settlements safe from faction_emerge.

    Some terms:
    • PO - Public Order
    • Target Settlement - the settlement we're trying to give away
    • Original Faction - the one that currently owns the settlement
    • Target Faction - the one that we want to give the settlement to
    • Hidden Faction - "spawnpool" in this example

    The idea of this method is:
    1. Give all settlements except the Target Settlement super-high public order
    2. Use faction_emerge so that the Hidden Faction takes ownership of the Original Faction settlement with the lowest PO - this should be the Target Settlement
    3. Use give_everything_to_faction to transfer everything from Hidden Faction to Target Faction, i.e. just the Target Settlement as this is all they own


    Public Order
    Public order manipulations are done with two new buildings:
    • ros_po_bonus - gives three +100% bonuses to public order
    • ros_target - removes public order bonuses

    Spoiler Alert, click show to read: 
    export_descr_buildings.txt:
    Code:
    building ros_temp_buildings
    {
        levels ros_po_bonus ros_target
        {
            ros_po_bonus city requires factions {   } 
            {
                capability
                {
                    law_bonus bonus 20 requires not building_present_min_level ros_temp_buildings ros_target
                    population_health_bonus bonus 20 requires not building_present_min_level ros_temp_buildings ros_target
                    happiness_bonus bonus 20 requires not building_present_min_level ros_temp_buildings ros_target
                }
                material wooden
                construction  1 
                cost  0 
                settlement_min village
                upgrades
                {
                    ros_target
                }
            }
            ros_target city requires factions {   } 
            {
                capability
                {
                    law_bonus bonus -20
                    population_health_bonus bonus -20
                    happiness_bonus bonus -20
                }
                material wooden
                construction  1 
                cost  0 
                settlement_min village
                upgrades
                {
                }
            }
        }
        plugins
        {
        }
    }
    export_buildings.txt:
    Code:
    {ros_target}Region Owner Switch Target
    {ros_target_desc}description
    {ros_target_desc_short}short description
    
    {ros_po_bonus}Region Owner Switch Public Order Bonus
    {ros_po_bonus_desc}description
    {ros_po_bonus_desc_short}short description
    "requires factions { }" is to prevent the player/AI from building it and appearing in the building browser.

    It won't be in existence long enough to be visible so there is no need for proper names and descriptions (export_buildings.txt) or any images.

    ~~~

    ros_po_bonus is built in all settlements, including the Target Settlement. As a result they get a 100% boost to these three bonuses which translates to about a +250% PO bonus.

    ros_target is built only in the Target Settlement. The "not building_present_min_level" conditions of ros_po_bonus mean that the Target Settlement will NOT get its bonuses. i.e. The Target Settlement has both buildings but the presence of ros_target prevents the bonuses of ros_po_bonus from happening there. Additionally, ros_target itself reduces public order by having -100% on these bonuses. This counters any of these bonuses that the settlement has from other buildings, governor traits, etc., dropping them to zero.

    e.g. If a settlement has +150% PO including +30% from law/happiness/population_health then with ros_target it will drop it to +120%.

    So by giving the Target Settlement this ros_target building its PO will/might drop a bit. All other settlements will get something like a +250% PO boost.

    This should make the Target Settlement the one with the lowest PO in the faction.

    (An alternative to using these "not building_present_min_level" conditions would be to simply NOT build ros_po_bonus in the Target Settlement. But this would add more script - potentially hundreds of lines - because each "build ros_po_bonus" call would need to be wrapped in an "if not target settlement" check.)


    Special Unit
    If the settlement is empty then this technique would fail: it would end up owned by the slaves.

    This is avoided by spawning a unit into the settlement prior to the transfer and then destroying the unit afterward. To do that we need a dedicated unit that no faction can use.

    A new unit: ros_Peasants
    Spoiler Alert, click show to read: 
    export_descr_unit.txt:
    Code:
    type             ros_Peasants	;temporary unit for Region Owner Switch
    dictionary       ros_Peasants
    category         infantry
    class            light
    voice_type       Light
    banner faction   main_infantry
    banner holy      crusade
    soldier          Peasants, 4, 0, 0.8
    attributes       sea_faring, hide_forest, can_withdraw, is_peasant, peasant, no_custom, general_unit
    formation        1.2, 1.2, 2.4, 2.4, 6, square
    stat_health      1, 0
    stat_pri         4, 0, no, 0, 0, melee, melee_simple, piercing, spear, 25, 0.6
    ;stat_pri_ex      0, 0, 0
    stat_pri_attr    no
    stat_sec         0, 0, no, 0, 0, no, melee_simple, blunt, none, 25, 1
    ;stat_sec_ex      0, 0, 0
    stat_sec_attr    no
    stat_pri_armour  0, 3, 0, flesh
    ;stat_armour_ex   0, 4, 0, 0, 3, 0, 0, flesh
    stat_sec_armour  0, 0, flesh
    stat_heat        2
    stat_ground      1, -2, 3, 2
    stat_mental      1, low, untrained
    stat_charge_dist 30
    stat_fire_delay  0
    stat_food        60, 300
    stat_cost        1, 110, 90, 65, 50, 110, 4, 20
    armour_ug_levels 0
    armour_ug_models Peasants
    ownership        slave
    era 0            slave
    era 1            slave
    era 2            slave
    export_units.txt:
    Code:
    {ros_Peasants}Peasants
    {ros_Peasants_descr}Peasants leaving the settlement
    {ros_Peasants_descr_short}Peasants leaving the settlement
    To avoid being recruited/spawned by the game it has "slave" ownership, the "general_unit" attribute and is absent from the EDB. Plus "no_custom" to avoid Custom Battle usage.

    It also has a low unit count to minimise the amount of garrison PO bonus.

    Other than that it is just a renamed copy of the Peasants unit. It shouldn't be in existence long enough to be seen so the name and description aren't important.


    Script
    This example is transferring London from England to France...

    Code:
    monitor_event {whatever}
    
      if I_SettlementOwner London england
        and not I_SettlementUnderSiege London
    
        ;give all settlements a public order bonus building
        ;(We only need to give it to the target faction's settlements but to work out which ones they are
        ; would take a lot of script.  For simplicity just give it to every settlement on the map.)
        console_command create_building Acre ros_po_bonus
        console_command create_building Adana ros_po_bonus
        console_command create_building Ajaccio ros_po_bonus
        console_command create_building Aleppo ros_po_bonus
        console_command create_building Alexandria ros_po_bonus
        console_command create_building Algiers ros_po_bonus
        console_command create_building Angers ros_po_bonus
        ;... and all other settlements on the map!
    
        ;target settlement...
        console_command create_building London ros_target    
        console_command create_unit London ros_Peasants 1 0 0
        
        ;Spawning a named character from the hidden faction prior to faction_emerge 
        ; makes it ignore its label parameter, thus avoiding "label already exists"
        ; errors when this faction_emerge is reused.
        spawn_army
          faction spawnpool
          character  spA, named character, age 18, x 0, y 0
          unit Peasants	exp 0 armour 0 weapon_lvl 0  
        end      
    
        faction_emerge spawnpool england 1 400.0 0.0 1.2 town false unused_label1 unused_name 30
        
        ;we no longer need this guy
        kill_character spA
        
        ;pause to give time for the character to die (avoids unkilled characters 
        ; when using this method in quick succession)
        campaign_wait 0.1
        
        if I_NumberOfSettlements spawnpool == 0
          ;nothing was transferred: do a "give everything" to avoid "faction 
          ; destroyed" message
          give_everything_to_faction spawnpool england false
        end_if
        
        if I_NumberOfSettlements spawnpool > 0
        
          if not I_SettlementOwner London spawnpool
            ;a settlement was transferred but it wasn't our target...        
            ;give it back to the original owner    
            give_everything_to_faction spawnpool england false
          end_if
          
          if I_SettlementOwner London spawnpool
            ;our target settlement was successfully transferred...
            ;give it to the target faction
            give_everything_to_faction spawnpool france false
          end_if
          
        end_if    
            
        ;clean up: destroy the temporary units and buildings
        ;(they could belong to either faction at this point: destroy them in both)
        destroy_units england ros_Peasants
        destroy_buildings england ros_temp_buildings false
        destroy_buildings england ros_temp_buildings false
        destroy_units france ros_Peasants
        destroy_buildings france ros_temp_buildings false
        destroy_buildings france ros_temp_buildings false
        ;... and all other factions!
        
      end_if
      
    end_monitor
    Done. Just replace, as needed, "england", "france" and "London" (and "spawnpool" if you have a different hidden faction).

    spawn_army
    The sole purpose of this is to spawn a named character into spawnpool prior to the faction_emerge. He isn't used for anything and is killed straight after the emerge. His name doesn't matter, so long as it is a valid name in that emerging faction.

    His bodyguard doesn't matter either. See the Unique Names tutorial regarding bodyguards of hidden faction generals. You should be able to use any unit here.

    Without this spawned character faction_emerge would need a different "label" parameter each time it is called: a dark road to head down.

    faction_emerge
    The parameters are:
    • [emerging_faction] spawnpool - emerge the spawnpool faction
    • [target_faction] england - target england's settlements
    • [min_num_remain] 1 - the minimum number of settlements england should keep after this. Presumably, if 1 and england currently only has 1 settlement, then this command won't do anything because that would leave them with 0 which is below this "1" value. In hindsight, 0 would be a better value here.
    • [max_order_threshold] 400.0 - explained below
    • [max_order_threshold_surrounding] 0.0 - this is for letting it also take surrounding settlements: we don't want this to happen
    • [max_order_dropoff] 1.2 - I'm not sure what this is
    • [min_level_threshold] town - the lowest wall level that can be taken by this: here we want "anything >= town"
    • [fire_emerge_message] false - no, we don't want to see a "faction emerges" message
    • unused_label1 unused_name 30 - emerging faction's leader info: unused since we already have our spawned general

    max_order_threshold = 400.0
    max_order_threshold means "only consider settlements with a public order less than or equal to this value". It doesn't really matter what the number is so long as it is higher than what our target settlement's PO could possibly be.

    e.g. If this number was 200 and the target settlement's PO was 210% then this settlement will be excluded from the faction_emerge calculations and will not be transferred to spawnpool.

    I doubt that a settlement could reach more than 400% PO by normal means. If you think that it's possible in your mod then increase this value.

    min_level_threshold = town
    What about villages? Well, they seem to be included even if we specify "town" here. So no problem. By using "town" we are effectively saying "anything of 'town' level or higher, AND villages". i.e. All levels.

    ~~~

    The last step in the script (before the cleanup) is to transfer the settlement to the appropriate faction. In this example it is France but it first tests that the right settlement was taken from England...
    • If spawnpool owns no settlements then nothing was transferred to them (e.g. max_order_threshold was too low) : give all of spawnpool to England. Actually there is nothing to give as they don't own anything but this avoids a "faction destroyed (spawnpool)" message.
    • If spawnpool does own a settlement (>0) but not London then another settlement must have been transferred to them instead (a settlement has lower PO than London, despite the bonuses) : give everything (i.e. this one other settlement) back to England
    • If spawnpool does own London then mission completed: give everything (London) to France.


    Building Creation/Destruction
    The ros_po_bonus building only needs to be built in the Owner Faction's settlements. But it would take a fair bit of script to work out which ones they are. To keep the script to a minimum the building is instead built in every settlement on the map. There is no harm in other factions having it.

    The Target Settlement will have both a ros_po_bonus and po_target building. destroy_buildings will only destroy one of them: it needs to be called twice to destroy both during the cleanup at the end.


    The script can be run multiple times, in quick succession if need be. If you need to transfer 3 settlements then run this entire script 3 times using the appropriate factions and settlements. But don't change the script to somehow make it do 3 settlements at once: the ownership tests - and their give_everything's - at the end are working on the assumption of one settlement only.

    Limitations

    Under Siege
    The script will do nothing if the target settlement is under siege, via the "and not I_SettlementUnderSiege" test. If you take that line out then the process could fail: transferring another settlement instead. faction_emerge seems to ignore besieged settlements.

    i.e. This is a limitation of this technique: you can't transfer a beseiged settlement.

    Public Order : Wrong Settlement
    If, despite all of the PO adjustments from the buildings, another settlement has a lower PO than our target settlement then that settlement will be transferred instead. The script handles that outcome - giving it back to the original owner - but its characters and units will now be standing outside. Not a game-breaking result but another faction could then walk in and take it before the player/AI can move them back in.

    The likely cause of this is PO due to garrison. There is no way to counter this PO bonus with negative building bonuses.

    A way to further reduce the target settlement's PO is via a governor trait that adds things like Squalor, Unrest, and perhaps negative LocalPopularity and Health. However, giving him the trait at the desired time could be tricky and it's possible that the settlement has no governor.

    UPDATE: some ideas on garrison and governor are in post 58.

    Crusade-related CTD
    If the region is the target of the current crusade, and the give-to faction is catholic, then a crash-to-desktop occurs. This is a bug with give_everything_to_faction as reported here.

    Post 2 shows a way around this.


    Incidentally, the GiveSettlement event fires during this transfer. BUT: it only fires during the faction_emerge, not the give_everything_to_faction. Meaning that TargetFactionType will be "spawnpool" in this example, not "france".

    Something worth noting: if this is used to transfer a region to the faction that already owns it then they keep the region but all of their characters and units will exit the settlement. Other-faction spies remain inside. This could be a useful way to empty a settlement, for whatever reason. But this is really just a shortcut: the same result would be had by giving the region to another faction then back to the first.

    Alternative, without a hidden faction
    Post 52 suggests an alternative: using faction_emerge directly to the target faction (even though it's already alive on the map) instead of faction_emerge a hidden faction and then giving all from the hidden faction to the target faction. This removes the need to use a hidden faction at all.

    Using the same script example as above, transferring London from England to France...

    Spoiler Alert, click show to read: 
    Code:
    monitor_event {whatever}
    
      if I_SettlementOwner London england
        and not I_SettlementUnderSiege London
    
        ;give all settlements a public order bonus building
        ;(We only need to give it to the target faction's settlements but to work out which ones they are
        ; would take a lot of script.  For simplicity just give it to every settlement on the map.)
        console_command create_building Acre ros_po_bonus
        console_command create_building Adana ros_po_bonus
        console_command create_building Ajaccio ros_po_bonus
        console_command create_building Aleppo ros_po_bonus
        console_command create_building Alexandria ros_po_bonus
        console_command create_building Algiers ros_po_bonus
        console_command create_building Angers ros_po_bonus
        ;... and all other settlements on the map!
    
        ;target settlement...
        console_command create_building London ros_target    
        console_command create_unit London ros_Peasants 1 0 0
        
        ;Spawning a named character from the hidden faction prior to faction_emerge 
        ; makes it ignore its label parameter, thus avoiding "label already exists"
        ; errors when this faction_emerge is reused.
        spawn_army
          faction spawnpool
          character  spA, named character, age 18, x 0, y 0
          unit Peasants	exp 0 armour 0 weapon_lvl 0  
        end      
    
        faction_emerge france england 1 400.0 0.0 1.2 town false unused_label1 unused_name 30
        
        ;we no longer need this guy
        kill_character spA
        
        ;pause to give time for the character to die (avoids unkilled characters 
        ; when using this method in quick succession)
        campaign_wait 0.1
        
        if I_NumberOfSettlements spawnpool == 0
          ;nothing was transferred: do a "give everything" to avoid "faction 
          ; destroyed" message
          give_everything_to_faction spawnpool england false
        end_if
        
        if I_NumberOfSettlements spawnpool > 0
        
          if not I_SettlementOwner London spawnpool
            ;a settlement was transferred but it wasn't our target...        
            ;give it back to the original owner    
            give_everything_to_faction spawnpool england false
          end_if
          
          if I_SettlementOwner London spawnpool
            ;our target settlement was successfully transferred...
            ;give it to the target faction
            give_everything_to_faction spawnpool france false
          end_if
          
        end_if 
            
        ;clean up: destroy the temporary units and buildings
        ;(they could belong to either faction at this point: destroy them in both)
        destroy_units england ros_Peasants
        destroy_buildings england ros_temp_buildings false
        destroy_buildings england ros_temp_buildings false
        destroy_units france ros_Peasants
        destroy_buildings france ros_temp_buildings false
        destroy_buildings france ros_temp_buildings false
        ;... and all other factions!
        
      end_if
      
    end_monitor

    The scripts in the next post, and the generator tool, still do it the original way using a hidden faction. I haven't personally tested this alternative extensively to confirm that it always works reliably.


    ~~~~~~

    Hopefully this will be of use to somebody. If anyone has any ideas on how to further increase or decrease PO via buildings or script then please say so: the bigger the gap between the target settlement's PO and all other settlements, the more reliable this will be. e.g. Is there any way to increase Squalor or Unrest (other than by traits) or to reduce Garrison bonus?
    Last edited by Withwnar; December 16, 2020 at 04:14 AM.

  2. #2
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    Part II : making it more generic

    The examples in this post are for Kingdoms grand campaign: all regions and all factions.
    To make your own script with fewer regions/factions - thus smaller script - or for any Kingdoms mod there is this tool: TWRegionOwnerSwitch.

    The OP script example can only transfer one settlement: London. Furthermore, it requires you to know who the current owner is. In reality the settlement could belong to anybody by the time the script needs to fire. So you would need one copy of that monitor per faction and trigger the one that matches the owning faction. And that's just for London.

    Below are two 'common' scripts that can be reused for different settlements and owner/target factions. That is, one monitor that does it all: you just feed it the settlement and faction options via counters.

    Type 1 : one huge monitor
    See the attached: ROS-Type1.txt

    This monitor knows all of the possible factions (from a Kingdoms grand campaign), works out for itself who the current owner is and uses this owner wherever necessary in its command calls. You tell it which settlement (ros_region_id) and who to give it to (ros_target_faction_id) and then trigger it from your script...

    Code:
    ;give London to France
    if not I_SettlementOwner London france
      set_event_counter ros_region_id 60 ;London
      set_event_counter ros_target_faction_id 4 ;France
      set_event_counter ros_switch_now 0
      set_event_counter ros_switch_now 1
      while I_EventCounter ros_switch_now > 0
      end_while
      campaign_wait 0.1
    end_if
    This would go into your script where you would normally be doing something like "console_command capture_settlement London".

    The steps are:
    1. Check that it isn't already owned by France
    2. Set ros_region_id to the number representing the target settlement (the list is at the top of that monitor) - in this example "London"
    3. Set ros_target_faction_id to the number representing the target faction (the list is at the top of that monitor) - in this example "France"
    4. Set ros_switch_now to 0 to 'clear it' ready for the next step
    5. Set ros_switch_now to 1 - this will trigger the monitor
    6. Wait until ros_switch_now is no longer > 0 (the monitor will set it to 0 or -1 when it has finished). i.e. Wait until the monitor has finished doing its thing.
    7. Wait 0.1 seconds. This just ensures that the monitor has fully exited before you move onto the next line in your script.


    The monitor - at its end - sets ros_switch_now to indicate whether the settlement was indeed transferred. Specifically:
    • -1 if it was
    • 0 if it wasn't

    For example, if you need to show a message when the transfer happens then you could do something like this...

    Code:
    ;give London to France
    if not I_SettlementOwner London france
      set_event_counter ros_region_id 60 ;London
      set_event_counter ros_target_faction_id 4 ;France
      set_event_counter ros_switch_now 0
      set_event_counter ros_switch_now 1
      while I_EventCounter ros_switch_now > 0
      end_while
      campaign_wait 0.1
      if I_EventCounter ros_switch_now == -1
        historic_event london_given_to_france
      end_if
    end_if
    The monitor is huge: ~9600 lines. Speed wise it is fine (including turn end times: harmless) but a large campaign_script can be annoying to maintain. There is another option...


    Type 2 : much smaller but more calling script
    See the attached: ROS-Type2.txt

    8100 lines (85%) of Type 1's monitor is just to establish who the current owner is and whether it is under siege. Because it is catering for all possible settlements.

    In all likelihood you will only need to transfer a small number of settlements in your mod. By taking these two tests out of the monitor and putting them in the calling script instead drastically reduces the monitor size: from ~9600 to ~1600 lines.

    It is now the responsibility of the calling script to determine the current owner (and the besieged status). This complicates the calling script a bit but not too badly...

    Spoiler Alert, click show to read: 
    Code:
    ;give London to France
    if not I_SettlementOwner London france
      and not I_SettlementUnderSiege London
      
      ;get the current owner...
      set_event_counter ros_owner 0    
      if I_SettlementOwner London denmark
        set_event_counter ros_owner 1
      end_if
      if I_SettlementOwner London egypt
        set_event_counter ros_owner 2
      end_if
      if I_SettlementOwner London england
        set_event_counter ros_owner 3
      end_if
      if I_SettlementOwner London france
        set_event_counter ros_owner 4
      end_if
      if I_SettlementOwner London hungary
        set_event_counter ros_owner 5
      end_if
      if I_SettlementOwner London milan
        set_event_counter ros_owner 6
      end_if
      if I_SettlementOwner London slave
        set_event_counter ros_owner 7
      end_if
      if I_SettlementOwner London moors
        set_event_counter ros_owner 8
      end_if
      if I_SettlementOwner London poland
        set_event_counter ros_owner 9
      end_if
      if I_SettlementOwner London portugal
        set_event_counter ros_owner 10
      end_if
      if I_SettlementOwner London russia
        set_event_counter ros_owner 11
      end_if
      if I_SettlementOwner London scotland
        set_event_counter ros_owner 12
      end_if
      if I_SettlementOwner London sicily
        set_event_counter ros_owner 13
      end_if
      if I_SettlementOwner London spain
        set_event_counter ros_owner 14
      end_if
      if I_SettlementOwner London aztecs
        set_event_counter ros_owner 15
      end_if
      if I_SettlementOwner London byzantium
        set_event_counter ros_owner 16
      end_if
      if I_SettlementOwner London hre
        set_event_counter ros_owner 17
      end_if
      if I_SettlementOwner London mongols
        set_event_counter ros_owner 18
      end_if
      if I_SettlementOwner London papal_states
        set_event_counter ros_owner 19
      end_if
      if I_SettlementOwner London turks
        set_event_counter ros_owner 20
      end_if
      if I_SettlementOwner London timurids
        set_event_counter ros_owner 21
      end_if
      if I_SettlementOwner London venice
        set_event_counter ros_owner 22
      end_if
      
      ;switch...
      if I_EventCounter ros_owner > 0
        set_event_counter ros_region_id 60 ;London
        set_event_counter ros_target_faction_id 4 ;France
        set_event_counter ros_switch_now 0
        set_event_counter ros_switch_now 1
        while I_EventCounter ros_switch_now > 0
        end_while
        campaign_wait 0.1
      end_if
    end_if


    Crusade CTD Avoidance
    As mentioned earlier (and here) we must avoid using this on a settlement that is the current crusade target when the give-to faction is catholic.

    One solution is a counter and some monitors...

    Code:
    set_event_counter ros_crusade_region_id 0
    
    monitor_event CrusadeEnds IsCrusade
      set_event_counter ros_crusade_region_id 0
    end_monitor
    
    monitor_event CrusadeCalled IsCrusade
      and TargetSettlementName Acre
      set_event_counter ros_crusade_region_id 1
    end_monitor
    monitor_event CrusadeCalled IsCrusade
      and TargetSettlementName Adana
      set_event_counter ros_crusade_region_id 2
    end_monitor
    monitor_event CrusadeCalled IsCrusade
      and TargetSettlementName Ajaccio
      set_event_counter ros_crusade_region_id 3
    end_monitor
    ...other settlements...
    e.g. If a crusade is in progress and Ajaccio is its target then ros_crusade_region_id will be 3. We can include a test for that in our calling script...

    Code:
    if not I_SettlementOwner Ajaccio france
      and not I_SettlementUnderSiege Ajaccio
      and not I_EventCounter ros_crusade_region_id = 3
    	
      ...
    ...which means that the switch will not happen (but also no CTD). If the give-to faction is NOT catholic then no CTD occurs so that extra condition is not required.

    The script generated by the TWRegionOwnerSwitch tool includes that counter and monitors - with ros_crusade_region_id = ros_target_faction_id for each region that the script supports.

    This extra script has also been added to the files attached to this post.

    ~~~

    Another solution (as mentioned here) is to change the to-faction's religion just before the switch and back again just after.

    For example, if france is the to-faction and they are catholic...

    Code:
    	set_religion france heretic
    	set_event_counter ros_switch_now 0
    	set_event_counter ros_switch_now 1
    	while I_EventCounter ros_switch_now > 0
    	end_while
    	campaign_wait 0.1
    	set_religion france catholic
    If done this way then the counter and monitors that TWRegionOwnerSwitch generates (for the previous solution technique) are not needed; you could remove them from your script.



    ~~~~

    WARNING: the region orders - and therefore their IDs - have been changed since the previous versions of these attached files. If you are using them in your script then check your calling script to make sure that it is using the correct IDs for the regions you are trying to switch.
    Attached Files Attached Files
    Last edited by Withwnar; February 07, 2014 at 02:31 AM.

  3. #3
    Emperor of Hell's Avatar SPA-NED 1-5
    Join Date
    Jul 2011
    Location
    Netherlands
    Posts
    5,747

    Default Re: Give a region to another faction via script

    Does anyone know if any of this is a Kingdoms-only thing? I haven't tried it on M2TW.
    Yes it is. Some of the scripting commands don't work in vanilla M2TW

  4. #4
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    Can you give an example of one?

  5. #5
    Emperor of Hell's Avatar SPA-NED 1-5
    Join Date
    Jul 2011
    Location
    Netherlands
    Posts
    5,747

    Default Re: Give a region to another faction via script

    destroy_buildings, faction_emerge, give_everything_to_faction, etc.

  6. #6
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    destroy_buildings?! Wow, I wasn't expecting that one. Thanks EoH. I'll add a "Kingdoms only" note.

  7. #7
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    Post 2 updated.

    EDIT: Posts 1 & 2 updated. A unit has been added to avoid problems when ungarrisoned, plus a third option in Part II.
    Last edited by Withwnar; April 06, 2012 at 03:38 AM.

  8. #8
    UndyingNephalim's Avatar Primicerius
    Patrician Artifex

    Join Date
    Jan 2011
    Posts
    3,967

    Default Re: Give a region to another faction via script

    It really does seem like a silly mistake on CA's part to not include a command that simply gives a region from X faction to Y faction, but this substitute you came up with works perfectly and I've not run into any issues with it yet. I'll be sure to let you know if I do though. In the mean time +rep.

  9. #9
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    Thanks. Yes, it's shame that it takes a new building, new unit and a big chunk of script to do what a simple command could have done in one line. I'm glad to hear that it's working okay.

  10. #10
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    Uh-oh. It seems that this falls over if the owning faction has any villages: a village will be transferred instead if it has a lower public order than the target settlement.

    Villages don't have walls so can't get the PO boost, as already mentioned. But this...
    Code:
    faction_emerge spawnpool england 1 400.0 0.0 1.2 town false unused_label1 unused_name 30
    ...should be excluding villages as candidates for the emerging faction. Apparently not, despite what the docudemons say:
    Evaluates the target factions settlements with a settlement level >= min_level_threshold
    I had tested villages but clearly not enough.

    It turns out that this is also the reason why this method didn't always work for transferring a slave-owned settlement: the slaves own some villages in vanilla.

    But good news: I have an alternative solution which works correctly and, even better, doesn't have the Villages and Slaves limitations: it can be used to transfer villages and transfer any slave-owned settlement.

    I'll update shortly. I just wanted to point out the existing problem at this stage and mention the faction_emerge 'bug'.

  11. #11
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    The OPs have been rewritten using the new method. There is also a tool that can generate the scripts - see either OP for the link.

  12. #12
    Gigantus's Avatar I am not special - I am a limited edition.
    Patrician Moderator Emeritus Administrator Emeritus

    Join Date
    Aug 2006
    Location
    Goa - India
    Posts
    53,095
    Blog Entries
    35

    Default Re: Give a region to another faction via script

    This way one can avoid the diplomatic mess - I have been using spawned armies and 'auto_win attacker' to do it. Understandably restrictive use there as even a scripted peace afterward still messes with diplomacy (allies or faction of the same religion take a hit in faction standing)










  13. #13

    Default Re: Give a region to another faction via script

    This is great. Will be using this.
    ...longbows, in skilled hands, could reach further than trebuchets...

  14. #14
    RollingWave's Avatar Praepositus
    Join Date
    Feb 2005
    Location
    Taiwan
    Posts
    5,083

    Default Re: Give a region to another faction via script

    wow is there a less complicated way of doing this?

    for example, if I have Cuman/Kipchak faction and want to use it's slot for Mongols (if i'm not playing as them of course), wouldn't I just need something like

    monitor_event (enter condition)
    give_everything_to_faction slave

    and then start with the spawn_army script?
    1180, an unprecedented period of peace and prosperity in East Asia, it's technology and wealth is the envy of the world. But soon conflict will engulf the entire region with great consequences and lasting effects for centuries to come, not just for this region, but the entire known world, when one man, one people, unites.....

  15. #15
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    This gives one settlement to another faction. give_everything_to_faction gives everything to another faction.

  16. #16
    RollingWave's Avatar Praepositus
    Join Date
    Feb 2005
    Location
    Taiwan
    Posts
    5,083

    Default Re: Give a region to another faction via script

    Quote Originally Posted by Withwnar View Post
    This gives one settlement to another faction. give_everything_to_faction gives everything to another faction.
    ahh, but if that's my intention.... using the give_everything_to_faction would make for a lot less headache right?

    My script intention is essentially letting the Cuman-Kipchak and Mongols share the same faction slot (afterall the Golden horde was also known as the Kipchak Khanate) the idea is that if your not playing as the Cumans, when the Mongol invasion comes I automatically destroy the current Cuman holding.. given them all to the Rebels, and then respawn the faction on the edge of the map with Genghis Khan as the new leader ... it's not a perfect solution of course, but the limits of the faction slot seems to make it worthwhile..
    1180, an unprecedented period of peace and prosperity in East Asia, it's technology and wealth is the envy of the world. But soon conflict will engulf the entire region with great consequences and lasting effects for centuries to come, not just for this region, but the entire known world, when one man, one people, unites.....

  17. #17
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Give a region to another faction via script

    If you want to wipe out a faction then yes: either give_everything_to_faction (to slave or other) or surrender_regions (goes to slaves).

  18. #18

    Default Re: Give a region to another faction via script

    Great work Withwnar! It’s a very good idea.

    Greetings.

  19. #19
    Mr.Jox's Avatar WHY SO SERIOUS?!
    Join Date
    Mar 2013
    Location
    Crimea
    Posts
    2,362

    Default Re: Give a region to another faction via script

    I need a help. There is my code:
    Code:
    monitor_event EventCounter EventCounterType ros_switch_now  and EventCounter = 1
      set_event_counter ros_status 1
      console_command create_building Udun ros_po_bonus
      if I_EventCounter ros_region_id = 1
        console_command create_building Udun ros_target
        console_command create_unit Udun Peasants 1 0 0
      end_if
      spawn_army
        faction hungary
        character spA, named character, age 18, x 0, y 0
        unit Peasants	exp 0 armour 0 weapon_lvl 0
      end
      faction_emerge hungary england 1 400.0 0.0 1.2 town false unused_label1 unused_name 30
      kill_character spA
      campaign_wait 0.1
      if I_NumberOfSettlements hungary == 0
        set_event_counter ros_status 0
      end_if
      if I_NumberOfSettlements hungary > 0
        if I_EventCounter ros_region_id == 1
          and not I_SettlementOwner Udun hungary
          set_event_counter ros_status 0
        end_if
      end_if
      if I_EventCounter ros_status == 0
        if I_EventCounter ros_owner == 1
          give_everything_to_faction hungary england false
        end_if
      end_if
      if I_EventCounter ros_status == 1
        if I_EventCounter ros_target_faction_id == 1
          give_everything_to_faction hungary england false
        end_if
      end_if
      destroy_buildings england ros_temp_buildings false
      destroy_buildings england ros_temp_buildings false
      destroy_units england ros_Peasants
      
      if I_EventCounter ros_status == 0
        set_event_counter ros_switch_now 0
      end_if
      if I_EventCounter ros_status == 1
        set_event_counter ros_switch_now -1
      end_if
      
    end_monitor
    There are not the target settlement(Udun) doing transfer. Transfer is doing with any settlements except target

  20. #20

    Default Re: Give a region to another faction via script

    This line should be so:

    Code:
    and not I_SettlementOwner Udun = hungary

Page 1 of 4 1234 LastLast

Posting Permissions

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