Code reading understanding PW

Users who are viewing this thread

hakjimmy

Sergeant Knight at Arms
I am trying to learn coding atm
Could any of you pls help me with comprehending this part of the code of pw mod system?
cf_use_teleport_door
I don't understand the else try part
as the vornne tries to do if player has faction door key =1
if door is unlocked then lock the door and trigger the lock sound after he entered the door
but what would happen if player doesn't have the faction door key

also why the send msg part of the code is attached in the last else try ,would could trigger the send msg part?

("cf_use_teleport_door", # server: handle agents using a door which teleports to another linked door
[(store_script_param, ":agent_id", 1), # must be valid
(store_script_param, ":instance_id", 2), # must be valid
(store_script_param, ":mad:_offset", 3),
(store_script_param, ":y_offset", 4), # position offset relative to the linked door that the agent is moved to
(store_script_param, ":z_offset", 5),
(store_script_param, ":is_pickable", 6),

(scene_prop_get_slot, ":linked_door_instance_id", ":instance_id", slot_scene_prop_linked_scene_prop),
(gt, ":linked_door_instance_id", 0),
(agent_get_player_id, ":player_id", ":agent_id"),
(player_is_active, ":player_id"),
(player_get_slot, ":player_faction_id", ":player_id", slot_player_faction_id),
(call_script, "script_scene_prop_get_owning_faction", ":instance_id"),
(assign, ":faction_id", reg0),
(assign, ":fail", 0),
(try_begin),
(eq, ":faction_id", "fac_commoners"),
(else_try),
(eq, ":faction_id", ":player_faction_id"),
(player_slot_eq, ":player_id", slot_player_has_faction_door_key, 1),
(try_begin),
(scene_prop_slot_eq, ":instance_id", slot_scene_prop_unlocked, 1),
(scene_prop_set_slot, ":instance_id", slot_scene_prop_unlocked, 0),
(scene_prop_set_slot, ":linked_door_instance_id", slot_scene_prop_unlocked, 0),
(agent_play_sound, ":agent_id", "snd_lock"),
(try_end),
(else_try),
(scene_prop_slot_eq, ":instance_id", slot_scene_prop_unlocked, 1),
(else_try),
(assign, reg0, 0),
(eq, ":is_pickable", 1),
(call_script, "script_cf_agent_pick_lock", ":agent_id", 100),
(scene_prop_set_slot, ":instance_id", slot_scene_prop_unlocked, 1),
(scene_prop_set_slot, ":linked_door_instance_id", slot_scene_prop_unlocked, 1),
(else_try),
(assign, ":fail", 1),
(gt, reg0, 0),
(else_try),
(multiplayer_send_3_int_to_player, ":player_id", server_event_preset_message, "str_door_locked_by_s1", preset_message_faction|preset_message_fail_sound, ":faction_id"),
(try_end),
(eq, ":fail", 0),
(prop_instance_get_position, pos1, ":linked_door_instance_id"),
(position_move_x, pos1, ":mad:_offset"),
(position_move_y, pos1, ":y_offset"),
(position_move_z, pos1, ":z_offset"),
(agent_set_position, ":agent_id", pos1),
]),
 
