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:
Changelog:
This is a work in progress as, indicated in the subject so there's a TODO list
[/list]
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)
- Current party terrain provide a flat base value depending on type
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)
- 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 -
- 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]