Equip_item problem on Dedicated Server

正在查看此主题的用户

REXE

Recruit
Hi. Tell please as to me to make in module_scene_props in the form of such code so that to the player the armor was put on?

插入代码块:
check_broom_1 = (ti_on_scene_prop_use,
    [
      (store_trigger_param_1, ":agent_id"),
      (store_trigger_param_2, ":instance_id"),

      (multiplayer_is_server),
      (assign, ":cost", 100), #gold required for refilling arrows
      (agent_get_player_id,":player_no",":agent_id"),
      (try_begin),
        (player_is_active, ":player_no"),
        (player_get_gold, ":player_gold", ":player_no"),
        (ge, ":player_gold", ":cost"), 

        
       (set_item, "itm_nordic_archer_helmet"),
      
        (val_sub, ":player_gold", ":cost"),
        (player_set_gold, ":player_no", ":player_gold", multi_max_gold_that_can_be_stored),
      (try_end),
    ])

How change (set_item, "itm_nordic_archer_helmet") ?
 
REXE 说:
How change (set_item, "itm_nordic_archer_helmet") ?
I guess you need (agent_equip_item, ":agent_id", "itm_nordic_archer_helmet").
 
I have added a script in scene_props:
插入代码块:
check_broom_1 = (ti_on_scene_prop_use,
    [
      (store_trigger_param_1, ":agent_id"),
      (store_trigger_param_2, ":instance_id"),

      (multiplayer_is_server),
      (assign, ":cost", 100), #gold required for refilling arrows
      (agent_get_player_id,":player_no",":agent_id"),
      (try_begin),
        (player_is_active, ":player_no"),
        (player_get_gold, ":player_gold", ":player_no"),
        (ge, ":player_gold", ":cost"), 

        
       (agent_equip_item, ":agent_id", "itm_nordic_archer_helmet").
      
        (val_sub, ":player_gold", ":cost"),
        (player_set_gold, ":player_no", ":player_gold", multi_max_gold_that_can_be_stored),
      (try_end),
    ])

When I create game through "the Host the Game" item puts on. And when I create through "Dedicated Server" money is spent, and the thing isn't present. What's the problem?
 
Always thought (multiplayer_is_server) includes dedicated servers and ones hosted from within the game and (multiplayer_is_dedicated_server) only works on dedicated ones.
 
And how to solve this problem?

The most interesting that if to change
插入代码块:
(agent_equip_item, ":agent_id", "itm_nordic_archer_helmet"),
on
插入代码块:
(agent_set_ammo,":agent_id","itm_arrows",30),
arrows appear
 
The first one works too. However, items aren't kept in sync between server and clients, so you have to send a network message that tells the client to equip that item. Even if you host it locally, it will work just for you, not others.
 
How it to make? And whether it is possible to make that worked for all? Help please
 
cmpxchg8b 说:
The first one works too. However, items aren't kept in sync between server and clients, so you have to send a network message that tells the client to equip that item. Even if you host it locally, it will work just for you, not others.
To clarify, the visual part of armor items is not updated on clients - weapons work fine with just agent_equip_item and armor stats for the combat calculations are correct with it, but to show the visual mesh you need to also send a network message to all clients to run the same agent_equip_item operation.

Basic example code:

Add a new event id to header_common - the number must not be already used for another event, and must be in the range from 0 to 127:
插入代码块:
multiplayer_event_agent_equip_item = 48
Then make a new script in module_scripts, something like this:
插入代码块:
  ("agent_equip_item",
   [(store_script_param, ":agent_id", 1),
    (store_script_param, ":item_id", 2),

    (try_begin),
      (multiplayer_is_server), # this script should only be called on the server, so this check is just to make sure
      (agent_equip_item, ":agent_id", ":item_id"), # for the server combat calculations
      (item_get_type, ":item_type", ":item_id"),
      (is_between, ":item_type", itp_head_armor, itp_hand_armor + 1), # make sure the item is an armor one before messaging all clients
      (get_max_players, ":max_players"),
      (try_for_range, ":player_id", 1, ":max_players"), # start at 1, since 0 is the server
        (player_is_active, ":player_id"),
        (multiplayer_send_2_int_to_player, ":player_id", multiplayer_event_agent_equip_item, ":agent_id", ":item_id"),
      (try_end),
    (try_end),
    ]),
