Encumbrance System

正在查看此主题的用户

cucas

Regular
Hey everyone!

I was thinking about adding a basic encumbrance system to my private mod.

So far, I've already tried two systems, unsuccessfully. One in which your weight affects your skills and the other in which the equipment itself will affect your skills. Maybe there's a more straightforward method?

I've been trying this for days, editing the *.PYs, researching, etc, but I just can't seem to get something this simple right...

Thanks, I'll release the script here for the public if I manage to get it to work!

Here is my research so far:
1. Insert this code in module_scripts.py (green color is original text, blue is text to insert)

# -*- coding: cp1254 -*-
from header_common import *
from header_operations import *
from module_constants import *
from module_constants import *
from header_parties import *
from header_skills import *
from header_mission_templates import *
from header_items import *
from header_triggers import *
from header_terrain_types import *
from header_music import *
from header_map_icons import *
from ID_animations import *

#from header_presentations import *

### > Encumbrance System: Part 1/3
def get_hrd_weight(y):
  a = (y >> ibf_weight_bits) & ibf_armor_mask
  return int(25 * a)

def set_item_score():
  item_score = []
  for i_item in xrange(len(items)):
    ## weight
    item_score.append((item_set_slot, i_item, slot_item_weight, get_hrd_weight(items[i_item][6])))
### < Encumbrance System: Part 1/3

####################################################################################################################
# scripts is a list of script records.
# Each script record contns the following two fields:
# 1) Script id: The prefix "script_" will be inserted when referencing scripts.
# 2) Operation block: This must be a valid operation block. See header_operations.py for reference.
####################################################################################################################

