Recent content by dsfrozen

  1. dsfrozen

    How to code a Breakable Helmet

    It works perfectly now! Thank you for taking the time to explain me the basics of mission_templates!
  2. dsfrozen

    How to code a Breakable Helmet

    Thank you for the detailed explanation, I finally managed to make it work like in the video that you posted!

    I've got one last question, please. Every time I hit an enemy I get the following error onscreen. As far as I can tell, it does not stop the code from working properly.

    Code:
    Invalid Item Kind ID: -1; LINE NO: 41:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 43:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 40:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 41:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. vdt_regular discard_buffer()
     SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 41:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 43:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 40:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 41:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 41:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. SCRIPT ERROR ON OPCODE 527: Invalid Item Kind ID: -1; LINE NO: 43:
     At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences. At Mission Template mst_lead_charge trigger no: 2 consequences.

    By any chance did you experience something similar and you know what is causing the error? I'm also including my mst_lead_charge below. Thanks!
    Code:
      (
        "lead_charge",mtf_battle_mode|mtf_synch_inventory,charge,
        "You lead your men to battle.",
        [
         (1,mtef_defenders|mtef_team_0,0,aif_start_alarmed,12,[]),
         (0,mtef_defenders|mtef_team_0,0,aif_start_alarmed,0,[]),
         (4,mtef_attackers|mtef_team_1,0,aif_start_alarmed,12,[]),
         (4,mtef_attackers|mtef_team_1,0,aif_start_alarmed,0,[]),
         ],
        [
        
          (ti_on_agent_spawn, 0, 0, [],
           [
             (store_trigger_param_1, ":agent_no"),
             (call_script, "script_agent_reassign_team", ":agent_no"),
    
             (assign, ":initial_courage_score", 5000),
    
             (agent_get_troop_id, ":troop_id", ":agent_no"),
             (store_character_level, ":troop_level", ":troop_id"),
             (val_mul, ":troop_level", 100), #was 35
             (val_add, ":initial_courage_score", ":troop_level"), #average : 20 * 35 = 700
    
             (store_random_in_range, ":randomized_addition_courage", 0, 3000), #average : 1500
             (val_add, ":initial_courage_score", ":randomized_addition_courage"),
    
             (agent_get_party_id, ":agent_party", ":agent_no"),
             (party_get_morale, ":cur_morale", ":agent_party"),
    
             (store_sub, ":morale_effect_on_courage", ":cur_morale", 70),
             (val_mul, ":morale_effect_on_courage", 30), #this can effect morale with -2100..900
             (val_add, ":initial_courage_score", ":morale_effect_on_courage"),
    
             #average = 5000 + 700 + 1500 = 7200; min : 5700, max : 8700
             #morale effect = min : -2100(party morale is 0), average : 0(party morale is 70), max : 900(party morale is 100)
             #min starting : 3600, max starting  : 9600, average starting : 7200
             (agent_set_slot, ":agent_no", slot_agent_courage_score, ":initial_courage_score"),
             ]),
            
            #Breakable Item Begin+
          (ti_on_agent_spawn, 0, 0, [],
            [
              (store_trigger_param_1, ":agent"),
    
                (try_for_range, ":equipment_slot", 4, 8),
                (agent_get_item_slot, ":equipment", ":agent", ":equipment_slot"),
                (gt, ":equipment", 0), # Agent does have an armor equipped here
     
                #(item_get_hit_points, ":hp", ":equipment"),
                (assign, ":hp", 1), #Flat Hitpoints
     
                (try_begin),
                (eq, ":equipment_slot", 4), # Head
                (agent_set_slot, ":agent", agent_armor_dur_head, ":hp"),
                (else_try),
                (eq, ":equipment_slot", 5),    # Body
                (agent_set_slot, ":agent", agent_armor_dur_main, ":hp"),
                (else_try),
                (eq, ":equipment_slot", 6),    # Leg
                (agent_set_slot, ":agent", agent_armor_dur_feet, ":hp"),
                (else_try),
                # Would be 7, Hand
                (agent_set_slot, ":agent", agent_armor_dur_hand, ":hp"),
                (try_end),
                (try_end),
    
            ]),
            
            
            
            
            
            (ti_on_agent_hit, 0, 0, [],
        [
        (set_fixed_point_multiplier, 100),
        (store_trigger_param, ":agent", 1),
        (store_trigger_param, ":attacker", 2),
        (store_trigger_param, ":damage", 3),
        (store_trigger_param, ":bodypart", 4),
        # (store_trigger_param, ":missile", 5),
        (agent_get_troop_id, ":troop", ":agent"),
        (agent_get_troop_id, ":attacker_troop", ":attacker"),
        (assign, ":attacker_weapon", reg0),
    
        (agent_is_alive, ":agent"),
        (agent_is_human, ":agent"),
    
        (store_agent_hit_points, ":health_remaining_actual", ":agent", 1),
    
        (store_troop_health, ":current_health", ":troop"),
        (troop_set_health, ":troop", 100),
        (store_troop_health, ":max_health_actual", ":troop", 1),
        (troop_set_health, ":troop", ":current_health"),
    
    
        # This is a listing of bones for usage in locational damage tracking
        # hb_abdomen = 0
        # hb_thigh_l = 1
        # hb_calf_l = 2
        # hb_foot_l = 3
        # hb_thigh_r = 4
        # hb_calf_r = 5
        # hb_foot_r = 6
        # hb_spine = 7
        # hb_thorax = 8
        # hb_head = 9
        # hb_shoulder_l = 10
        # hb_upperarm_l = 11
        # hb_forearm_l = 12
        # hb_hand_l = 13
        # hb_item_l = 14
        # hb_shoulder_r = 15
        # hb_upperarm_r = 16
        # hb_forearm_r = 17
        # hb_hand_r = 18
    
        (try_begin),
            (gt, ":attacker_weapon", 0),
            (item_get_swing_damage_type, ":damage_type", ":attacker_weapon"),
            # I dunno how to determine which attack was unleashed, but this will work
            # We can use this to make certain damage types, such as blunt, do more damage
            # to armor durability vs things like pierce which should nearly pass through
        (else_try),
            (assign, ":damage_type", 2),
        (try_end),
    
        (try_begin),
            (eq, ":damage_type", 0),    # Cut
            (assign, ":dampen", 3),
        (else_try),
            (eq, ":damage_type", 1),    # Pierce
            (assign, ":dampen", 5),
        (else_try),
            (eq, ":damage_type", 2),    # Blunt
            (assign, ":dampen", 2),
        (try_end),
    
        (store_div, ":durability_hit", ":damage", ":dampen"),
    
        (agent_get_slot, ":head_durability", ":agent", agent_armor_dur_head),
        (agent_get_slot, ":hand_durability", ":agent", agent_armor_dur_hand),
        (agent_get_slot, ":feet_durability", ":agent", agent_armor_dur_feet),
        (agent_get_slot, ":main_durability", ":agent", agent_armor_dur_main),
    
        (agent_get_item_slot, ":head_armor", ":agent", 4),
        (agent_get_item_slot, ":hand_armor", ":agent", 7),
        (agent_get_item_slot, ":feet_armor", ":agent", 6),
        (agent_get_item_slot, ":main_armor", ":agent", 5),
    
        (item_get_slot, ":head_damaged_var", ":head_armor", slot_damaged_variant),
        (item_get_slot, ":hand_damaged_var", ":hand_armor", slot_damaged_variant),
        (item_get_slot, ":feet_damaged_var", ":feet_armor", slot_damaged_variant),
        (item_get_slot, ":main_damaged_var", ":main_armor", slot_damaged_variant),
     
        (try_begin),
            (this_or_next|eq, ":bodypart", 0), # Guts
            (is_between, ":bodypart", 7, 9), # Spine and Thorax
     
            (gt, ":main_armor", 0), # Has Armor
    
            (val_sub, ":main_durability", ":durability_hit"),
            (val_max, ":main_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_main, ":main_durability"),
            (eq, ":main_durability", 0),
            (agent_unequip_item, ":agent", ":main_armor", 5),
            (neq, ":main_damaged_var", 0),
            (item_get_hit_points, ":hp", ":main_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_main, ":hp"),
            (agent_equip_item, ":agent", ":main_damaged_var", 5),
        (else_try),
            (is_between, ":bodypart", 1, 7), # Legs
    
            (gt, ":feet_armor", 0), # Has Armor
    
            (val_sub, ":feet_durability", ":durability_hit"),
            (val_max, ":feet_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_feet, ":feet_durability"),
            (eq, ":feet_durability", 0),
            (agent_unequip_item, ":agent", ":feet_armor", 4),
            (neq, ":feet_damaged_var", 0),
            (item_get_hit_points, ":hp", ":feet_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_feet, ":hp"),
            (agent_equip_item, ":agent", ":feet_damaged_var", 4),
        (else_try),
            (eq, ":bodypart", 9), # head
    
            (gt, ":head_armor", 0), # Has Armor
    
            (val_sub, ":head_durability", ":durability_hit"),
            (val_max, ":head_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_head, ":head_durability"),
            (eq, ":head_durability", 0),
            (agent_unequip_item, ":agent", ":head_armor", 5),
            (neq, ":head_damaged_var", 0),
            (item_get_hit_points, ":hp", ":head_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_head, ":hp"),
            (agent_equip_item, ":agent", ":head_damaged_var", 5),
        (else_try),
            (this_or_next|is_between, ":bodypart", 12, 14), # Left Forearms and Hand
            (gt, ":bodypart", 17), # Right Forearms and Hand
    
            (gt, ":hand_armor", 0), # Has Armor
    
            (val_sub, ":hand_durability", ":durability_hit"),
            (val_max, ":hand_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_hand, ":hand_durability"),
            (eq, ":hand_durability", 0),
            (agent_unequip_item, ":agent", ":hand_armor", 5),
            (neq, ":hand_damaged_var", 0),
            (item_get_hit_points, ":hp", ":hand_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_hand, ":hp"),
            (agent_equip_item, ":agent", ":hand_damaged_var", 5),
        (try_end),
    
        (set_trigger_result, ":damage"),
        ]),
            #Breakable Item End+
    
    
          common_battle_init_banner,
    
    #more triggers...
  3. dsfrozen

    How to code a Breakable Helmet

    That's pretty great! Thank you for following up on this, the video shows exactly what I had in mind.

    Due to my (very) modest knowledge of MS I'm still struggling to make it work: it compiles with no error but in-game I can't see results.

    So if it's not it's not too much trouble I'd ask you if you could post a longer version of your code, in particular highlighting how you integrated ti_on_agent_spawn and ti_on_agent_hit entries in mission_templates; also including in 'lead_charge' mission for example.

    Thanks!

    PS. I guess you'll get the best answer because the video shows that this is clearly working!
  4. dsfrozen

    How to code a Breakable Helmet

    Thank you I haven't disappeared. I'm still trying to implement it according to the way you suggested but so far no luck.

    Oh well, I'll continue trying and update if there is a breakthrough!
  5. dsfrozen

    How to code a Breakable Helmet

    So I can offer some guidance as to how I would do it.

    Step 1: Set up per-agent item durability via slots and fill them in ti_on_agent_spawn

    In module_constants
    Python:
    # First among your agent slots
    agent_armor_dur_head = 100 # whatever number is open for you
    agent_armor_dur_hand = agent_armor_dur_head + 1
    agent_armor_dur_feet = agent_armor_dur_head + 2
    agent_armor_dur_main = agent_armor_dur_head + 3
    
    # and in your item_slots
    slot_damaged_variant = 100 # Or, again, whatever you have available

    In mission_templates, attached to a common ti_on_agent_spawn
    Python:
    agent_spawn_effects = (
        ti_on_agent_spawn, 0, 0, [], [
        (store_trigger_param_1, ":agent"),
    
        (try_for_range, ":equipment_slot", 4, 8),
            (agent_get_item_slot, ":equipment", ":agent", ":equipment_slot"),
            (gt, ":equipment", 0), # Agent does have an armor equipped here
     
            (item_get_hit_points, ":hp", ":equipment"),
     
            (try_begin),
                (eq, ":equipment_slot", 4), # Head
                (agent_set_slot, ":agent", agent_armor_dur_head, ":hp"),
            (else_try),
                (eq, ":equipment_slot", 5),    # Body
                (agent_set_slot, ":agent", agent_armor_dur_main, ":hp"),
            (else_try),
                (eq, ":equipment_slot", 6),    # Leg
                (agent_set_slot, ":agent", agent_armor_dur_feet, ":hp"),
            (else_try),
                # Would be 7, Hand
                (agent_set_slot, ":agent", agent_armor_dur_hand, ":hp"),
            (try_end)
        (try_end),
    
        ]),

    As you can tell, this assumes you are declaring hitpoints for EACH AND EVERY ARMOR, if you do not, every hit will be shattering these poor things.

    Also you need to set up a script inside game_start and game_quick_start to assign the damaged variants to their original forms

    Step 2: Locational Damage, Breaking and Swapping -
    First, we need to determine where damage was on the agent.

    In mission_templates, attached to a common ti_on_agent_hit
    Python:
    common_damage_system= (
    ti_on_agent_hit, 0, 0, [],
    [
        (set_fixed_point_multiplier, 100),
        (store_trigger_param, ":agent", 1),
        (store_trigger_param, ":attacker", 2),
        (store_trigger_param, ":damage", 3),
        (store_trigger_param, ":bodypart", 4),
        # (store_trigger_param, ":missile", 5),
        (agent_get_troop_id, ":troop", ":agent"),
        (agent_get_troop_id, ":attacker_troop", ":attacker"),
        (assign, ":attacker_weapon", reg0),
    
        (agent_is_alive, ":agent"),
        (agent_is_human, ":agent"),
    
        (store_agent_hit_points, ":health_remaining_actual", ":agent", 1),
    
        (store_troop_health, ":current_health", ":troop"),
        (troop_set_health, ":troop", 100),
        (store_troop_health, ":max_health_actual", ":troop", 1),
        (troop_set_health, ":troop", ":current_health"),
    
    
        # This is a listing of bones for usage in locational damage tracking
        # hb_abdomen = 0
        # hb_thigh_l = 1
        # hb_calf_l = 2
        # hb_foot_l = 3
        # hb_thigh_r = 4
        # hb_calf_r = 5
        # hb_foot_r = 6
        # hb_spine = 7
        # hb_thorax = 8
        # hb_head = 9
        # hb_shoulder_l = 10
        # hb_upperarm_l = 11
        # hb_forearm_l = 12
        # hb_hand_l = 13
        # hb_item_l = 14
        # hb_shoulder_r = 15
        # hb_upperarm_r = 16
        # hb_forearm_r = 17
        # hb_hand_r = 18
    
        (try_begin),
            (gt, ":attacker_weapon", 0),
            (item_get_swing_damage_type, ":damage_type", ":attacker_weapon"),
            # I dunno how to determine which attack was unleashed, but this will work
            # We can use this to make certain damage types, such as blunt, do more damage
            # to armor durability vs things like pierce which should nearly pass through
        (else_try),
            (assign, ":damage_type", 2),
        (try_end),
    
        (try_begin),
            (eq, ":damage_type", 0),    # Cut
            (assign, ":dampen", 30),
        (else_try),
            (eq, ":damage_type", 1),    # Pierce
            (assign, ":dampen", 35),
        (else_try),
            (eq, ":damage_type", 2),    # Blunt
            (assign, ":dampen", 15),
        (try_end),
    
        (store_div, ":durability_hit", ":damage", ":dampen"),
    
        (agent_get_slot, ":head_durability", ":agent", agent_armor_dur_head),
        (agent_get_slot, ":hand_durability", ":agent", agent_armor_dur_hand),
        (agent_get_slot, ":feet_durability", ":agent", agent_armor_dur_feet),
        (agent_get_slot, ":main_durability", ":agent", agent_armor_dur_main),
    
        (agent_get_item_slot, ":head_armor", ":agent", 4),
        (agent_get_item_slot, ":hand_armor", ":agent", 7),
        (agent_get_item_slot, ":feet_armor", ":agent", 6),
        (agent_get_item_slot, ":main_armor", ":agent", 5),
    
        (item_get_slot, ":head_damaged_var", ":head_armor", slot_damaged_variant),
        (item_get_slot, ":hand_damaged_var", ":hand_armor", slot_damaged_variant),
        (item_get_slot, ":feet_damaged_var", ":feet_armor", slot_damaged_variant),
        (item_get_slot, ":main_damaged_var", ":main_armor", slot_damaged_variant),
     
        (try_begin),
            (this_or_next|eq, ":bodypart", 0), # Guts
            (is_between, ":bodypart", 7, 9), # Spine and Thorax
     
            (gt, ":main_armor", 0), # Has Armor
    
            (val_sub, ":main_durability", ":durability_hit"),
            (val_max, ":main_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_main, ":main_durability"),
            (eq, ":main_durability", 0),
            (agent_unequip_item, ":agent", ":main_armor", 5),
            (neq, ":main_damaged_var", 0),
            (item_get_hit_points, ":hp", ":main_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_main, ":hp"),
            (agent_equip_item, ":agent", ":main_damaged_var", 5),
        (else_try),
            (is_between, ":bodypart", 1, 7), # Legs
    
            (gt, ":feet_armor", 0), # Has Armor 
    
            (val_sub, ":feet_durability", ":durability_hit"),
            (val_max, ":feet_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_feet, ":feet_durability"),
            (eq, ":feet_durability", 0),
            (agent_unequip_item, ":agent", ":feet_armor", 4),
            (neq, ":feet_damaged_var", 0),
            (item_get_hit_points, ":hp", ":feet_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_feet, ":hp"),
            (agent_equip_item, ":agent", ":feet_damaged_var", 4),
        (else_try),
            (eq, ":bodypart", 9), # head
    
            (gt, ":head_armor", 0), # Has Armor
    
            (val_sub, ":head_durability", ":durability_hit"),
            (val_max, ":head_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_head, ":head_durability"),
            (eq, ":head_durability", 0),
            (agent_unequip_item, ":agent", ":head_armor", 5),
            (neq, ":head_damaged_var", 0),
            (item_get_hit_points, ":hp", ":head_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_head, ":hp"),
            (agent_equip_item, ":agent", ":head_damaged_var", 5),
        (else_try),
            (this_or_next|is_between, ":bodypart", 12, 14), # Left Forearms and Hand
            (gt, ":body_part", 17), # Right Forearms and Hand
    
            (gt, ":hand_armor", 0), # Has Armor
    
            (val_sub, ":hand_durability", ":durability_hit"),
            (val_max, ":hand_durability", 0), # Durability cannot be negative
    
            (agent_set_slot, ":agent", agent_armor_dur_hand, ":hand_durability"),
            (eq, ":hand_durability", 0),
            (agent_unequip_item, ":agent", ":hand_armor", 5),
            (neq, ":hand_damaged_var", 0),
            (item_get_hit_points, ":hp", ":hand_damaged_var"),
            (agent_set_slot, ":agent", agent_armor_dur_hand, ":hp"),
            (agent_equip_item, ":agent", ":hand_damaged_var", 5),
        (try_end),
    
        (set_trigger_result, ":damage"),
    ])
    That bad boy will also handle breaking, and equipping a damaged variant if applicable

    I did not fact-check, prototype or demo this at all, so, I cannot guarantee its functionality, but it looks accurate enough to me.

    Also, the above is part of OSP, you may use it at your discretion, credit is always appreciated, but not necessary.

    Tweaks I would do to make it more satisfying:
    Store the location of the bone, make a particle burst at the location.
    Create a physics item for the armor in the mod and allow it to pop off into the scene if destroyed.

    Thanks for your help! I gave it a go but unfortunately I cannot see any effect in game; I must be missing something.

    1. I'd need some guidance / example on the script to assign damage variants (I assumed that for testing purposes without this script it would swap to the character's naked head)

    2. In mission_templates, does it matter where I place the two blocks of code? I placed them right after the first ti_on_agent_spawn, ti_on agent_hit in the file. Maybe that's the reason why it is not triggered?

    Thanks again for the help!
  6. dsfrozen

    How to code a Breakable Helmet

    You are not fully correct.

    Singleplayer

    Changing/replacing armors of agents in singleplayer works straight away.. There is no need to respawn agent.

    Multiplayer

    You can do that without re-spawning agent. You have to create client & server event and inform other clients about that "event".
    Without doing that, other clients will still see old armor.

    Multiplayer Serverside Only

    As @Eärendil Ardamírë said. You have to re-spawn agent in order to achieve that.


    General

    Let us know if you are working on MP script or SP script.
    MP script will be more complex.
    You will have to make slots which gonna keep current "hitpoints" of agents helmets.
    Part of your code will be located in on_hit trigger.You will have to update "hitpoints" of damaged agent helmet.
    If "hitpoints" of helmet are less than X, send info to client about that. Tell other players to update that agent armor.


    Additional tips

    WSE can provide information about which part of the agent body was damaged.
    That can help you in making your script more immersing.

    Sorry I should have specified it’s single player only!
    Would you mind elaborating on what it’s required to implement it? Thanks!
  7. dsfrozen

    How to code a Breakable Helmet

    Hello, I am trying to implement a breakable helmet in MB Warband. In my mind this should work in-game like shields, where after a certain amount of hitpoints is consumed the helmet (itm_breakable_helmet) switches to a damaged mesh (itm_breakable_helmet_broken) and then eventually disappears...
  8. dsfrozen

    Error with tweaked initialize_aristocracy script

    Okay, I think I've found a solution. Apparently you have to set explicitly slot_troop_spouse for the wife as well. I included the following block for each faction and now it works:
    Code:
      (troop_set_slot, "trp_kingdom_1_lady_1", slot_troop_spouse, "trp_knight_1_1"),
      (troop_set_slot, "trp_kingdom_1_lady_2", slot_troop_spouse, "trp_knight_1_2"),
      (troop_set_slot, "trp_kingdom_1_lady_3", slot_troop_spouse, "trp_knight_1_3"),
      (troop_set_slot, "trp_kingdom_1_lady_4", slot_troop_spouse, "trp_knight_1_4"),
      (troop_set_slot, "trp_kingdom_1_lady_5", slot_troop_spouse, "trp_knight_1_5"),
      (troop_set_slot, "trp_kingdom_1_lady_6", slot_troop_spouse, "trp_knight_1_6"),
      (troop_set_slot, "trp_kingdom_1_lady_7", slot_troop_spouse, "trp_knight_1_7"),
      (troop_set_slot, "trp_kingdom_1_lady_8", slot_troop_spouse, "trp_knight_1_8"),
  9. dsfrozen

    Error with tweaked initialize_aristocracy script

    Hello, I tweaked my initialize aristocracy script in order to have set family relationships (I've got some factions with 10 lords/ladies and some others with standard 20 lord/ladies). Everything works fine except that when I enter a town / castle where ladies are present I get the following...
  10. dsfrozen

    Recruitment from Settlement Outside from Town/Castle/Village range

    Thank you both for your help, based on the input that you provided I finally managed to solve my problem this way:
    Code:
      [anyone ,"start", [(eq,"$g_talk_troop","trp_konrad"),], "Good day, {sir/madam}. Here to take a look at Balion's finest?", "mercenary_recruit",[]],
      [anyone ,"start", [(eq,"$g_talk_troop","trp_sun_knightess"),], "Mind your manners within the walls and we'll have no trouble.", "close_window",[]],
    
      [anyone|plyr,"mercenary_recruit", [], "I wish to recruit some of your men.", "mercenary_buy_troops",[]],
    
        [anyone ,"mercenary_buy_troops",
            [
                (store_relation, ":keep_faction_relation", "fac_knight_order_1", "fac_player_faction"),
                (ge, ":keep_faction_relation", 0),
            ],
        "I'll gather the men available, they'll do anything you say as long as you pay them for it.", "mercenary_buy_troops_2",
            [
                (set_mercenary_source_party, "$g_talk_troop_party"),
                (change_screen_buy_mercenaries)
            ]],
        
        [anyone, "mercenary_buy_troops",
            [
                #(store_faction_of_party, "fac_knight_order_1", "p_merc_camp_balion"),
                (store_relation, ":keep_faction_relation", "fac_knight_order_1", "fac_player_faction"),
                (lt, ":keep_faction_relation", 0),
            ],
        "Sorry, your relationship with my faction is negative.", "mercenary_buy_troops_2", []],
    Basically instead of trying to get the faction of the settlement via "store_faction_of_party", I hardcoded the faction of the settlement in the dialog (store_relation, ":keep_faction_relation", "fac_knight_order_1", "fac_player_faction").
    This also makes script_cf_keep_recruit_volunteers_cond unnecessary.

    I suppose it is a less refined way of tackling the issue and I will have to create separate dialogs for each new faction, but this was something I was planning to do anyway and it kind of works for me.
  11. dsfrozen

    Recruitment from Settlement Outside from Town/Castle/Village range

    I had to look for the 'OSP Mercenary Camps (of Calradia)' to see how it worked, it already has a system to update recruitable troops, I also see that you have shown me the same but commenting the rest of the settlements.
    'slot_center_volunteer_troop_amount' and 'slot_center_volunteer_troop_type' belong to the system that native uses to update recruitable troops.

    I insist, if you do not give the player the possibility of changing the relationship with the settlement faction, what is the use of applying a condition in this regard, you need to create the relationship system with the new faction first, do you understand the point?
    Python:
        [anyone|plyr, "mercenary_recruit", [],
        "I wish to recruit some of your men.", "mercenary_buy_troops", []],
    
        [anyone, "mercenary_buy_troops",
            [
                (store_faction_of_party, ":keep_faction", "p_merc_camp_balion"),
                (store_relation, ":keep_faction_relation", ":keep_faction", "fac_player_faction"),
                (ge, ":keep_faction_relation", 0),
            ],
        "I'll gather the men available, they'll do anything you say as long as you pay them for it.", "mercenary_buy_troops_2",
            [
                (set_mercenary_source_party, "$g_talk_troop_party"),
                (change_screen_buy_mercenaries)
            ]],
    
        [anyone, "mercenary_buy_troops",
            [
                (store_faction_of_party, ":keep_faction", "p_merc_camp_balion"),
                (store_relation, ":keep_faction_relation", ":keep_faction", "fac_player_faction"),
                (lt, ":keep_faction_relation", 0),
            ],
        "Sorry, your relationship with my faction is negative.", "mercenary_buy_troops_2", []],
    
        [anyone, "mercenary_buy_troops_2", [],
        "Anything else?", "mercenary_recruit", []],
    
        [anyone|plyr ,"mercenary_recruit", [],
        "I'll be on my way.", "close_window", []],
    'keep_faction_relation' will always be 0 or the value that you have set for the faction relations in 'module_factions'. I don't think I can be more clear about this, mmm although my English may suck and I probably won't express myself properly.

    Thank you I appreciate your help. To answer your question: yes, I already implemented a system to give the player the possibility of changing the relationship with the settlement faction (there are some patrols spawning on the map that can be attacked / helped and this changes the relationship with the faction).

    I changed module_dialogs in the way that you suggested and as a result the NPC always offers me the possibility of recruiting troops (even when the player relationship with the faction is -3).

    My suspect is that the this piece of code cannot detect the faction of the settlement where I am at: (store_faction_of_party, ":keep_faction", "p_merc_camp_balion"). Do you mind elaborating how store_faction_of_party works and how could I fix it? Thanks!

    By the way I think your English is pretty good!
  12. dsfrozen

    Recruitment from Settlement Outside from Town/Castle/Village range

    @Dj_FRedy

    The way that I did it is for the player to get a relationship with the faction, not with the center, and I would like my conditional to work based on the relationship with the faction (settlement is not conquerable by other factions).

    My understanding was that script 'cf_keep_master_volunteers_cond' was only using $current_town to determine which faction it belongs to and then check if the player relationship with faction is greater than 0. Is this not the case?
  13. dsfrozen

    Recruitment from Settlement Outside from Town/Castle/Village range

    The script game_start assigns villages to centers and assigns the villages a faction based on that of its owner. The script only populates store_faction_of_party within the range villages_begin to villages_end. Similarly, where your script checks slots such as slot_center_volunteer_troop_amount, you need to understand how these slots are populated. Slot_center_volunteer_troop_amount for example is populated by script_update_volunteer_troops_in_village, which is called by game_start, but only for in range villages.
    Tip - search all files for a slot_slotname, then look at instances where it is used with party_set_slot to understand how it is populated with values.
    Okay, I think I am following what you are saying.

    At the moment my script "cf_keep_master_volunteers_cond" is referencing "slot_center_volunteer_troop_amount" and "slot_center_volunteer_troop_type" which are populated by 'script_update_volunteer_troops_in_village'; this script uses the range 'village_begin' - 'village_end', hence it does not recognise my settlement as part of this range.

    I defined a custom range for the new settlements and a script to refresh troops recruitable in these settlements (I also defined the faction of the settlement directly in module_parties so I don't think I need to bother touching script_game_start).

    Code:
    # Merc Camp Begin 
          (try_for_range, ":camp_no", mercenary_camp_begin, mercenary_camp_end),
            (call_script, "script_refresh_mercenary_camp_troops",":camp_no"),
          (try_end),   
    # Merc Camp End

    Code:
      # script_refresh_mercenary_camp_troops
      # Input: arg1 = camp_no
      # Output: none
      ("refresh_mercenary_camp_troops",
        [
          (store_script_param_1, ":camp_no"),
          (assign, ":ideal_size", 50), # Past this value the troop pool of the camp will be reset
    
          (try_begin),
            (eq, ":camp_no", "p_merc_camp_balion"),   
            (assign, ":party_template", "pt_merc_camp_balion_troops"),     
          #(else_try),
            #(eq, ":camp_no", "p_merc_camp_geroia"),   
            #(assign, ":party_template", "pt_merc_camp_geroia_troops"),     
          #(else_try),
            #(eq, ":camp_no", "p_merc_camp_jumne"),   
            #(assign, ":party_template", "pt_merc_camp_jumne_troops"),           
          #(else_try),
            #(eq, ":camp_no", "p_merc_camp_zendar"),   
            #(assign, ":party_template", "pt_merc_camp_zendar_troops"),               
          (try_end),
            
            (party_get_num_companions, ":party_size", ":camp_no"),   
          (try_begin),
            (gt, ":party_size", ":ideal_size"), # We're past the ideal number of troops in the camp
            (party_clear,":camp_no"), # Reset the troop pool
            (party_add_template, ":camp_no", ":party_template"),     
          (else_try),
            (party_add_template, ":camp_no", ":party_template"),         
          (try_end),
      ]),

    My question at this point are the following:
    1. Do I need something like 'slot_center_volunteer_troop_amount' in order to achieve what I want? I believed that the script was checking the player relation with the faction at this point: store_relation, ":keep_faction_relation", ":keep_faction", "fac_player_faction" so I should be able to comment out this part (and update dialogs):
    Code:
         (party_slot_ge, "$current_town", slot_center_volunteer_troop_amount, 1), #SB : ge 1, not 0     (party_slot_ge, "$current_town", slot_center_volunteer_troop_type, 1),
    2. I still think that the script is unable to detect the settlement to be part of the faction (right now I can see the dialog option even when I have negative relationship with the faction). How can I address this?

    Thank you!
  14. dsfrozen

    Recruitment from Settlement Outside from Town/Castle/Village range

    The first thing I would ask before suggesting any change would be if you have started the dialogue for "keep_master_talk", as it is specified in the header of 'module_dialogs':
    Code:
    # 2) Starting dialog-state:
    #    If the dialog is started by speaking to an NPC in a town, initially, the active dialog state is "start"
    Yes, the dialog starts fine. One of the two options is to ask the keep master for the backstory and that one shows up fine. I'd like the second option (recruit) to show only if the player has a certain relationship level with the faction of the current settlement but so far I haven't managed to make it work
  15. dsfrozen

    Recruitment from Settlement Outside from Town/Castle/Village range

    Hello, I used the OSP kit Mercenary Camp to create a new faction with only one settlement (keep) and one lord (keep master) from where I can recruit the faction's troops. I have been trying now to adapt the 'village_elder_talk' in module_dialogs and 'cf_village_recruit_volunteers_cond' scripts...
Back
Top Bottom