Modding Q&A [For Quick Questions and Answers]

Users who are viewing this thread

Status
Not open for further replies.
Getting stuck atm.

The new/upgraded towns/castles initially get assigned an owner (the one who built them, duh!), but if the fief gets captured by enemies, it never gets assigned a new owner. For native walled centers, the faction still assigns new owners.

Any ideas, where I could start looking to debug this?
kalarhan said:
Fire_and_Blood said:
What gives?
did you reset your flags? They don't share the memory address (see header_parties)
Derp  :oops:
 
burspa said:
Hello, is it possible to use custom skeletons for horses (same bones different positions)?

I believe you can only have one horse skeleton. https://forums.taleworlds.com/index.php?topic=156386.0

However, you can vary its scale. In module_items.py use say horse_scale(110) for a bigger horse and horse_scale(90) for a smaller horse. I used horse_scale(30) to animate cats with the horse skeleton & animations.

The horse skeleton can be used for all sorts of creatures for example https://forums.taleworlds.com/index.php/topic,370782.0.html
 
burspa said:
Thank you kindly, would it be possible then to change the mount position of riders?

Sorry, I don't know.

You could check out this OSP camel https://forums.taleworlds.com/index.php/topic,114455.msg2759125.html#msg2759125 and this OSP elephant https://forums.taleworlds.com/index.php?topic=209497.0 to see how they mounted their riders.

In The Last Days (Lord of the Rings) mod they mount orcs on wargs (monsterous wolves). When the rider's killed the wargs remain in battle, but only because the game engine is fooled by their code providing an invisible rider to control the mount. I've not seen any instances of an invisible rider with a visible passenger in an unusual riding position.
 
burspa said:
Thanks for your help, invisible riders is an interesting idea.

Just be careful though, as if you only put an invisible rider without modifying it's size/scale, troops will target that invisible rider, leading to arrows sticking into that invisible body.

In TLD, we 'deform' the invisible rider so that he is 'inside' the warg/mount. Viking Conquest had an improved version of this for their dog companion, where they use a new 'skin' that has a very small scale, so that it is like a very very small rider, riding the mount, instead of hiding the rider within the body of the mount.

Take a look at VC code for how they implemented it. Specifically, module_skins, module_mission_templates(for dog companion), and module_troops.

 
burspa said:
Thanks for your help, invisible riders is an interesting idea.
Khamukkamu said:
(...) VC (...) module_mission_templates(for dog companion)

pay special attention to the triggers that handle things like: order to dismount; rider killed; etc. VC uses a dedicated group/division just for the dog (#9), that way it stops you from giving a order like dismount (which works for horseman). Otherwise you will end up with a dog/horse and a invisible warrior in the scene.



Dazzer said:
Compared to vanilla NW animations again, all the same stuff
When you don't know something start with the basic checkout :
1) Flags
  For your case: module_items.py, module_animations.py
2) Flags memory address
  For your case: header_items.py (see if the values are the same as vanilla NW)
3) Setting flags
  For your case: module.ini
4) Event triggers
  For your case: look for triggers that detect the use of defense/zoom/aim action (like when you click/hold the aim button) + walking event

Eg: spyglass event
Code:
multiplayer_client_walking = (
  0, 0, 0.1, [
  (neg|multiplayer_is_dedicated_server),
  (neg|is_presentation_active, "prsnt_multiplayer_admin_chat"),
  (neg|is_presentation_active, "prsnt_game_multiplayer_admin_panel"),
  (game_key_clicked,gk_zoom),
  ],
  [
    (try_begin),
      (neg|is_zoom_disabled),
      (multiplayer_get_my_player, ":player_id"),
      (player_is_active, ":player_id"),
      (multiplayer_send_int_to_server, multiplayer_event_send_player_action, player_action_has_cheat),
    (else_try),
      (call_script,"script_client_get_my_agent"),
      (assign,":agent_id",reg0),
      (agent_is_active,":agent_id"),
      (agent_is_alive,":agent_id"),
      (multiplayer_send_int_to_server, multiplayer_event_send_player_action, player_action_toggle_walk),
    (try_end),
  ])