Python:
("cf_use_teleport_door", # server: handle agents using a door which teleports to another linked door
[
    # Script Input Variable Set-up
    (store_script_param, ":agent_id", 1), # must be valid
    (store_script_param, ":instance_id", 2), # must be valid
    (store_script_param, ":x_offset", 3),
    (store_script_param, ":y_offset", 4), # position offset relative to the linked door that the agent is moved to
    (store_script_param, ":z_offset", 5),
    (store_script_param, ":is_pickable", 6),

    # Variable Set-up
  
    (scene_prop_get_slot, ":linked_door_instance_id", ":instance_id", slot_scene_prop_linked_scene_prop),
    (gt, ":linked_door_instance_id", 0),        # This is a check to prevent warning messages
    (agent_get_player_id, ":player_id", ":agent_id"),    # This is a multiplayer operation, pulls the player's id based on their agent's id
    (player_is_active, ":player_id"),                    # Makes sure the player_id is valid by making sure the player is active and not like the server or absent
    (player_get_slot, ":player_faction_id", ":player_id", slot_player_faction_id),    # This stores the referenced player's slot inside the first local var, in this case it looks at the slot named slot_player_faction_id and stores it inside of ":player_faction_id"
    (call_script, "script_scene_prop_get_owning_faction", ":instance_id"),    # Calls a script and passes it the prop instance id, assumedly it outputs the prop faction to reg0
    (assign, ":faction_id", reg0),    # Storing a reg value into a local var to make it readable
    (assign, ":fail", 0),        # this, my friend, is a flow control variable, commonly used to prematurely break scripts if the desired result isn't matched.
  
    # This try block is the bulk of the work, basically it's a if-else statement
    # Best way to read it is, if the first flow-statement is met, then the script
    # will not check other blocks, but if it is not met, it skips to the next (else_try),
    # block. This is where the branching nature of scripts is made.
  
    (try_begin),
        (eq, ":faction_id", "fac_commoners"), # If TRUE, prop faction = common
        # Don't do anything, but go ahead and skip the rest as we found our TRUE statement
    (else_try),
        (eq, ":faction_id", ":player_faction_id"),    #If TRUE, prop faction = player faction
        # The above was true, so no longer go to the next else_try. But ALSO. . .
        (player_slot_eq, ":player_id", slot_player_has_faction_door_key, 1), #If True, player_id slot slot_player_has_faction_door_key = 1
        # So this second statement does not effect the status of continuining within the try_block
        # but it prevents this next block from firing.
        (try_begin),    # This block actually doesn't need to be a try_block, they could have done without it. For readability, I do the same thing though.
            (scene_prop_slot_eq, ":instance_id", slot_scene_prop_unlocked, 1), # If Locked
            (scene_prop_set_slot, ":instance_id", slot_scene_prop_unlocked, 0),    # Unlock
            (scene_prop_set_slot, ":linked_door_instance_id", slot_scene_prop_unlocked, 0), # Unlock here, too
            (agent_play_sound, ":agent_id", "snd_lock"),    # Play a sound at the agent, I don't do MP but I assume sounds are synced with the server and nearby players can hear it.
        (try_end),
    (else_try),
        (scene_prop_slot_eq, ":instance_id", slot_scene_prop_unlocked, 1),    # This should really be the first one thing inside the try_block since there's no reason to check anything else if the door is already unlocked.
    (else_try),
        (assign, reg0, 0),        # I am assuming that script_cf_agent_pick_lock uses reg0 to determine lockpick chance.
        (eq, ":is_pickable", 1),    # I did not see this get set earlier, so, this should always fail. Unless script_scene_prop_get_owning_faction set it, which seems outside the scope of the script based on name.
        (call_script, "script_cf_agent_pick_lock", ":agent_id", 100),    # But, if the above is somehow true, run this script. Assumedly it rolls for a chance to pick the lock.
        (scene_prop_set_slot, ":instance_id", slot_scene_prop_unlocked, 1), # If successful, Unlock
        (scene_prop_set_slot, ":linked_door_instance_id", slot_scene_prop_unlocked, 1), # Unlock here, too.
        # Not gonna lie, the above block seems like it's not fully finished.
    (else_try),
        # No flow control statements here eq|neq|gt|lt|etc, which means this will always be fired if an above block didn't find itself being used
        (assign, ":fail", 1),    # sets fail to true
        (gt, reg0, 0),    # And reg0 is a positive number, which may be possible, sure.
        # DONT DO ANYTHING.
        # for some reason
        # It seems as though this is meant to interact with script_cf_agent_pick_lock or the faction_id from earlier? But why not call faction_id then?
        # Let's assume it's seeing if the faction of the prop is a positive number, and if so, keep the message of the next block from firing.
        # Though, if that's the case, why not make them the same else_try block?
    (else_try),
        # No flow control statements here eq|neq|gt|lt|etc, which means this will always be fired if an above block didn't find itself being used
        (multiplayer_send_3_int_to_player, ":player_id", server_event_preset_message, "str_door_locked_by_s1", preset_message_faction|preset_message_fail_sound, ":faction_id"),
        # Reads as if it tells the player the door was locked, and maybe by which faction.
    (try_end),
  
    (eq, ":fail", 0),    # if the fail local var didn't get set to 1 by the second to last else_try block
    (prop_instance_get_position, pos1, ":linked_door_instance_id"),
    (position_move_x, pos1, ":x_offset"),
    (position_move_y, pos1, ":y_offset"),
    (position_move_z, pos1, ":z_offset"),
    (agent_set_position, ":agent_id", pos1), # Teleport the player agent.
]),

I added comments and reformatted the tabs to help you make sense of it.

To prevent a situation where you get :mad: instead of:x or lose your tabs again, use [CODE=python][/CODE] tags.
 
