OSP Code SP [WB v1.127, WIP] Adding a new skill: Foraging (v0.1)

Users who are viewing this thread

jrider

Veteran
The way food is handled in warband can be a bit frustrating especially if you have a large party forcing you to fill a lot of your inventory slots with food if you don't want to go back every 2 day or so refill supplies.

So I started to think about a way to address the problem (without changing the food quantities) and came up with foraging as skill which was very common in older armies (soldiers lived off the land).

First the design part:
  • standard character skill that the player or companion can invest in
  • it does not provide food items, it simply reduce the food consumed at each meal
  • this is an Agility based party skill with max level of 10
  • the skill level (modified by party bonus) sets a hard limit of the maximum number of food unit that can be foraged (5 units max per level for now)
    i.e. even if you can forage 30 food units from the area and you have only 1 level you foraging, you'll get a 5 units reduction to food consumption.
  • the skill level determine the range around player party foraging will be done (set at 2, try 5 first but the radius was too large)
  • since the main goal is to reduce food consumption (a minimum of 1 unit is eaten from the player's inventory), it's triggered at meal time
  • a visible way to see the impact of food consumption
  • works all the time but the amount foraged has a bonus of x1.5 if camping (standard camp, waiting 24h on siege),
    limited by max forage according to skill level
  • Tiers (2-4, 5-7, 8-9 and 10+) of skill (modified by party bonus) provide a bonus (respectively, x1.5, x2, x2.5, x.3) to foraged food to represent the character's experience,
    limited by max forage according to skill level
  • The amount of food that can be foraged depends on local resources (these a modified by the bonus mentionned above):
    • Current party terrain provide a flat base value depending on type
      Steppe/Plain (for game): 2, Rivers/Bridge (for fish): 4, all forests (for game): 4
    • Nearby village or town within the current range provide forage according to the following resources
      • Household gardens and apiaries give a flat value (2 and 1 respectively)
      • Grain fields, vineyards (twice for grapes and fruits), olives fields and date fields provide about 1/4 of the production value
      • Cattle and sheep provide 1/4 of the production value for meat products only (i.e. beef and sausage)
      • Fur traps provide as many units as there are traps in the center (for game, if you skin it you kill it first, usually)
           
Adding the code won't cause problem for an existing savegame (moving the skill in module_skills.py will though).

Changelog:
  • v0.1
    • initial post

This is a work in progress as, indicated in the subject so there's a TODO list
  • tweak the numbers
  • the character's sheet placement is awkward and doesn't scale, if someone can find a way to resize that or shift the list a bit downward
  • impact on party morale
  • impact on foraged from town and villages (relation, production)
and here is the code (v1.0, for Warband v1.127) :

  • new (well modified since it replaces reserved_8, to have it displayed after looting) entry to put in module_skills.py
Code:
  ## Jrider + FORAGING 1.0 adding skill
  #("reserved_8","Reserved Skill 8",sf_base_att_int|sf_inactive,10,"This is a reserved skill."), 
  ("foraging","Foraging",sf_base_att_agi|sf_effects_party,10,"Allows the party to forage for 5 food per skill level (camp, siege, raiding) and increase foraging range (Party skill) Max level: 10."), 
  ## Jrider -

  • in header_skills.py do the following changes
Code:
## Jrider + FORAGING v1.0
#skl_reserved_8 = 21 
skl_foraging = 21
## Jrider -
Code:
## Jrider + FORAGING v1.0, foraging flags
#knows_reserved_8_1 = 19342813113834066795298816
#knows_reserved_8_2 = 38685626227668133590597632
#knows_reserved_8_3 = 58028439341502200385896448
#knows_reserved_8_4 = 77371252455336267181195264
#knows_reserved_8_5 = 96714065569170333976494080
#knows_reserved_8_6 = 116056878683004400771792896
#knows_reserved_8_7 = 135399691796838467567091712
#knows_reserved_8_8 = 154742504910672534362390528
#knows_reserved_8_9 = 174085318024506601157689344
#knows_reserved_8_10 = 193428131138340667952988160
knows_foraging_1 = 19342813113834066795298816
knows_foraging_2 = 38685626227668133590597632
knows_foraging_3 = 58028439341502200385896448
knows_foraging_4 = 77371252455336267181195264
knows_foraging_5 = 96714065569170333976494080
knows_foraging_6 = 116056878683004400771792896
knows_foraging_7 = 135399691796838467567091712
knows_foraging_8 = 154742504910672534362390528
knows_foraging_9 = 174085318024506601157689344
knows_foraging_10 = 193428131138340667952988160
## Jrider - 
[code][/spoiler]
[/list]
[list]
	[*]New scripts to put in [b]module_scripts.py[/b]
[spoiler][code]
  ## FORAGING v1.0 #######################################################################
  ## Script food_consumption_display_message
  ## display food consumption
  ## use reg1 and reg2 and reg4 from forage
  ## hooked in simple trigger for food consumption every 14 hours
  ("food_consumption_display_message",
   [
    (store_script_param, ":num_men", 1),

    (assign, reg1, ":num_men"),
    # Display day of food left with current amount and party size
    (assign, ":available_food", 0),
    (troop_get_inventory_capacity, ":capacity", "trp_player"),
    (try_for_range, ":cur_slot", 0, ":capacity"),
      (troop_get_inventory_slot, ":cur_item", "trp_player", ":cur_slot"),
      (try_begin),
        (is_between, ":cur_item", food_begin, food_end),
        (troop_get_inventory_slot_modifier, ":item_modifier", "trp_player", ":cur_slot"),
        (neq, ":item_modifier", imod_rotten),
        (troop_inventory_slot_get_item_amount, ":cur_amount", "trp_player", ":cur_slot"),
        (val_add, ":available_food", ":cur_amount"),
      (try_end),
    (try_end),
    
    (assign, ":num_food_hours", ":available_food"),
    (val_mul, ":num_food_hours", 14),
    (val_div, ":num_food_hours", 24),
    (val_div, ":num_food_hours", ":num_men"),
    (assign, ":num_food_days", ":num_food_hours"),
    (assign, reg2, ":num_food_days"),
    
    (try_begin),
      (lt, reg2, 4),
      (display_message, "@Your party consumed {reg1} units of food{reg4?, {reg4} from foraging : }({reg2} days left).", 0xFF0000),
    (else_try),
      (display_message, "@Your party consumed {reg1} units of food{reg4?, {reg4} from foraging : }({reg2} days left)."),
    (try_end),
   ]),

  # Script forage_for_food
  # Compute foraging amount
  # use s2, reg0, reg1 and reg10
  # for DEBUG, use s1 and reg11
  # use reg4 for return value
  ("forage_for_food",
   [
        # Get max skill in party for foraging
        (call_script, "script_get_max_skill_of_player_party", "skl_foraging"),
        (assign, ":max_foraging_in_party", reg0),
        (assign, ":max_skill_owner", reg1),

        # Initialize foraged food amount and register
        (assign, ":foraged_food", 0),
        (assign, reg4, 0),
        
        (try_begin),
          # stop if no-one has foraging skill
          (gt, ":max_foraging_in_party", 0),

          (try_begin),
            # set limits and range for foraging
            (assign,  ":foraging_limit", ":max_foraging_in_party"),
            (val_mul, ":foraging_limit", 5),
            (assign,  ":foraging_distance", ":max_foraging_in_party"),
            (val_mul, ":foraging_distance", 2),

            # Check distance from village or town
            (try_for_parties,":foraging_site"),
              (assign, ":foraged_food_at_site", 0),
              (this_or_next|party_slot_eq, ":foraging_site", slot_party_type, spt_town),
              (party_slot_eq, ":foraging_site", slot_party_type, spt_village),
              (neg|party_slot_eq, ":foraging_site", slot_village_state, svs_looted), # no foraging from looted village

              # Compute center distance to party
              (store_distance_to_party_from_party, ":distance", ":foraging_site", "p_main_party"),
              (try_begin),
                (le,":distance",":foraging_distance"), # we can forage from this center

                # Forage from fields
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_grain),
                (val_div, ":temp_forage", 1000), # 500 was too low, try 1000
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_vineyard),
                (val_div, ":temp_forage", 800), # 400 was too low, try 800
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_vineyard), # second time for fruits
                (val_div, ":temp_forage", 1000), # 500 was too low, try 1000
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_olives),
                (val_div, ":temp_forage", 1200), # 600 was too low, try 1200
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_dates),
                (val_div, ":temp_forage", 960), # 480 was to low, try 960
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                # Forage from herds
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_head_cattle),
                (val_div, ":temp_forage", 36),
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_head_sheep),
                (val_div, ":temp_forage", 60),
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                # Forage from gardens and apiaries
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_household_gardens),
                (val_add, ":foraged_food_at_site", 2),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_apiaries),
                (val_add, ":foraged_food_at_site", 1),
 
                # Forage game in traps
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_fur_traps),
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                # Add amount foraged off the center to the total
                (val_add, ":foraged_food", ":foraged_food_at_site"),

                # DEBUG message to tweak values, uncomment to display
                #(str_store_party_name, s1, ":foraging_site"),
                #(assign, reg11, ":foraged_food_at_site"),
                #(display_message, "@DEBUG foraging: foraged {reg11} units from {s1}.", 0xFF00FF),
              (try_end),
            (try_end), # end of centers loop

            # Check terrain for foraging from the countryside
            (party_get_current_terrain, ":cur_terrain", "p_main_party"),
            (try_begin),
              (is_between, ":cur_terrain", rt_bridge, rt_desert_forest),
              (assign, reg10, 4),
            (else_try),
              (is_between, ":cur_terrain", rt_steppe, rt_plain),
              (assign, reg10, 2),
            (else_try),
              (assign, reg10, 0),
            (try_end),

            # Add foraged amount from countryside to total amount
            (val_add, ":foraged_food", reg10),

            # DEBUG message to tweak values, uncomment to display
            #(display_message, "@DEBUG foraging: foraged {reg10} units from countryside.", 0xFF00FF),

            # Tier Multiplier, foraging value multiplied by foraging skill tier bonus
            # Represent experience, less time to find forage means more food foraged
            (try_begin), 
              # between 2-4, x1.5 bonus
              (gt, ":max_foraging_in_party", 1),
              (lt, ":max_foraging_in_party", 5),
              (val_mul, ":foraged_food", 3), 
              (val_div, ":foraged_food", 2), 
            (else_try), 
              # between 5-7, x2 bonus
              (gt, ":max_foraging_in_party", 4),
              (lt, ":max_foraging_in_party",,
              (val_mul, ":foraged_food", 2), 
            (else_try), 
              # between 8-9, x2.5 bonus
              (gt, ":max_foraging_in_party", 7),
              (lt, ":max_foraging_in_party", 10),
              (val_mul, ":foraged_food", 5), 
              (val_div, ":foraged_food", 2), 
            (else_try), 
              # 10 and more, x3 bonus
              (ge, ":max_foraging_in_party", 10),
              (val_mul, ":foraged_food", 3), 
            (try_end),

            # Apply Camp bonus x1.5 (represent more time to forage)
            (try_begin),
              #(this_or_next|ge, "$current_camp_party", -1), # uncomment if using Entrenchment
              (this_or_next|eq, "$g_camp_mode", 1), 
              (eq, "$g_siege_force_wait", 1),
              (val_mul, ":foraged_food", 3),
              (val_div, ":foraged_food", 2),        
            (try_end),

            # Apply foraging limit according to skill level (modified by party bonus)
            (try_begin),
              (gt, ":foraged_food", ":foraging_limit"),
              (assign, ":foraged_food", ":foraging_limit"),
            (try_end),

            # assign amount foraged to register to deduct from party consumption
            (assign, reg4, ":foraged_food"),

            # End of foraging message
            (try_begin),
              (gt, ":foraged_food", 0),
              (str_store_troop_name, s2, ":max_skill_owner"),
              (display_message, "@{s2} managed to forage {reg4} units of food to complement supplies.", 0x00FF00),
            (try_end),
          (try_end),
        (try_end),
   ]),
