Modding Q&A [For Quick Questions and Answers]

Users who are viewing this thread

Status
Not open for further replies.
Hello,

Code:
raw_spear_drop =  (ti_on_item_unwielded, 0, 0, [], #ti_on_item_unwield should make this code trigger when sheating the weapon
   [
	(store_trigger_param_1, ":agent"), 
    (store_trigger_param_2, ":item"),
	
    (agent_is_active, ":agent"), # Prevents errors		
    (agent_is_alive, ":agent"),	# Prevents errors
    (agent_is_human, ":agent"),	# Doesn't trigger for other agents
	
       (try_for_range, ":item_slot", ek_item_0, ek_head), # Cycles through the slots
           (agent_get_item_slot,  ":item", ":agent", ":item_slot"),

           (gt, ":item", itm_no_item), # Has the item
           (item_get_type, reg0, ":item"), # Get type of the item
           (eq,itp_type_polearm,reg0), # It's a polearm
			
		(agent_unequip_item, ":agent", ":item"), # Remove item
        (agent_get_position, pos1, ":agent"), # Get player position
        (set_spawn_position, pos1), # Spawn stuff on player's position
        (spawn_item, ":item", 0),	# Stuff that will be spawned		
      (try_end),		
   ])
Designed a code to drop the spear if you decided to sheate it, works well in client side (hosting with bots) but it makes the servers crash somehow, delivering the following error message:
ERROR: Synchronization with server failed: trying to recreate existing object (id: 1226, meta_type: 6, sub_kind_id: 836, variation_id: 0) with meta_type: 7, sub_kind_id: 590, variation_id: 29, do_prune: 1   
I feel a bit clueless about it and I would appreciate some directions if you may. Some notes might be wrong, thank you for your time.
 
Vades said:
I know I could also change script_game_get_troop_wage to reduce the costs of troops.  If anyone thinks I should go this route, Would they be willing to share some variables they used instead of natives?
script_hire_men_to_kingdom_hero_party covers lords paying for their new recruits. The constant reinforcement_cost_moderate (normally 450) is paid by lords of the player's faction, and also all others if the campaign AI is average. The latter pay the amount of reinforcement_cost_easy (600) if it's poor, but reinforcement_cost_hard (300) it's high. The lower these values are the better.
 
I've run into an unexpected problem with my item code.

All I wanted to do was store the damage values for weapons and apply some min-max logic, then store them in item slots.  Got the storage-in-item-slots problem licked, but now I need the data.

Simple, right?  Well, not so fast!  Turns out, the method used by Custom Commander doesn't produce a good result.  I tested it and I immediately started seeing non-sensical results in my damage system code. 

Traced it back to this.  Weapon damage for swing and thrust are coming back with bitwise modifications when getting written to the data.  Why they didn't just use more table entries and used what is essentially some data compression is beyond me, since it has to get unpacked in the engine anyhow, but it's how it works:

Code:
def get_swing_damage(y):
  return (y >> iwf_swing_damage_bits) & ibf_damage_mask

This means that weapons with Pierce and Blunt damage come back with very funky numbers.  It probably also means there is a maximum damage number before weapons are actually getting treated as another damage type, but one problem at a time  :lol:

How do I clean them up and get the right number, without knowing in advance what type of damage we're talking about?  I don't understand bitwise operations really well.  I'm almost tempted to drop Pierce and Blunt entirely as Cut weapons aren't having problems returning good numbers, but then there may be other serious issues; for example, I don't know whether a weapon that is doing zero damage due to armor gets passed to ti_on_agent_hit (if yes, then I can just make everything "cut" and add another flag to emulate Pierce...).

Anybody out there know enough about bitwise stuff to have a clue as to how I'd write a proper evaluator? 

[EDIT]For now, if I hit values > 255, they're getting set to my maximum-damage floor of 50, which is OK, since we're mainly talking about Pierce attacks that rarely do a lot more than that.  I'd really like a way to solve this properly, though...[/EDIT]
 
Designed a code to drop the spear if you decided to sheate it, works well in client side (hosting with bots) but it makes the servers crash somehow
Use the evaluators:

(this_or_next|multiplayer_is_dedicated_server),
(this_or_next|multiplayer_is_server),
(neg|game_in_multiplayer_mode),

Basically, game states aren't matching, causing the server to crash.
 
xenoargh said:
How do I clean them up and get the right number, without knowing in advance what type of damage we're talking about?
Code:
def get_damage_amount(packed_value):
	return packed_value & ibf_armor_mask;