Last edited:
Python:
("cf_use_teleport_door", # server: handle agents using a door which teleports to another linked door
[
    # Script Input Variable Set-up
    (store_script_param, ":agent_id", 1), # must be valid
    (store_script_param, ":instance_id", 2), # must be valid
    (store_script_param, ":x_offset", 3),
    (store_script_param, ":y_offset", 4), # position offset relative to the linked door that the agent is moved to
    (store_script_param, ":z_offset", 5),
    (store_script_param, ":is_pickable", 6),

    # Variable Set-up
 
    (scene_prop_get_slot, ":linked_door_instance_id", ":instance_id", slot_scene_prop_linked_scene_prop),
    (gt, ":linked_door_instance_id", 0),        # This is a check to prevent warning messages
    (agent_get_player_id, ":player_id", ":agent_id"),    # This is a multiplayer operation, pulls the player's id based on their agent's id
    (player_is_active, ":player_id"),                    # Makes sure the player_id is valid by making sure the player is active and not like the server or absent
    (player_get_slot, ":player_faction_id", ":player_id", slot_player_faction_id),    # This stores the referenced player's slot inside the first local var, in this case it looks at the slot named slot_player_faction_id and stores it inside of ":player_faction_id"
    (call_script, "script_scene_prop_get_owning_faction", ":instance_id"),    # Calls a script and passes it the prop instance id, assumedly it outputs the prop faction to reg0
    (assign, ":faction_id", reg0),    # Storing a reg value into a local var to make it readable
    (assign, ":fail", 0),        # this, my friend, is a flow control variable, commonly used to prematurely break scripts if the desired result isn't matched.
 
    # This try block is the bulk of the work, basically it's a if-else statement
    # Best way to read it is, if the first flow-statement is met, then the script
    # will not check other blocks, but if it is not met, it skips to the next (else_try),
    # block. This is where the branching nature of scripts is made.
 
    (try_begin),
        (eq, ":faction_id", "fac_commoners"), # If TRUE, prop faction = common
        # Don't do anything, but go ahead and skip the rest as we found our TRUE statement
    (else_try),
        (eq, ":faction_id", ":player_faction_id"),    #If TRUE, prop faction = player faction
        # The above was true, so no longer go to the next else_try. But ALSO. . .
        (player_slot_eq, ":player_id", slot_player_has_faction_door_key, 1), #If True, player_id slot slot_player_has_faction_door_key = 1
        # So this second statement does not effect the status of continuining within the try_block
        # but it prevents this next block from firing.
        (try_begin),    # This block actually doesn't need to be a try_block, they could have done without it. For readability, I do the same thing though.
            (scene_prop_slot_eq, ":instance_id", slot_scene_prop_unlocked, 1), # If Locked
            (scene_prop_set_slot, ":instance_id", slot_scene_prop_unlocked, 0),    # Unlock
            (scene_prop_set_slot, ":linked_door_instance_id", slot_scene_prop_unlocked, 0), # Unlock here, too
            (agent_play_sound, ":agent_id", "snd_lock"),    # Play a sound at the agent, I don't do MP but I assume sounds are synced with the server and nearby players can hear it.
        (try_end),
    (else_try),
        (scene_prop_slot_eq, ":instance_id", slot_scene_prop_unlocked, 1),    # This should really be the first one thing inside the try_block since there's no reason to check anything else if the door is already unlocked.
    (else_try),
        (assign, reg0, 0),        # I am assuming that script_cf_agent_pick_lock uses reg0 to determine lockpick chance.
        (eq, ":is_pickable", 1),    # I did not see this get set earlier, so, this should always fail. Unless script_scene_prop_get_owning_faction set it, which seems outside the scope of the script based on name.
        (call_script, "script_cf_agent_pick_lock", ":agent_id", 100),    # But, if the above is somehow true, run this script. Assumedly it rolls for a chance to pick the lock.
        (scene_prop_set_slot, ":instance_id", slot_scene_prop_unlocked, 1), # If successful, Unlock
        (scene_prop_set_slot, ":linked_door_instance_id", slot_scene_prop_unlocked, 1), # Unlock here, too.
        # Not gonna lie, the above block seems like it's not fully finished.
    (else_try),
        # No flow control statements here eq|neq|gt|lt|etc, which means this will always be fired if an above block didn't find itself being used
        (assign, ":fail", 1),    # sets fail to true
        (gt, reg0, 0),    # And reg0 is a positive number, which may be possible, sure.
        # DONT DO ANYTHING.
        # for some reason
        # It seems as though this is meant to interact with script_cf_agent_pick_lock or the faction_id from earlier? But why not call faction_id then?
        # Let's assume it's seeing if the faction of the prop is a positive number, and if so, keep the message of the next block from firing.
        # Though, if that's the case, why not make them the same else_try block?
    (else_try),
        # No flow control statements here eq|neq|gt|lt|etc, which means this will always be fired if an above block didn't find itself being used
        (multiplayer_send_3_int_to_player, ":player_id", server_event_preset_message, "str_door_locked_by_s1", preset_message_faction|preset_message_fail_sound, ":faction_id"),
        # Reads as if it tells the player the door was locked, and maybe by which faction.
    (try_end),
 
    (eq, ":fail", 0),    # if the fail local var didn't get set to 1 by the second to last else_try block
    (prop_instance_get_position, pos1, ":linked_door_instance_id"),
    (position_move_x, pos1, ":x_offset"),
    (position_move_y, pos1, ":y_offset"),
    (position_move_z, pos1, ":z_offset"),
    (agent_set_position, ":agent_id", pos1), # Teleport the player agent.
]),