That sanity check should be done in a few minutes. After that comes the complicated stuff.





Fire_and_Blood said:
The new/upgraded towns/castles initially get assigned an owner (the one who built them, duh!), but if the fief gets captured by enemies, it never gets assigned a new owner

see the use of
Code:
slot_town_lord                 = 7

use a regular expression to narrow down the search, like
Code:
(party_set_slot)(.)*(slot_town_lord)
Code:
(assign)(.)*(slot_town_lord)
 
Quick question: The first code runs fine. When replaced with second code, it gives SCRIPT ERROR ON OPCODE 541: Invalid Party.
Does party_slot_eq require a valid party and is_between not?
Code:
            (is_between, ":besieged_center", walled_centers_begin, walled_centers_end),
Code:
			(this_or_next|party_slot_eq, ":besieged_center", slot_party_type, spt_town),     
			(party_slot_eq, ":besieged_center", slot_party_type, spt_castle),    #F&B
 
Fire_and_Blood said:
Quick question: The first code runs fine. When replaced with second code, it gives SCRIPT ERROR ON OPCODE 541: Invalid Party.
Does party_slot_eq require a valid party and is_between not?
Code:
            (is_between, ":besieged_center", walled_centers_begin, walled_centers_end),
Code:
			(this_or_next|party_slot_eq, ":besieged_center", slot_party_type, spt_town),     
			(party_slot_eq, ":besieged_center", slot_party_type, spt_castle),    #F&B

the first operation doesn't care about the TYPE of the entity. It is just a numeric check.

walled_centers_begin = p_town_1 => from ID_parties.py :: p_town_1 = 50 (e.g.) => walled_centers_begin = 50
...
(is_between, ":something", 50, 100)  :: 50 <= something < 100


while the second case is using a operation on a party (ENTITY), which will have to collect said ENTITY from the memory allocation and then check for flags/slots of that ENTITY. If said ENTITY doesn't exist in memory (invalid), you have a error
 
