PYTHON SCRIPT/SCHEME EXCHANGE

Users who are viewing this thread

Another small piece of code...
Make the starting merchant and his brother look like they are related.

This is how:
In module_dialogs.py find the dialogue that starts our first conversation with the merchant. Look for "start_up_quest_1_next"
This is how it looks in my module system:
Python:
    #Quest 0 - Alley talk
    [anyone|auto_proceed,"start",
        [
            (is_between,"$g_talk_troop","trp_swadian_merchant","trp_startup_merchants_end"),
            (eq,"$talk_context",tc_back_alley),
            (eq,"$talked_with_merchant",0),
        ],
        "{!}.",
        "start_up_quest_1_next",
        [
            #MOD BEGIN - starting merchant and his brother look like they are related
            #merchant's face is randomized, but each town has different merchant, and we can set his face to match the town's culture (so Swadian-looking guy in Praven, Sarranid-looking guy in Shariz)
            #merchant's younger brother however is just 1 NPC regardless of city, so we have to set his face in runtime
            (str_store_agent_face_keys,s59,"$g_talk_agent"), #get merchant's face code
            (face_keys_set_beard,s59,0), #remove beard from it, for younger look
            (face_keys_get_age,reg59,s59), #get age from face code
            (val_mul,reg59,3), #merchant's age is between 20-80% range of the slider, where min and max are roughly 20 years and 60 (upper limit is highly random, but on avg)
            (val_div,reg59,4), #reduce value by 25%, this should give us visibly younger face
            (face_keys_set_age,s59,reg59), #put newly calculated age into face code
            (troop_set_face_keys,"trp_relative_of_merchant",s59), #set the modified face code to merchant's brother
            #MOD END - starting merchant and his brother look like they are related
        ]
    ],
    [anyone,"start_up_quest_1_next",
        [],
        "Are you all right? Well... I guess you're alive, at any rate. I'm not sure that we can say the same for the other fellow. That's one less thief to trouble our streets at night, although Heaven knows he won't be the last... Anyway, maybe you can help me with something. Let's talk more inside. Out here, we don't know who's listening.", #MOD - typos
        "close_window",
        [
            (assign,"$talked_with_merchant",1),
            (mission_disable_talk),
        ]
    ],

The code above requires an operation that normally isn't declared in WB vanilla header_operations.py, but is supported by game engine, so we gotta declare it:
Python:
player_set_face_keys       = 2748 #(player_set_face_keys, <player_id>, <string_no>), #Sets <player_id>'s face keys from string.
#MOD BEGIN - starting merchant and his brother look like they are related
str_store_agent_face_keys  = 2749 #(str_store_agent_face_keys, <string_reg>, <agent_id>), #Stores agent face code. Regular agents have random generated face from two face codes of the troop.
#MOD END - starting merchant and his brother look like they are related
str_store_troop_face_keys  = 2750 #(str_store_troop_face_keys, <string_no>, <troop_no>, [<alt>]), #Stores <troop_no>'s face key into string. if [<alt>] is non-zero the second pair of face keys is stored
The operation is documented here: https://mbcommands.fandom.com/wiki/Operators

Now you can use the fact that every town has its own merchant and for example go to module_troops.py and set face codes for merchants so that their ethnicity matches the town.
I recommend Swyter's editor for that, as it allows you to paste in existing face codes and modify them:
https://swyter.github.io/mab-tools/face
 
Last edited:
Hello everyone.
Im currently working on a small Diplomacy mod with fun expansions to the battle system.
I will be sharing some aditions, mostly code taken from this forum and modified by me!
(ps: Im still working the forum stuff out as I always have being a forum ghost reader for 99.999% of my life :razz:)

Working Surgery skill for the enemy party:
Credits: @Erundil for the initial code "Quest Spies fall unconscious instead of dying"¹
¹ Already included in the code below.

Edit: Improved the code, made so Blunt weapons can kill about 25% of the time, and also made it so Surgery only gives 3% more chance to save from lethal. All these changes are commentated besides so you can decide to change them or not!
Edit²: Some corrections in internal header_operations used that I made "only" for my own mod dev... oops, sorry!