I added comments and reformatted the tabs to help you make sense of it.

To prevent a situation where you get :mad: instead of:x or lose your tabs again, use [CODE=python][/CODE] tags.
Python:
(else_try),
        (assign, reg0, 0),        # I am assuming that script_cf_agent_pick_lock uses reg0 to determine lockpick chance.
        (eq, ":is_pickable", 1),    # I did not see this get set earlier, so, this should always fail. Unless script_scene_prop_get_owning_faction set it, which seems outside the scope of the script based on name.
        (call_script, "script_cf_agent_pick_lock", ":agent_id", 100),    # But, if the above is somehow true, run this script. Assumedly it rolls for a chance to pick the lock.
        (scene_prop_set_slot, ":instance_id", slot_scene_prop_unlocked, 1), # If successful, Unlock
        (scene_prop_set_slot, ":linked_door_instance_id", slot_scene_prop_unlocked, 1), # Unlock here, too.
        # Not gonna lie, the above block seems like it's not fully finished.
    (else_try),
        # No flow control statements here eq|neq|gt|lt|etc, which means this will always be fired if an above block didn't find itself being used
        (assign, ":fail", 1),    # sets fail to true
        (gt, reg0, 0),    # And reg0 is a positive number, which may be possible, sure.
        # DONT DO ANYTHING.
        # for some reason
        # It seems as though this is meant to interact with script_cf_agent_pick_lock or the faction_id from earlier? But why not call faction_id then?
        # Let's assume it's seeing if the faction of the prop is a positive number, and if so, keep the message of the next block from firing.
        # Though, if that's the case, why not make them the same else_try block?
    (else_try),
        # No flow control statements here eq|neq|gt|lt|etc, which means this will always be fired if an above block didn't find itself being used
        (multiplayer_send_3_int_to_player, ":player_id", server_event_preset_message, "str_door_locked_by_s1", preset_message_faction|preset_message_fail_sound, ":faction_id"),
        # Reads as if it tells the player the door was locked, and maybe by which faction.
    (try_end),


Does it mean since reg0=0 and reg0>0 is impossible , so the last try block will always be fired with condition fail=1
 
Python:
    (else_try),
        # No flow control statements here eq|neq|gt|lt|etc, which means this will always be fired if an above block didn't find itself being used
        (assign, ":fail", 1),    # sets fail to true
        (multiplayer_send_3_int_to_player, ":player_id", server_event_preset_message, "str_door_locked_by_s1", preset_message_faction|preset_message_fail_sound, ":faction_id"),
        # Reads as if it tells the player the door was locked, and maybe by which faction.
    (try_end),
why not make the code like this isn't this more simple ?
 
The comment explains the apparent intent of the script and my thoughts on how it should have been structured.

You're correct in thinking the (assign, ":fail", 1), will always happen even if reg0 is less than or equal to 0, but wrong in assuming that reg0 cannot be less than or equal to 0. If the door is factionless it would feed 0 to that register. That check seems to be there to prevent error messages from invalid faction ids.

Your restructuring is messing with that because yours will send a message no matter what since (gt, reg0, 0), is missing, causing errors if that id is invalid.

Reach out to the original author and ask them why it's structured that way. That's the best you can do in this situation.
 
Back
Top Bottom