## Jrider -
[/list]
  • Hooks in simple_triggers.py, insert the tagged code in this trigger :
    Code:
      # Consuming food at every 14 hours
      (14,
       [
        (eq, "$g_player_is_captive", 0),
        (party_get_num_companion_stacks, ":num_stacks","p_main_party"),
        (assign, ":num_men", 0),
        (try_for_range, ":i_stack", 0, ":num_stacks"),
          (party_stack_get_size, ":stack_size","p_main_party",":i_stack"),
          (val_add, ":num_men", ":stack_size"),
        (try_end),
        (val_div, ":num_men", 3),
        (try_begin),
          (eq, ":num_men", 0),
          (val_add, ":num_men", 1),
        (try_end),
    
        ## Jrider + FORAGING v1.0, add foraging
        (call_script, "script_forage_for_food"),
    
        # backup original number for message display
        (assign, ":orig_men", ":num_men"),
        (try_begin), 
          # set min consumption to 1 unit of food in inventory
          (ge, reg4, ":num_men"),
          (assign, ":num_men", 1),
        (else_try),
          # else deduct foraged amount from consumed from party size
          (val_sub, ":num_men", reg4),
        (try_end),
        ## Jrider -
        
        (assign, ":consumption_amount", ":num_men"),

    still in the same trigger, a bit lower insert the following tagged code for the display message :
    Code:
    #NPC companion changes end
          (try_end),
        (try_end),
        ## Jrider + FORAGING v1.0, call food consummed/left script
        (call_script, "script_food_consumption_display_message", ":orig_men"),
        ## Jrider -
    # Party Morale: Move morale towards target value.
  • finally, in game menu add the following line to the following character backgrounds' stats additions in the begin_adventuring menu :
              cb_forester, cb2_urchin, cb3_poacher
    Code:
            (troop_raise_skill, "trp_player","skl_foraging",1), ## Jrider : FORAGING v1.0, increase foraging skill
    • [/l][/l]
 
To adjust the skill display, changing the following in addition to char_b/sc/t/bo_skills... should work:
Code:
char_b_skill_increment_x = 0.2625
char_b_skill_increment_y_a = 0.005
char_b_skill_increment_h_a = 0.002
char_b_skill_increment_t_s = 0.018

Party morale can be changed here by adjusting the bonus based on the skill.
Code:
          (call_script, "script_cf_player_has_item_without_modifier", ":cur_edible", imod_rotten),
          (item_get_slot, ":food_bonus", ":cur_edible", slot_item_food_bonus),
In addition, you could conceivably modify slot_item_food_bonus (or create another one) directly inside script_forage_for_food, and reset it every call. You could probably also display this value inside script_game_get_item_extra_text just for kicks.

You'll want to change the line (neg|party_slot_eq, ":foraging_site", slot_village_state, svs_looted), to (party_slot_eq, ":foraging_site", slot_village_state, svs_normal), which also works for towns since the slot value (and those of svs_normal) are 0 by default. Otherwise, foraging is possible from centers under siege and deserted/recovering/currently raided villages, etc.
 
sorry to reply to this post as it is already quite old. I added the code and it works fine. The issue that i have is that by adding this I seem to have lost access to game notes. when I compile, what I get is:

Initializing...
Compiling all global variables...
Exporting strings...
Exporting skills...
Exporting tracks...
Exporting animations...
Exporting meshes...
Exporting sounds...
Exporting skins...
Exporting map icons...
Creating new tag_uses.txt file...
Creating new quick_strings.txt file...
Exporting faction data...
Exporting item data...
Exporting scene data...
Exporting troops data
Exporting particle data...
Exporting scene props...
Exporting tableau materials data...
Exporting presentations...
Exporting party_template data...
Exporting parties
Exporting quest data...
Exporting info_page data...
Exporting scripts...
WARNING: Script can fail at operation #1. Use cf_ at the beginning of its name:
get_player_party_morale_values
Exporting mission_template data...
Exporting game menus data...
exporting simple triggers...
exporting triggers...
exporting dialogs...
Checking global variable usages...
Exporting postfx_params...

______________________________

Script processing has ended.
Press any key to exit. . .


so, basically, the issue is directly linked to the last portion of the code which tries to adjust party morale.

The issue when I play the game is that any game notes (eg: when I press view notes about a character or town, etc) become blanc. Nothing shows.

Has anyone, who has implemented this code, come up with the same issue? If yes, what is the solution?

Thanks
 
The code snippet I posted isn't meant to be added to the beginning of the script - it's a reference location to where you can modify the party morale bonus based on your foraging skills.
 
Thanks for the script jrider!

One small typo in  the module_scripts text, I think:

(lt, ":max_foraging_in_party",,

should be

(lt, ":max_foraging_in_party", :cool:,
 
Hey everyone, I'm resurrecting this thread, because I found some flaws with this WIP script and I'd like to contribute to make it perfect :p

A few years ago, I found that the code doesn't correctly predict the remaining days of food left and it was pretty annoying wathing mods telling me I had food for a period I knew was blatantly wrong. Back then, I was a big, big, noob (like that was even possible), so I began testing this for days until I got it right. Because of my limited coding skills, it took me quite a while to figure the right formulae and proper checks, but here is my contribution. So far, I am yet to be disappointed with the results, so I'm sharing this one with you :smile:

Naturally, throughout the years I turned this into a much simpler and personalized code to fit my needs (I like short and simple). You only need to take a look at the math and change it accordingly to make it work like the original. Otherwise, you can just use the whole thing, like I do.

Before, I release it, let me tell you about the main differences. On my script, the skill isn't called foraging, it's called hunting and I merged it with the tracking skill. It made sense, to me (and I will probably merge these with spotting if I find more useful skills to add to my mod). So, although it makes things simpler, you'll still have to account for this. Also, each skill point steadily gives you 10 food units, regardless of terrain and whatnot. It may seem much, but it isn't, really, as I changed the food consumption for one food ration per troop to make it more manageable. I also changed the frequency at which you troops feed for once a day to make it easier to account, reduce spam/lag, etc. Other minor things, like giving your party morale if your hunters are successful in feeding everybody, etc...

and, now, here goes (blue should be the original Native code, so you know where things go):

on module_skills:

  ("reserved_8","Reserved Skill 8",sf_base_att_int|sf_inactive,10,"This is a reserved skill."),
Code:
  ("tracking","Hunting",sf_base_att_agi|sf_effects_party,10,"Allows your party to hunt for food and to read tracks. (Party skill)"),

on module_scripts:


  # script_refresh_center_stables
  ("refresh_center_stables",
  [
    (reset_item_probabilities, 100),
    (set_merchandise_modifier_quality, 150),
    (try_for_range, ":cur_merchant", horse_merchants_begin, horse_merchants_end),
  (troop_clear_inventory, ":cur_merchant"),
      (store_sub, ":cur_town", ":cur_merchant", horse_merchants_begin),
      (val_add, ":cur_town", towns_begin),
      (party_get_slot, ":cur_faction", ":cur_town", slot_center_original_faction),
      (troop_add_merchandise_with_faction, ":cur_merchant", ":cur_faction", itp_type_horse, 5),
      (troop_ensure_inventory_space, ":cur_merchant", 65),
      (troop_sort_inventory, ":cur_merchant"),
      (store_troop_gold, ":cur_gold", ":cur_merchant"),
      (lt, ":cur_gold", 10000),
      (store_random_in_range, ":new_gold", 1000, 2000),
      (call_script, "script_troop_add_gold", ":cur_merchant", ":new_gold"),
    (try_end),
  ]),

Code:
  ### > FORAGING/HUNTING (1/2) ############################################################
  ### Script food_consumption_display_message
  ### display food consumption
  ### use reg1 and reg2 and reg4 from forage
  ### hooked in simple trigger for food consumption every 24 hours
  ("food_consumption_display_message",
   [
    (store_script_param, ":num_men", 1),

    (assign, reg1, ":num_men"),
    (assign, ":available_food", 0),
    (troop_get_inventory_capacity, ":capacity", "trp_player"),
    (try_for_range, ":cur_slot", 0, ":capacity"),
      (troop_get_inventory_slot, ":cur_item", "trp_player", ":cur_slot"),
      (try_begin),
        (is_between, ":cur_item", food_begin, food_end),
        (troop_get_inventory_slot_modifier, ":item_modifier", "trp_player", ":cur_slot"),
        (neq, ":item_modifier", imod_rotten),
        (troop_inventory_slot_get_item_amount, ":cur_amount", "trp_player", ":cur_slot"),
        (val_add, ":available_food", ":cur_amount"),
      (try_end),
    (try_end),

    (assign, ":num_food_days", ":available_food"),
    (assign, reg2, ":num_food_days"),

    (try_begin),
      (ge, reg4, reg1),
      (display_message, "@Today, our hunters came back with a feast for the whole party! We have {reg2} supplies left.", 0x00FF00),
      (call_script, "script_change_player_party_morale", 3),
    (else_try),
      (gt, reg4, 0),
      (assign, reg5, reg1),(val_sub, reg5, reg4),(val_div, reg2, reg5),(val_sub, reg2, 1),
      (try_begin),
        (gt, reg2, 1),
        (display_message, "@Today, our hunters were able to feed {reg4} of our men. Our supplies should be enough for {reg2} days..."),
      (else_try),
        (gt, reg2, 0),
        (display_message, "@Today, our hunters brought enough food for {reg4} men. Our supplies will only last one more day!", 0xFF0000),
      (else_try),
        (display_message, "@We're out of supplies! Still, our hunters still managed to provide for {reg4} men.", 0xFF0000),
      (try_end),
    (else_try),
      (val_div, reg2, reg1),(val_sub, reg2, 1),
      (try_begin),
        (eq, reg2, 1),
        (display_message, "@Today, our party consumed {reg1} food. Our supplies will only last one more day!", 0xFF0000),
      (else_try),
        (eq, reg2, 0),
        (display_message, "@Our party ran out of food!", 0xFF0000),
      (else_try),
        (lt, reg2, 0),
      (else_try),
        (display_message, "@Today, our party consumed {reg1} food. Our supplies should be enough for {reg2} days..."),
      (try_end),
    (try_end),
   ]),
  ### < FORAGING/HUNTING (1/2) ############################################################

  ### > Jrider/Cuts Hunting/Foraging (2/2) :: Compute foraging amount
  # Use s2, reg0, reg1 and reg10
  # For DEBUG, use s1 and reg11
  # Output reg4 to return amount
  ("forage_for_food",
   [
        # Get max skill in party for foraging
        (call_script, "script_get_max_skill_of_player_party", "skl_tracking"),
        (assign, ":max_foraging_in_party", reg0),

        # Initialize foraged food amount and register
        (assign, ":foraged_food", 0),
        (assign, reg4, 0),

        (try_begin),
          # stop if no-one has foraging skill
          (gt, ":max_foraging_in_party", 0),
          (try_begin),
            # assign amount foraged to register to deduct from party consumption
            (assign,  ":foraged_food", ":max_foraging_in_party"),
            (val_mul, ":foraged_food", 10),
            (assign, reg4, ":foraged_food"),
          (try_end),
        (try_end),
   ]),
  ### < Jrider/Cuts Hunting/Foraging (2/2) :: Compute foraging amount
]

On simple_triggers:


  # Centers give alarm if the player is around
  (0.5,
  [
    (store_current_hours, ":cur_hours"),
    (store_mod, ":cur_hours_mod", ":cur_hours", 11),
    (store_sub, ":hour_limit", ":cur_hours", 5),
    (party_get_num_companions, ":num_men", "p_main_party"),
    (party_get_num_prisoners, ":num_prisoners", "p_main_party"),
    (val_add, ":num_men", ":num_prisoners"),
    (convert_to_fixed_point, ":num_men"),
    (store_sqrt, ":num_men_effect", ":num_men"),
    (convert_from_fixed_point, ":num_men_effect"),
    (try_begin),
      (eq, ":cur_hours_mod", 0),
      #Reduce alarm by 2 in every 11 hours.
      (try_for_range, ":cur_faction", kingdoms_begin, kingdoms_end),
        (faction_get_slot, ":player_alarm", ":cur_faction", slot_faction_player_alarm),
        (val_sub, ":player_alarm", 1),
        (val_max, ":player_alarm", 0),
        (faction_set_slot, ":cur_faction", slot_faction_player_alarm, ":player_alarm"),
      (try_end),
    (try_end),
    (eq, "$g_player_is_captive", 0),
    (try_for_range, ":cur_center", centers_begin, centers_end),
      (store_faction_of_party, ":cur_faction", ":cur_center"),
      (store_relation, ":reln", ":cur_faction", "fac_player_supporters_faction"),
      (lt, ":reln", 0),
      (store_distance_to_party_from_party, ":dist", "p_main_party", ":cur_center"),
      (lt, ":dist", 5),
      (store_mul, ":dist_sqr", ":dist", ":dist"),
      (store_sub, ":dist_effect", 20, ":dist_sqr"),
      (store_sub, ":reln_effect", 20, ":reln"),
      (store_mul, ":total_effect", ":dist_effect", ":reln_effect"),
      (val_mul, ":total_effect", ":num_men_effect"),
      (store_div, ":spot_chance", ":total_effect", 10),
      (store_random_in_range, ":random_spot", 0, 1000),
      (lt, ":random_spot", ":spot_chance"),
      (faction_get_slot, ":player_alarm", ":cur_faction", slot_faction_player_alarm),
      (val_add, ":player_alarm", 1),
      (val_min, ":player_alarm", 100),
      (faction_set_slot, ":cur_faction", slot_faction_player_alarm, ":player_alarm"),
      (try_begin),
        (neg|party_slot_ge, ":cur_center", slot_center_last_player_alarm_hour, ":hour_limit"),
        (str_store_party_name_link, s1, ":cur_center"),
        (display_message, "@Your party is spotted by {s1}."),
        (party_set_slot, ":cur_center", slot_center_last_player_alarm_hour, ":cur_hours"),
      (try_end),
    (try_end),
    ]),
 
Code:
  # Consuming food every night
  (8,
   [
    (is_currently_night),
    (eq, "$g_player_is_captive", 0),
    (party_get_num_companion_stacks, ":num_stacks","p_main_party"),
    (assign, ":num_men", 0),
    (try_for_range, ":i_stack", 0, ":num_stacks"),
      (party_stack_get_size, ":stack_size","p_main_party",":i_stack"),
      (val_add, ":num_men", ":stack_size"),
    (try_end),
#    (val_div, ":num_men", 3),
    (try_begin),
      (eq, ":num_men", 0),
      (val_add, ":num_men", 1),
    (try_end),
    
    (try_begin),
      (assign, ":number_of_foods_player_has", 0),
      (try_for_range, ":cur_edible", food_begin, food_end),      
        (call_script, "script_cf_player_has_item_without_modifier", ":cur_edible", imod_rotten),
        (val_add, ":number_of_foods_player_has", 1),
      (try_end),
      (try_begin),
        (ge, ":number_of_foods_player_has", 6),
        (unlock_achievement, ACHIEVEMENT_ABUNDANT_FEAST),        
      (try_end),
    (try_end),
    
    ### > Jrider/Cuts Foraging/Hunting
    (call_script, "script_forage_for_food"),
    # backup original number for message display
    (assign, ":orig_men", ":num_men"),
    (try_begin), 
      # deduct foraged amount from consumed from party size
      (val_sub, ":num_men", reg4),
    (try_end),

    # Call food consummed/left script
    (call_script, "script_food_consumption_display_message", ":orig_men"),

    ### < Jrider/Cuts Foraging/Hunting

    (assign, ":consumption_amount", ":num_men"),
    (assign, ":no_food_displayed", 0),
    (try_for_range, ":unused", 0, ":consumption_amount"),
      (assign, ":available_food", 0),
      (try_for_range, ":cur_food", food_begin, food_end),
        (item_set_slot, ":cur_food", slot_item_is_checked, 0),
        (call_script, "script_cf_player_has_item_without_modifier", ":cur_food", imod_rotten),
        (val_add, ":available_food", 1),
      (try_end),
      (try_begin),
        (gt, ":available_food", 0),
        (store_random_in_range, ":selected_food", 0, ":available_food"),
        (call_script, "script_consume_food", ":selected_food"),
      (else_try),
        (eq, ":no_food_displayed", 0),
        (display_message, "@Your party has nothing to eat!", 0xFF0000),
        (call_script, "script_change_player_party_morale", -3),
        (assign, ":no_food_displayed", 1),
#NPC companion changes begin
        (try_begin),
            (call_script, "script_party_count_fit_regulars", "p_main_party"),
            (gt, reg0, 0),
            (call_script, "script_objectionable_action", tmt_egalitarian, "str_men_hungry"),
        (try_end),
#NPC companion changes end
      (try_end),
    (try_end),
    ]),

  # Setting item modifiers for food

Thanks for this script, Jrider! If I screwed anything up, let me now :smile:
 
Somebody said:
To adjust the skill display, changing the following in addition to char_b/sc/t/bo_skills... should work:
Code:
char_b_skill_increment_x = 0.2625
char_b_skill_increment_y_a = 0.005
char_b_skill_increment_h_a = 0.002
char_b_skill_increment_t_s = 0.018

How would I change these values?
 
Good afternoon. It seems to have done everything according to the instructions, but it gives out such an error

Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_init.py", line 2, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_global_variables.py", line 12, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Exporting strings...
Exporting skills...
Exporting tracks...
Exporting animations...
Exporting meshes...
Exporting sounds...
Exporting skins...
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_map_icons.py", line 6, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Exporting faction data...
Exporting item data...
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_items.py", line 66, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Exporting scene data...
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_scenes.py", line 15, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Exporting troops data
Exporting particle data...
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_scene_props.py", line 7, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_tableau_materials.py", line 8, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_presentations.py", line 8, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Exporting party_template data...
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_parties.py", line 6, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Exporting quest data...
Exporting info_page data...
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_scripts.py", line 4, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_mission_tmps.py", line 8, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_game_menus.py", line 8, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_simple_triggers.py", line 5, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_dialogs.py", line 9, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "F:\Games\Warband\Modules\1487AD\Source Code\process_global_variables_unused.py", line 3, in <module>
from process_operations import *
File "F:\Games\Warband\Modules\1487AD\Source Code\process_operations.py", line 20, in <module>
from module_scripts import *
File "F:\Games\Warband\Modules\1487AD\Source Code\module_scripts.py", line 87556
]),
^
SyntaxError: invalid syntax
Exporting postfx_params...

______________________________

Script processing has ended.
Press any key to exit. . .

code
Python:
  ## FORAGING v1.0 #######################################################################
  ## Script food_consumption_display_message
  ## display food consumption
  ## use reg1 and reg2 and reg4 from forage
  ## hooked in simple trigger for food consumption every 14 hours
  ("food_consumption_display_message",
   [
    (store_script_param, ":num_men", 1),

    (assign, reg1, ":num_men"),
    # Display day of food left with current amount and party size
    (assign, ":available_food", 0),
    (troop_get_inventory_capacity, ":capacity", "trp_player"),
    (try_for_range, ":cur_slot", 0, ":capacity"),
      (troop_get_inventory_slot, ":cur_item", "trp_player", ":cur_slot"),
      (try_begin),
        (is_between, ":cur_item", food_begin, food_end),
        (troop_get_inventory_slot_modifier, ":item_modifier", "trp_player", ":cur_slot"),
        (neq, ":item_modifier", imod_rotten),
        (troop_inventory_slot_get_item_amount, ":cur_amount", "trp_player", ":cur_slot"),
        (val_add, ":available_food", ":cur_amount"),
      (try_end),
    (try_end),
   
    (assign, ":num_food_hours", ":available_food"),
    (val_mul, ":num_food_hours", 14),
    (val_div, ":num_food_hours", 24),
    (val_div, ":num_food_hours", ":num_men"),
    (assign, ":num_food_days", ":num_food_hours"),
    (assign, reg2, ":num_food_days"),
   
    (try_begin),
      (lt, reg2, 4),
      (display_message, "@Your party consumed {reg1} units of food{reg4?, {reg4} from foraging : }({reg2} days left).", 0xFF0000),
    (else_try),
      (display_message, "@Your party consumed {reg1} units of food{reg4?, {reg4} from foraging : }({reg2} days left)."),
    (try_end),
   ]),

  # Script forage_for_food
  # Compute foraging amount
  # use s2, reg0, reg1 and reg10
  # for DEBUG, use s1 and reg11
  # use reg4 for return value
  ("forage_for_food",
   [
        # Get max skill in party for foraging
        (call_script, "script_get_max_skill_of_player_party", "skl_foraging"),
        (assign, ":max_foraging_in_party", reg0),
        (assign, ":max_skill_owner", reg1),

        # Initialize foraged food amount and register
        (assign, ":foraged_food", 0),
        (assign, reg4, 0),
       
        (try_begin),
          # stop if no-one has foraging skill
          (gt, ":max_foraging_in_party", 0),

          (try_begin),
            # set limits and range for foraging
            (assign,  ":foraging_limit", ":max_foraging_in_party"),
            (val_mul, ":foraging_limit", 5),
            (assign,  ":foraging_distance", ":max_foraging_in_party"),
            (val_mul, ":foraging_distance", 2),

            # Check distance from village or town
            (try_for_parties,":foraging_site"),
              (assign, ":foraged_food_at_site", 0),
              (this_or_next|party_slot_eq, ":foraging_site", slot_party_type, spt_town),
              (party_slot_eq, ":foraging_site", slot_party_type, spt_village),
              (neg|party_slot_eq, ":foraging_site", slot_village_state, svs_looted), # no foraging from looted village

              # Compute center distance to party
              (store_distance_to_party_from_party, ":distance", ":foraging_site", "p_main_party"),
              (try_begin),
                (le,":distance",":foraging_distance"), # we can forage from this center

                # Forage from fields
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_grain),
                (val_div, ":temp_forage", 1000), # 500 was too low, try 1000
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_vineyard),
                (val_div, ":temp_forage", 800), # 400 was too low, try 800
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_vineyard), # second time for fruits
                (val_div, ":temp_forage", 1000), # 500 was too low, try 1000
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_olives),
                (val_div, ":temp_forage", 1200), # 600 was too low, try 1200
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_acres_dates),
                (val_div, ":temp_forage", 960), # 480 was to low, try 960
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                # Forage from herds
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_head_cattle),
                (val_div, ":temp_forage", 36),
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_head_sheep),
                (val_div, ":temp_forage", 60),
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                # Forage from gardens and apiaries
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_household_gardens),
                (val_add, ":foraged_food_at_site", 2),

                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_apiaries),
                (val_add, ":foraged_food_at_site", 1),
 
                # Forage game in traps
                (party_get_slot, ":temp_forage", ":foraging_site", slot_center_fur_traps),
                (val_add, ":foraged_food_at_site", ":temp_forage"),

                # Add amount foraged off the center to the total
                (val_add, ":foraged_food", ":foraged_food_at_site"),

                # DEBUG message to tweak values, uncomment to display
                #(str_store_party_name, s1, ":foraging_site"),
                #(assign, reg11, ":foraged_food_at_site"),
                #(display_message, "@DEBUG foraging: foraged {reg11} units from {s1}.", 0xFF00FF),
              (try_end),
            (try_end), # end of centers loop

            # Check terrain for foraging from the countryside
            (party_get_current_terrain, ":cur_terrain", "p_main_party"),
            (try_begin),
              (is_between, ":cur_terrain", rt_bridge, rt_desert_forest),
              (assign, reg10, 4),
            (else_try),
              (is_between, ":cur_terrain", rt_steppe, rt_plain),
              (assign, reg10, 2),
            (else_try),
              (assign, reg10, 0),
            (try_end),

            # Add foraged amount from countryside to total amount
            (val_add, ":foraged_food", reg10),

            # DEBUG message to tweak values, uncomment to display
            #(display_message, "@DEBUG foraging: foraged {reg10} units from countryside.", 0xFF00FF),

            # Tier Multiplier, foraging value multiplied by foraging skill tier bonus
            # Represent experience, less time to find forage means more food foraged
            (try_begin),
              # between 2-4, x1.5 bonus
              (gt, ":max_foraging_in_party", 1),
              (lt, ":max_foraging_in_party", 5),
              (val_mul, ":foraged_food", 3),
              (val_div, ":foraged_food", 2),
            (else_try),
              # between 5-7, x2 bonus
              (gt, ":max_foraging_in_party", 4),
              (lt, ":max_foraging_in_party", 10,
              (val_mul, ":foraged_food", 2),
            (else_try),
              # between 8-9, x2.5 bonus
              (gt, ":max_foraging_in_party", 7),
              (lt, ":max_foraging_in_party", 10),
              (val_mul, ":foraged_food", 5),
              (val_div, ":foraged_food", 2),
            (else_try),
              # 10 and more, x3 bonus
              (ge, ":max_foraging_in_party", 10),
              (val_mul, ":foraged_food", 3),
            (try_end),

            # Apply Camp bonus x1.5 (represent more time to forage)
            (try_begin),
              #(this_or_next|ge, "$current_camp_party", -1), # uncomment if using Entrenchment
              (this_or_next|eq, "$g_camp_mode", 1),
              (eq, "$g_siege_force_wait", 1),
              (val_mul, ":foraged_food", 3),
              (val_div, ":foraged_food", 2),      
            (try_end),

            # Apply foraging limit according to skill level (modified by party bonus)
            (try_begin),
              (gt, ":foraged_food", ":foraging_limit"),
              (assign, ":foraged_food", ":foraging_limit"),
            (try_end),

            # assign amount foraged to register to deduct from party consumption
            (assign, reg4, ":foraged_food"),

            # End of foraging message
            (try_begin),
              (gt, ":foraged_food", 0),
              (str_store_troop_name, s2, ":max_skill_owner"),
              (display_message, "@{s2} managed to forage {reg4} units of food to complement supplies.", 0x00FF00),
            (try_end),
          (try_end),
        (try_end),        
   ]),
 
Did you put it in module_scripts.py? It says there is something wrong with syntax and, according to cuts (who upgraded the feature), you should place everything correctly in the ModSys files of Simple Triggers, Scripts and Skills.
Yes, I prescribed everything as indicated above. and scripts and triggers.
 
Back
Top Bottom