The following condition is to be added to [module_mission_templates.py].
Python:
#Code by RedMythos, no credits needed! ^^
#Thanks to everyone in the Warband modding community!
not_always_lethal = (ti_on_agent_killed_or_wounded, 0, 0, [],
       [
        (store_trigger_param_1, ":dead_agent_no"),
        (store_trigger_param_2, ":killer_agent_no"),
        (store_trigger_param_3, ":is_wounded"),
    
        #Note: setting the trigger_result as 0 will follow the default game logic and not alter the result. Setting it to 1 will force kill, and to 2 will force wound.
        (ge, ":dead_agent_no", 0),
        (agent_is_human, ":dead_agent_no"),
        (agent_get_troop_id, ":dead_agent_troop_id", ":dead_agent_no"),
        (neg|troop_is_hero, ":dead_agent_troop_id"),
        (party_add_members, "p_total_enemy_casualties", ":dead_agent_troop_id", 1), #addition_to_p_total_enemy_casualties.
    
           (try_begin), #The code below is credited to Erundil, and guarantees the enemies on the Spy quests to NOT die.
              (this_or_next|eq,":dead_agent_troop_id","trp_spy"), #the spy that we were following.
              (eq,":dead_agent_troop_id","trp_spy_partner"), #his boss that was waiting for him, usually accompanied by a few mercenaries.
              (assign, ":is_wounded", 1),
              (set_trigger_result, 2), #Set as wounded.
           (else_try),
              (agent_get_wielded_item, ":weapon", ":killer_agent_no", 0), #Checks for blunt weapons.
              (try_begin),
              (lt, ":weapon", 0),
              (assign, ":weapon", 0), #Prevents error "Item ID: -1" when hitting with your fists.
              (try_end),
              (item_get_swing_damage_type, ":is_blunt", ":weapon"), #Only checks if its blunt on swing damage, as not every mace has thrust damage.
              (eq, ":is_blunt", 2),
              (try_begin),
              (store_random_in_range, ":d100", 0, 101),
              (le, ":d100", 75), #~25% of chance to kill using blunt weapon.
              (assign, ":is_wounded", 1),
              (set_trigger_result, 2),
              (else_try),
              (assign, ":is_wounded", 0),
              (set_trigger_result, 1),
              (try_end),
           (else_try),
              (agent_get_team, ":dead_tm", ":dead_agent_no"),
              (team_get_leader, ":dead_lead", ":dead_tm"),
              (neg|agent_is_non_player, ":dead_lead"),
              (party_get_skill_level, ":ld_surgery", "p_main_party", "skl_surgery"), #Gets skill level from your party.
              (val_mul, ":ld_surgery", 3), #+3% survival rate from each point in Surgery.
              (val_add, ":ld_surgery", 25), #default base chance, but can be altered here!
              (try_begin),
              (store_random_in_range, ":d100", 0, 101),
              (le, ":d100", ":ld_surgery"),
              (assign, ":is_wounded", 1),
              (set_trigger_result, 2),
              (else_try),
              (assign, ":is_wounded", 0),
              (set_trigger_result, 1),
              (try_end),
           (else_try),
              (agent_get_team, ":dead_tm", ":dead_agent_no"),
              (team_get_leader, ":dead_lead", ":dead_tm"),
              (agent_is_non_player, ":dead_lead"),
              (agent_get_troop_id, ":dead_lead_id", ":dead_lead"),
              (store_skill_level, ":ld_surgery", "skl_surgery", ":dead_lead_id"), #Gets skill level directly from enemy party's leader, as lords dont have NPCs on party.
              (val_mul, ":ld_surgery", 3), #+3% survival rate from each point in Surgery.
              (val_add, ":ld_surgery", 25), #default base chance, but can be altered here!
              (try_begin),
              (store_random_in_range, ":d100", 0, 101),
              (le, ":d100", ":ld_surgery"),
              (assign, ":is_wounded", 1),
              (set_trigger_result, 2),
              (else_try),
              (assign, ":is_wounded", 0),
              (set_trigger_result, 1), #If all above fails, R.I.P.
              (try_end),
           (try_end),
          (try_begin), #Assigns wounded troops as prisoners in post-battle screen
          (eq, ":is_wounded", 1),
          (party_wound_members, "p_total_enemy_casualties", ":dead_agent_troop_id", 1),
        (try_end),
        (call_script, "script_apply_death_effect_on_courage_scores", ":dead_agent_no", ":killer_agent_no"),
       ])

