Results 1 to 9 of 9

Thread: How to Create Custom Chapter Missions and Intros for Any Faction

  1. #1

    Default How to Create Custom Chapter Missions and Intros for Any Faction

    This guide will explain how to make custom chapter missions, even for factions that are not normally playable. It assumes a basic knowledge of modding database tables and the startpos. In this example I will be using Massilia's entries as to create an introduction and missions for Liguria (Genua).

    *This tutorial assumes you have made the faction playable and that the faction has a Chapter Mission entry in its FACTION ARRAY. If it does not have that, it will not trigger any chapter missions. Factions made playable using the Assembly Kit should have the chapter missions unlocked. In order to insert a Chapter Mission array into an existing startpos, you must first use the esf to xml method to unpack the startpos. You can then manually insert the Chapter mission parameters into the FACTION ARRAY.

    Files you will need in your mod pack (Example is for the Grand Campaign):
    /campaigns/main_rome/startpos.esf with the new faction set as playable
    /campaigns/main_rome/missions.txt
    /campaigns/main_rome/scripting.lua
    /db/advice_levels_table
    /db/advice_threads_table
    /db/missions_table
    /lua_scripts/export_advice.lua
    /text/db/advice_levels.loc
    /text/db/mission_text.loc
    /text/db/missions.loc

    Step One: Create a Custom Introduction for the Faction
    - Every faction has a custom introduction that triggers the chapter missions for that faction.
    1. Create a custom advice entry for your new introduction. Open /db/advice_levels and find an existing faction intro. They will have a key that looks like "3088_TWRII_Faction_Intro_Massilia_1_Thread". Clone that row.
    2. Find the row you just cloned and change the Key and ID number to custom values. For our example we will use "40001_TWRII_Faction_Intro_Liguria_1_Thread" and 40001 as the ID to keep it simple. In the advice_levels.loc file, make new entries for the title and description of your introduction.
    3. Create an entry in /db/advice_threads that matches the custom key you made. For our example, "40001_TWRII_Faction_Intro_Liguria_1_Thread". These 2 tables can be made into fragments and simply have these entries only, if you prefer.
    4. Open /lua_scripts/export_advice.lua and find an entry for one of the faction introductions. They should look like this:
    Code:
    --[[ 3088_TWRII_Faction_Intro_Massilia_1_Trigger ]]--
    
    function impl_3088_TWRII_Faction_Intro_Massilia_1_Trigger (context)
            return conditions.FactionIsLocal(context) and conditions.FactionName("rom_massilia", context) and conditions.CampaignName("main_rome", context) and conditions.TurnNumber(context) == 1
    end 
    
    
    events.FactionTurnStart[#events.FactionTurnStart+1] =
    function (context)
        if impl_3088_TWRII_Faction_Intro_Massilia_1_Trigger(context) then
            effect.advance_contextual_advice_thread("3088_TWRII_Faction_Intro_Massilia_1_Thread", 1, context)
            return true
        end
        return false
    end
    5. Copy that entry and paste it under the previous entry. Change each instance of the old key to the new one and also change the faction name. For our example it would now look like this:
    Code:
    --[[ 40001_TWRII_Faction_Intro_Liguria_1_Trigger ]]--
    
    
    function impl_40001_TWRII_Faction_Intro_Liguria_1_Trigger (context)
            return conditions.FactionIsLocal(context) and conditions.FactionName("rom_liguria", context) and conditions.CampaignName("main_rome", context) and conditions.TurnNumber(context) == 1
    end 
    
    
    events.FactionTurnStart[#events.FactionTurnStart+1] =
    function (context)
        if impl_40001_TWRII_Faction_Intro_Liguria_1_Trigger(context) then
            effect.advance_contextual_advice_thread("40001_TWRII_Faction_Intro_Liguria_1_Thread", 1, context)
            return true
        end
        return false
    end
    6. Open up campaigns/main_rome/scripting.lua. You will find various entries here that trigger the introductions and also the chapter missions. There are 5 parts to each of the faction scripts, you will need to add new entries to all 5.
    7. The first part transitions the advice trigger we just created in the export_advice.lua into the introduction. It looks like this:
    Code:
    -- MASSILIA
        elseif conditions.AdviceJustDisplayed("2139663973", context) and not CampaignUI.IsMultiplayer() and intro_advice_shown == false then
            out.ting("intro advice issued")
            ActivateCinematicCam(true)
            intro_advice_shown = true
            scripting.game_interface:scroll_camera_with_direction(5.5,    
                                                            {150.406403, 306.824707, 1.05, 0},
                                                            {150.406403, 306.824707, 0.76, 0})
            camera_pan = 380
    Copy that and paste it under the last entry. Change the number 2139663973 to the ID you chose for your custom advice entry above (40001). The coordinates should be coordinates of the starting city of that faction. You can find this in the startpos or by guessing . Set the camera_pan=# to 420 in your entry. This number increases by 10 for each new entry here and the final entry in the vanilla script is 410.
    8. The next entry to be copy and pasted looks like this:
    Spoiler Alert, click show to read: 
    Code:
    -- MASSILIA
        elseif camera_pan == 380 then
            scripting.game_interface:make_region_visible_in_shroud("rom_massilia", "rom_corsica_et_sardinia_corsica");
            scripting.game_interface:make_region_visible_in_shroud("rom_massilia", "rom_cisalpina_liguria");
            scripting.game_interface:scroll_camera_with_direction(8.5,
                                                    {150.406403, 306.824707, 0.76, 0},
                                                    {172.036133, 293.137665, 0.76, 0},
                                                    {176.476837, 328.051575, 0.76, 0})
            camera_pan = 381        
        elseif camera_pan == 381 then
            scripting.game_interface:make_region_visible_in_shroud("rom_massilia", "rom_raetia_et_noricum_helvetia");
            scripting.game_interface:scroll_camera_with_direction(4.5,
                                                    {176.476837, 328.051575, 0.76, 0},
                                                    {168.45517, 355.067596, 0.76, 0})
            camera_pan = 382    
        elseif camera_pan == 382 then
            scripting.game_interface:scroll_camera_with_direction(2,
                                                    {168.45517, 355.067596, 0.76, 0},
                                                    {168.45517, 355.067596, 0.76, 0.15})
            camera_pan = 383        
        elseif camera_pan == 383 then
            scripting.game_interface:make_region_visible_in_shroud("rom_massilia", "rom_cisalpina_insubria");
            scripting.game_interface:scroll_camera_with_direction(3,
                                                    {168.45517, 355.067596, 0.76, 0.15},
                                                    {185.166992, 342.331482, 0.76, 0})
            camera_pan = 384        
        elseif camera_pan == 384 then
            scripting.game_interface:scroll_camera_with_direction(2,
                                                    {185.166992, 342.331482, 0.76, 0},
                                                    {185.166992, 342.331482, 0.76, 0.15})
            camera_pan = 385
    
    
        elseif camera_pan == 385 then
            scripting.game_interface:scroll_camera_with_direction(6,
                                                    {185.166992, 342.331482, 0.76, 0.15},
                                                    {120.993591, 314.543579, 0.76, 0})                                            
            camera_pan = 386
        elseif camera_pan == 386 then
            scripting.game_interface:make_region_visible_in_shroud("rom_massilia", "rom_provincia_narbonensis");
            scripting.game_interface:scroll_camera_with_direction(4,
                                                    {120.993591, 314.543579, 0.76, 0},
                                                    {120.993591, 314.543579, 0.76, 0.15})                                                
            camera_pan = 387    
        elseif camera_pan == 387 then
            scripting.game_interface:scroll_camera_with_direction(4,
                                                    {120.993591, 314.543579, 0.76, 0.15},
                                                    {150.406403, 306.824707, 0.76, 0.15})
            camera_pan = 388    
        elseif camera_pan == 388 then
            scripting.game_interface:scroll_camera_with_direction(3,
                                                    {150.406403, 306.824707, 0.76, 0.15},
                                                    {150.406403, 306.824707, 0.76, 0})
            camera_pan = 389
        elseif camera_pan == 389 then
            panning = false
            ActivateCinematicCam(false)
            CampaignUI.SetCameraZoom(0.76)
            CampaignUI.SetCameraHeading(0.0)
            CampaignUI.SetCameraTargetInstant(150.406403, 306.824707)
            camera_pan = 0
            scripting.game_interface:add_time_trigger("rom_intro_mission_massilia", 0.01)

    9. These are the commands for the camera's movement. The easiest thing to do is simply create an entry that stays at one spot. But, you can choose to make multiple entries for the camera movement. The key is that you need the first and last entry at least and you must change the numbers to the new values. In the previous step we changed the camera_pan value to 420. That was the trigger for the script to begin the camera pan.
    10. So, take the new script you copied from above and change the values to start with 420 (instead of 380) and move up to 429. At the very least you need both 420 and 429. The coordinate values are where the camera will travel and how it will orient. Finally, change the last text "rom_intro_mission_massilia" to your own custom entry. Let's use "rom_intro_mission_liguria" for our example.
    11. The third part of the script to copy and paste looks like this:
    Code:
    elseif camera_pan >= 380 and camera_pan <= 389 then
                camera_pan = 389
                OnCameraMoverFinished(context)
    This is simply telling the script that if the camera pan stops before 389, assume it is the 389 value. Copy that and paste it, then change the values to 420 rather than 380 and 429 rather than 389.
    12. The fourth part looks like this:
    Code:
    elseif conditions.FactionName("rom_massilia", context) and conditions.FactionIsHuman("rom_massilia", context) and camera_pan==0 then
                out.ting("local player is Massilia and intro camera pan is not being played")
                CampaignUI.SetCameraZoom(0.85)
                CampaignUI.SetCameraHeading(0.0)
                CampaignUI.SetCameraTargetInstant(150.406403, 306.824707)
    Copy/paste it under the final part and change the faction name to your faction, in our case rom_liguria. The coordinates at the end are the city coordinates.
    13. The final script to add is:
    Code:
    elseif (context.string == "rom_intro_mission_massilia") or ((context.string == "check_intro_runs") and (intro_advice_shown == false) and (player_faction == "rom_massilia")) then
            scripting.game_interface:trigger_custom_mission("rom_massilia", "objective_massilia_1_primary")
            out.ting("DEBUG: Intro advice shown:"..tostring(intro_advice_shown))
    This triggers the Chapter Missions. Change the rom_intro_mission_massilia to the custom entry you created above (rom_intro_mission_liguria in our example). Change the faction name and also change the entry "objective_massilia_1_primary" to a custom entry. We will use "objective_liguria_1_primary."
    Last edited by Dresden; January 09, 2015 at 10:50 PM.

    ----> Website -- Patreon -- Steam -- Forums -- Youtube -- Facebook <----

  2. #2

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction [WIP]

    Step Two: Creating the Custom Missions
    - Now that we have a working faction introduction for our new faction, we can create custom chapter missions that will be triggered from that introduction script.
    1. Open the /db/missions table and find a group of vanilla mission entries for chapter missions. They will have names like "objective_massilia_1_primary". Select all 9 entries for one of the factions, in our example massilia. Clone those rows and rename them to match the name you used in the script above. For our example its "objective_liguria_1_primary." Rename each row (1-9). You can once again use a table fragment here with only your new entries if you choose.
    2. Open /campaigns/main_rome/missions.txt. Find one of the faction mission groups you want to copy. You can technically make your own from scratch but its easier to use an existing one as we did with the script entries above. For example, the start of Massilia's mission entry looks like this:
    Code:
    //************** MASSILIA ****************//
    	mission
    	{
    		chapter 1;						
    		key objective_massilia_1_primary;	// First chapter-based mission for massilia
    		issuer CLAN_ELDERS;			
    		primary_objectives_and_payload		
    		{	
    			heading		mission_text_text_objective_1_primary_heading;
    			description mission_text_text_objective_1_primary_description;
    			objective
    			{
    				type CONTROL_N_PROVINCES_INCLUDING;
    				total 2;
    			}
    			payload
    			{
    				money 2500;
    				issue_mission objective_massilia_2_primary;
    			}
    		}
    		secondary_objectives_and_payloads
    		{
    			objectives_and_payload
    			{					
    				heading		mission_text_text_objective_massilia_1_1_heading;
    				description 	mission_text_text_objective_massilia_1_1_description;
    				objective
    				{
    				type CONTROL_N_REGIONS_INCLUDING;
    				total 1;
    				region rom_cisalpina_liguria;
    				}
    				payload
    				{
    					money 1500;
    				}
    			}
    			objectives_and_payload		
    			{					
    				heading		mission_text_text_objective_massilia_1_2_heading;
    				description 	mission_text_text_objective_massilia_1_2_description;
    				objective
    				{
    					type RESEARCH_TECHNOLOGY;	
    					technology rom_black_sea_dlc_voyages_of_pytheas;
    				}
    				payload
    				{
    					money 1000;
    				}
    			}
    		}
    	}
    3. Copy Massilia's entire entry (or the faction you are using instead). It is a long entry, copy all mission script entries from 1-9 for that faction. Paste the entries at the bottom of the script file. Rename the part that says "key objective_massilia_1_primary" to whatever you chose for your mission key above. For us it will be "key objective_liguria_1_primary." Do this for all 9 primary mission entries.
    4. Now, you can customize both the text and the actual mission parameters. First, you can change the primary mission heading (which is normally shared by all factions and is found in the missions.loc text file). Second, you can change the secondary mission heading and text which is faction specific. For example, in the script above you will see "mission_text_text_objective_massilia_1_1_heading;". You can change that to, for example, "mission_text_text_objective_liguria_1_1_heading;"
    5. Open up /text/db/mission_text.loc. Here you can add a heading and description for your new mission entry that you just created. Do this for all the various custom missions you wish to use. You can also use the existing missions from the faction you copied as a template to reduce the workload.
    6. The mission scripts themselves can be customized to change the mission parameters and income payload. If you look through the various faction missions you will see multiple different options for your missions. Simply copy/paste those commands over the commands you wish to replace, changing province names, region names or faction names to suit your purpose.
    7. The missions are broken up into a primary mission and multiple secondary missions. When the primary mission is completed, it moves the script to the next primary mission and also completes the secondary missions if the player has met the parameters. You can change both primary and secondary mission parameters according to your desired outcome for the faction.
    Last edited by Dresden; January 08, 2015 at 03:32 PM.

    ----> Website -- Patreon -- Steam -- Forums -- Youtube -- Facebook <----

  3. #3

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction

    Thanks a lot, i'd been trying to do this for a long time!

  4. #4

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction

    Thank you very much for the tutorial, I was able to edit chapter missions and intro sequences so far but I still need to find the entry in the startpos file to trigger the missions that you have talked about at the beginning.

  5. #5

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction

    You have to tag them as playable if you create a startpos using BoB. Otherwise its something you have to manually edit into the startpos using a third party exporter.

    ----> Website -- Patreon -- Steam -- Forums -- Youtube -- Facebook <----

  6. #6

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction

    So basically I set the bit playable to 1 and a chapter mission entry should pop up in the faction array?

  7. #7

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction

    If you set them to playable in the assembly kit and export the startpos, the faction should then have the chapter mission entry in their faction array.

    ----> Website -- Patreon -- Steam -- Forums -- Youtube -- Facebook <----

  8. #8
    Gyan-Avspar's Avatar Foederatus
    Join Date
    Aug 2017
    Location
    Islamic Republic of Iran,Mazandaran,Chalus
    Posts
    44

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction

    Excellent!!!
    Last edited by Gyan-Avspar; September 29, 2017 at 12:28 AM.

  9. #9

    Default Re: How to Create Custom Chapter Missions and Intros for Any Faction

    Great Tutor! But it does not work with Emperor campaign. For example there are completely no strings of factions' objectives in export_advice.lua. Could you please make such Tutorial for Augustus map factions?
    Regards!

Posting Permissions

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