def get_damage_type(packed_value):
	return packed_value >> iwf_damage_type_bits;

packed_value = get_swing_damage(item[6])
damage_amount = get_damage_amount(packed_value)
damage_type = get_damage_type(packed_value)
 
This is probably a silly question but is it possible to assign a party template a different faction type when you spawn it? And if so does its template AI and faction coherence stay the same? I imagine both are yes and it would look something like this:

[(try_for_range, ":center_no", towns_begin, towns_end),
(party_slot_eq,":center_no",slot_center_has_training_ground,1),
(assign, ":counter", 0),
(try_for_parties, ":party_no"),
(party_get_template_id, ":template", ":party_no"),
(eq, ":template", "pt_guard"),
(party_slot_eq, ":party_no", slot_center, ":center_no"),
(val_add, ":counter", 1),
(try_end),
(lt, ":counter", 1),
(store_faction_of_party, ":cur_faction", ":center_no"),
                (set_spawn_radius, 1),
                (store_faction_of_party,"pt_guard", ":cur_faction"),
                #####I'm not sure how to set the centers faction to the party_template######
                (spawn_around_party, ":center_no", "pt_guard"),
(try_end),


        ]),

I'm not sure if a party_template is considered a "party"

Thanks for any feed back!
 
Seek n Destroy said:
ERROR: Synchronization with server failed: trying to recreate existing object (id: 1226, meta_type: 6, sub_kind_id: 836, variation_id: 0) with meta_type: 7, sub_kind_id: 590, variation_id: 29, do_prune: 1
For a multiplayer mod, never run spawn_item (or spawn_scene_prop, spawn_horse, etc.) on a client, only run it on the server: your error message is because the client is trying to create something not existing on the server, so the item instance id would get reused by something else and all the synchronization messages get mixed up from then on. It happens to work on a player hosted game because your client is the server (any other player that joins would crash). It is generally not a good idea to test multiplayer scripts with client hosted games: use a dedicated server to reveal many different types of errors not otherwise detected, so you don't waste time doing things that will never work in practice.

Basically, clean up your indentation and then put a multiplayer_is_server operation at the start, so when the trigger runs on a client it just fails and breaks out immediately, rather than doing anything.

You also might want to set a prune time for spawn_item (optional third parameter) particularly if your mission can be long (like deathmatch rather than battle), so the spawned item will be removed after that amount of seconds if unused, rather than staying there permanently, slowing down the game if many items accumulate.
 
Vades said:
This is probably a silly question but is it possible to assign a party template a different faction type when you spawn it? And if so does its template AI and faction coherence stay the same? I imagine both are yes and it would look something like this:

[(try_for_range, ":center_no", towns_begin, towns_end),
(party_slot_eq,":center_no",slot_center_has_training_ground,1),
(assign, ":counter", 0),
(try_for_parties, ":party_no"),
(party_get_template_id, ":template", ":party_no"),
(eq, ":template", "pt_guard"),
(party_slot_eq, ":party_no", slot_center, ":center_no"),
(val_add, ":counter", 1),
(try_end),
(lt, ":counter", 1),
(store_faction_of_party, ":cur_faction", ":center_no"),
                (set_spawn_radius, 1),
                (store_faction_of_party,"pt_guard", ":cur_faction"),
                #####I'm not sure how to set the centers faction to the party_template######
                (spawn_around_party, ":center_no", "pt_guard"),
(try_end),


        ]),

I'm not sure if a party_template is considered a "party"

Thanks for any feed back!
Party templates are not parties.
Typically you spawn a party with a party template, then change the party's faction with party_set_faction.
Example:
(spawn_around_party,":center","pt_errant_knights"),
(assign, ":new_party", reg0),
(party_set_faction,":new_party",":faction_no"),
 
Thanks for the info MadVader, I didn't think the template was considered a party.  Does the faction need to be set prior to spawning, or will the way you wrote it work? Also, what was reg0 original value? The party template?

Thanks!

[(try_for_range, ":center_no", towns_begin, towns_end),
      (party_slot_eq,":center_no",slot_center_has_training_ground,1),
      (assign, ":counter", 0),
  (try_for_parties, ":party_no"),
      (party_get_template_id, ":template", ":party_no"),
      (eq, ":template", "pt_guard"),
      (party_slot_eq, ":party_no", slot_center, ":center_no"),
      (val_add, ":counter", 1),
  (try_end),
      (lt, ":counter", 1),
      (store_faction_of_party, ":cur_faction", ":center_no"),
      (set_spawn_radius, 1),
      (spawn_around_party, ":center_no", "pt_guard"),
      (assign, ":new_party",reg0),
      (party_set_faction, ":new_party", ":cur_faction"),
  (try_end),


        ]),
 