(...)

    #script_game_get_skill_modifier_for_troop
    # This script is called from the game engine when a skill's modifiers are needed
    # INPUT: arg1 = troop_no, arg2 = skill_no
    # OUTPUT: trigger_result = modifier_value
    ("game_get_skill_modifier_for_troop",
      [(store_script_param, ":troop_no", 1),
        (store_script_param, ":skill_no", 2),
        (assign, ":modifier_value", 0),
        (try_begin),
          (eq, ":skill_no", "skl_wound_treatment"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_wound_treatment_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
        (else_try),
          (eq, ":skill_no", "skl_trainer"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_training_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
        (else_try),
          (eq, ":skill_no", "skl_surgery"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_surgery_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),

          ### > Encumbrance System: Part 2/3
        (else_try),
          (eq, ":skill_no", "skl_riding"),
          (eq, "$g_encumbrance_penalty", 1),
          (this_or_next|eq, ":troop_no", "trp_player"),
          (is_between, ":troop_no", companions_begin, companions_end),
        (main_party_has_troop, ":troop_no"), ##Floris fix so companions-as-lords aren't affected
          (store_attribute_level, ":agi", ":troop_no", ca_agility),
          (call_script, "script_get_total_equipment_weight", ":troop_no"),
          (assign, ":total_weight", reg0),
          (val_sub, ":total_weight", 10),
          (val_sub, ":total_weight", ":agi"),
          (val_div, ":total_weight", 10),
          (store_sub, ":modifier_value", 0, ":total_weight"),
          (val_min, ":modifier_value", 0),
        (else_try),
          (eq, ":skill_no", "skl_power_draw"),
          (eq, "$g_encumbrance_penalty", 1),
          (this_or_next|eq, ":troop_no", "trp_player"),
          (is_between, ":troop_no", companions_begin, companions_end),
        (main_party_has_troop, ":troop_no"), ##Floris fix so companions-as-lords aren't affected
          (store_attribute_level, ":str", ":troop_no", ca_strength),
          (call_script, "script_get_total_equipment_weight", ":troop_no"),
          (assign, ":total_weight", reg0),
          (val_sub, ":total_weight", 10),
          (val_sub, ":total_weight", ":str"),
          (val_div, ":total_weight", 10),
          (store_sub, ":modifier_value", 0, ":total_weight"),
          (val_min, ":modifier_value", 0),
        (else_try),
          (eq, ":skill_no", "skl_horse_archery"),
          (eq, "$g_encumbrance_penalty", 1),
          (this_or_next|eq, ":troop_no", "trp_player"),
          (is_between, ":troop_no", companions_begin, companions_end),
        (main_party_has_troop, ":troop_no"), ##Floris fix so companions-as-lords aren't affected
          (store_attribute_level, ":agi", ":troop_no", ca_agility),
          (store_attribute_level, ":str", ":troop_no", ca_strength),
          (call_script, "script_get_total_equipment_weight", ":troop_no"),
          (assign, ":total_weight", reg0),
          (val_mul, ":total_weight", 2),
          (val_sub, ":total_weight", 20),
          (val_sub, ":total_weight", ":agi"),
          (val_sub, ":total_weight", ":str"),
          (val_div, ":total_weight", 10),
          (store_sub, ":modifier_value", 0, ":total_weight"),
          (val_min, ":modifier_value", 0),
### < Encumbrance System: Part 2/3

        (try_end),
    (set_trigger_result, ":modifier_value"),
    ]),

### > Encumbrance System: Part 3/3
# script_get_total_equipment_weight:
# INPUT:
# param1: troop_no
# OUTPUT: total equipment weight
("get_total_equipment_weight",[
(store_script_param_1, ":troop_no"),
(assign, ":total_weight", 0),
(try_for_range, ":cur_slot", 0, 8 ),
(troop_get_inventory_slot, ":cur_item", ":troop_no", ":cur_slot"),
(ge, ":cur_item", 0),
(item_get_slot, ":cur_item_weight", ":cur_item", slot_item_weight),
(val_add, ":total_weight", ":cur_item_weight"),
(try_end),
(val_div, ":total_weight", 100),
(assign, reg0, ":total_weight"),
]),
### < Encumbrance System: Part 3/3

(...)

2. Put this in module_constants.py

(...)

slot_item_multiplayer_item_class  = 61 #temporary, can be moved to higher values
slot_item_multiplayer_availability_linked_list_begin = 62 #temporary, can be moved to higher values

slot_item_weight = 63

slot_item_multiplayer_faction_price_multipliers_begin = 30 #reserve around 10 slots after this
########################################################
##  AGENT SLOTS            #############################
########################################################

(...)

Simple, huh? Well, apparently, this isn't working yet. =/
So, if you could lend a hand, it'd be great! This simple system, would be a very nice addition to any mod. It could balance tremendously the game.
 
Thank you, we're much closer to do it, now!

I took a look at your link and I still can't figure it out yet (I have to admit I don't even know how to use modmerger). I prefer to handle the script itself and even at that I am a noob :p

Anyway, I took a look at this, meanwhile. I can only understand a few lines here in the code, so I can't mod this properly. However, I get the meaning, as a whole. I'm sure there is a way to turn this code into something much simpler to meet my needs.

http://forums.taleworlds.com/index.php/topic,8652.msg2038677.html#msg2038677

I think this code, analyses the inventory to look for specific items names/IDs to give specific bonus. What I would want, is to analyze items as well, but instead of analyzing its name/ID, I would like it to analyze its weight. Then, I would come up with a proper formula to give bonuses/penalties. If not, I could just get the total weight somehow and make this affect the player's skills, etc.

I also tried using some of Floris' source, but I got errors :/
What would I need to mod? The compiler says that the problem is with the "slot_item_weight". It says it's not defined, as if I need to call it somewhere, first.

    #script_game_get_skill_modifier_for_troop
    # This script is called from the game engine when a skill's modifiers are needed
    # INPUT: arg1 = troop_no, arg2 = skill_no
    # OUTPUT: trigger_result = modifier_value
    ("game_get_skill_modifier_for_troop",
      [(store_script_param, ":troop_no", 1),
        (store_script_param, ":skill_no", 2),
        (assign, ":modifier_value", 0),
        (try_begin),
          (eq, ":skill_no", "skl_wound_treatment"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_wound_treatment_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
        (else_try),
          (eq, ":skill_no", "skl_trainer"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_training_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
        (else_try),
          (eq, ":skill_no", "skl_surgery"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_surgery_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
          ## CC
        (else_try),
          (eq, ":skill_no", "skl_pathfinding"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_pathfinding_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
        (else_try),
          (eq, ":skill_no", "skl_spotting"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_spotting_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
        (else_try),
          (eq, ":skill_no", "skl_first_aid"),
          (call_script, "script_get_troop_item_amount", ":troop_no", "itm_book_first_aid_reference"),
          (gt, reg0, 0),
          (val_add, ":modifier_value", 1),
        (else_try),
          (eq, ":skill_no", "skl_riding"),
          (eq, "$g_encumbrance_penalty", 1),
          (this_or_next|eq, ":troop_no", "trp_player"),
          (is_between, ":troop_no", companions_begin, companions_end),
  (main_party_has_troop, ":troop_no"), ##Floris fix so companions-as-lords aren't affected
          (store_attribute_level, ":agi", ":troop_no", ca_agility),
          (call_script, "script_get_total_equipment_weight", ":troop_no"),
          (assign, ":total_weight", reg0),
          (val_sub, ":total_weight", 10),
          (val_sub, ":total_weight", ":agi"),
          (val_div, ":total_weight", 10),
          (store_sub, ":modifier_value", 0, ":total_weight"),
          (val_min, ":modifier_value", 0),
        (else_try),
          (eq, ":skill_no", "skl_power_draw"),
          (eq, "$g_encumbrance_penalty", 1),
          (this_or_next|eq, ":troop_no", "trp_player"),
          (is_between, ":troop_no", companions_begin, companions_end),
  (main_party_has_troop, ":troop_no"), ##Floris fix so companions-as-lords aren't affected
          (store_attribute_level, ":str", ":troop_no", ca_strength),
          (call_script, "script_get_total_equipment_weight", ":troop_no"),
          (assign, ":total_weight", reg0),
          (val_sub, ":total_weight", 10),
          (val_sub, ":total_weight", ":str"),
          (val_div, ":total_weight", 10),
          (store_sub, ":modifier_value", 0, ":total_weight"),
          (val_min, ":modifier_value", 0),
        (else_try),
          (eq, ":skill_no", "skl_horse_archery"),
          (eq, "$g_encumbrance_penalty", 1),
          (this_or_next|eq, ":troop_no", "trp_player"),
          (is_between, ":troop_no", companions_begin, companions_end),
  (main_party_has_troop, ":troop_no"), ##Floris fix so companions-as-lords aren't affected
          (store_attribute_level, ":agi", ":troop_no", ca_agility),
          (store_attribute_level, ":str", ":troop_no", ca_strength),
          (call_script, "script_get_total_equipment_weight", ":troop_no"),
          (assign, ":total_weight", reg0),
          (val_mul, ":total_weight", 2),
          (val_sub, ":total_weight", 20),
          (val_sub, ":total_weight", ":agi"),
          (val_sub, ":total_weight", ":str"),
          (val_div, ":total_weight", 10),
          (store_sub, ":modifier_value", 0, ":total_weight"),
          (val_min, ":modifier_value", 0),
        (try_end),

# script_get_total_equipment_weight:
# INPUT:
# param1: troop_no
# OUTPUT: total equipment weight
("get_total_equipment_weight",[
(store_script_param_1, ":troop_no"),
(assign, ":total_weight", 0),
(try_for_range, ":cur_slot", 0, 8 ),
(troop_get_inventory_slot, ":cur_item", ":troop_no", ":cur_slot"),
(ge, ":cur_item", 0),
(item_get_slot, ":cur_item_weight", ":cur_item", slot_item_weight),
(val_add, ":total_weight", ":cur_item_weight"),
(try_end),
(val_div, ":total_weight", 100),
(assign, reg0, ":total_weight"),
]),

When I compile I get this error:
插入代码块:
    (item_get_slot, ":cur_item_weight", ":cur_item", slot_item_weight),
NameError: name 'slot_item_weight' is not defined

I hope I can get through this to the end. In any case, thanks a bunch!
 
If you're pulling your system from Floris you'll need to look for the file "module_my_mod_set.py".  It comes from Custom Commander and has a section in it that uses python scripting to populate item slots with weight.

插入代码块:
def get_hrd_weight(y):
  a = (y >> ibf_weight_bits) & ibf_armor_mask
  return int(25 * a)

def set_item_score():
  item_score = []
  for i_item in xrange(len(items)):
    ## weight
    item_score.append((item_set_slot, i_item, slot_item_weight, get_hrd_weight(items[i_item][6])))

You will probably want that entire file though.
 
AAhhh thanks! I knew I was missing something. I think I got it now! :grin:


Edit: Okay, one more obstacle. I've never added any libraries before.

So, I copied the «module_my_mod_set.py» into my modules folder and declared it right at the beginning of my module_script.py like this

插入代码块:
from module_my_mod_set import *

However, the compiler keeps giving me the same error.
NameError: name 'slot_item_weight' is not defined
So I must still be missing something... I know this must look like a silly question, but what am I missing, here? Do I need to do anything else to use this library?
 
Declare that index in module_constants, look for the next available number for slot_item_x so as to avoid conflicts.
 
Interesting, every time I get closer something strange happens. I followed your suggestion and added «slot_item_weight = 63» to module_contants.

I no longer get errors. However, the game still wont calculate the weight for some reason, so nothing really happens... :/
 
后退
顶部 底部