Page 1 of 6 123456 LastLast
Results 1 to 20 of 105

Thread: The S2 Script-o-Rama

  1. #1

    Default The S2 Script-o-Rama

    The S2 Script-o-Rama is a resource based on alpaca's ETW Script-o-Rama and my NTW Script-o-Rama that aims to serve many similar purposes:
    Firstly it's meant as a general scripting discussion point, so if you'd like to just talk about some freak ideas or anything, they're welcome here.
    Secondly it will serve as a focal point for scripting help and advice. You will find a lot of information here that alpaca never got round to posting in his old thread, but that is common knowledge among us more experienced scripters. I will also keep an eye on this thread and whenever I get the chance try to help people out with scripting related issues

    As of yet this is a direct copy of the NTW Script-o-Rama and can simply be used as a reference manual for those looking to do some basic S2 scripting. I've started documenting functions for S2, but I don't have time to post them here yet (as you can see this thread takes a lot of manual formatting to be so accessible).

    NOTE: Some of the content here is completely alpaca's work, I have just updated it and added a lot of new info. Credit goes to him for the idea and the basis of this work


    Table of Contents:

    I. Basic Introduction & Scripting Documentation

    II. Script Writing Tutorials
    III. Miscellaneous





    Section I: Basic Introduction & Scripting Documentation


    This section will explain some basic scripting rules, and give some tips to help get you started. Also contained here is extensive script documentation on usage, output, arguments and caveats.


    I.1 Basics:

    Click to view content: 

    Scripting Language:
    NTW uses Lua. So what is Lua?
    Lua is a powerful, fast, lightweight, embeddable scripting language.
    Lua is an open source, very fast, real-world scripting language. This means that in-game scripting is not technically limited to functions provided by the game - we can extend it with operators and functions that are not ever seen in CA's scripting code. Although this doesn't offer us much in terms of practicality for simple scripting, it can be put to great use for those interested in more advanced scripting.

    Case sensitivity:
    All Lua functions and objects are case-sensitive. That is, CampaignUI is not equal to campaignui, campaignUi or anything like that. So a mistake with case will cause your script to malfunction.

    Whitespace:
    Lua ignores whitespace, where applicable. So 3 > 1 is the same as 3>1 is the same as 3> 1

    Key Words:
    Click to view content: 
    • Strings: Strings are sentences containing numbers, characters or symbols. They begin and end with quotation marks. Eg:
      Code:
      "Hello World"
    • Boolean Values: Boolean values can only be true or false
    • Type: The type of a variable can either be boolean, function, nil, number, string, table, thread or userdata. If any function requests a variable of a certain type, and a variable of a different type is passed to it it may well cause a CTD.
    • int: Short for integer. (Negative or positive whole number)
    • Comments:Comments are part of the scripting file that will be ignored by the game. A normal comment begins with "--" (without the quotes) and lasts the length of the line. A long comment begins with "--[[" (without the quotes) and ends with "]]--" (without the quotes). Long comments comment everything inside them out, so can be used to efficiently comment out large blocks of code. Examples:
      Code:
      --I'm a short comment
      --[[And 
      I'm
      A
      Long
      Comment ]]--



    Basic Lua Operators & Statements:
    Click to view content: 

    Arithmetic Operators:
    Click to view content: 

    • Addition:
      +
    • Subtraction:
      -
    • Multiplication:
      *
    • Division:
      /
    • Exponentiation:
      ^

    Relational Operators:
    Click to view content: 

    • Equal to:
      ==
    • Not equal to:
      ~=
    • Less than:
      <
    • Less than or equal to:
      <=
    • Greater than:
      >
    • Greater than or equal to:
      >=

    Logical Operators:
    Note: Logical operators are sometimes referred to as Boolean Operators, but they can be given non-boolean values.
    Click to view content: 

    • and
      and takes two or more arguments and only returns true if they are all true
    • or
      or only gives a false result if both of it's arguments are false
    • not
      not is, simply put, a logical no. Putting not before a statement that would otherwise return true, will make it return false and vice versa.


    Basic Statements:
    Click to view content: 

    • if
    • while
      while is a type of loop. I'll not be explaining loops here, you can find tutorials on them with google very easily.
    • for
      Another type of loop.


    Backslash Escaping (Very important for logging):
    Click to view content: 
    Backslash escaping allows the user to do things inside strings that would normally be quite akward to do. It is a very simple method of manipulating text. The following list contains the most relevant escape sequences used in game scripting:
    • \n - Newline. This moves the following text onto a new line.
    • \t - Tab. This tabs horizontally.
    • \\ - Backslash. This allows a single backslah to be inserted into the text.
    • \" - double quote. This allows a double quote to be inserted without ending the string.


    Concatenation:
    Click to view content: 
    Lua's string concatenation operator is written as follows:
    Code:
    ..
    That's two periods with no spaces between them. The whitespace rule does not apply here as this is an operator, which is easy to forget.
    It is used for splicing strings together, as follows(output is listed respectively in the next spoiler):
    Code:
    print("Hello".."World")
    
    ScriptORamaVariable = "World"
    print("Hello "..ScriptORamaVariable)
    And the output:

    Code:
    HelloWorld
    Hello World
    Notice that it doesn't put spaces between arguments there for you (the first example), so it has to be done manually(the second example).






    I.2 Effects
    The game's general effect library not specifically geared towards scripting. From here you can do stuff like edit cash amounts, edit traits + ancillaries etc.
    Click to view content: 

    The following functions are documented here:
    adjust_treasury
    ancillary
    remove_ancillary
    trait
    remove_trait
    historical_event



    Documentation:

    adjust_treasury(int amount, context)
    effect.adjust_treasury will change the treasury of a certain faction.
    Spoiler Alert, click show to read: 

    Parameters: Amount of money (int), context

    Example:
    Code:
    events.FactionTurnStart[#events.FactionTurnStart+1] =
    function (context)
    	effect.adjust_treasury(-1000,context)
    end


    ancillary(Ancillary name (string), Chance of ancillary being added (int), context)
    effect.ancillary() will add the given ancillary to the selected character.
    Spoiler Alert, click show to read: 

    Parameters: Ancillary name (string), % Chance of ancillary being added (int), context

    Example:
    Code:
    events.CharacterTurnEnd[#events.CharacterTurnEnd+1] = 
    function (context)
    	effect.ancillary("Anc_Balloonist", 100,  context)
    end


    remove_ancillary(Ancillary name (string), context)
    effect.remove_ancillary() will remove the given ancillary from the selected character.
    Spoiler Alert, click show to read: 

    Parameters: Ancillary name (string), context

    Example:
    Code:
    events.CharacterTurnEnd[#events.CharacterTurnEnd+1] = 
    function (context)
    	effect.remove_ancillary("Anc_Balloonist", context)
    end


    trait(Trait name(string), Game entity type(string), Trait points to add(int), % Chance of trait being added(int), context)
    effect.trait() will add the given trait to the selected game entity.
    Spoiler Alert, click show to read: 

    Parameters: Trait name(string), Game entity type(string), Trait points to add(int), % Chance of trait being added(int), context

    Example:
    Code:
    events.CharacterTurnEnd[#events.CharacterTurnEnd+1] = 
    function (context)
    	effect.trait("C_Admiral_Attacker_Good", "agent", 2, 12, context)
    end


    remove_trait(Trait name(string), POSSIBLY NEEDS: Game entity type(string), context)
    effect.remove_trait() will remove the given trait from the selected game entity.
    Spoiler Alert, click show to read: 

    Parameters: Trait name(string), POSSIBLY NEEDS: Game entity type(string), context

    Example:
    Code:
    events.CharacterTurnEnd[#events.CharacterTurnEnd+1] = 
    function (context)
    	effect.remove_trait("C_Admiral_Attacker_Good", "agent", context)
    end


    historical_event(Event key(string), context)
    effect.historical_event() will trigger a historic event.
    Spoiler Alert, click show to read: 

    Parameters: Event key(string), context
    Example:
    Code:
    events.HistoricalEvents[#events.HistoricalEvents+1] = 
    function (context)
    	effect.historical_event("luddite_movement", context)
    end





    I.3 Campaign UI
    CampaignUI seems to have loads of useful functions (see the list above). The main advantage of using CamaignUI is that the functions often don't require any arguments and return boolean values, making them very useable. CUI's main use is to retrieve data from the game - it has very little use for actually changing things.
    Click to view content: 

    The following functions are documented here:
    CurrentSeasonString
    CurrentTurn
    CurrentYear
    DisplayingTurns
    EndTurn
    EntityTypeSelected
    FactionDetails
    IsPlayersTurn
    InitialiseRegionInfoDetails
    IsCharacterPlayerControlled
    PlayerFactionId
    PrestigeDetails
    RetrieveDiplomacyDetails
    RetrieveDiplomaticOpinions
    RetrieveDiplomaticStanceString
    RegionsOwnedByFaction
    RetrieveFactionRegionList
    RetrieveFactionMilitaryForceLists



    Documentation:

    CurrentSeasonString()
    Calling CampaignUI.CurrentSeasonString() will return the current season as a string.
    Spoiler Alert, click show to read: 
    Returns: Current season as string. One of Summer or Winter

    Example:
    Code:
    CampaignUI.CurrentSeasonString() == "Summer"
    Notes:
    Be careful about case sensitivity


    CurrentTurn()
    Calling CampaignUI.CurrentTurn() will return the current turn number.
    Spoiler Alert, click show to read: 
    Returns: Current turn as int.

    Example:
    Code:
    CampaignUI.CurrentTurn() == 0


    CurrentYear()
    Calling CampaignUI.CurrentYear() will return the current year.
    Spoiler Alert, click show to read: 
    Returns: Current year as int.

    Example:
    Code:
    CampaignUI.CurrentYear() >= 1700


    DisplayingTurns()
    Calling CampaignUI.DisplayingTurns() will tell you if the game is displaying years or turns.
    Spoiler Alert, click show to read: 
    Returns: Boolean: true if displaying turns, false if displaying years

    Example:
    Code:
    if CampaignUI.DisplayingTurns() then
    ...
    end


    EndTurn()
    Calling CampaignUI.EndTurn() will end the turn.
    Spoiler Alert, click show to read: 
    Example:
    Code:
    CampaignUI.EndTurn()


    EntityTypeSelected()
    CampaignUI.EntityTypeSelected() will give you information about the currently selected game entity
    Spoiler Alert, click show to read: 
    Returns: Entity details table. Important here is CampaignUI.EntityTypeSelected().Entity which holds a pointer (e.g. a Character Pointer) that can be used in other functions

    Example:
    Code:
    CampaignUI.EntityTypeSelected()
    Will return a table containing this info:
    Code:
      Character: boolean: true
      Unit: boolean: false
      Slot: boolean: false
      Settlement: boolean: false
      Entity: userdata
        type: string: Pointer<CHARACTER>
        __tostring: function
        __eq: function
      LocalPlayerOwned: boolean: true
      Fort: boolean: false


    FactionDetails(string faction_key)
    CampaignUI.FactionDetails() will give you information about a certain faction.
    Spoiler Alert, click show to read: 
    Arguments: Faction ID string

    Returns: Faction details table

    Example:
    Code:
    CampaignUI.FactionDetails("britain")
    Will return a table containing this info:
    Code:
      VictoryConditions: table
        Regions: table
          1: table
            Name: string:New France
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          2: table
            Name: string:Georgia
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          3: table
            Name: string:Leeward Islands
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          4: table
            Name: string:Ireland
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          5: table
            Name: string:Gibraltar
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          6: table
            Name: string:Florida
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          7: table
            Name: string:Hindustan
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          8: table
            Name: string:Scotland
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
          9: table
            Name: string:England
            Address: userdata
              type: string:Pointer<REGION>
              __tostring: function
              __eq: function
        ConquestDescription: string:Capture and hold 25 regions by the end of the year 1750, including the regions shown.
        TotalRegionsNeeded: number
        PrestigeDescription: string:
      WealthRanking: string:Spectacular
      Leader: table
        ActionPointsPerTurn: number
        Flag: string:data\ui\flags\britain/portrait_flags.tga
        Title: string: 
        Traits: table
          1: table
            ExplanationText: string:This man has invested heavily in the navy.
            IconFilename: string:data/ui/campaign ui/pips/effect_characters.tga
            Name: string:Likes Uniforms
            Effects: table
              1: table
                Priority: number
                Description: string:-10% recruitment cost for all naval units
                IconFilename: string:data/ui/campaign ui/pips/effect_navy.tga
            ColourText: string:He has taken to wearing ceremonial uniforms at all times, which makes bathing a difficult business.
            AttributeEffects: table
            RemovalText: string:This trait can be lost by more balanced spending.
          2: table
            ExplanationText: string:Youthful obsessions are one thing, but they are supposed to be set aside.
            IconFilename: string:data/ui/campaign ui/pips/effect_characters.tga
            Name: string:Lewd and Loose
            Effects: table
              1: table
                Priority: number
                Description: string:-10 to diplomatic relations
                IconFilename: string:
            ColourText: string:This man's behaviour is boorish and nationally embarrassing, even if the ambassador's wife did have a fantastic arse!
            AttributeEffects: table
            RemovalText: string:This man's ways are set, unfortunately.
        Effects: table
          1: table
            Icon: string:
            Tooltip: string:-10 to diplomatic relations
          2: table
            Icon: string:data/ui/campaign ui/pips/effect_navy.tga
            Tooltip: string:-10% recruitment cost for all naval units
        PostEffects: table
          diplomacy: table
            Value: number
            Description: string:+0 to diplomatic relations
          prestige: table
            Value: number
            Description: string:+0 Prestige per turn
        FactionColour: table
          b: number
          g: number
          r: number
        ShowAsCharacter: boolean
        IsMilitary: boolean
        Attributes: table
          morale_sea: table
            Value: number
            AttributeName: string:Morale
            PipPath: string:PLACEHOLDER
          research: table
            Value: number
            AttributeName: string:Research Skill
            PipPath: string:data/ui/campaign ui/pips/skill_research.tga
          land_siege_engineering: table
            Value: number
            AttributeName: string:Siege engineering
            PipPath: string:PLACEHOLDER
          movement_points_land: table
            Value: number
            AttributeName: string:movement_points_land_name
            PipPath: string:PLACEHOLDER
          management: table
            Value: number
            AttributeName: string:Management Skill
            PipPath: string:data/ui/campaign ui/pips/skill_managing.tga
          PrimaryAttributePath: string:data/ui/campaign ui/pips/skill_managing.tga
          PrimaryAttributeName: string:Management Skill
          zeal: table
            Value: number
            AttributeName: string:Religious Zeal
            PipPath: string:data/ui/campaign ui/pips/skill_zeal.tga
          subterfuge: table
            Value: number
            AttributeName: string:Subterfuge Skill
            PipPath: string:data/ui/campaign ui/pips/skill_spying.tga
          duelling_swords: table
            Value: number
            AttributeName: string:Sword duelling
            PipPath: string:data/ui/campaign ui/pips/skill_swordfighting.tga
          duelling_pistols: table
            Value: number
            AttributeName: string:Pistol duelling
            PipPath: string:data/ui/campaign ui/pips/skill_shooting.tga
          morale_land: table
            Value: number
            AttributeName: string:Morale
            PipPath: string:PLACEHOLDER
          trade: table
            Value: number
            AttributeName: string:Trade
            PipPath: string:PLACEHOLDER
          PrimaryLevel: number
          land_defence_engineering: table
            Value: number
            AttributeName: string:Land defence engineering
            PipPath: string:PLACEHOLDER
          command_sea: table
            Value: number
            AttributeName: string:Command at Sea
            PipPath: string:data/ui/campaign ui/pips/skill_naval.tga
          command_land: table
            Value: number
            AttributeName: string:Command on Land
            PipPath: string:data/ui/campaign ui/pips/skill_command.tga
        Abilities: table
          can_research: boolean
          can_assassinate: boolean
          can_attack_naval: boolean
          can_build_religious: boolean
          can_attack_land: boolean
          can_receive_duel: boolean
          can_build_fort: boolean
          can_duel: boolean
          can_convert: boolean
          can_sabotage: boolean
          can_spy: boolean
        PostName: string:King
        CommanderType: number
        ActionPoints: number
        Post: string:faction_leader
        AgentType: string:Minister
        IsNaval: boolean
        SmallFlag: string:data\ui\flags\britain/small.tga
        UniformColour: table
          b: number
          g: number
          r: number
        MaskImage: string:
        TechImage: string:
        Playable: boolean
        CardImage: string:data/ui/portraits/european/cards/king/old/014.tga
        InfoImage: string:data/ui/portraits/european/Info/king/old/014.jpg
        Address: userdata
          type: string:Pointer<CHARACTER>
          __tostring: function
          __eq: function
        Location: string:England
        Name: string:William III
        Age: number
        Ancillaries: table
      PrestigeRanking: string:Sublime
      FlagPath: string:data\ui\flags\britain
      UniformColour: table
        B: number
        G: number
        R: number
      Address: userdata
        type: string:Pointer<FACTION>
        __tostring: function
        __eq: function
      Name: string:Great Britain
      PrimaryColour: table
        B: number
        G: number
        R: number
      Key: string:britain
      PowerRanking: string:Terrifying


    IsPlayersTurn()
    IsPlayersTurn returns a boolean stating the obvious
    Click to view content: 
    Returns: true or false depending on whether or not it is the player's turn.
    Example:
    Code:
    CampaignUI.IsPlayersTurn()




    InitialiseRegionInfoDetails(<Pointer>REGION)
    InitialiseRegionInfoDetails returns all info you can get on a certain region. You have to supply a pointer (get it from RegionsOwnedByFaction for example)
    Spoiler Alert, click show to read: 
    Arguments: Region pointer

    Returns: Region details table

    Example:
    Code:
    tab = CampaignUI.RegionsOwnedByFaction("france")
    	details = CampaignUI.InitialiseRegionInfoDetails(tab[1].Address)
    Will return a table containing this info:
    Code:
    UpperOrder: table
      1: table
        Total: number: 2
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Government type: 2 (Predicted)||Your government type has a positive effect on this class.
        Pip: string: data/ui/campaign ui/pips/government-happy.tga
        Tooltip: string: Government type: 2||Your government type has a positive effect on this class.
        EqualPipPredictedTooltip: string: Government type: 2 / 2 (Predicted)||Your government type has a positive effect on this class.
      2: table
        Total: number: 4
        Predicted: number: 0
        Positive: boolean: false
        PredictedTooltip: string: Tax burden: 4 (Predicted)||To lessen the tax burden on your population simply lower taxes.||You can do this on the Government panel.
        Pip: string: data/ui/campaign ui/pips/taxes-unhappy.tga
        Tooltip: string: Tax burden: 4||To lessen the tax burden on your population simply lower taxes.||You can do this on the Government panel.
        EqualPipPredictedTooltip: string: Tax burden: 4 / 4 (Predicted)||To lessen the tax burden on your population simply lower taxes.||You can do this on the Government panel.
      3: table
        Total: number: 5
        Predicted: number: 0
        Positive: boolean: false
        PredictedTooltip: string: People in government: 5 (Predicted) ||This is from your ministers' traits.||You can view all their traits on the Government panel.
        Pip: string: data/ui/campaign ui/pips/character_traits-unhappy.tga
        Tooltip: string: People in government: 5 ||This is from your ministers' traits.||You can view all their traits on the Government panel.
        EqualPipPredictedTooltip: string: People in government: 5 / 5 (Predicted) ||This is from your ministers' traits.||You can view all their traits on the Government panel.
      4: table
        Total: number: 1
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Government buildings (Repression): 1 (Predicted)||Increase repression in your regions by upgrading government buildings.
        Pip: string: data/ui/campaign ui/pips/buildings-repression.tga
        Tooltip: string: Government buildings (Repression): 1||Increase repression in your regions by upgrading government buildings.
        EqualPipPredictedTooltip: string: Government buildings (Repression): 1 / 1 (Predicted)||Increase repression in your regions by upgrading government buildings.
      5: table
        Total: number: 3
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: People in government (Repression): 3 (Predicted)||This is from your minister's traits.||You can view all their effects on the Government panel.
        Pip: string: data/ui/campaign ui/pips/character_traits-repression.tga
        Tooltip: string: People in government (Repression): 3||This is from your minister's traits.||You can view all their effects on the Government panel.
        EqualPipPredictedTooltip: string: People in government (Repression): 3 / 3 (Predicted)||This is from your minister's traits.||You can view all their effects on the Government panel.
      6: table
        Total: number: 1
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Town Watch (Repression): 1 (Predicted)||This is an expensive emergency measure to suppress unrest.
        Pip: string: data/ui/campaign ui/pips/policing-repression.tga
        Tooltip: string: Town Watch (Repression): 1||This is an expensive emergency measure to suppress unrest.
        EqualPipPredictedTooltip: string: Town Watch (Repression): 1 / 1 (Predicted)||This is an expensive emergency measure to suppress unrest.
      Total: number: -2
      IsPercentage: boolean: false
      PipValue: number: 1
    ReligionKey: string: rel_catholic
    WealthChange: number: 2
    Settlement: string: Cayenne
    Wealth: number: 782
    ActiveLowerClass: string: Lower Class
    TownWealth: table
      1: table
        Total: number: 3
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Ports: 3 (Predicted) ||Increase this by developing your trading ports and fisheries.
        Pip: string: data/ui/campaign ui/pips/eco-trade_harbour.tga
        Tooltip: string: Ports: 3 ||Increase this by developing your trading ports and fisheries.
        EqualPipPredictedTooltip: string: Ports: 3 / 3 (Predicted) ||Increase this by developing your trading ports and fisheries.
      2: table
        Total: number: 8
        Predicted: number: 1
        Positive: boolean: false
        PredictedTooltip: string: Tax: 9 (Predicted) ||Tax rates are slowing economic growth.||Reduce this by lowering tax rates.
        Pip: string: data/ui/campaign ui/pips/taxes-unhappy.tga
        Tooltip: string: Tax: 8 ||Tax rates are slowing economic growth.||Reduce this by lowering tax rates.
        EqualPipPredictedTooltip: string: Tax: 8 / 9 (Predicted) ||Tax rates are slowing economic growth.||Reduce this by lowering tax rates.
      3: table
        Total: number: 3
        Predicted: number: 2
        Positive: boolean: true
        PredictedTooltip: string: Enlightenment: 5 (Predicted) ||Researching certain technologies increases economic growth.
        Pip: string: data/ui/campaign ui/pips/town_research.tga
        Tooltip: string: Enlightenment: 3 ||Researching certain technologies increases economic growth.
        EqualPipPredictedTooltip: string: Enlightenment: 3 / 5 (Predicted) ||Researching certain technologies increases economic growth.
      PipValue: number: 50
      Total: number: -2
      IsPercentage: boolean: false
    Taxed: boolean: true
    ReligiousBreakdown: table
      1: table
        Change: number: 0
        Name: string: Animism
        Key: string: rel_animist
        Icon: string: data/ui/campaign ui/pips/animism.tga
        Percentage: number: 15.000000953674
      2: table
        Change: number: 0
        Name: string: Catholicism
        Key: string: rel_catholic
        Icon: string: data/ui/campaign ui/pips/roman_catholic.tga
        Percentage: number: 85.000007629395
    RegionWealth: table
      1: table
        Total: number: 440
        LostTooltip: string: Port: 0 (Predicted)
        Positive: boolean: true
        Tooltip: string: Port: 440
        EqualPipPredictedTooltip: string: Port: 440
        Predicted: number: 0
        Lost: number: 0
        PredictedTooltip: string: Port: 440 (Predicted)
        Pip: string: data/ui/campaign ui/pips/trade_port.tga
      2: table
        Total: number: 342
        LostTooltip: string: Spice exports: 0 (0 Pounds) (Predicted)
        Positive: boolean: true
        Tooltip: string: Spice exports: 342 (18 Pounds)
        EqualPipPredictedTooltip: string: Spice exports: 342 (18 Pounds)
        Predicted: number: 0
        Lost: number: 0
        PredictedTooltip: string: Spice exports: 342 (18 Pounds) (Predicted)
        Pip: string: data/ui/campaign ui/pips/spices.tga
      PipValue: number: 50
      Total: number: 782
      IsPercentage: boolean: false
    PopulationGrowth: table
      1: table
        Total: number: 0.29999998211861
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Subsistence agriculture: 0.3% (Predicted)||This is the background level of food production in the region.
        Pip: string: data/ui/campaign ui/pips/population_subsistence.tga
        Tooltip: string: Subsistence agriculture: 0.3%||This is the background level of food production in the region.
        EqualPipPredictedTooltip: string: Subsistence agriculture: 0.3% / 0.3% (Predicted)||This is the background level of food production in the region.
      2: table
        Total: number: 0.37000000476837
        Predicted: number: 0
        Positive: boolean: false
        PredictedTooltip: string: Tax burden: 0.37% (Predicted)||To counter this, simply lower taxes for the lower classes.||You can do this on the Government panel.
        Pip: string: data/ui/campaign ui/pips/taxes-unhappy.tga
        Tooltip: string: Tax burden: 0.37%||To counter this, simply lower taxes for the lower classes.||You can do this on the Government panel.
        EqualPipPredictedTooltip: string: Tax burden: 0.37% / 0.37% (Predicted)||To counter this, simply lower taxes for the lower classes.||You can do this on the Government panel.
      3: table
        Total: number: 5.0099997520447
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Immigration from the home theatre: 5.01% (Predicted)||Unhappiness drives people to seek a better life elsewhere.
        Pip: string: data/ui/campaign ui/pips/migration_happy.tga
        Tooltip: string: Immigration from the home theatre: 5.01%||Unhappiness drives people to seek a better life elsewhere.
        EqualPipPredictedTooltip: string: Immigration from the home theatre: 5.01% / 5.01% (Predicted)||Unhappiness drives people to seek a better life elsewhere.
      PipValue: number: 0.0099999997764826
      Total: number: 4.9399995803833
      IsPercentage: boolean: true
    UpperTax: number: 0.16489998996258
    Theatre: string: 1
    Effects: table
    Governor: table
      ActionPointsPerTurn: number: 0
      Flag: string: data\ui\flags\france/portrait_flags.tga
      Title: string:  
      Traits: table
        1: table
          ExplanationText: string: This fellow believes that ministers should set the right example.
          IconFilename: string: data/ui/campaign ui/pips/effect_characters.tga
          Name: string: Honest
          Effects: table
          ColourText: string: This man believes in truth and honesty, something he pursues through his work.
          AttributeEffects: table
            1: string: +1 to Management.
          RemovalText: string: This trait is permanent and cannot be lost.
        2: table
          ExplanationText: string: This man has done much for his nation's cultural landscape.
          IconFilename: string: data/ui/campaign ui/pips/effect_characters.tga
          Name: string: Sybarite
          Effects: table
            1: table
              Priority: number: 9019
              Description: string: +1 happiness (lower classes)
              IconFilename: string: data/ui/campaign ui/pips/effect_public_order.tga
            2: table
              Priority: number: 9017
              Description: string: -1 happiness (nobility)
              IconFilename: string: data/ui/campaign ui/pips/effect_public_order.tga
          ColourText: string: Whereas most people can be appeased with cheap whores and gin by the bucket, some of us have more refined tastes.
          AttributeEffects: table
          RemovalText: string: This character trait cannot be lost, only improved.
        3: table
          ExplanationText: string: The treasury has remained virtually untouched since he took charge.
          IconFilename: string: data/ui/campaign ui/pips/effect_characters.tga
          Name: string: Frugal and Thrifty
          Effects: table
            1: table
              Priority: number: 4
              Description: string: -2 to Management for treasury administration
              IconFilename: string: data/ui/campaign ui/pips/effect_economy.tga
            2: table
              Priority: number: 9017
              Description: string: -1 happiness (nobility)
              IconFilename: string: data/ui/campaign ui/pips/effect_public_order.tga
          ColourText: string: He keeps a tight rein on the privy purse strings, all expenditure must be justified in writing. In triplicate.
          AttributeEffects: table
            1: string: +1 to Management.
          RemovalText: string: This character trait can be lost by more generous use of tax income.
      PostEffects: table
        tax_efficiency: table
          Value: number: 4
          Description: string: +4% bonus to tax income across theatre
        repression: table
          Value: number: 2
          Description: string: +2 to repression across the theatre
        land_upkeep_cost: table
          Value: number: -4
          Description: string: -4% upkeep costs for all army units
      FactionColour: table
        b: number: 240
        g: number: 255
        r: number: 255
      ShowAsCharacter: boolean: true
      Effects: table
        1: table
          Icon: string: data/ui/campaign ui/pips/effect_public_order.tga
          Tooltip: string: +1 happiness (lower classes)
        2: table
          Icon: string: data/ui/campaign ui/pips/effect_public_order.tga
          Tooltip: string: -2 happiness (nobility)
        3: table
          Icon: string: data/ui/campaign ui/pips/effect_economy.tga
          Tooltip: string: -2 to Management for treasury administration
      IsMilitary: boolean: false
      Attributes: table
        morale_sea: table
          Value: number: -1
          AttributeName: string: Morale
          PipPath: string: PLACEHOLDER
        research: table
          Value: number: -1
          AttributeName: string: Research Skill
          PipPath: string: data/ui/campaign ui/pips/skill_research.tga
        land_siege_engineering: table
          Value: number: -1
          AttributeName: string: Siege engineering
          PipPath: string: PLACEHOLDER
        movement_points_land: table
          Value: number: -1
          AttributeName: string: movement_points_land_name
          PipPath: string: PLACEHOLDER
        management: table
          Value: number: 4
          AttributeName: string: Management Skill
          PipPath: string: data/ui/campaign ui/pips/skill_managing.tga
        PrimaryAttributePath: string: data/ui/campaign ui/pips/skill_managing.tga
        PrimaryAttributeName: string: Management Skill
        zeal: table
          Value: number: -1
          AttributeName: string: Religious Zeal
          PipPath: string: data/ui/campaign ui/pips/skill_zeal.tga
        subterfuge: table
          Value: number: -1
          AttributeName: string: Subterfuge Skill
          PipPath: string: data/ui/campaign ui/pips/skill_spying.tga
        duelling_swords: table
          Value: number: -1
          AttributeName: string: Sword duelling
          PipPath: string: data/ui/campaign ui/pips/skill_swordfighting.tga
        duelling_pistols: table
          Value: number: -1
          AttributeName: string: Pistol duelling
          PipPath: string: data/ui/campaign ui/pips/skill_shooting.tga
        morale_land: table
          Value: number: -1
          AttributeName: string: Morale
          PipPath: string: PLACEHOLDER
        trade: table
          Value: number: -1
          AttributeName: string: Trade
          PipPath: string: PLACEHOLDER
        PrimaryLevel: number: 5
        land_defence_engineering: table
          Value: number: -1
          AttributeName: string: Land defence engineering
          PipPath: string: PLACEHOLDER
        command_sea: table
          Value: number: -1
          AttributeName: string: Command at Sea
          PipPath: string: data/ui/campaign ui/pips/skill_naval.tga
        command_land: table
          Value: number: -1
          AttributeName: string: Command on Land
          PipPath: string: data/ui/campaign ui/pips/skill_command.tga
      Abilities: table
        can_research: boolean: false
        can_assassinate: boolean: false
        can_attack_naval: boolean: false
        can_build_religious: boolean: false
        can_attack_land: boolean: false
        can_receive_duel: boolean: false
        can_build_fort: boolean: false
        can_duel: boolean: false
        can_convert: boolean: false
        can_sabotage: boolean: false
        can_spy: boolean: false
      CommanderType: number: 0
      ActionPoints: number: 0
      Post: string: governor_america
      AgentType: string: Minister
      IsNaval: boolean: false
      SmallFlag: string: data\ui\flags\france/small.tga
      UniformColour: table
        b: number: 240
        g: number: 255
        r: number: 255
      MaskImage: string: 
      TechImage: string: 
      Playable: boolean: false
      CardImage: string: data/ui/portraits/european/Cards/minister/young/077.tga
      InfoImage: string: data/ui/portraits/european/Info/minister/young/077.jpg
      Address: userdata
        type: string: Pointer<CHARACTER>
        __tostring: function
        __eq: function
      Location: string: France
      Name: string: Gaston Rousseau
      Age: number: 43
      Ancillaries: table
    OwningFactionKey: string: france
    AdministrationCostPercentage: number: -0.029999999329448
    GovernorPercentage: number: 0.03999999910593
    LowerTax: number: 0.16489998996258
    BuildingPercentage: number: 0
    UpperTaxPercentage: number: 0.1499999910593
    PopulationNumber: number: 4390
    Population: string: 4390
    LowerTaxPercentage: number: 0.1499999910593
    Name: string: French Guyana
    Address: userdata
      type: string: Pointer<REGION>
      __tostring: function
      __eq: function
    LowerOrder: table
      1: table
        Total: number: 4
        Predicted: number: 0
        Positive: boolean: false
        PredictedTooltip: string: Tax burden: 4 (Predicted)||To lessen the tax burden on your population simply lower taxes.||You can do this on the Government panel.
        Pip: string: data/ui/campaign ui/pips/taxes-unhappy.tga
        Tooltip: string: Tax burden: 4||To lessen the tax burden on your population simply lower taxes.||You can do this on the Government panel.
        EqualPipPredictedTooltip: string: Tax burden: 4 / 4 (Predicted)||To lessen the tax burden on your population simply lower taxes.||You can do this on the Government panel.
      2: table
        Total: number: 2
        Predicted: number: 0
        Positive: boolean: false
        PredictedTooltip: string: People in government: 2 (Predicted) ||This is from your ministers' traits.||You can view all their traits on the Government panel.
        Pip: string: data/ui/campaign ui/pips/character_traits-unhappy.tga
        Tooltip: string: People in government: 2 ||This is from your ministers' traits.||You can view all their traits on the Government panel.
        EqualPipPredictedTooltip: string: People in government: 2 / 2 (Predicted) ||This is from your ministers' traits.||You can view all their traits on the Government panel.
      3: table
        Total: number: 1
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Government buildings (Repression): 1 (Predicted)||Increase repression in your regions by upgrading government buildings.
        Pip: string: data/ui/campaign ui/pips/buildings-repression.tga
        Tooltip: string: Government buildings (Repression): 1||Increase repression in your regions by upgrading government buildings.
        EqualPipPredictedTooltip: string: Government buildings (Repression): 1 / 1 (Predicted)||Increase repression in your regions by upgrading government buildings.
      4: table
        Total: number: 3
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: People in government (Repression): 3 (Predicted)||This is from your minister's traits.||You can view all their effects on the Government panel.
        Pip: string: data/ui/campaign ui/pips/character_traits-repression.tga
        Tooltip: string: People in government (Repression): 3||This is from your minister's traits.||You can view all their effects on the Government panel.
        EqualPipPredictedTooltip: string: People in government (Repression): 3 / 3 (Predicted)||This is from your minister's traits.||You can view all their effects on the Government panel.
      5: table
        Total: number: 1
        Predicted: number: 0
        Positive: boolean: true
        PredictedTooltip: string: Town Watch (Repression): 1 (Predicted)||This is an expensive emergency measure to suppress unrest.
        Pip: string: data/ui/campaign ui/pips/policing-repression.tga
        Tooltip: string: Town Watch (Repression): 1||This is an expensive emergency measure to suppress unrest.
        EqualPipPredictedTooltip: string: Town Watch (Repression): 1 / 1 (Predicted)||This is an expensive emergency measure to suppress unrest.
      IsPercentage: boolean: false
      PipValue: number: 1
      Total: number: -1
    ActiveUpperClass: string: Nobility
    ReligionIcon: string: data/ui/campaign ui/pips/roman_catholic.tga
    PopulationChange: number: 1


    IsCharacterPlayerControlled(CharacterPointer pointer)
    CampaignUI.IsCharacterPlayerControlled() will tell you whether a character is controlled by the player.
    Spoiler Alert, click show to read: 

    Returns: boolean true or false

    Example:
    Code:
    entity = CampaignUI.EntityTypeSelected()
    if entity.Character then
    	if CampaignUI.IsCharacterPlayerControlled(entity.Entity) then
    		...
    	end
    end


    PlayerFactionId()
    Calling CampaignUI.PlayerFactionId() will return the player's faction key.
    Spoiler Alert, click show to read: 
    Returns: Faction ID as a string, e.g. "britain"

    Example:
    Code:
    CampaignUI.PlayerFactionId() == "britain"


    PrestigeDetails()
    CampaignUI.PrestigeDetails() will give you access to the prestige points for each faction
    Spoiler Alert, click show to read: 

    Returns: Prestige details table

    Example:
    Code:
    CampaignUI.PrestigeDetails()
    Will return a table containing this info:
    Code:
     scale: number: 34
      factions: table
        1: table
          faction_colour: table
            b: number: 0
            g: number: 0
            r: number: 0.8705883026123
          history: table
            1: table
              military: number: 5
              overall: number: 30
              enlightenment: number: 5
              naval: number: 10
              economics: number: 10
            2: table
              military: number: 5
              overall: number: 30
              enlightenment: number: 5
              naval: number: 10
              economics: number: 10
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Great Britain
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: britain
          flag_path: string: data\ui\flags\britain
          is_ally: boolean: false
        2: table
          faction_colour: table
            b: number: 0.94117653369904
            g: number: 1
            r: number: 1
          history: table
            1: table
              military: number: 18
              overall: number: 34
              enlightenment: number: 4
              naval: number: 5
              economics: number: 7
            2: table
              military: number: 18
              overall: number: 34
              enlightenment: number: 4
              naval: number: 5
              economics: number: 7
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: France
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: france
          flag_path: string: data\ui\flags\france
          is_ally: boolean: false
        3: table
          faction_colour: table
            b: number: 0.33725491166115
            g: number: 0.56470590829849
            r: number: 0.64705884456635
          history: table
            1: table
              military: number: 17
              overall: number: 24
              enlightenment: number: 0
              naval: number: 0
              economics: number: 7
            2: table
              military: number: 17
              overall: number: 24
              enlightenment: number: 0
              naval: number: 0
              economics: number: 7
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Austria
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: austria
          flag_path: string: data\ui\flags\austria
          is_ally: boolean: true
        4: table
          faction_colour: table
            b: number: 0.11372549831867
            g: number: 0.5137255191803
            r: number: 1
          history: table
            1: table
              military: number: 0
              overall: number: 23
              enlightenment: number: 5
              naval: number: 5
              economics: number: 13
            2: table
              military: number: 0
              overall: number: 23
              enlightenment: number: 5
              naval: number: 5
              economics: number: 13
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: United Provinces
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: netherlands
          flag_path: string: data\ui\flags\netherlands_republic
          is_ally: boolean: true
        5: table
          faction_colour: table
            b: number: 0.0039215688593686
            g: number: 0.85098046064377
            r: number: 0.99215692281723
          history: table
            1: table
              military: number: 5
              overall: number: 23
              enlightenment: number: 0
              naval: number: 8
              economics: number: 10
            2: table
              military: number: 5
              overall: number: 23
              enlightenment: number: 0
              naval: number: 8
              economics: number: 10
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Spain
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: spain
          flag_path: string: data\ui\flags\spain
          is_ally: boolean: false
        6: table
          faction_colour: table
            b: number: 0.32549020648003
            g: number: 0.19215688109398
            r: number: 0
          history: table
            1: table
              military: number: 16
              overall: number: 16
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            2: table
              military: number: 16
              overall: number: 16
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Prussia
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: prussia
          flag_path: string: data\ui\flags\prussia
          is_ally: boolean: false
        7: table
          faction_colour: table
            b: number: 0.21960785984993
            g: number: 0.18823531270027
            r: number: 0.62745100259781
          history: table
            1: table
              military: number: 10
              overall: number: 13
              enlightenment: number: 0
              naval: number: 0
              economics: number: 3
            2: table
              military: number: 10
              overall: number: 13
              enlightenment: number: 0
              naval: number: 0
              economics: number: 3
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Poland-Lithuania
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: poland_lithuania
          flag_path: string: data\ui\flags\poland_lithuania
          is_ally: boolean: false
        8: table
          faction_colour: table
            b: number: 0
            g: number: 0
            r: number: 0.52549022436142
          history: table
            1: table
              military: number: 6
              overall: number: 16
              enlightenment: number: 0
              naval: number: 0
              economics: number: 10
            2: table
              military: number: 6
              overall: number: 16
              enlightenment: number: 0
              naval: number: 0
              economics: number: 10
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Ottoman Empire
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: ottomans
          flag_path: string: data\ui\flags\ottomans
          is_ally: boolean: false
        9: table
          faction_colour: table
            b: number: 0.13333334028721
            g: number: 0.41568630933762
            r: number: 0.13333334028721
          history: table
            1: table
              military: number: 16
              overall: number: 16
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            2: table
              military: number: 16
              overall: number: 16
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Russia
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: russia
          flag_path: string: data\ui\flags\russia
          is_ally: boolean: false
        10: table
          faction_colour: table
            b: number: 0.60000002384186
            g: number: 0.35686275362968
            r: number: 0.05882353335619
          history: table
            1: table
              military: number: 11
              overall: number: 12
              enlightenment: number: 0
              naval: number: 1
              economics: number: 0
            2: table
              military: number: 11
              overall: number: 12
              enlightenment: number: 0
              naval: number: 1
              economics: number: 0
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Sweden
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: sweden
          flag_path: string: data\ui\flags\sweden
          is_ally: boolean: false
        11: table
          faction_colour: table
            b: number: 0.10980392992496
            g: number: 0.41960787773132
            r: number: 0.70980393886566
          history: table
            1: table
              military: number: 7
              overall: number: 7
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            2: table
              military: number: 7
              overall: number: 7
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Maratha Confederacy
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: maratha
          flag_path: string: data\ui\flags\maratha
          is_ally: boolean: false
        12: table
          faction_colour: table
            b: number: 0.10588236153126
            g: number: 0.41960787773132
            r: number: 0.37647062540054
          history: table
            1: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            2: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            3: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            4: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            5: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
            6: table
              military: number: 0
              overall: number: 0
              enlightenment: number: 0
              naval: number: 0
              economics: number: 0
          name: string: Mughal Empire
          is_enemy: boolean: false
          is_neighbouring: boolean: false
          key: string: mughal
          flag_path: string: data\ui\flags\mughal
          is_ally: boolean: false


    RetrieveDiplomacyDetails(Faction Key (string))
    RetrieveDiplomacyDetails returns a table with diplomacy details of the given faction.
    Click to view content: 
    Returns: A table with diplomacy details of the faction.
    Example:
    Code:
    RetrieveDiplomacyDetails("france")
    Example Returns:
    Code:
    TradeRights	table: 1AD793B8
    				wurttemberg	table: 1AD79518
    						Flag	data\ui\flags\wurttemberg/small.tga
    						Name	Baden-Württemberg
    						Label	wurttemberg
    				italy_kingdom	table: 1AD79458
    						Flag	data\ui\flags\italy_kingdom/small.tga
    						Name	Kingdom of Italy
    						Label	italy_kingdom
    				netherlands	table: 1AD7FF58
    						Flag	data\ui\flags\united_netherlands/small.tga
    						Name	Batavian Republic
    						Label	netherlands
    				swiss_confederation	table: 1AD79478
    						Flag	data\ui\flags\swiss_confederation/small.tga
    						Name	Swiss Confederation
    						Label	swiss_confederation
    				spain	table: 1AD7FDD8
    						Flag	data\ui\flags\spain/small.tga
    						Name	Spain
    						Label	spain
    AtWar	table: 1AD79378
    				austria	table: 1AD794B8
    						Flag	data\ui\flags\austria/small.tga
    						Name	Austria
    						Label	austria
    				sicily	table: 1AD795B8
    						Flag	data\ui\flags\naples_sicily/small.tga
    						Name	Kingdom of Sicily
    						Label	sicily
    				naples	table: 1AD79558
    						Flag	data\ui\flags\naples/small.tga
    						Name	Kingdom of Naples
    						Label	naples
    				britain	table: 1AD794D8
    						Flag	data\ui\flags\britain/small.tga
    						Name	Great Britain
    						Label	britain
    				sweden	table: 1AD7FDF8
    						Flag	data\ui\flags\sweden/small.tga
    						Name	Sweden
    						Label	sweden
    				russia	table: 1AD79498
    						Flag	data\ui\flags\russia/small.tga
    						Name	Russia
    						Label	russia
    Protectorates	table: 1AD793F8
    ProtectorOf	table: 1AD79418
    Allies	table: 1AD79398
    				wurttemberg	table: 1AD794F8
    						Flag	data\ui\flags\wurttemberg/small.tga
    						Name	Baden-Württemberg
    						Label	wurttemberg
    				bavaria	table: 1AD79578
    						Flag	data\ui\flags\bavaria/small.tga
    						Name	Bavaria
    						Label	bavaria
    				italy_kingdom	table: 1AD79438
    						Flag	data\ui\flags\italy_kingdom/small.tga
    						Name	Kingdom of Italy
    						Label	italy_kingdom
    				netherlands	table: 1AD799B8
    						Flag	data\ui\flags\united_netherlands/small.tga
    						Name	Batavian Republic
    						Label	netherlands
    				swiss_confederation	table: 1AD79538
    						Flag	data\ui\flags\swiss_confederation/small.tga
    						Name	Swiss Confederation
    						Label	swiss_confederation
    				spain	table: 1AD799D8
    						Flag	data\ui\flags\spain/small.tga
    						Name	Spain
    						Label	spain


    RetrieveDiplomaticOpinions(Faction Key 1 (string), Faction Key 2(string))
    RetrieveDiplomaticOpinions returns the diplomatic opinions of two factions.
    Click to view content: 
    Returns: A string stating the diplomatic opinions of the given faction
    Example:
    Code:
    CampaignUI.RetrieveDiplomaticOpinions("france", "britain")
    Example Returns:
    Code:
    Hostile


    RetrieveDiplomaticStanceString(Faction Key 1 (string), Faction Key 2(string))
    RetrieveDiplomaticStanceString returns the diplomatic stance of two factions.
    Click to view content: 
    Returns: a string stating the diplomatic stance of the two given factions (at war, allied etc)
    Example:
    Code:
    CampaignUI.RetrieveDiplomaticStanceString("france", "britain")
    Example Returns:
    Code:
    at war


    RegionsOwnedByFaction(<faction_key>)
    CampaignUI.RegionsOwnedByFaction() will give you a list of all of a faction's regions
    Spoiler Alert, click show to read: 

    Parameters: Faction key as string

    Returns: Table with a list of region pointers and localised region names

    Example:
    Code:
    CampaignUI.RegionsOwnedByFaction("britain")
    Will return a table containing this info:
    Code:
    1: table
      Name: string: Ireland
      Address: userdata
        type: string: Pointer<REGION>
        __tostring: function
        __eq: function
    2: table
      Name: string: England
      Address: userdata
        type: string: Pointer<REGION>
        __tostring: function
        __eq: function
    3: table
      Name: string: Jamaica
      Address: userdata
        type: string: Pointer<REGION>
        __tostring: function
        __eq: function
    4: table
      Name: string: Bahamas
      Address: userdata
        type: string: Pointer<REGION>
        __tostring: function
        __eq: function
    5: table
      Name: string: Rupert's Land
      Address: userdata
        type: string: Pointer<REGION>
        __tostring: function
        __eq: function
    6: table
      Name: string: Scotland
      Address: userdata
        type: string: Pointer<REGION>
        __tostring: function
        __eq: function


    RetrieveFactionRegionList(<faction_key>)
    CampaignUI.RetrieveFactionRegionList() will give you a list of all of a faction's settlements. Similar to RegionsOwnedByFaction but returns settlement pointers instead of region pointers
    Spoiler Alert, click show to read: 

    Parameters: Faction key as string

    Returns: Table with a list of settlement pointers

    Example:
    Code:
    CampaignUI.RetrieveFactionRegionList("britain")
    Will return a table containing this info:
    Code:
    1: table
      SettlementAddress: userdata
        type: string: Pointer<SETTLEMENT>
        __tostring: function
        __eq: function
    2: table
      SettlementAddress: userdata
        type: string: Pointer<SETTLEMENT>
        __tostring: function
        __eq: function
    3: table
      SettlementAddress: userdata
        type: string: Pointer<SETTLEMENT>
        __tostring: function
        __eq: function
    4: table
      SettlementAddress: userdata
        type: string: Pointer<SETTLEMENT>
        __tostring: function
        __eq: function
    5: table
      SettlementAddress: userdata
        type: string: Pointer<SETTLEMENT>
        __tostring: function
        __eq: function
    6: table
      SettlementAddress: userdata
        type: string: Pointer<SETTLEMENT>
        __tostring: function
        __eq: function


    RetrieveFactionMilitaryForceLists(<faction_key>,armies/navies)
    CampaignUI.RetrieveFactionMilitaryForceLists() will give you a list of all of a faction's armies or navies.
    Spoiler Alert, click show to read: 

    Parameters: Faction key as string, armies or navies as bool (armies = true)

    Returns: Table with a huge list of army or navy details

    Example:
    Code:
    CampaignUI.RetrieveFactionMilitaryForceLists("france",true)
    Will return a table containing this info:
    Code:
    1: table
      ActionPointsPerTurn: number: 22
      Transitioning: boolean: false
      Ancillaries: table
      Traits: table
      Flag: string: data\ui\flags\france/portrait_flags.tga
      Effects: table
      Abilities: table
        can_research: boolean: false
        can_assassinate: boolean: false
        can_attack_naval: boolean: false
        can_build_religious: boolean: false
        can_attack_land: boolean: true
        can_receive_duel: boolean: false
        can_build_fort: boolean: false
        can_duel: boolean: false
        can_convert: boolean: false
        can_sabotage: boolean: false
        can_spy: boolean: false
      Attributes: table
        morale_sea: table
          Value: number: -1
          AttributeName: string: Morale
          PipPath: string: PLACEHOLDER
        research: table
          Value: number: -1
          AttributeName: string: Research Skill
          PipPath: string: data/ui/campaign ui/pips/skill_research.tga
        land_siege_engineering: table
          Value: number: -1
          AttributeName: string: Siege engineering
          PipPath: string: PLACEHOLDER
        movement_points_land: table
          Value: number: -1
          AttributeName: string: movement_points_land_name
          PipPath: string: PLACEHOLDER
        management: table
          Value: number: -1
          AttributeName: string: Management Skill
          PipPath: string: data/ui/campaign ui/pips/skill_managing.tga
        PrimaryAttributePath: string: data/ui/campaign ui/pips/skill_command.tga
        PrimaryAttributeName: string: Command on Land
        zeal: table
          Value: number: -1
          AttributeName: string: Religious Zeal
          PipPath: string: data/ui/campaign ui/pips/skill_zeal.tga
        subterfuge: table
          Value: number: -1
          AttributeName: string: Subterfuge Skill
          PipPath: string: data/ui/campaign ui/pips/skill_spying.tga
        duelling_swords: table
          Value: number: -1
          AttributeName: string: Sword duelling
          PipPath: string: data/ui/campaign ui/pips/skill_swordfighting.tga
        duelling_pistols: table
          Value: number: -1
          AttributeName: string: Pistol duelling
          PipPath: string: data/ui/campaign ui/pips/skill_shooting.tga
        morale_land: table
          Value: number: -1
          AttributeName: string: Morale
          PipPath: string: PLACEHOLDER
        trade: table
          Value: number: -1
          AttributeName: string: Trade
          PipPath: string: PLACEHOLDER
        PrimaryLevel: number: 1
        land_defence_engineering: table
          Value: number: -1
          AttributeName: string: Land defence engineering
          PipPath: string: PLACEHOLDER
        command_sea: table
          Value: number: -1
          AttributeName: string: Command at Sea
          PipPath: string: data/ui/campaign ui/pips/skill_naval.tga
        command_land: table
          Value: number: 0
          AttributeName: string: Command on Land
          PipPath: string: data/ui/campaign ui/pips/skill_command.tga
      IsMilitary: boolean: true
      FactionColour: table
        b: number: 240
        g: number: 255
        r: number: 255
      ShowAsCharacter: boolean: false
      PosX: number: 16.522933959961
      Soldiers: number: 122
      Units: number: 3
      PosY: number: 347.06695556641
      CommanderType: number: 5
      ActionPoints: number: 22
      Title: string:  
      AgentType: string: Brigadier
      IsNaval: boolean: false
      SmallFlag: string: data\ui\flags\france/small.tga
      UniformColour: table
        b: number: 240
        g: number: 255
        r: number: 255
      MaskImage: string: data/ui/units/icons/Euro_Provincial_Cavalry_icon_cavs_mask.tga
      TechImage: string: 
      Playable: boolean: true
      CardImage: string: data/ui/units/icons/Euro_Provincial_Cavalry_icon_cavs.tga
      InfoImage: string: 
      Address: userdata
        type: string: Pointer<CHARACTER>
        __tostring: function
        __eq: function
      Location: string: Paris
      Name: string: Charles Lagrange
      Age: number: 18
      CommandedUnit: table
        Charge: number: 7
        DisplayAsUnit: boolean: true
        Reloading: number: 0
        FactionColour: table
          b: number: 240
          g: number: 255
          r: number: 255
        Firepower: number: 0
        Manoeuvrability: string: manoeuverability_medium
        InTransit: boolean: false
        RecruitCost: number: 975
        CommanderType: number: 5
        Accuracy: number: 0
        Id: string: unit35
        Defence: number: 5
        knowledge_mask: number: 15
        PromotionCost: number: 1950
        IsArtillery: boolean: false
        Replenished: boolean: false
        Men: number: 30
        Ammunition: number: 0
        Description: string: These locally recruited cavalry are a valuable aid in keeping order.
        InfoPic: string: data/ui/units/info/euro_provincial_cavalry
        Replenishable: boolean: false
        UnitRecord: table
          Ammunition: number: 0
          RecruitTime: number: 1
          UpkeepCost: number: 310
          InfoPic: string: data/ui/units/info/euro_provincial_cavalry
          Class: string: Cavalry
          Range: number: 0
          MPCost: number: 650
          Key: string: euro_provincial_cavalry_gendarmerie
          IsArtillery: boolean: false
          IsNaval: boolean: false
          Experience: number: 0
          RecruitCost: number: 975
          Men: number: 60
          Defence: number: 5
          Reloading: number: 0
          Melee: number: 10
          Accuracy: number: 0
          Firepower: number: 0
          DisplayNumber: number: 60
          ClassID: number: 9
          Charge: number: 7
          Guns: number: 0
          Description: string: These locally recruited cavalry are a valuable aid in keeping order.
          Name: string: Gendarmerie
          Morale: number: 7
          SiegeUnit: boolean: false
          Icon: string: data/ui/units/icons/Euro_Provincial_Cavalry_icon_cavs
          LongDescription: string: 
    
    These light horsemen are often little more than mounted militia, but with a greater social standing. Cavalry always see themselves as better than footsoldiers, but in this case, it may be true. It is, after all, not cheap to purchase and maintain a decent horse, and this means that men with financial standing make up the majority of recruits.
    
    They are, however, not as disciplined as regular cavalry, simply because they do not have the time or available resources to learn the craft of war as thoroughly. They are, however, extremely useful in policing the rougher, lower orders and keeping the existing social structure intact.
    
    Historically, there are many examples of yeomanry or gendarmes turning on their own citizenry with surprising and horrific violence. They were widely used against the anti-factory Luddites in northern England and, most infamously, were responsible for the Peterloo Massacre in 1819, when the Manchester and Salford Yeomanry charged a mostly peaceful, but excited crowd, and cut down many unarmed protestors.
          MPCategory: number: 1
        RegimentName: string: 1st Regiment of Horse
        LongDescription: string: 
    
    These light horsemen are often little more than mounted militia, but with a greater social standing. Cavalry always see themselves as better than footsoldiers, but in this case, it may be true. It is, after all, not cheap to purchase and maintain a decent horse, and this means that men with financial standing make up the majority of recruits.
    
    They are, however, not as disciplined as regular cavalry, simply because they do not have the time or available resources to learn the craft of war as thoroughly. They are, however, extremely useful in policing the rougher, lower orders and keeping the existing social structure intact.
    
    Historically, there are many examples of yeomanry or gendarmes turning on their own citizenry with surprising and horrific violence. They were widely used against the anti-factory Luddites in northern England and, most infamously, were responsible for the Peterloo Massacre in 1819, when the Manchester and Salford Yeomanry charged a mostly peaceful, but excited crowd, and cut down many unarmed protestors.
        ExistingUnit: boolean: true
        Speed: number: 0
        UniformColour: table
          b: number: 240
          g: number: 255
          r: number: 255
        Icon: string: data/ui/units/icons/Euro_Provincial_Cavalry_icon_cavs
        NeedsRepair: boolean: false
        ActionPoints: number: 28
        RepairCost: number: 0
        Melee: number: 10
        IsNaval: boolean: false
        ShowAsCharacter: boolean: false
        UpkeepCost: number: 298
        Portrait: string: 
        Range: number: 0
        HullStrength: number: 0
        Morale: number: 7
        Experience: number: 0
        Address: userdata
          type: string: Pointer<UNIT>
          __tostring: function
          __eq: function
        Traits: table
        Guns: number: 0
        Name: string: Gendarmerie
        CommandersName: string: Charles Lagrange
    2: table
      ActionPointsPerTurn: number: 23
      Transitioning: boolean: false
      ...





    I.3 Game Interface
    Called by using scripting.game_interface (after requiring the EpisodicScripting package) this is the primary package to allow us to change things in the game. Unfortunately it doesn't have too much content yet.
    Click to view content: 

    The following functions are documented here:
    add_exclusion_zone
    add_restricted_unit_record
    add_restricted_building_level_record
    disable_movement_for_faction
    enable_movement_for_faction
    episodic_attack
    episodic_defend
    force_diplomacy
    grant_faction_handover
    grant_unit
    remove_restricted_building_level_record
    remove_restricted_unit_record
    show_shroud
    spawn_town_level
    trigger_custom_mission



    Documentation:

    add_exclusion_zone(left(int), top(int), right(int), bottom(int), exclude_armies(bool), exclude_navies(bool), exclude_agents(bool), faction key(string))
    add_exclusion_zone adds a no-go area for the AI.
    Spoiler Alert, click show to read: 

    Parameters: left(int), top(int), right(int), bottom(int), exclude_armies(bool), exclude_navies(bool), exclude_agents(bool), faction key(string)

    Example:
    Code:
    scripting.game_interface:add_exclusion_zone(-100, 100, 100, -100, true, true, true, "britain")



    add_restricted_unit_record(<unit_key>)
    add_restricted_unit_record allows you to remove a unit from being available for recruitment world-wide (similar to the SF units)
    Spoiler Alert, click show to read: 

    Parameters: Unit key as string (as it appears in the units table)

    Example:
    Code:
    scripting.game_interface:add_restricted_unit_record("euro_expat_infantry_regiments_etrangeres")


    add_restricted_building_level_record(building key(string))
    add_restricted_building_level_record allows you to remove a building from being available for building world-wide.
    Spoiler Alert, click show to read: 

    Parameters: Building key as string (as it appears in the db)

    Example:
    Code:
    scripting.game_interface:add_restricted_building_level_record("tFactory1_manufactory")


    disable_movement_for_faction(Faction Key(String))
    disable_movement_for_faction freezes movement for the specified faction
    Spoiler Alert, click show to read: 

    Parameters: Faction key as string (as it appears in the db)

    Example:
    Code:
    scripting.game_interface:disable_movement_for_faction("france")


    enable_movement_for_faction(Faction Key(String))
    enable_movement_for_faction allows movement for the faction previously froze.
    Spoiler Alert, click show to read: 

    Parameters: Faction key as string (as it appears in the db)

    Example:
    Code:
    scripting.game_interface:enable_movement_for_faction("france")


    episodic_attack(faction key (string), target faction(string))
    episodic_attack advises the AI to attack a faction. It is largely untested, results may vary.
    Spoiler Alert, click show to read: 

    Parameters: faction key (string), target faction(string)

    Example:
    Code:
    scripting.game_interface:episodic_attack("france", "britain")


    episodic_defend(faction key (string), region(string))
    episodic_defend advises the AI to defend a region. It is largely untested, results may vary.
    Spoiler Alert, click show to read: 

    Parameters: faction key (string), region(string)

    Example:
    Code:
    scripting.game_interface:episodic_defend("france", "eur_norway")


    force_diplomacy(faction_key(string), target_faction(string), diplomatic option(string), can offer (bool), will accept(bool))
    force_diplomacy forces a certain stance from one faction towards another
    Spoiler Alert, click show to read: 

    Parameters: faction_key(string), target_faction(string), diplomatic option(string), can offer (bool), will accept(bool)

    Example:
    Code:
    scripting.game_interface:force_diplomacy("france", "britain", "war" true, true)



    grant_faction_handover(recipient faction key(string), handed over faction key(string), first possible turn(int), last possible turn(int), context)
    grant_faction_handover hands over the specified faction to the specified recipient.
    Spoiler Alert, click show to read: 

    Parameters: recipient faction key(string), handed over faction key(string), first possible turn(int), last possible turn(int), context

    Example:
    Code:
    scripting.game_interface:grant_faction_handover("britain", "france", 1, 2, context)


    grant_unit(location(string), unit to grant(string))
    Spawns the given unit at the given location. The location must be a settlement.
    Spoiler Alert, click show to read: 

    Parameters: location(string), unit to grant(string)

    Example:
    Code:
    scripting.game_interface:grant_unit("settlement:ita_milano:milan", "Inf_Light_Lombardy-Cisalpine_Legion")


    remove_restricted_building_level_record(building key(string))
    remove_restricted_building_level_record removes the restriction on a building record that was previously set with add_restricted_building_level_record
    Spoiler Alert, click show to read: 

    Parameters: Building key as string (as it appears in the db)

    Example:
    Code:
    scripting.game_interface:remove_restricted_building_level_record("tFactory1_manufactory")


    remove_restricted_unit_record(<unit_key>)
    remove_restricted_unit_record removes the restriction on a unit record that was previously set with add_restricted_unit_record
    Spoiler Alert, click show to read: 

    Parameters: Unit key as string (as it appears in the units table)

    Example:
    Code:
    scripting.game_interface:remove_restricted_unit_record("euro_expat_infantry_regiments_etrangeres")


    show_shroud(true/false)
    show_shroud disables or enables the fog of war
    Spoiler Alert, click show to read: 

    Parameters: true/ false

    Example:
    Code:
    scripting.game_interface:show_shroud(false)


    spawn_town_level(region key (string), level(int), notification(bool))
    spawn_town_level spawns a town up to the specified level.
    Spoiler Alert, click show to read: 

    Parameters: region key (string), level(int), trigger notification(bool)

    Example:
    Code:
    scripting.game_interface:spawn_town_level("virginia", 1, true)


    trigger_custom_mission(mission id (string), faction key(string), mission type(string), turn limit(int), parameters(string), heading key(string), description key(string), reward key(string), reward money(int), reward faction key(string), context)
    trigger_custom_mission triggers a custom mission.
    Spoiler Alert, click show to read: 

    Parameters: mission id (string), faction key(string), mission type(string), turn limit(int), parameters(string), heading key(string), description key(string), reward key(string), reward money(int), reward faction key(string), context

    Example:
    Code:
    sscripting.game_interface:trigger_custom_mission("eur_prussia_alliance_austria","prussia","forge_alliance", 0, "austria", "mission_text_text_eur_prussia_alliance_austria_heading", "mission_text_text_eur_prussia_alliance_austria_text",
    "", 0, "", context






    I.5 Events
    This is a list of hookable events as shown in the events.lua file in the data pack and certain patch packs. Events are not explicitly documented as they are mostly self-explanatory. If you have any questions on any of them just ask.

    Click to view content: 
    AdviceDismissed
    AdviceFinishedTrigger
    AdviceIssued
    AdviceSuperseded
    ArmySabotageAttemptSuccess
    AssassinationAttemptSuccess
    BattleBoardingActionCommenced
    BattleCommandingShipRouts
    BattleCommandingUnitRouts
    BattleCompleted
    BattleConflictPhaseCommenced
    BattleDeploymentPhaseCommenced
    BattleFortPlazaCaptureCommenced
    BattleShipAttacksEnemyShip
    BattleShipCaughtFire
    BattleShipMagazineExplosion
    BattleShipRouts
    BattleShipRunAground
    BattleShipSailingIntoWind
    BattleShipSurrendered
    BattleUnitAttacksBuilding
    BattleUnitAttacksEnemyUnit
    BattleUnitAttacksWalls
    BattleUnitCapturesBuilding
    BattleUnitDestroysBuilding
    BattleUnitRouts
    BattleUnitUsingBuilding
    BattleUnitUsingWall
    BuildingCardSelected
    BuildingCompleted
    BuildingConstructionIssuedByPlayer
    BuildingInfoPanelOpenedCampaign
    CameraMoverCancelled
    CameraMoverFinished
    CampaignArmiesMerge
    CampaignBuildingDamaged
    CampaignSettlementAttacked
    CampaignSlotAttacked
    CharacterAttacksAlly
    CharacterBlockedPort
    CharacterBrokePortBlocke
    CharacterBuildsSpyNetwork
    CharacterCandidateBecomesMinister
    CharacterCanLiberate
    CharacterCompletedBattle
    CharacterCreated
    CharacterCriticallyFailsAssassination
    CharacterDamagedByDisaster
    CharacterDisembarksNavy
    CharacterEmbarksNavy
    CharacterEntersAttritionalArea
    CharacterEntersGarrison
    CharacterFactionCompletesResearch
    CharacterFactionSpyAttemptSuccessful
    CharacterFactionSuffersSuccessfulSpyAttempt
    CharacterInfoPanelOpened
    CharacterLootedSettlement
    CharacterPromoted
    CharacterSelected
    CharacterTurnEnd
    CharacterTurnStart
    ComponentLClickUp
    DuelDemanded
    DuelFought
    DummyEvent
    EspionageAgentApprehended
    evaluate_mission
    EventMessageOpenedBattle
    EventMessageOpenedCampaign
    FactionGovernmentTypeChanged
    FactionRoundStart
    FactionTurnEnd
    FactionTurnStart
    FortSelected
    GarrisonResidenceCaptured
    GovernorshipTaxRateChanged
    HarassmentAttemptSuccess
    HistoricalCharacters
    HistoricalEvents
    historical_events
    HudRefresh
    IncomingMessage
    LandTradeRouteRaided
    LoadingGame
    LocationEntered
    LocationUnveiled
    MissionCancelled
    MissionCheckAssassination
    MissionCheckBlockePort
    MissionCheckBuild
    MissionCheckCaptureCity
    MissionCheckDuel
    MissionCheckEngageCharacter
    MissionCheckEngageFaction
    MissionCheckGainMilitaryAccess
    MissionCheckMakeAlliance
    MissionCheckMakeTradeAgreement
    MissionCheckRecruit
    MissionCheckResearch
    MissionCheckSpyOnCity
    MissionEvaluateAssassination
    MissionEvaluateBlockadePort
    MissionEvaluateBuild
    MissionEvaluateCaptureCity
    MissionEvaluateDuel
    MissionEvaluateEngageCharacter
    MissionEvaluateEngageFaction
    MissionEvaluateGainMilitaryAccess
    MissionEvaluateMakeAlliance
    MissionEvaluateMakeTradeAgreement
    MissionEvaluateRecruit
    MissionEvaluateResearch
    MissionEvaluateSpyOnCity
    MissionFailed
    MissionIssued
    MissionNearingExpiry
    MissionSucceeded
    ModelCreated
    MovementPointsExhausted
    MultiTurnMove
    NewCampaignStarted
    NewSession
    PanelviceRequestedBattle
    PanelviceRequestedCampaign
    PanelClosedBattle
    PanelClosedCampaign
    PanelOpenedBattle
    PanelOpenedCampaign
    PendingBankruptcy
    PreBattle
    RecruitmentItemIssuedByPlayer
    RegionIssuesDemands
    RegionRebels
    RegionRiots
    RegionStrikes
    RegionTurnEnd
    RegionTurnStart
    ResearchCompleted
    SabotageAttemptSuccess
    SavingGame
    SeaTradeRouteRaided
    SettlementOccupied
    SettlementSelected
    SiegeLifted
    SlotOccupied
    SlotOpens
    SlotRoundStart
    SlotSelected
    SlotTurnStart
    SpyingAttemptSuccess
    SufferAssassinationAttempt
    SufferSpyingAttempt
    TechnologyInfoPanelOpenedCampaign
    TestEvent
    TimeTrigger
    Tooltipvice
    TradeLinkEstablished
    TradeRouteEstablished
    UICreated
    UIDestroyed
    UngarrisonedFort
    UnitCompletedBattle
    UnitCreated
    UnitSelectedCampaign
    UnitTrained
    UnitTurnEnd
    VictoryConditionFailed
    VictoryConditionMet
    WorldCreated


    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  2. #2

    Default Re: The S2 Script-o-Rama

    Section II: Script Writing Tutorials

    This section explains how to write your own script and will contain more advanced stuff as it is fleshed out.

    II.1 How to use events.
    Click to view content: 
    To tie some code into an event you need to add a function onto the end of the event table needed (remember all events are tables) as follows:
    Code:
    events.EventName[#events.EventName+1] = function(context)
    	code
    end
    So the following code adds some cash to a faction at the start of it's turn.
    Code:
    events.FactionTurnStart[#events.FactionTurnStart+1] = function(context)
    	effect.adjust_treasury(100000, context)
    end
    This method of event hooking saves filling functions such as OnFactionTurnStart() up with your own code (thus possibly confusing you) and is more reliable for people not too familiar with scripting.
    Just remember not to place the code chunk inside another function. Code that relies on a region starting it's turn will never fire off if placed inside the OnFactionTurnStart function, as the faction and the region both start their turns at different times.


    II.2 How to create custom missions.
    Click to view content: 
    In-depth tutorial here


    II.3 How to write logs.
    Click to view content: 
    Getting the game to write logs is by far the easiest way of narrowing down bugs and telling you that certain things are working in a script. The following code chunks are functions for (i) Creating a log and (ii) Writing to the log. To understand some of the operators used, I would advise you to look at the basics section (I.1) which explains them in detail.

    Spoiler Alert, click show to read: 
    Code:
    function TCS_Create_Log ()
    	local DateAndTime = os.date()
    	local TCSLog = io.open("data/Logs/log.txt","w")
    	TCSLog:write("[Log Created] "..DateAndTime.."\n\n")
    	TCSLog:close()
    end
    Code:
    function TCS_Log_Update(update_arg)
    	local DateAndTime1 = os.date("%H:%M.%S")
    	local TCSLogU = io.open("data/Logs/log.txt","a")
    	TCSLogU:write("\n["..DateAndTime1.."]\t\t"..tostring(update_arg)) 
    	TCSLogU:close()
    end


    These functions may not make sense to anyone unfamiliar with Lua, so I've included some with comments below.

    Spoiler Alert, click show to read: 
    Code:
    --create a function that takes no arguments
    function TCS_Create_Log ()
    	--sets a variable to the time and date
    	local DateAndTime = os.date()
    	--opens the text file in the directory supplied. Set to write mode ("w"), so if the text file 
    	--exists it will be overwritten, if it doesn't it will be created.
    	local TCSLog = io.open("data/Logs/log.txt","w")
    	--write a header tith the date to the log, so you know when it's been updated.
    	TCSLog:write("[Log Created] "..DateAndTime.."\n\n")
    	--Close the log
    	TCSLog:close()
    end
    Code:
    --create a function that takes only one argument
    function TCS_Log_Update(update_arg)
    	--set the date in HMS format to the variable
    	local DateAndTime1 = os.date("%H:%M.%S")
    	--open the log in the supplied path. Opened in append mode ("a") which will append to
    	--the file rather than overwrite it
    	local TCSLogU = io.open("data/Logs/log.txt","a")
    	--write the date in HMS format before each log entry
     	TCSLogU:write("\n["..DateAndTime1.."]\t\t"..tostring(update_arg)) 
    	--close the log
    	TCSLogU:close()
    end


    Usage of the functions:
    The functions must both be defined, so I'd advise you to do that at the top of your script. Remember that scripts are read logically (mostly) so you must define the function before attempting to call it. I would then advise that you call the function to create the log only once, as it overwrites any logs that already exist. So it is done as follows:
    Code:
    TCS_Create_Log ()
    Then you can use the log updater as often as you wish. Here is an example of basic usage:
    Code:
    TCS_Log_Update("hello World!")
    Which will output the following to the log file:
    Code:
    [12:46.13]		Hello World!
    If you supply an argument to the function that doesn't exist, it will most likely catch it out as it uses the tostring() converter.
    So this code:
    Code:
    TCS_Log_Update(hello World!)
    Outputs this:
    Code:
    [12:46.13]		nil
    Keep in mind that I've left out the error catching I would use on my own logging functions so as to keep the code simple - it may not handle all incorrect syntax values the same.

    Another excellent use of this is to log the output of functions. The following code logs the output of a CampaignUI function.
    Code:
    local Logvariable = CampaignUI.RetrieveDiplomaticStanceString("france", "britain")
    TCS_Log_Update(Logvariable)
    And the output itself:
    Code:
    [12:46.13]		at war


    II.4 How to edit UI components (basic).
    Click to view content: 
    To edit UI components the most effective way is to get a decompiled file, fix it, edit it and recompile it. This obviously isn't an option for most people, so what follows is a basic example of how to do it via scripting.lua and episodicscripting.

    First things first, you need to know the name of your component to edit. There's no simple way to do this, you just have to crawl through game files and find somewhere else where it is referenced globally (i.e. not locally). When you know the name of your component to edit, you need to add an entry to the table m_features table of episodicscripting. This is done by adding some code as follows to the end of the table:
    Code:
    	["disable_end_turn"] = {
    		["Enable"] = function()
    			out.ting("End turn disabled")
    			UIComponent(m_root:Find("button_end_turn")):SetVisible(false)
    			UIComponent(m_root:Find("button_end_turn")):SetDisabled(true)
    		end,
    		["Disable"] = function()
    			out.ting("End turn re-enabled")
    			UIComponent(m_root:Find("button_end_turn")):SetVisible(true)
    			UIComponent(m_root:Find("button_end_turn")):SetDisabled(false)
    		end
    		},
    And here it is with some comments to make it easier to understand:

    Code:
    	--set the feature name
    	["disable_end_turn"] = {
    		--define the enable function
    		["Enable"] = function()
    			--code that will be executed when the enable function is called
    			out.ting("End turn disabled")
    			UIComponent(m_root:Find("button_end_turn")):SetVisible(false)
    			UIComponent(m_root:Find("button_end_turn")):SetDisabled(true)
    		end,
    		--define the disable function
    		["Disable"] = function()
    			--code that will be executed when the disable func is called
    			out.ting("End turn re-enabled")
    			UIComponent(m_root:Find("button_end_turn")):SetVisible(true)
    			UIComponent(m_root:Find("button_end_turn")):SetDisabled(false)
    		end
    		},
    To actually edit the UI components you need to use the UIComponent() function. This is documented as follows:
    Code:
    UIComponent(m_root:Find(<<Name of component>>)):<<function to call on component>>
    And an example here:
    Code:
    UIComponent(m_root:Find("button_end_turn")):SetDisabled(false)
    I've only seen SetDisabled or SetVisible used in episodicscripting but here are other commands used in luacs:
    • SetStateText(<<string>>)
    • SetState(<<string>>) (Only useable if you can compare to UI xmls)
    • SetTooltipText(<<string>>)


    There are lots more, but those are the most relevant.

    So now you've added your feature to the table, you'll need to call it. That's pretty simple to do - from scripting.lua (or anywhere else where the episodicscripting module is loaded) just use the following code:
    Code:
    scripting.EnableFeature(<<feature name>>)
    scripting.DisableFeature(<<Feature name>>)
    EnableFeature will execute any code defined under the "Enable" table and Disable Feature will do the same for anything under the "Disable" table.

    Examples of useage:
    Code:
    scripting.EnableFeature("Hide_prestige_tab") 
    scripting.DisableFeature("hide_campaign_hud")


    Section III: Miscellaneous

    Everything that doesn't fit somewhere else goes here.

    III.1 Use Cases

    Click to view content: 
    Saving the game
    Note: this is for my own reference, if you don't understand it don't bother
    For saving, three types should be distinguished:
    - Save via the save-load dialog
    - Autosave
    - Quicksave via shortcut

    If you need a savegame list, the savegame will be missing during save - that's a way to know the filename of the game that was just saved. Unfortunately we then need an event that we can use after saving and that can be enabled by a bool flag.

    For the saving via save-load, use PanelOpenedCampaign, if you want with context.string == dialogue_box (this is called by the "Save successful" dialog).
    For saving via auto-save, use FactionTurnEnd or somesuch
    For saving via quicksave we can get a problem if the player hits alt+f4 so we need to use FactionTurnEnd along with the auto-save and UIDestroyed


    III.2 Useful Links

    Click to view content: 
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  3. #3

    Default Re: The S2 Script-o-Rama

    Reserved
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  4. #4

    Default Re: The S2 Script-o-Rama

    Reserved.
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  5. #5
    DaVinci's Avatar TW Modder 2005-2016
    Patrician Artifex

    Join Date
    Apr 2005
    Location
    The plastic poisoned and d(r)ying surface of planet Earth in before Armageddon
    Posts
    15,366

    Default Re: The S2 Script-o-Rama

    Again excellent presentation

    Perhaps i'll apply event and unit spawn/uprising scripting some day in future.
    Last edited by DaVinci; April 23, 2011 at 08:36 AM.
    #Anthropocene #not just Global Warming but Global Disaster, NASA #Deforestation #Plastic Emission #The Blob #Uninhabitable Earth #Savest Place On Earth #AMOC #ICAN #MIT study "Falsehoods Win" #Engineers of Chaos
    #"there can be no doubt about it: the enemy stands on the Right!" 1922, by Joseph Wirth.
    Rightwingers, like in the past the epitome of incompetence, except for evilness where they own the mastership.
    Iirc., already 2013 i spoke of "Renaissance of Fascism", it was accurate.
    #"Humanity is in ‘final exam’ as to whether or not it qualifies for continuance in universe." Buckminster Fuller
    Any chance for this exam? Very low, the established Anthropocentrism destroys the basis of existence.
    #My Modding #The Witcher 3: Lore Friendly Tweaks (LFT)
    #End, A diary of the Third World War (A.-A. Guha, 1983) - now, it started on 24th February 2022.

  6. #6

    Default Re: The S2 Script-o-Rama

    Quote Originally Posted by DaVinci View Post
    Again excellent presentation

    Perhaps i'll apply event and unit spawn/uprising scripting some day in future.
    Thanks

    If anyone has any questions or wants functions documented, shout here. I'll do my best to help. And if anyone wants to know how to start documenting functions, get in contact with me - I can show people how to use pcall() (for getting info on funcs) if they are interested
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  7. #7
    Hazbones's Avatar Senator
    Join Date
    May 2007
    Location
    Iwakuni, Japan
    Posts
    1,104

    Default Re: The S2 Script-o-Rama

    Great work taking all the time to post your knowledge but I think there is something missing in the "Basic" section like:
    1. What file(s) are you manipulating
    2. Where do you type the scripts inside the file? Is it a table that you add to the last blank line? Pics would be nice.

    Thanks

  8. #8

    Default Re: The S2 Script-o-Rama

    Quote Originally Posted by Hazbones View Post
    Great work taking all the time to post your knowledge but I think there is something missing in the "Basic" section like:
    1. What file(s) are you manipulating
    2. Where do you type the scripts inside the file? Is it a table that you add to the last blank line? Pics would be nice.

    Thanks
    1. The scripting.lua
    2. Inside the desired function/event. I don't really have time to write an "introduction to scripting" tutorial right now. I suggest you Google Garry's Mod lua tutorials, they are very beginner friendly and will teach you some basics about scripting - enough to see what is going on inside scripting.lua.

    Edit: Here you go. You'll just have to apply practical sense to pick out the bits relevant to Garrys Mod.
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  9. #9
    Tribunus
    Join Date
    Jan 2011
    Location
    Ascension, St. Helena
    Posts
    7,336

    Default Re: The S2 Script-o-Rama

    This should really be stickied

    Well as soon as it is converted for STW2...
    Last edited by Magicman2051; April 28, 2011 at 08:00 AM.

  10. #10
    CoconutFred's Avatar Senator
    Join Date
    Jul 2010
    Location
    Your local ShopRite, at 5% off on Fridays.
    Posts
    1,067

    Default Re: The S2 Script-o-Rama

    Awesome Resource... +rep

  11. #11

    Default Re: The S2 Script-o-Rama

    So, I would like to track the population of a certain town... Or the populations of all towns that belong to a specific clan (STW2). Any ideas?

    Is there a list of Character/Town etc. details/tags/parameters that has been published by CA? Something similar in NTW?

    Thanks for the replies

  12. #12

    Default Re: The S2 Script-o-Rama

    Quote Originally Posted by Seikales View Post
    So, I would like to track the population of a certain town... Or the populations of all towns that belong to a specific clan (STW2). Any ideas?

    Is there a list of Character/Town etc. details/tags/parameters that has been published by CA? Something similar in NTW?

    Thanks for the replies
    I don't know your level of competency with Lua, but here is a function I use in EiC for manpower calculations.

    Code:
    function FindTotalPopulation(faction)
    	local regions = CampaignUI.RegionsOwnedByFactionOrByProtectorates(faction)
    	local population = 0
    	for i = 1, #regions do
    		local Region_details = CampaignUI.InitialiseRegionInfoDetails(regions[i].Address)
    		local Region_population = Region_details["PopulationNumber"]
    		population = population + Region_population
    	end
    		return population
    end
    You can see how I've queried that information from the tables by looking at the function output documented in my OP (InitialiseRegionInfoDetails() and RegionsOwnedByFactionOrByProtectorates())
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  13. #13

    Default Re: The S2 Script-o-Rama

    Alright, so you call the 'properties/variables' within quotations.

    So, if I wanted to get the information on effect of ports on town wealth for example;

    -- Initialize the object A
    local A = CampaignUI.InitialiseRegionInfoDetails(region.Address)
    local B = A["TownWealth"]

    - now since B is a table
    local C = B[1]
    - one corresponding to first table in TownWealth table

    local D = C[1] -- the actual value for the wealth from town

    Am I right?

    And could you please tell where we should place this script function for the program to check it all the time? If I use an event function that fires, can I do it in any script file, or do I use my own script file or what?

    Your answer was very helpful, thank you!

    Edit: Can we do the above in one sentence, so that
    local A = CampaignUI.InitialiseRegionInfoDetails(region.Address)["TownWealth"][1][1]
    or something similar?
    Last edited by Seikales; May 23, 2011 at 01:30 PM.

  14. #14

    Default Re: The S2 Script-o-Rama

    Do you know if they have functions other then the effects you mentioned above? Can I for example, following the discussion above, change the population of a city?

  15. #15
    Inevitability won
    Patrician Citizen

    Join Date
    Mar 2010
    Posts
    9,594

    Default Re: The S2 Script-o-Rama

    Quote Originally Posted by Seikales View Post
    Alright, so you call the 'properties/variables' within quotations.

    So, if I wanted to get the information on effect of ports on town wealth for example;

    -- Initialize the object A
    local A = CampaignUI.InitialiseRegionInfoDetails(region.Address)
    local B = A["TownWealth"]

    - now since B is a table
    local C = B[1]
    - one corresponding to first table in TownWealth table

    local D = C[1] -- the actual value for the wealth from town

    Am I right?

    And could you please tell where we should place this script function for the program to check it all the time? If I use an event function that fires, can I do it in any script file, or do I use my own script file or what?

    Your answer was very helpful, thank you!

    Edit: Can we do the above in one sentence, so that
    local A = CampaignUI.InitialiseRegionInfoDetails(region.Address)["TownWealth"][1][1]
    or something similar?
    Your on your way there for sure.

    First thing I'd say is don't use variables like "A" and "B", you will lose track of them and what they are, name them appropriatly.

    For your script, you pretty much wrote it almost.

    local A = CampaignUI.InitialiseRegionInfoDetails(region.Address)

    "A" now holds the details of the region.

    local B = A["TownWealth"]

    "B" now holds the TownWealth details of "A", "A" being the region. B isn't a table like you suggested, its just a plain old variable.

    You don't need any of the B = C = D extra stuff.

    Now B has the town wealth of the region you can do whatever you want. If you need more help just ask.

    As for doing it in one line, the correct syntax could be:

    local A = (CampaignUI.InitialiseRegionInfoDetails(region.Address))["TownWealth"]

    But you'd need to place the CampaignUI bit within some operators, and I don't know the standard operators for LUA. In Visual Basic you'd place the campaignUI bit within () to make sure that it does that first then it will apply the TownWealth bit to the variable in the brackets, tbh, its easier just to do another line.
    Last edited by .Mitch.; May 23, 2011 at 02:22 PM.

  16. #16

    Default Re: The S2 Script-o-Rama

    Quote Originally Posted by Seikales View Post
    Alright, so you call the 'properties/variables' within quotations.
    No, in that case the table key was a string rather than a number.

    Quote Originally Posted by .Mitch. View Post
    As for doing it in one line, the correct syntax could be:

    local A = (CampaignUI.InitialiseRegionInfoDetails(region.Address))["TownWealth"]
    I see what you both are trying to do, but I think you've both flown a little wide of the mark. For syntax safety reasons I'd store the return value (a table in this case) in a variable - if nothing else it's easier on the eye. Once you have it in a variable, say RegionDetails, you can cut out as many lines as you like :

    Code:
    RegionDetails["TownWealth"][1]["Total"]
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  17. #17

    Default Re: The S2 Script-o-Rama

    Thanks for the answers people. Yeah, I use A and B here for simplicity of discussion. Sound advice on your part though Mitch.

    Would you have any answers on the questions below?

    And could you please tell where we should place this script function for the program to check it all the time? If I use an event function that fires, can I do it in any script file, or do I use my own script file or what?
    Do you know if they have functions other then the effects you mentioned above? Can I for example, following the discussion above, change the population of a city?

    Cheers

  18. #18

    Default Re: The S2 Script-o-Rama

    Quote Originally Posted by Seikales View Post
    Thanks for the answers people. Yeah, I use A and B here for simplicity of discussion. Sound advice on your part though Mitch.

    Would you have any answers on the questions below?

    Cheers
    @Question 1 - it depends what you want to do, you could tie it into an event such as OnPanelOpenedCampaign or something like that, but that's liable to cause lag if the script is large.

    @Question 2 - that's about the most interesting stuff. There's more stuff in CUI but I haven't documented it here yet.
    My Tools, Tutorials and Resources

    Was running out of space, so see the full list here!

    Consider the postage stamp: its usefulness consists in the ability to stick to one thing till it gets there.- Josh Billings
    The creatures outside looked from pig to man, and from man to pig, and from pig to man again; but already it was impossible to say which was which.- George Orwell

  19. #19
    Inevitability won
    Patrician Citizen

    Join Date
    Mar 2010
    Posts
    9,594

    Default Re: The S2 Script-o-Rama

    For your question 1: The 'On Turn Start' event would be the best, thats the event in which townwealth will have changed for the player or the AI, it will remain a constant throughout the turn, so using the panels like topcat suggested is being overly complicated for this imo.

    So you'd be looking to use:

    local function OnFactionTurnStart(context)
    your script here
    end

  20. #20

    Default Re: The S2 Script-o-Rama

    Alright. So, I place this at any script file? Or the campaign one? Or the events one? Does it really matter? I assume they all get regularly checked out whether any of them fire or no?

    Or do they get stored in some memory and tracked all the time? I guess what I am asking is, when an event is fired, the program will go read all the script files for the proper action, or just look at the events script file?

    Man, even I lost track of my thought. Kinda tired. Need to prepare a large poster for a conference Cheers!

Page 1 of 6 123456 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
  •