For a multiplayer mod, never run spawn_item (or spawn_scene_prop, spawn_horse, etc.) on a client, only run it on the server: your error message is because the client is trying to create something not existing on the server, so the item instance id would get reused by something else and all the synchronization messages get mixed up from then on. It happens to work on a player hosted game because your client is the server (any other player that joins would crash). It is generally not a good idea to test multiplayer scripts with client hosted games: use a dedicated server to reveal many different types of errors not otherwise detected, so you don't waste time doing things that will never work in practice.

Basically, clean up your indentation and then put a multiplayer_is_server operation at the start, so when the trigger runs on a client it just fails and breaks out immediately, rather than doing anything.

You also might want to set a prune time for spawn_item (optional third parameter) particularly if your mission can be long (like deathmatch rather than battle), so the spawned item will be removed after that amount of seconds if unused, rather than staying there permanently, slowing down the game if many items accumulate.
[/quote]
I shouldn't have missed the evaluators as Xenoargh stated and setting a prune timer is indeed a good idea.
Thanks to you both, I shall be more careful next time.
 
Vades said:
Thanks for the info MadVader, I didn't think the template was considered a party.  Does the faction need to be set prior to spawning, or will the way you wrote it work? Also, what was reg0 original value? The party template?

Thanks!

[(try_for_range, ":center_no", towns_begin, towns_end),
      (party_slot_eq,":center_no",slot_center_has_training_ground,1),
      (assign, ":counter", 0),
  (try_for_parties, ":party_no"),
      (party_get_template_id, ":template", ":party_no"),
      (eq, ":template", "pt_guard"),
      (party_slot_eq, ":party_no", slot_center, ":center_no"),
      (val_add, ":counter", 1),
  (try_end),
      (lt, ":counter", 1),
      (store_faction_of_party, ":cur_faction", ":center_no"),
      (set_spawn_radius, 1),
      (spawn_around_party, ":center_no", "pt_guard"),
      (assign, ":new_party",reg0),
      (party_set_faction, ":new_party", ":cur_faction"),
  (try_end),


        ]),

try_for_parties is a wasteful operation and can take some time to go through all the parties, better avoid it if concerned over performance, especially don't put it in another loop.
reg0 is a return value from spawn_around_party, just as it says in the operations. You should read those.
You need to store the center in a party slot like slot_party_home_center, so you can check for it later.
You'll also need to set up the patrol party to do stuff. Like this:
...
        (party_set_slot, ":new_party", slot_party_home_center, ":center_no"),
        (str_store_party_name,s1,":center_no"),
        (party_set_name, ":new_party", "@{s1} hapless guards"),
        (store_faction_of_party, ":faction_no", ":center_no"),               
        (party_set_faction,":new_party",":faction_no"),
        (party_set_ai_behavior, ":new_party", ai_bhvr_patrol_party),
        (party_set_ai_patrol_radius, ":new_party", 5),
        (party_set_ai_object, ":new_party", ":center_no"),
        (party_set_flags, ":new_party", pf_default_behavior, 0),             
 
Hi guys I'm trying to modify the mnu_captivity_castle_taken_prisoner into showing up the time you are to serve in the dungeon (as if sentenced by a tribunal). So I did this:

(
    "captivity_town_hooligan",0,
    [
(store_random_in_range, ":random_hours", 24, 72),
# (assign, reg5, ":random_hours"),
"You are quickly surrounded by guards who take away your weapons. With curses and insults, they throw you into the dungeon where you are to serve {:random_hours} hours for your crimes.",
],

    "none",
    [
        (troop_get_type, ":is_female", "trp_player"),
        (try_begin),
          (eq, ":is_female", 1),
          (set_background_mesh, "mesh_pic_prisoner_fem"),
        (else_try),
          (set_background_mesh, "mesh_pic_prisoner_man"),
        (try_end),
    ],
    [
      ("continue",[],"Continue...",
      [
          (assign, "$g_player_is_captive", 1),
          #(store_random_in_range, ":random_hours", 16, 22),
          (call_script, "script_event_player_captured_as_prisoner"),
          (call_script, "script_stay_captive_for_hours", ":random_hours"),
          (assign,"$auto_menu", "mnu_captivity_castle_check"),
          (change_screen_return)
        ]),
    ]
  ),