(ps²: Im so sorry, the neat spacing in the code itself got lost in posting this[...])
(ps³: Code got properly formated into a |code| block, all thanks to @SupaNinjaMan's heads up on my PM, thank you! :party:)

Now, search on [module_mission_templates.py] for:
Python:
     common_battle_init_banner,


You will find multiple stances of it. Put the aforementioned condition below these original lines, like so:
Python:
      common_battle_init_banner,
      not_always_lethal,
Mind your spaces and align the first letter of the first line to the first letter of the second line in the code above!!

That should be all of the code needed, now enemy troops who suffer lethal cut/pierce damage will survive at least 25% of the time, just like it is for the player team. Lord and NPC's Surgery skill also take part in this matter, so I heavily suggest modifying some "knows" variables on your [module_troops.py] file. You can capture prisioners even without the need for blunt weapons, even if most of them die anyways... well, you better invest in some Prisoner Management now, just in case!! My next post will cover that, coming soon!

More code to come, I hope we all can make the Warband modding community keep thriving together as one.
Thanks for reading, cya!
-Red
 
Last edited:
[..] well, you better invest in some Prisoner Management now, just in case!! My next post will cover that, coming soon!
So here it is, in hope that someone find this useful, I present to you:

Prisoner Limit based on Party Size - Prisoner Management skill serves as % bonus instead and acts as (Party Skill):

To make Prsioner Management act as a Party Skill (like Pathfinding, Surgery, Trade etc.), you can use the following code:

Search your [module_skills.py] for the following:
Python:
("prisoner_management", "Prisoner Management",

Paste this over the entire "prisoner_management" line in your [module_skills.py]:
Python:
  ("prisoner_management", "Slavekeeping",sf_base_att_int|sf_effects_party,10,"Every level of this skill increases your maximum number of prisoners by 20%% relative to your party size. (Party skill)"),
(Mind your spaces! Also made it based on INT for obvious reasons... CHA never made any sense whatsoever for this purpose, but well...)
(Be aware that the skill name "Prisoner Management" is too big to be properly formated into the Party screen where it shows your skill bonuses. It has been renamed to "Slavekeeping" instead for this reason. This change is only esthetic and does not modify/break any code present in the game)

Now search your [module_scripts.py] for the following:

Python:
  ("game_get_party_prisoner_limit",
    [

Delete or comment out (using the # character at the beggining of every line) the whole script, until the last " ]) " line, and use this instead:
Python:
#Code by RedMythos, no credits needed ^^
#Thanks to everyone in the Warband modding community!
#This script uses the Party Size as the base for calculating your Prisoner Limit.
#Every point in Prisoner Management (PARTY SKILL) adds 20% to your Prisoner Limit, again, based on your current Party Size.
  ("game_get_party_prisoner_limit",
    [
      (party_get_skill_level, ":skill", "p_main_party", "skl_prisoner_management"),
      (party_get_num_companions, ":p_size", "p_main_party"),
      (store_mul, ":pm_mod", ":p_size", ":skill"),
      (store_div, ":pm_final", ":pm_mod", 5),
      (assign, reg0, ":pm_final"),
      (set_trigger_result, reg0),
  ]),

The deed is done, now you can have generally more prisoners the larger your current party size is, because you know, it just makes sense. It also reflects the AI tendency to have more prisoners the more troops they have (that is for other reasons, but its the best I could manage as a parallel, because AI parties does not have any prisoner limit whatsoever afaik :lol:).
At the maximum of 14 points in Slavekeeping (now formely "Prisoner Management"), you can have a whopping 280 prisoners with a party of 100 members. Thats a LOT of gold to make with the Ransom Brokers... And speaking of them... more code incoming, thats all I have to say for now! :wink:

I hope you guys find this useful. More scripts to come, but Im currenlty focusing on mission_templates stuff and planning to add my codes as a bundle of sorts. Any feedback til now is appreciated!
Thanks for reading, cya!
-Red
 
Last edited:
This script can be used for right shifting flag bits. For example, you can define flag_constant = 8. You can just rshift of 3 in the code. But what if you want to change flag_constant =16. Than you need to search all right shifting of 3 and change to 4. With this script it can be done automatically.
Python:
 # script_store_log_2
  # Input:  value
  # Output: reg0 - log2(value)
  # Note: value should be power of 2 and equal to 0
  ("store_log_2", [
    (store_script_param, ":value", 1),
    (assign, ":end", 1),
    (try_for_range, ":result", 0, ":end"),
      (gt, ":end", 1000000), # prevent soft lock
    (else_try),
      (eq, ":value", 1),
    (else_try),
      (val_add, ":end", 1),
      (val_rshift, ":value", 1),
    (try_end),
    (assign, reg0, ":result"),
  ]),
 
Last edited:
Back
Top Bottom