Fire_and_Blood said:
So (party_is_active, ":party_no"), above (party_set_slot, ... should fix the error.

Is that ok, or do I need to worry about why the script is trying to use an invalid party?

that depends. You need to examine the chain of calls, what happens if the script fails, etc, to determine if it is OK to call that script on a invalid party or if the caller is at fault.

Say that snippet is called on a dialog. The dialog doesn't check for the party, calls the script to change some flags, assumes it worked, and keeps going. You now have a bug on your game.
 
KnightV said:
I have installed  pbod to my own mod but when i start a battle the speed of battle it is very very very very very veryyyyyyyyyy slow

"speed of battle" could mean a few things. If you are talking slow motion (not simple walking speed) then disable EDIT MODE on game launcher and try again, as the only operation for slow motion requires it.

If that was not a issue you will need to be more clear on your description and then start to track down what is causing the issue.


Fire_and_Blood said:
OPCODE ERROR in simple_trigger_57. Is there an easy way to figure out, which simple_trigger that is?

count to 58. My 10 years old nephew already knows how to count to 99.

joking aside you can use a few methods:

1) use Python console, import your file, and navigate the array
2) use the .txt file and find the trigger from there (easier to count)
3) add a comment on each trigger with the position number (#0, #1, #2, #3, ...)
4) use proper indentation on the entire file (see VC process_line_correction.py), then it is a easy way to search the code (just use a IDE and hide the code/content of each trigger, and a macro to go down 58 search of "])," or use a expression for the trigger header.
 
Alright, labeled all those little ****ers in simple_triggers.

Going back to the previous OPCODE ERRORS with (party_slot_eq, ":center_no", slot_party_type, spt_town)

I'm trying to fix it, but with no luck. The code is mostly in scripts, where it checks, whether its true, and if not falls back to something else, so it's ok, if it's not true.

What is the difference between:

    (party_is_active, ":center_no",),      #party_enabled/disabled check?

    (ge, ":center_no", 0),  # It checks, whether center_no is greater than 0, so it holds a value?
 
Fire_and_Blood said:
What is the difference between:

    (party_is_active, ":center_no",),      #party_enabled/disabled check?

    (ge, ":center_no", 0),  # It checks, whether center_no is greater than 0, so it holds a value?

Code:
party_is_active                       =  132  # (party_is_active, <party_id>),
                                              # Checks that <party_id> is valid and not disabled.
Valid means the ID code makes sense. There are no negative parties. It starts at 0 (zero). Dynamic parties are created all the time and thus get higher and higher IDs, while the parties from module_parties.py are well know (fixed ID).
A party can still exist but also be disabled, and so you can't/shouldn't call operations on it.

The other check only makes sure a early call didn't return -1 (party not found). It doesn't mean it is valid, that it exists, or even if the ID makes sense at all.
-> But as it is a simple numeric test that means it is fast (performance wise)

Code:
disable_party                         = 1230  # (disable_party, <party_id>),
                                              # Party disappears from the map. Note that (try_for_parties) will still iterate over disabled parties, so you need to make additional checks with (party_is_active).
Code:
remove_party                          = 1232  # (remove_party, <party_id>),
                                              # Destroys a party completely. Should ONLY be used with dynamically spawned parties, as removing parties pre-defined in module_parties.py file will corrupt the savegame.



Remember there is a huge difference between a ID check and a logic check. The first just validates memory allocation/address, the second is about your game rules and bugs.
 
Anyone has idea?
frozenpainter said:
In mission templates: I added a new mission look like, my army size is 160, I join a battle with this mission templates, spawned 20 my soldier, when 20 soldier died other men doe'snt spawn, I want to spawn other men.
(red lines for spawn other troops but doen't works)
(
    "kayi_yagma_oymak",mtf_battle_mode,-1,
    "Default town visit",
    [
(1,mtef_team_0,0,aif_start_alarmed,20,[]),
    (0,mtef_team_0,0,aif_start_alarmed,0,[]),
#(0,mtef_scene_source|mtef_team_0,0,0,aif_start_alarmed,[]),
    # (1,mtef_scene_source|mtef_team_0,0,0,1,[]),


(49,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(50,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(51,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(52,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(53,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(54,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
   
(55,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(56,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(57,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(58,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(59,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(60,mtef_visitor_source|mtef_team_1,af_override_horse,aif_start_alarmed,1,[]),
(61,mtef_scene_source,af_override_horse,0,1,[]),
   
    ],
    [

(0.1, 0.1, ti_once, [],[(music_set_culture, mtf_culture_all),(music_set_situation, mtf_sit_fight),]),
(ti_before_mission_start, 0, 0, [(mission_cam_set_screen_color, 0xFF000000),], [
  (mission_cam_animate_to_screen_color, 0x00000000, 1500)]),
  (0, 0, ti_once, [], [(assign,"$g_battle_won",0),
                          (assign,"$defender_reinforcement_stage",0),
                          (assign,"$attacker_reinforcement_stage",0),
                          (call_script, "script_place_player_banner_near_inventory"),
                          (call_script, "script_combat_music_set_situation_with_culture"),
                          (assign, "$g_defender_reinforcement_limit", 2),
                          ]),
  (1, 0, 5, [
                             
      #new (25.11.09) starts (sdsd = TODO : make a similar code to also helping ally encounters)
      #count all total (not dead) enemy soldiers (in battle area + not currently placed in battle area)
      (call_script, "script_party_count_members_with_full_health", "p_collective_enemy"),
      (assign, ":total_enemy_soldiers", reg0),
     
      #decrease number of agents already in battle area to find all number of reinforcement enemies
      (assign, ":enemy_soldiers_in_battle_area", 0),
      (try_for_agents,":cur_agent"),
        (agent_is_human, ":cur_agent"),
        (agent_get_party_id, ":agent_party", ":cur_agent"),
        (try_begin),
          (neq, ":agent_party", "p_main_party"),
          (neg|agent_is_ally, ":cur_agent"),
          (val_add, ":enemy_soldiers_in_battle_area", 1),
        (try_end),
      (try_end),
      (store_sub, ":total_enemy_reinforcements", ":total_enemy_soldiers", ":enemy_soldiers_in_battle_area"),

      (try_begin),
        (lt, ":total_enemy_reinforcements", 15),
        (ge, "$defender_reinforcement_stage", 1),
        (eq, "$defender_reinforcement_limit_increased", 0),
        (val_add, "$g_defender_reinforcement_limit", 1),                   
        (assign, "$defender_reinforcement_limit_increased", 1),
      (try_end),   
      #new (25.11.09) ends
     
      (lt,"$defender_reinforcement_stage","$g_defender_reinforcement_limit"),
                (store_mission_timer_a,":mission_time"),
                (ge,":mission_time",10),
                (store_normalized_team_count,":num_defenders", 0),
                (lt,":num_defenders",6)],
          [(add_reinforcements_to_entry,0,7),(assign, "$defender_reinforcement_limit_increased", 0),(ge,"$defender_reinforcement_stage",20)]),
     
      (1, 0, 5, [(lt,"$attacker_reinforcement_stage",1),
                (store_mission_timer_a,":mission_time"),
                (ge,":mission_time",10),
                (store_normalized_team_count,":num_attackers", 1),
                (lt,":num_attackers",6)],
          [(add_reinforcements_to_entry,3,7),(ge,"$attacker_reinforcement_stage",20)]),


      common_battle_check_victory_condition,
      common_battle_victory_display,

            (1, 4, 0, [(main_hero_fallen)],
          [
              (assign, "$pin_player_fallen", 1),
          (assign, ":num_allies", 0),
          (try_for_agents, ":agent"),
              (agent_is_ally, ":agent"),
            (agent_is_alive, ":agent"),
            (val_add, ":num_allies", 1),
          (try_end),
          (try_begin),
            (eq, ":num_allies", 0),
            (assign, "$g_battle_result", -1),
                (set_mission_result,-1),
                (call_script, "script_count_mission_casualties_from_agents"),
                (finish_mission,0),
          (try_end),
          ]),

      common_battle_inventory,
 
 
 
common_battle_order_panel,
      common_battle_order_panel_tick,
(2, 2, 0,
      [
        (store_mission_timer_a,":cur_time"),
        (ge, ":cur_time", 5),
        (this_or_next|main_hero_fallen),
        (num_active_teams_le,1)
        ],
      [
        (try_begin),
          (main_hero_fallen),
          (jump_to_menu, "mnu_yagma_basarisiz"),
        (else_try),
          (jump_to_menu, "mnu_yagma_basarili"),
        (try_end),
        (finish_mission),
        ]),
      ]+cihad_triggers,
 
    ),
 
frozenpainter said:
Anyone has idea?

compare the reinforcement system with Native, your code has a few bugs on it.

Then if you are still having issues (re-post your new code):
1) You as a attacker. Working?
2) You as a defender. Working?

If not working: describe what should happen. Your army size. The enemy army size. How many lords on each side. Did you check the collective_army parties size to make sure it is counting everyone? Did you get a wave? Two waves? Waves too small? Wrong place? Wrong team? And so on.
 
I need a solution for this: What can I change in either .txt files or .py files to always have control over ally lord's troops in battle? I am sick of seeing them charge recklessly into the enemy only to get destroyed within seconds. I *NEED* to fix this. It has been bugging me for years and every time I tried to search for an answer I found nothing. I think that it can be done since I seem to gain control over their troops sometimes but that might as well be a bug. I don't **** know.
 
Status
Not open for further replies.
Back
Top Bottom