aaaand I get a bunch of errors like AtributeError: 'list' object has no attribute 'replace'. As you can see I tried before to assign it to some reg5 variable in order to display it afterwards. The thing is I expanded the text string into a bunch of lines of code between to square brackets [ ... ] as it seems (to me) that's the way to introduce more code in a tuple.

Obviously I did something wrong there and I cannot see it. Can anyone point out the problem? Thanks in advance.
 
Dawiduh said:
The thing is I expanded the text string into a bunch of lines of code between to square brackets [ ... ] as it seems (to me) that's the way to introduce more code in a tuple.
No.
####################################################################################################################
#  (menu-id, menu-flags, menu_text, mesh-name, [<operations>], [<options>]),
#
#  Each game menu is a tuple that contains the following fields:

#  1) Game-menu id (string): used for referencing game-menus in other files.
#    The prefix menu_ is automatically added before each game-menu-id
#
#  2) Game-menu flags (int). See header_game_menus.py for a list of available flags.
#    You can also specify menu text color here, with the menu_text_color macro
#  3) Game-menu text (string).
#  4) mesh-name (string). Not currently used. Must be the string "none"
#  5) Operations block (list). A list of operations. See header_operations.py for reference.
#    The operations block is executed when the game menu is activated.
#  6) List of Menu options (List).
#    Each menu-option record is a tuple containing the following fields:
#  6.1) Menu-option-id (string) used for referencing game-menus in other files.
#        The prefix mno_ is automatically added before each menu-option.
#  6.2) Conditions block (list). This must be a valid operation block. See header_operations.py for reference.
#        The conditions are executed for each menu option to decide whether the option will be shown to the player or not.
#  6.3) Menu-option text (string).
#  6.4) Consequences block (list). This must be a valid operation block. See header_operations.py for reference.
#        The consequences are executed for the menu option that has been selected by the player.
#
#
# Note: The first Menu is the initial character creation menu.
####################################################################################################################
 
@cmp:  Works, just built a loop to do what I needed, which in this case was to divide the swing / thrust damage by 2 and then store only the highest value:

Code:
  
######Item damage / damage-type stripper, allowing Module System scripts to get these values back out of the item table with correct values.
## cmpxchg8b
######This section's commented out but serves as an example
######REQUIRES header_items include in any context where you wish to use it
#def get_damage_amount(packed_value):
#	return packed_value & ibf_armor_mask;

#def get_damage_type(packed_value):
#	return packed_value >> iwf_damage_type_bits;

#packed_value = get_swing_damage(item[6])
#damage_amount = get_damage_amount(packed_value)
#damage_type = get_damage_type(packed_value) 

def get_damage_unpacked(packed_value):
 return packed_value & ibf_armor_mask;  

#Simple example of stripping this data out of the tables and pushing it to an item slot
 for i_item in xrange(len(items)):
   item_flags.append((item_set_slot, i_item, slot_item_difficulty, get_difficulty(items[i_item][6])))
   swing_damage = int(get_swing_damage(items[i_item][6]))
   swing_damage = int(get_damage_unpacked(swing_damage))
   thrust_damage = int(get_thrust_damage(items[i_item][6]))
   thrust_damage = int(get_damage_unpacked(thrust_damage))
   swing_damage = swing_damage / 2
   thrust_damage = thrust_damage / 2
   print str(items[i_item][0]) + " swing_damage: " + str(swing_damage) + " thrust_damage: " + str(thrust_damage)
   if (swing_damage >= thrust_damage):
    item_flags.append((item_set_slot, i_item, slot_item_max_damage, swing_damage))
   else:
    item_flags.append((item_set_slot, i_item, slot_item_max_damage, thrust_damage))
I hope that I don't run into any more bitwise issues, this appears to be something where I'm having issues getting my head wrapped around it  :lol:
 
Osviux said:
Is it possible to provide a player with random faces after each respawn? If yes, how?

you can spawn a regular ai troop,with the player's selected items,and then use (player_control_agent, <player_id>, <agent_id>),
the ai troop will spawn with a random face,and then the player will gain the agent control
 
How can i make a spear throwable????
so i spawn it melee,and when i press x,it will became ranged....

i get the message that "you don't carry eny bolts blahblah"
and also when i hit x,the icon of the weapon dissapear

i simply copied the scipt of the throwing spears,and then moved the throwing item under the melee item,and then added the flag itp_next_idtem_as_melee at the melee item(and removed it from the throwing item)
 
Status
Not open for further replies.
Back
Top Bottom