And then in script_game_recieve_url_response, in the client section (bottom half):
插入代码块:
        (else_try),
          (eq, ":event_type", multiplayer_event_agent_equip_item),
          (store_script_param, ":agent_id", 3),
          (store_script_param, ":item_id", 4),
          (try_begin),
            (agent_is_active, ":agent_id"),
            (is_between, ":item_id", all_items_begin, all_items_end),
            (agent_equip_item, ":agent_id", ":item_id"),
          (try_end),
And then to equip an armor item in your script or trigger running on the server, use this:
插入代码块:
    (call_script, "script_agent_equip_item", ":agent_id", "itm_my_armor"),
For a more detailed tutorial about sending messages to clients, see here. You should use warband version 1.143 (or later) to avoid various bugs with equipping shields or unequipping armor (which is another more complicated story).
 
Hello All, I tried to use this fix, but it turned out like this:
插入代码块:
WARNING: Script can fail at operation #1. Use cf_ at the beginning of its name:
game_receive_url_response
ERROR: Usage of unassigned local variable: :event_type
 
joker7by 说:
WARNING: Script can fail at operation #1. Use cf_ at the beginning of its name:
game_receive_url_response
You stuffed up the code in that script somehow (probably didn't add the new event handler in the right place), as that script should never fail (all "can fail" operations being enclosed in try_begin and try_end).
joker7by 说:
ERROR: Usage of unassigned local variable: :event_type
As above; the ":event_type" variable is set on the second line of the native version of that script, so you have probably added the section of code at the very start, which is wrong.
 
Ok, I just tried to do so:
  ("game_receive_url_response",
    [
  (store_script_param, ":event_type", 2),
  (try_begin),
          (eq, ":event_type", multiplayer_event_agent_equip_item),
          (store_script_param, ":agent_id", 3),
          (store_script_param, ":item_id", 4),
          (try_begin),
            (agent_is_active, ":agent_id"),
            (is_between, ":item_id", all_items_begin, all_items_end),
            (agent_equip_item, ":agent_id", ":item_id"),
          (try_end),
  ]),
And so is everything else:
  (ti_on_agent_hit, 0, 0, [],
    [
(multiplayer_is_server),
  (store_trigger_param_1, ":agent"),
(agent_is_human, ":agent"),
    (store_trigger_param_3, ":damage"),

(ge, ":damage", 30), # Strong blow
(store_agent_hit_points, ":hp", ":agent", 1),
(val_add, ":hp", 5),
(ge, ":damage", ":hp"), # Damage > HP + 5 (account for armour soak)
(agent_get_position, pos1, ":agent"),
(get_distance_between_positions, ":distance", pos1, pos0),
(is_between, ":distance", 160, 176), # If neck hit
(agent_get_item_slot, ":item", ":agent", 4),
(try_begin),
    (ge, ":item", 1),

(agent_unequip_item, ":agent", ":item"),
(call_script, "script_agent_equip_item", ":agent", ":item"), # dedecate fix
        (try_end),
(agent_equip_item, ":agent", "itm_invisible_head"), # Replace with invisible head
(particle_system_burst, "psys_game_blood_3", pos1, 200), # Blood
    (play_sound_at_position, "snd_decapitation", pos4),
(try_begin),
(agent_set_position, ":agent", pos1),
        (agent_set_animation, ":agent", "anim_death_cut_head"),
(try_end),
(set_spawn_position, pos1),

(spawn_scene_prop, "spr_head_dynamic_male"), # *


]),

*spr_head_dynamic_male -  written in module_scene_props.py and work ok.

  (item_set_slot, "itm_invisible_head", slot_item_multiplayer_item_class, multi_item_class_type_light_helm),

# dedicate fix
("agent_equip_item",
  [(store_script_param, ":agent_id", 1),
    (store_script_param, ":item_id", 2),

    (try_begin),
      (multiplayer_is_server), # this script should only be called on the server, so this check is just to make sure
      (agent_equip_item, ":agent_id", ":item_id"), # for the server combat calculations
      (item_get_type, ":item_type", ":item_id"),
      (is_between, ":item_type", itp_type_head_armor), # make sure the item is an armor one before messaging all clients
      (get_max_players, ":max_players"),
      (try_for_range, ":player_id", 1, ":max_players"), # start at 1, since 0 is the server
        (player_is_active, ":player_id"),
        (multiplayer_send_2_int_to_player, ":player_id", multiplayer_event_agent_equip_item, ":agent_id", ":item_id"),
      (try_end),
    (try_end),
    ]),
No errors at compile time, but still no sync, my head stays in place when connected to dedicate, but when you create a multiplayer game and it works.
 
joker7by 说:
Ok, I just tried to do so:
  ("game_receive_url_response",
    [
  (store_script_param, ":event_type", 2),
  (try_begin),
          (eq, ":event_type", multiplayer_event_agent_equip_item),
          (store_script_param, ":agent_id", 3),
          (store_script_param, ":item_id", 4),
          (try_begin),
            (agent_is_active, ":agent_id"),
            (is_between, ":item_id", all_items_begin, all_items_end),
            (agent_equip_item, ":agent_id", ":item_id"),
          (try_end),
  ]),
Wrong! Add it to the correct section of that script:
Vornne 说:
And then in script_game_recieve_url_response, in the client section (bottom half):
Scroll down many pages to basically the end of that script, past the
插入代码块:
        ###############
        #CLIENT EVENTS#
        ###############
comment, after the last block with a similar (else_try), (eq, ":event_type", ... bit, so the else_try and try_end match up for the added section to be another case of all the event_type tests.

Also wrong:
joker7by 说:
(call_script, "script_agent_equip_item", ":agent", ":item"), # dedecate fix
You are equipping the current head item again rather than the invisible head: the added script should replace the agent_equip_item operation two lines lower down. You should also use agent_play_sound rather than play_sound_at_position, since the latter is not synched automatically. And use ek_head rather than 4 with agent_get_item_slot.
 
It does not work and no longer appear remarks head on the ground  :roll:
    (ti_on_agent_hit, 0, 0, [],
    [
(multiplayer_is_server),
  (store_trigger_param_1, ":agent"),
(agent_is_human, ":agent"),
    (store_trigger_param_3, ":damage"),

(ge, ":damage", 30), # Strong blow
(store_agent_hit_points, ":hp", ":agent", 1),
(val_add, ":hp", 5),
(ge, ":damage", ":hp"), # Damage > HP + 5 (account for armour soak)
(agent_get_position, pos1, ":agent"),
(get_distance_between_positions, ":distance", pos1, pos0),
(is_between, ":distance", 160, 176), # If neck hit
(agent_get_item_slot, ":item", ":agent", 4),
(try_begin),
    (ge, ":item", 1),

(agent_unequip_item, ":agent", ":item"),

        (try_end),
(call_script, "script_agent_equip_item", ":agent", "itm_invisible_head"), # dedecate fix

(particle_system_burst, "psys_game_blood_3", pos1, 200), # Blood
    (agent_play_sound, "snd_decapitation"),
(try_begin),
(agent_set_position, ":agent", pos1),
        (agent_set_animation, ":agent", "anim_death_cut_head"),
(try_end),
(set_spawn_position, pos1),

(spawn_scene_prop, "spr_head_dynamic_male"), # Flying head, SP only


]),
        (else_try),
          (eq, ":event_type", multiplayer_event_set_num_agents_around_flag),
          (store_script_param, ":flag_no", 3),
          (store_script_param, ":current_owner_code", 4),
          (call_script, "script_set_num_agents_around_flag", ":flag_no", ":current_owner_code"),
        (else_try),
          (eq, ":event_type", multiplayer_event_ask_for_poll),
          (store_script_param, ":value", 3),
          (store_script_param, ":value_2", 4),
          (store_script_param, ":value_3", 5),
          (store_script_param, ":value_4", 6),
          (assign, ":continue_to_poll", 0),
#insert start
  (else_try), # dedicate fix
          (eq, ":event_type", multiplayer_event_agent_equip_item),
          (store_script_param, ":agent_id", 3),
          (store_script_param, ":item_id", 4),
          (try_begin),
            (agent_is_active, ":agent_id"),
            (is_between, ":item_id", all_items_begin, all_items_end),
            (agent_equip_item, ":agent_id", ":item_id"),
          (try_end),
#insert end

(try_begin),
            (this_or_next|eq, ":value", 1),
            (eq, ":value", 2),
            (player_is_active, ":value_2"), #might go offline before here
            (assign, ":continue_to_poll", 1),
          (else_try),
            (assign, ":continue_to_poll", 1),
          (try_end),
          (try_begin),

Vornne 说:
And use ek_head rather than 4 with agent_get_item_slot.

I do not know how to use it.
 
joker7by 说:
        (else_try),
          (eq, ":event_type", multiplayer_event_set_num_agents_around_flag),
          (store_script_param, ":flag_no", 3),
          (store_script_param, ":current_owner_code", 4),
          (call_script, "script_set_num_agents_around_flag", ":flag_no", ":current_owner_code"),
        (else_try),
          (eq, ":event_type", multiplayer_event_ask_for_poll),
          (store_script_param, ":value", 3),
          (store_script_param, ":value_2", 4),
          (store_script_param, ":value_3", 5),
          (store_script_param, ":value_4", 6),
          (assign, ":continue_to_poll", 0),
#insert start
  (else_try), # dedicate fix
          (eq, ":event_type", multiplayer_event_agent_equip_item),
          (store_script_param, ":agent_id", 3),
          (store_script_param, ":item_id", 4),
          (try_begin),
            (agent_is_active, ":agent_id"),
            (is_between, ":item_id", all_items_begin, all_items_end),
            (agent_equip_item, ":agent_id", ":item_id"),
          (try_end),
#insert end

(try_begin),
            (this_or_next|eq, ":value", 1),
            (eq, ":value", 2),
            (player_is_active, ":value_2"), #might go offline before here
            (assign, ":continue_to_poll", 1),
          (else_try),
            (assign, ":continue_to_poll", 1),
          (try_end),
          (try_begin),
Still wrong - you have inserted it inside the multiplayer_event_ask_for_poll handler - though it would break polls rather than stop the equip event working. As said, add it near the very end of that entire script: if you have not made any other changes from native to it, insert after multiplayer_event_show_server_message, like this (additions in red):
        (else_try),
          (eq, ":event_type", multiplayer_event_show_server_message),
          (display_message, "str_server_s0", 0xFFFF6666),
        (else_try),
          (eq, ":event_type", multiplayer_event_agent_equip_item),
          (store_script_param, ":agent_id", 3),
          (store_script_param, ":item_id", 4),
          (try_begin),
            (agent_is_active, ":agent_id"),
            (is_between, ":item_id", all_items_begin, all_items_end),
            (agent_equip_item, ":agent_id", ":item_id"),
          (try_end),

        (try_end),
    ]),
Eagle eyed readers might notice that there is a missing (try_end) at the end of that script - an error from native that happens not to affect functionality (don't do it in your own scripts though). I don't know why it isn't working for you, so you'll have to test things to try diagnose it - the code works fine for me (and similar code works fine for many players in a released mod, see signature).
joker7by 说:
Vornne 说:
And use ek_head rather than 4 with agent_get_item_slot.
I do not know how to use it.
Like this:
插入代码块:
(agent_get_item_slot, ":head_item_id", ":agent_id", ek_head),
rather than using the number 4, since the named constants (defined in header_items.py to the numbers) are easier to understand. How the game understands it is not changed, but that line confused me at first until I remembered that 4 is the head slot number.
 
后退
顶部 底部