OSP Code Combat Perfectly Smooth, Mouse-Enabled Deathcam V1.4

Zephilinox

Knight
WB
Best answers
0
Video of V1.0

Tested for Warband 1.157, Warband 1.158, Warband 1.167, and Diplomacy 4.2 (view page 2 for details on diplomacy integration)

Please note that the smoothness is dependent on frame-rate. The higher your frame-rate the smoother the camera rotation will be.

Features:
  • Smooth Mouse Rotation
  • Smooth Numpad Rotation
  • Move in 3 Dimensions
  • Works in Windowed Mode
  • Movement Speed Multiplier key
  • Sensitivity Modifier Key
  • Invert Y Rotation Key
  • Reset Deathcam to Position of Death
  • Works with Battle Orders (Backspace) Presentation

Used in:

Changelog:
Version 1.4
  • Added: Press 'End' to flip Y rotation
  • Added: Use numpad to rotate the camera in addition to the mouse (useful when having the battle presentation open, or if you can't rotate with the mouse for some reason)
  • Fixed: Now detects what team the player is on and only causes that team to charge
Version 1.3
  • Added: Press 'Home' to reset cameras position to where you died
  • Fixed: Now entering a presentation and exiting will not cause the camera to rotate
  • Fixed: Clamped rotation speed to reduce wild rotations when other, non-native presentations may be open
Version 1.2
  • Fixed: Now after losing, press TAB to end the battle
  • Fixed: Now after deathcam starts, pressing TAB will not mention being surrounded by enemies
  • Fixed: Now using display_message instead of display_log_message (smaller savegame)
  • Fixed: Exit rotation code if resetting mouse_notmoved
  • Removed: Deadzone/Padding, unlikely to ever be used
Version 1.1
  • Added: Numpad +/- to increase/decrease sensitivity
  • Fixed: Now deathcam doesn't rotate while battle order presentation is open

Keep in mind the code uses a fixed point of 10,000 rather than the usual 1,000.



Place the following code at the top of module_mission_templates.py

Code:
##BEAN BEGIN - Deathcam
common_init_deathcam = (
   0, 0, ti_once,
   [],
   [
        (assign, "$deathcam_on", 0),
        (assign, "$deathcam_death_pos_x", 0),
        (assign, "$deathcam_death_pos_y", 0),
        (assign, "$deathcam_death_pos_z", 0),

        (assign, "$deathcam_mouse_last_x", 5000),
        (assign, "$deathcam_mouse_last_y", 3750),

        (assign, "$deathcam_mouse_last_notmoved_x", 5000),
        (assign, "$deathcam_mouse_last_notmoved_y", 3750),
        (assign, "$deathcam_mouse_notmoved_x", 5000), #Center screen (10k fixed pos)
        (assign, "$deathcam_mouse_notmoved_y", 3750),
        (assign, "$deathcam_mouse_notmoved_counter", 0),

        (assign, "$deathcam_total_rotx", 0),

        (assign, "$deathcam_sensitivity_x", 400), #4:3 ratio may be best
        (assign, "$deathcam_sensitivity_y", 300), #If modified, change values in common_move_deathcam

        (assign, "$deathcam_prsnt_was_active", 0),

        (assign, "$deathcam_keyboard_rotation_x", 0),
        (assign, "$deathcam_keyboard_rotation_y", 0),
        (assign, "$deathcam_flip_y_multiplier", 1),

        (get_player_agent_no, ":player_agent"),
        (agent_get_team, "$deathcam_player_team", ":player_agent"),
   ]
)

common_start_deathcam = (
    0, 1, ti_once, #1 second delay before the camera activates
    [
        (main_hero_fallen),
        (eq, "$deathcam_on", 0),
    ],
    [
        (set_fixed_point_multiplier, 10000),
        (assign, "$deathcam_on", 1),

        (display_message, "@You were defeated.", 0xFF0000),
        (display_message, "@Rotate with the mouse. Move with standard keys."),
        (display_message, "@Shift/Control for Up/Down. Space Bar to increase speed."),
        (display_message, "@Numpad Plus/Minus to change sensitivity. Numpad to rotate."),
        (display_message, "@Home to reset position. End to flip Y rotation"),

        (mission_cam_get_position, pos1), #Death pos
        (position_get_x, reg3, pos1),
        (position_get_y, reg4, pos1),
        (position_get_z, reg5, pos1),
        (assign, "$deathcam_death_pos_x", reg3),
        (assign, "$deathcam_death_pos_y", reg4),
        (assign, "$deathcam_death_pos_z", reg5),
        (position_get_rotation_around_z, ":rot_z", pos1),

        (init_position, pos47),
        (position_copy_origin, pos47, pos1), #Copy X,Y,Z pos
        (position_rotate_z, pos47, ":rot_z"), #Copying X-Rotation is likely possible, but I haven't figured it out yet

        (mission_cam_set_mode, 1, 0, 0), #Manual?

        (mission_cam_set_position, pos47),

        (team_give_order, "$deathcam_player_team", grc_everyone, mordr_charge),
   ]
)

common_move_deathcam = (
    0, 0, 0,
    [
        (eq, "$deathcam_on", 1),
        (this_or_next|game_key_is_down, gk_move_forward),
        (this_or_next|game_key_is_down, gk_move_backward),
        (this_or_next|game_key_is_down, gk_move_left),
        (this_or_next|game_key_is_down, gk_move_right),
        (this_or_next|key_is_down, key_left_shift),
        (this_or_next|key_is_down, key_left_control),
        (this_or_next|key_is_down, key_numpad_minus),
        (this_or_next|key_is_down, key_numpad_plus),
        (this_or_next|key_clicked, key_home),
        (key_clicked, key_end),
    ],
    [
        (set_fixed_point_multiplier, 10000),
        (mission_cam_get_position, pos47),

        (try_begin),
        (key_clicked, key_home),
            (position_set_x, pos47, "$deathcam_death_pos_x"),
            (position_set_y, pos47, "$deathcam_death_pos_y"),
            (position_set_z, pos47, "$deathcam_death_pos_z"),
        (try_end),

        (assign, ":move_x", 0),
        (assign, ":move_y", 0),
        (assign, ":move_z", 0),

        (try_begin),
        (game_key_is_down, gk_move_forward),
            (val_add, ":move_y", 10),
        (try_end),
        (try_begin),
        (game_key_is_down, gk_move_backward),
            (val_add, ":move_y", -10),
        (try_end),

        (try_begin),
        (game_key_is_down, gk_move_right),
            (val_add, ":move_x", 10),
        (try_end),
        (try_begin),
        (game_key_is_down, gk_move_left),
            (val_add, ":move_x", -10),
        (try_end),

        (try_begin),
        (key_is_down, key_left_shift),
            (val_add, ":move_z", 10),
        (try_end),
        (try_begin),
        (key_is_down, key_left_control),
            (val_add, ":move_z", -10),
        (try_end),

        (try_begin),
        (key_is_down, key_space),
            (val_mul, ":move_x", 4),
            (val_mul, ":move_y", 4),
            (val_mul, ":move_z", 2),
        (try_end),

        (try_begin),
        (key_is_down, key_end),
            (try_begin),
            (eq, "$deathcam_flip_y_multiplier", 1),
                (assign, "$deathcam_flip_y_multiplier", -1),
                (display_message, "@Y-Rotation Inverted"),
            (else_try),
                (assign, "$deathcam_flip_y_multiplier", 1),
                (display_message, "@Y-Rotation Normal"),
            (try_end),
        (try_end),

        (position_move_x, pos47, ":move_x"),
        (position_move_y, pos47, ":move_y"),
        (position_move_z, pos47, ":move_z"),

        (mission_cam_set_position, pos47),

        (try_begin),
        (key_is_down, key_numpad_minus),
        (ge, "$deathcam_sensitivity_x", 4), #Negative check.
        (ge, "$deathcam_sensitivity_y", 3),
            (val_sub, "$deathcam_sensitivity_x", 4),
            (val_sub, "$deathcam_sensitivity_y", 3),
            (store_mod, reg6, "$deathcam_sensitivity_x", 100), #25% increments
            (store_mod, reg7, "$deathcam_sensitivity_y", 75),
            (try_begin),
            (eq, reg6, 0),
            (eq, reg7, 0),
                (assign, reg8, "$deathcam_sensitivity_x"),
                (assign, reg9, "$deathcam_sensitivity_y"),
                (display_message, "@Sensitivity - 25% ({reg8}, {reg9})"),
            (try_end),
        (else_try),
        (key_is_down, key_numpad_plus),
            (val_add, "$deathcam_sensitivity_x", 4),
            (val_add, "$deathcam_sensitivity_y", 3),
            (store_mod, reg6, "$deathcam_sensitivity_x", 100), #25% increments
            (store_mod, reg7, "$deathcam_sensitivity_y", 75),
            (try_begin),
            (eq, reg6, 0),
            (eq, reg7, 0),
                (assign, reg8, "$deathcam_sensitivity_x"),
                (assign, reg9, "$deathcam_sensitivity_y"),
                (display_message, "@Sensitivity + 25% ({reg8}, {reg9})"),
            (try_end),
        (try_end),
   ]
)

common_rotate_deathcam = (
    0, 0, 0,
    [
        (eq, "$deathcam_on", 1),
    ],
    [
        (set_fixed_point_multiplier, 10000), #Extra Precision

        (try_begin),
        (this_or_next|is_presentation_active, "prsnt_battle"), #Opened (mouse must move)
        (this_or_next|key_clicked, key_escape), #Menu
        (this_or_next|key_clicked, key_q), #Notes, etc
        (key_clicked, key_tab), #Retreat
        (eq, "$deathcam_prsnt_was_active", 0),
            (assign, "$deathcam_prsnt_was_active", 1),
            (assign, "$deathcam_mouse_last_notmoved_x", "$deathcam_mouse_notmoved_x"),
            (assign, "$deathcam_mouse_last_notmoved_y", "$deathcam_mouse_notmoved_y"),
        (try_end),

        (assign, ":continue", 0),

        (try_begin),
        (neg|is_presentation_active, "prsnt_battle"),
            (mouse_get_position, pos1), #Get and set mouse position
            (position_get_x, reg1, pos1),
            (position_get_y, reg2, pos1),

            (mission_cam_get_position, pos47),

            (try_begin),
            (neq, "$deathcam_prsnt_was_active", 1),
                (try_begin), #Check not moved
                (eq, reg1, "$deathcam_mouse_last_x"),
                (eq, reg2, "$deathcam_mouse_last_y"),
                (this_or_next|neq, reg1, "$deathcam_mouse_notmoved_x"),
                (neq, reg2, "$deathcam_mouse_notmoved_y"),
                    (val_add, "$deathcam_mouse_notmoved_counter", 1),
                    (try_begin), #Notmoved for n cycles
                    (ge, "$deathcam_mouse_notmoved_counter", 15),
                        (assign, "$deathcam_mouse_notmoved_counter", 0),
                        (assign, "$deathcam_mouse_notmoved_x", reg1),
                        (assign, "$deathcam_mouse_notmoved_y", reg2),
                    (try_end),
                (else_try), #Has moved
                    (assign, ":continue", 1),
                    (assign, "$deathcam_mouse_notmoved_counter", 0),
                (try_end),
                (assign, "$deathcam_mouse_last_x", reg1), #Next cycle, this pos = last pos
                (assign, "$deathcam_mouse_last_y", reg2),
            (else_try), #prsnt was active
                (try_begin),
                (neq, reg1, "$deathcam_mouse_last_x"), #Is moving
                (neq, reg2, "$deathcam_mouse_last_y"),
                    (store_sub, ":delta_x2", reg1, "$deathcam_mouse_last_notmoved_x"), #Store pos difference
                    (store_sub, ":delta_y2", reg2, "$deathcam_mouse_last_notmoved_y"),
                (is_between, ":delta_x2", -10, 11), #when engine recenters mouse, there is a small gap
                (is_between, ":delta_y2", -10, 11), #usually 5 pixels, but did 10 to be safe.
                    (assign, "$deathcam_prsnt_was_active", 0),
                    (assign, "$deathcam_mouse_notmoved_x", "$deathcam_mouse_last_notmoved_x"),
                    (assign, "$deathcam_mouse_notmoved_y", "$deathcam_mouse_last_notmoved_y"),
                (else_try),
                    (assign, "$deathcam_mouse_notmoved_x", reg1),
                    (assign, "$deathcam_mouse_notmoved_y", reg2),
                (try_end),
                    (assign, "$deathcam_mouse_last_x", reg1), #Next cycle, this pos = last pos
                    (assign, "$deathcam_mouse_last_y", reg2),
            (try_end),
        (try_end),

        (assign, ":delta_x", 0),
        (assign, ":delta_y", 0),
        (assign, ":rotating_horizontal", 0),
        (assign, ":rotating_vertical", 0),

        (try_begin),
        (key_is_down, key_numpad_4),
            (try_begin),
            (ge, "$deathcam_keyboard_rotation_x", 0),
                (assign, "$deathcam_keyboard_rotation_x", -20),
            (try_end),
            (val_add, "$deathcam_keyboard_rotation_x", -1),
            (assign, ":continue", 2),
            (assign, ":rotating_horizontal", -1),
        (else_try),
        (key_is_down, key_numpad_6),
            (try_begin),
            (le, "$deathcam_keyboard_rotation_x", 0),
                (assign, "$deathcam_keyboard_rotation_x", 20),
            (try_end),
            (val_add, "$deathcam_keyboard_rotation_x", 1),
            (assign, ":continue", 2),
            (assign, ":rotating_horizontal", 1),
        (else_try),
            (assign, "$deathcam_keyboard_rotation_x", 0),
            (assign, ":rotating_horizontal", 0),
        (try_end),

        (try_begin),
        (key_is_down, key_numpad_8),
            (try_begin),
            (le, "$deathcam_keyboard_rotation_y", 0),
                (assign, "$deathcam_keyboard_rotation_y", 15),
            (try_end),
            (val_add, "$deathcam_keyboard_rotation_y", 1),
            (assign, ":continue", 2),
            (assign, ":rotating_vertical", 1),
        (else_try),
        (this_or_next|key_is_down, key_numpad_2),
        (key_is_down, key_numpad_5),
            (try_begin),
            (ge, "$deathcam_keyboard_rotation_y", 0),
                (assign, "$deathcam_keyboard_rotation_y", -15),
            (try_end),
            (val_add, "$deathcam_keyboard_rotation_y", -1),
            (assign, ":continue", 2),
            (assign, ":rotating_vertical", -1),
        (else_try),
            (assign, "$deathcam_keyboard_rotation_y", 0),
            (assign, ":rotating_vertical", 0),
        (try_end),

        (try_begin),
        (eq, ":continue", 1),
            (store_sub, ":delta_x", reg1, "$deathcam_mouse_notmoved_x"), #Store pos difference
            (store_sub, ":delta_y", reg2, "$deathcam_mouse_notmoved_y"),
        (else_try),
        (eq, ":continue", 2),
            (try_begin),
            (neq, ":rotating_horizontal", 0),
                (val_clamp, "$deathcam_keyboard_rotation_x", -80, 80),
                (assign, ":delta_x", "$deathcam_keyboard_rotation_x"),
            (try_end),

            (try_begin),
            (neq, ":rotating_vertical", 0),
                (val_clamp, "$deathcam_keyboard_rotation_y", -45, 45),
                (assign, ":delta_y", "$deathcam_keyboard_rotation_y"),
            (try_end),
        (try_end),

        (try_begin),
        (ge, ":continue", 1),
            (val_mul, ":delta_x", "$deathcam_sensitivity_x"),
            (val_mul, ":delta_y", "$deathcam_sensitivity_y"),
            (val_mul, ":delta_y", "$deathcam_flip_y_multiplier"),

            (val_clamp, ":delta_x", -80000, 80001), #8
            (val_clamp, ":delta_y", -60000, 60001), #6

            (store_mul, ":neg_rotx", "$deathcam_total_rotx", -1),
            (position_rotate_x_floating, pos47, ":neg_rotx"), #Reset x axis to initial state

            (position_rotate_y, pos47, 90), #Barrel roll by 90 degrees to inverse x/z axis
            (position_rotate_x_floating, pos47, ":delta_x"), #Rotate simulated z axis, Horizontal
            (position_rotate_y, pos47, -90), #Reverse

            (position_rotate_x_floating, pos47, "$deathcam_total_rotx"), #Reverse

            (position_rotate_x_floating, pos47, ":delta_y"), #Vertical
            (val_add, "$deathcam_total_rotx", ":delta_y"), #Fix yaw
            (mission_cam_set_position, pos47),
        (try_end),
    ]
)
##BEAN END - Deathcam

common_init_deathcam = (
  0, 0, ti_once,
  [],
  [
        (assign, "$deathcam_on", 0),
        (assign, "$deathcam_death_pos_x", 0),
        (assign, "$deathcam_death_pos_y", 0),
        (assign, "$deathcam_death_pos_z", 0),
       
        (assign, "$deathcam_mouse_last_x", 5000),
        (assign, "$deathcam_mouse_last_y", 3750),
       
        (assign, "$deathcam_mouse_last_notmoved_x", 5000),
        (assign, "$deathcam_mouse_last_notmoved_y", 3750),
        (assign, "$deathcam_mouse_notmoved_x", 5000), #Center screen (10k fixed pos)
        (assign, "$deathcam_mouse_notmoved_y", 3750),
        (assign, "$deathcam_mouse_notmoved_counter", 0),
       
        (assign, "$deathcam_total_rotx", 0),
       
        (assign, "$deathcam_sensitivity_x", 400), #4:3 ratio may be best
        (assign, "$deathcam_sensitivity_y", 300), #If modified, change values in common_move_deathcam
       
        (assign, "$deathcam_prsnt_was_active", 0),
  ]
)

common_start_deathcam = (
    0, 1, ti_once, #1 second delay before the camera activates
    [
        (main_hero_fallen),
        (eq, "$deathcam_on", 0),
    ],
    [
        (set_fixed_point_multiplier, 10000),
        (assign, "$deathcam_on", 1),
       
        (display_message, "@You were defeated.", 0xFF2222),
        (display_message, "@Rotate with the mouse, move with standard keys."),
        (display_message, "@Shift/Control for Up/Down, Space Bar to increase speed."),
        (display_message, "@Numpad Plus/Minus to change sensitivity, Home to reset position."),

        (mission_cam_get_position, pos1), #Death pos
        (position_get_x, reg3, pos1),
        (position_get_y, reg4, pos1),
        (position_get_z, reg5, pos1),
        (assign, "$deathcam_death_pos_x", reg3),
        (assign, "$deathcam_death_pos_y", reg4),
        (assign, "$deathcam_death_pos_z", reg5),
        (position_get_rotation_around_z, ":rot_z", pos1),
       
        (init_position, pos47),
        (position_copy_origin, pos47, pos1), #Copy X,Y,Z pos
        (position_rotate_z, pos47, ":rot_z"), #Copying X-Rotation is likely possible, but I haven't figured it out yet
       
        (mission_cam_set_mode, 1, 0, 0), #Manual?

        (mission_cam_set_position, pos47),
       
        (team_give_order, 0, grc_everyone, mordr_charge),
        (team_give_order, 1, grc_everyone, mordr_charge),
        (team_give_order, 2, grc_everyone, mordr_charge),
        (team_give_order, 3, grc_everyone, mordr_charge),
  ]
)

common_move_deathcam = (
    0, 0, 0,
    [
        (eq, "$deathcam_on", 1),
        (this_or_next|game_key_is_down, gk_move_forward),
        (this_or_next|game_key_is_down, gk_move_backward),
        (this_or_next|game_key_is_down, gk_move_left),
        (this_or_next|game_key_is_down, gk_move_right),
        (this_or_next|key_is_down, key_left_shift),
        (this_or_next|key_is_down, key_left_control),
        (this_or_next|key_is_down, key_numpad_minus),
        (this_or_next|key_is_down, key_numpad_plus),
        (key_clicked, key_home),
    ],
    [ 
        (set_fixed_point_multiplier, 10000),
        (mission_cam_get_position, pos47),
       
        (try_begin),
        (key_clicked, key_home),
            (position_set_x, pos47, "$deathcam_death_pos_x"),
            (position_set_y, pos47, "$deathcam_death_pos_y"),
            (position_set_z, pos47, "$deathcam_death_pos_z"),
        (try_end),
       
        (assign, ":move_x", 0),
        (assign, ":move_y", 0),
        (assign, ":move_z", 0),
       
        (try_begin),
        (game_key_is_down, gk_move_forward),
            (val_add, ":move_y", 10),
        (try_end),
        (try_begin),
        (game_key_is_down, gk_move_backward),
            (val_add, ":move_y", -10),
        (try_end),

        (try_begin),
        (game_key_is_down, gk_move_right),
            (val_add, ":move_x", 10),
        (try_end),
        (try_begin),
        (game_key_is_down, gk_move_left),
            (val_add, ":move_x", -10),
        (try_end),

        (try_begin),
        (key_is_down, key_left_shift),
            (val_add, ":move_z", 10),
        (try_end),
        (try_begin),
        (key_is_down, key_left_control),
            (val_add, ":move_z", -10),
        (try_end),
       
        (try_begin),
        (key_is_down, key_space),
            (val_mul, ":move_x", 4),
            (val_mul, ":move_y", 4),
            (val_mul, ":move_z", 2),
        (try_end),
       
        (position_move_x, pos47, ":move_x"),
        (position_move_y, pos47, ":move_y"),
        (position_move_z, pos47, ":move_z"),
       
        (mission_cam_set_position, pos47),
       
        (try_begin),
        (key_is_down, key_numpad_minus),
        (ge, "$deathcam_sensitivity_x", 4), #Negative check.
        (ge, "$deathcam_sensitivity_y", 3),
            (val_sub, "$deathcam_sensitivity_x", 4),
            (val_sub, "$deathcam_sensitivity_y", 3),
            (store_mod, reg6, "$deathcam_sensitivity_x", 100), #25% increments
            (store_mod, reg7, "$deathcam_sensitivity_y", 75),
            (try_begin),
            (eq, reg6, 0),
            (eq, reg7, 0),
                (assign, reg8, "$deathcam_sensitivity_x"),
                (assign, reg9, "$deathcam_sensitivity_y"),
                (display_message, "@Sensitivity - 25% ({reg8}, {reg9})"),
            (try_end),
        (else_try),
        (key_is_down, key_numpad_plus),
            (val_add, "$deathcam_sensitivity_x", 4),
            (val_add, "$deathcam_sensitivity_y", 3),
            (store_mod, reg6, "$deathcam_sensitivity_x", 100), #25% increments
            (store_mod, reg7, "$deathcam_sensitivity_y", 75),
            (try_begin),
            (eq, reg6, 0),
            (eq, reg7, 0),
                (assign, reg8, "$deathcam_sensitivity_x"),
                (assign, reg9, "$deathcam_sensitivity_y"),
                (display_message, "@Sensitivity + 25% ({reg8}, {reg9})"),
            (try_end),
        (try_end),
  ]
)

common_rotate_deathcam = (
    0, 0, 0,
    [
        (eq, "$deathcam_on", 1),
    ],
    [
        (set_fixed_point_multiplier, 10000), #Extra Precision
       
        (try_begin),
        (this_or_next|is_presentation_active, "prsnt_battle"), #Opened (mouse must move)
        (this_or_next|key_clicked, key_escape), #Menu
        (this_or_next|key_clicked, key_q), #Notes, etc
        (key_clicked, key_tab), #Retreat
        (eq, "$deathcam_prsnt_was_active", 0),
            (assign, "$deathcam_prsnt_was_active", 1),
            (assign, "$deathcam_mouse_last_notmoved_x", "$deathcam_mouse_notmoved_x"),
            (assign, "$deathcam_mouse_last_notmoved_y", "$deathcam_mouse_notmoved_y"),
        (try_end),
       
        (neg|is_presentation_active, "prsnt_battle"),
       
        (mouse_get_position, pos1), #Get and set mouse position
        (position_get_x, reg1, pos1),
        (position_get_y, reg2, pos1),
       
        (mission_cam_get_position, pos47),
       
        (assign, ":continue", 0),
       
        (try_begin),
        (neq, "$deathcam_prsnt_was_active", 1),
            (try_begin), #Check not moved
            (eq, reg1, "$deathcam_mouse_last_x"),
            (eq, reg2, "$deathcam_mouse_last_y"),
            (this_or_next|neq, reg1, "$deathcam_mouse_notmoved_x"),
            (neq, reg2, "$deathcam_mouse_notmoved_y"),
                (val_add, "$deathcam_mouse_notmoved_counter", 1),
                (try_begin), #Notmoved for n cycles
                (ge, "$deathcam_mouse_notmoved_counter", 15),
                    (assign, "$deathcam_mouse_notmoved_counter", 0),
                    (assign, "$deathcam_mouse_notmoved_x", reg1),
                    (assign, "$deathcam_mouse_notmoved_y", reg2),
                (try_end),
            (else_try), #Has moved
                (assign, ":continue", 1),
                (assign, "$deathcam_mouse_notmoved_counter", 0),
            (try_end),
            (assign, "$deathcam_mouse_last_x", reg1), #Next cycle, this pos = last pos
            (assign, "$deathcam_mouse_last_y", reg2),
        (else_try), #prsnt was active
            (try_begin),
            (neq, reg1, "$deathcam_mouse_last_x"), #Is moving
            (neq, reg2, "$deathcam_mouse_last_y"),
                (store_sub, ":delta_x2", reg1, "$deathcam_mouse_last_notmoved_x"), #Store pos difference
                (store_sub, ":delta_y2", reg2, "$deathcam_mouse_last_notmoved_y"),
            (is_between, ":delta_x2", -10, 11), #when engine recenters mouse, there is a small gap
            (is_between, ":delta_y2", -10, 11), #usually 5 pixels, but did 10 to be safe.
                (assign, "$deathcam_prsnt_was_active", 0),
                (assign, "$deathcam_mouse_notmoved_x", "$deathcam_mouse_last_notmoved_x"),
                (assign, "$deathcam_mouse_notmoved_y", "$deathcam_mouse_last_notmoved_y"),
            (else_try),
                (assign, "$deathcam_mouse_notmoved_x", reg1),
                (assign, "$deathcam_mouse_notmoved_y", reg2),
            (try_end),
                (assign, "$deathcam_mouse_last_x", reg1), #Next cycle, this pos = last pos
                (assign, "$deathcam_mouse_last_y", reg2),
        (try_end),
       
        (eq, ":continue", 1), #Else exit
           
        (store_sub, ":delta_x", reg1, "$deathcam_mouse_notmoved_x"), #Store pos difference
        (store_sub, ":delta_y", reg2, "$deathcam_mouse_notmoved_y"),

        (val_mul, ":delta_x", "$deathcam_sensitivity_x"),
        (val_mul, ":delta_y", "$deathcam_sensitivity_y"),
        (val_clamp, ":delta_x", -80000, 80001), #8
        (val_clamp, ":delta_y", -60000, 60001), #6
           
        (store_mul, ":neg_rotx", "$deathcam_total_rotx", -1),
        (position_rotate_x_floating, pos47, ":neg_rotx"), #Reset x axis to initial state
       
        (position_rotate_y, pos47, 90), #Barrel roll by 90 degrees to inverse x/z axis
        (position_rotate_x_floating, pos47, ":delta_x"), #Rotate simulated z axis, Horizontal
        (position_rotate_y, pos47, -90), #Reverse
       
        (position_rotate_x_floating, pos47, "$deathcam_total_rotx"), #Reverse
       
        (position_rotate_x_floating, pos47, ":delta_y"), #Vertical
        (val_add, "$deathcam_total_rotx", ":delta_y"), #Fix yaw
       
        (mission_cam_set_position, pos47),
    ]
)



Replace common_battle_tab_press

common_battle_tab_press = (
  ti_tab_pressed, 0, 0, [],
  [
    (try_begin),
      (eq, "$g_battle_won", 1),
      (call_script, "script_count_mission_casualties_from_agents"),
      (finish_mission,0),
    (else_try),
      (call_script, "script_cf_check_enemies_nearby"),
      (question_box,"str_do_you_want_to_retreat"),
    (else_try),
      (display_message,"str_can_not_retreat"),
    (try_end),
])

With:

common_battle_tab_press = (
    ti_tab_pressed, 0, 0, [],
    [
        (try_begin),
        (eq, "$g_battle_won", 1),
            (call_script, "script_count_mission_casualties_from_agents"),
            (finish_mission, 0),
      (else_try),
        (eq, "$pin_player_fallen", 1),
            (call_script, "script_simulate_retreat", 0, 0, 0),
            (assign, "$g_battle_result", -1),
            (set_mission_result, -1),
            (call_script, "script_count_mission_casualties_from_agents"),
            (finish_mission, 0),
        (else_try),
        (eq, "$deathcam_on", 1),
            (question_box,"str_do_you_want_to_retreat"),

        (else_try),
            (call_script, "script_cf_check_enemies_nearby"),
            (question_box,"str_do_you_want_to_retreat"),
        (else_try),
            (display_message,"str_can_not_retreat"),
        (try_end),
    ]
)



Replace any/all of these blocks of code for the relevant mission types (e.g lead_charge)

(1, 4, ti_once, [(main_hero_fallen)],
  [
      (assign, "$pin_player_fallen", 1),
      (str_store_string, s5, "str_retreat"),
      (call_script, "script_simulate_retreat", 5, 20, 0),
      (assign, "$g_battle_result", -1),
      (set_mission_result, -1),
      (call_script, "script_count_mission_casualties_from_agents"),
      (finish_mission,0)
      ]),

With:

(1, 4, ti_once,
        [
            (main_hero_fallen),
            (assign, ":pteam_alive", 0),
            (try_for_agents, ":agent"), #Check players team is dead
            (neq, ":pteam_alive", 1), #Break loop
            (agent_is_ally, ":agent"),
            (agent_is_alive, ":agent"),
                (assign, ":pteam_alive", 1),
            (try_end),
            (eq, ":pteam_alive", 0),
        ],
        [
            (assign, "$pin_player_fallen", 1),
            (display_message, "@Press TAB to end the battle."),
        ]),



Replace common_siege_check_defeat_condition

common_siege_check_defeat_condition = (
  1, 4, ti_once,
  [
    (main_hero_fallen)
    ],
  [
    (assign, "$pin_player_fallen", 1),
    (get_player_agent_no, ":player_agent"),
    (agent_get_team, ":agent_team", ":player_agent"),
    (try_begin),
      (neq, "$attacker_team", ":agent_team"),
      (neq, "$attacker_team_2", ":agent_team"),
      (str_store_string, s5, "str_siege_continues"),
      (call_script, "script_simulate_retreat", 8, 15, 0),
    (else_try),
      (str_store_string, s5, "str_retreat"),
      (call_script, "script_simulate_retreat", 5, 20, 0),
    (try_end),
    (assign, "$g_battle_result", -1),
    (set_mission_result,-1),
    (call_script, "script_count_mission_casualties_from_agents"),
    (finish_mission,0),
    ])

With:

common_siege_check_defeat_condition = (
    1, 4, ti_once,
    [
        (main_hero_fallen),
        (assign, ":pteam_alive", 0),
        (try_for_agents, ":agent"), #Check players team is dead
        (neq, ":pteam_alive", 1), #Break loop
        (agent_is_ally, ":agent"),
        (agent_is_alive, ":agent"),
            (assign, ":pteam_alive", 1),
        (try_end),
        (eq, ":pteam_alive", 0),
    ],
    [
        (assign, "$pin_player_fallen", 1),
        (display_message, "@Press TAB to end the battle."),
    ]
)



Replace common_battle_check_victory_condition

common_battle_check_victory_condition = (
  1, 60, ti_once,
  [
    (store_mission_timer_a,reg(1)),
    (ge,reg(1),10),
    (all_enemies_defeated, 5),
    (neg|main_hero_fallen, 0),
    (set_mission_result,1),
    (display_message,"str_msg_battle_won"),
    (assign,"$g_battle_won",1),
    (assign, "$g_battle_result", 1),
    (call_script, "script_play_victorious_sound"),
    ],
  [
    (call_script, "script_count_mission_casualties_from_agents"),
    (finish_mission, 1),
    ])

With:

common_battle_check_victory_condition = (
  1, 60, ti_once,
  [
    (store_mission_timer_a,reg(1)),
    (ge,reg(1),10),
    (all_enemies_defeated, 5),
    #(neg|main_hero_fallen, 0),
    (set_mission_result,1),
    (display_message,"str_msg_battle_won"),
    (assign,"$g_battle_won",1),
    (assign, "$g_battle_result", 1),
    (call_script, "script_play_victorious_sound"),
    ],
  [
    (call_script, "script_count_mission_casualties_from_agents"),
    (finish_mission, 1),
    ])



Finally, at the very top of each mission type you want the deathcam to be used (search for "common_battle_mission_start" as most relevant missions will use that too),  place these four lines:

common_init_deathcam,
common_start_deathcam,
common_move_deathcam,
common_rotate_deathcam,

Like this:

(
    "lead_charge",mtf_battle_mode|mtf_synch_inventory,charge,
    "You lead your men to battle.",
    [
    (1,mtef_defenders|mtef_team_0,0,aif_start_alarmed,12,[]),
    (0,mtef_defenders|mtef_team_0,0,aif_start_alarmed,0,[]),
    (4,mtef_attackers|mtef_team_1,0,aif_start_alarmed,12,[]),
    (4,mtef_attackers|mtef_team_1,0,aif_start_alarmed,0,[]),
    ],
    [
      common_init_deathcam,
      common_start_deathcam,
      common_move_deathcam,
      common_rotate_deathcam,

      #....
 

La Grandmaster

Sergeant Knight at Arms
Best answers
0
It seems to work fairly well, the only thing I can say is that if the player is in a party on their own and they are defeated, when they press tab instead of counting it so that the player has lost the battle, the game counts it as a retreat and then the player is allowed to charge at the enemy again. I dont know if this will also affect larger battles, but it may do Im not sure?
 

Zephilinox

Knight
WB
Best answers
0
La Grandmaster said:
It seems to work fairly well, the only thing I can say is that if the player is in a party on their own and they are defeated, when they press tab instead of counting it so that the player has lost the battle, the game counts it as a retreat and then the player is allowed to charge at the enemy again. I dont know if this will also affect larger battles, but it may do Im not sure?
Thanks, it would affect other battles too. I'll look in to it.

Edit:
Quick fix, haven't tested it outside of lead_charge, I believe there's a few other places that I need to modify for sieges, I'll update the main post when I have.

common_battle_tab_press = (
    ti_tab_pressed, 0, 0, [],
    [
        (try_begin),
        (eq, "$g_battle_won", 1),
            (call_script, "script_count_mission_casualties_from_agents"),
            (finish_mission, 0),
        (else_try),
        (eq, "$pin_player_fallen", 1),
            (call_script, "script_simulate_retreat", 0, 0, 0),
            (assign, "$g_battle_result", -1),
            (set_mission_result, -1),
            (call_script, "script_count_mission_casualties_from_agents"),
            (finish_mission, 0),
        (else_try),
        (eq, "$deathcam_on", 1),

            (question_box,"str_do_you_want_to_retreat"),
        (else_try),
            (call_script, "script_cf_check_enemies_nearby"),
            (question_box,"str_do_you_want_to_retreat"),
        (else_try),
            (display_message,"str_can_not_retreat", color_neutral_news),
        (try_end),
    ]
)

        (1, 4, ti_once,
        [
            (main_hero_fallen),
            (assign, ":pteam_alive", 0),
            (try_for_agents, ":agent"), #Check players team is dead
            (agent_is_ally, ":agent"),
            (agent_is_alive, ":agent"),
                (assign, ":pteam_alive", 1),
            (try_end),
            (eq, ":pteam_alive", 0),

        ],
        [
            (assign, "$pin_player_fallen", 1),
            (display_message, "@Press TAB to end the battle."),
        ]),

This also fixes the "Cannot retreat, enemies near by" message you get within 4 seconds of dieing when trying to leave the battle.
 

Swyter

Grandmaster Knight
WBM&BWF&S
Best answers
0
Friendly advice: Since like a week ago Janus added the possibility of directly embedding YouTube videos.
This may come in handy to you, so the demo has more exposure. Seems like an easy way to gain interest, even from non-coders.

Nice enhancement, by the way.
 

Zephilinox

Knight
WB
Best answers
0
Swyter said:
Friendly advice: Since like a week ago Janus added the possibility of directly embedding YouTube videos.
This may come in handy to you, so the demo has more exposure. Seems like an easy way to gain interest, even from non-coders.

Nice enhancement, by the way.
Thanks, I'll include the video in the main post soon. Coming from you that's high praise :smile:
 

Lumos

Section Moderator
WBWF&SNWM&BVC
Best answers
0
Yeah, you're the polar opposite of the newbie who asks questions all the time, posts two mod threads that have got plainly impossible concepts, and dies after two weeks (or less). :grin:
Keep up the good work.
 

Zephilinox

Knight
WB
Best answers
0
Lumos said:
Yeah, you're the polar opposite of the newbie who asks questions all the time, posts two mod threads that have got plainly impossible concepts, and dies after two weeks (or less). :grin:
Keep up the good work.
It always makes me cringe when I see those threads :razz:

Updated to V1.3. fixed the issue with crazy rotation when exiting a presentation and added a new key. Minimal testing done in Diplomacy 4.2, but works.
 

Michadr

Grandmaster Knight
WBM&BVC
Best answers
0
This made my year (litterly)
It works just fine replacing the "hard" to use Diplomacy cam. (version 4.3)
Amazing work by the way, every mod should have this.
 

FALX

Master Knight
Best answers
0
            (display_message,"str_can_not_retreat", color_neutral_news),

color_neutral_news    -  is not defined
                                                                            It`s with compilation errors .
 

Lumos

Section Moderator
WBWF&SNWM&BVC
Best answers
0
Define it then. What color do you want your neutral news to be in? White seems neutral enough, right? Slap
Code:
[color=navy]color_neutral_news = 0xFFFFFF[/color]
in module_constants.
 

Zephilinox

Knight
WB
Best answers
0
FALX said:
            (display_message,"str_can_not_retreat", color_neutral_news),

color_neutral_news    -  is not defined
                                                                            It`s with compilation errors .
Whoops, sorry, thought I had removed all of that. Delete ", color_neutral_news"

I'll fix it when I get back from camping.
 

FALX

Master Knight
Best answers
0
Lumos said:
Define it then. What color do you want your neutral news to be in? White seems neutral enough, right? Slap
Code:
[color=navy]color_neutral_news = 0xFFFFFF[/color]
in module_constants.
Zephilinox said:
FALX said:
            (display_message,"str_can_not_retreat", color_neutral_news),

color_neutral_news    -  is not defined
                                                                            It`s with compilation errors .
Whoops, sorry, thought I had removed all of that. Delete ", color_neutral_news"

I'll fix it when I get back from camping.
Thanks for the hint. So it really looks better Slap color_neutral_news = 0xFFFFFF in module_constants.". :grin:
 

Lumos

Section Moderator
WBWF&SNWM&BVC
Best answers
0
Slapping it in the constants will allow you to use it for other messages and stuff like that. Besides, you can never have too many constants. Except when they lead to the same thing, that is. :smile:
 

Zephilinox

Knight
WB
Best answers
0
I've checked the code but I don't see color_neutral_news so you are probably using an older version before I updated the main post, I would really recommend using V1.3

Nevermind, found it :b
 

aleeque

Sergeant
Best answers
0
Possibly a stupid question, but is there a simpler alternative way to import this mod into Diplomacy? Like, replacing a file somewhere or something? Because frankly I have no idea how to use modsys :???:
 

Zephilinox

Knight
WB
Best answers
0
aleeque said:
Possibly a stupid question, but is there a simpler alternative way to import this mod into Diplomacy? Like, replacing a file somewhere or something? Because frankly I have no idea how to use modsys :???:
Originally I hadn't bothered trying to implement it in Diplomacy however because of my previous work with Perisno I ended up supporting it, you can find the Diplomacy+Deathcam source for this here: https://github.com/Zephilinox/Bean/blob/f46835233ad3d48a8e0d8229358c5ef6f61e3c35/Bean%200.1/module_mission_templates.py (it should work fine)

However since you don't want to or don't know how to use the Module System I've uploaded the .txt files, whether it works or not I cannot say but it definitely will not work with any mod that alters mission_templates on top of the modifications made by Diplomacy. In other words this .txt can only be used with Pure Diplomacy.

As well as mission_templates.txt, I've included two .txt files to do with variables. I cannot remember if these are generated on-the-fly or not, I would first test just using the mission_templates.txt and if that does not work then try using all 3 files.

http://www.sendspace.com/file/8q1qww

Sorry for the extremely late reply, but I don't participate on this forums anymore.

Edit: this reminds me, I believe there was a bug I had found while working on the diplomacy integration of the Deathcam but I never updated the original post, to anyone wishing to use the non-diplomacy version I suggest you use WinMerge to compare the differences in order to find what I needed to change to fix it.
 

aigle_360

Squire
WBVC
Best answers
0
I don't know if it is the best spot to write this, well anyway, I implemented this death camera kit, it works properly, all smooth. I have also added the TPE source (http://forums.taleworlds.com/index.php/topic,182926.0.html) and was wondering how I could add the first kit to the second source. It simply means that I am  willing to have access to the camera when I will be knocked down in tournaments. It is set so the "tournament battle" continues while the player has been injured. :grin:
I currently use modmerger to get TPE working.

Basically, I tried to add this portion of code at certain places of the module_mission_templates
Code:
      common_init_deathcam,
      common_start_deathcam,
      common_move_deathcam,
      common_rotate_deathcam,

At first, I was inspired by the Floris mod pack and used their TPE source kit. I was looking somehow to add the previous code to the following one as I am not very experienced in coding.
Unfortunatly, I didn't manage to get it working as Floris uses a different Death cam which uses a particular script and the one from this topic relies on triggers.  This is TPE (modmerger)'s specific trigger :
Code:
	# TRIGGER 18: Player dies, round continues.  Warning of this feature to the player.
	(0, 0, ti_once, [(main_hero_fallen),],
	   [(display_message, "@You have fallen during this round, but will be able to continue onto the next round when only one team remains."),
	    (troop_set_slot, "trp_tpe_presobj", tpe_time_of_death, "$g_wp_tpe_timer"),
	    # (try_begin),
			# (eq, MOD_PBOD_INSTALLED, 1), # (dependency) PBOD - Custom camera
			# (display_message, "@You may move your camera around using the arrow keys."),
			# # Sets up camera for free movement.
			# (call_script, "script_cust_cam_init_death_cam", cam_mode_free),
		# (try_end),
		]),
Then, I tried to implement the first code to native's mission_template (of course via the module system) in the "arena_melee_fight" section.
Code:
    "arena_melee_fight",mtf_arena_fight,-1,
    "You enter a melee fight in the arena.",
    [
      (0,mtef_visitor_source|mtef_team_0,af_override_all,aif_start_alarmed,1,[itm_practice_bow,itm_practice_arrows,itm_practice_horse,itm_arena_tunic_red, itm_red_tourney_helmet]),
[...]
      (31,mtef_visitor_source|mtef_team_3,af_override_all,aif_start_alarmed,1,[itm_practice_lance,itm_practice_shield,itm_practice_horse,itm_arena_tunic_yellow, itm_gold_tourney_helmet]),

#32
      (32, mtef_visitor_source|mtef_team_1,af_override_all,aif_start_alarmed,1,[itm_heavy_practice_sword]),
[...]
      (39,mtef_visitor_source|mtef_team_4,af_override_all,aif_start_alarmed,1,[itm_practice_staff]),
#40-49 not used yet
      (24,mtef_visitor_source|mtef_team_3,af_override_all,aif_start_alarmed,1,[itm_practice_bow,itm_practice_arrows,itm_practice_horse,itm_arena_tunic_yellow, itm_gold_tourney_helmet]),
[...]
      (24,mtef_visitor_source|mtef_team_3,af_override_all,aif_start_alarmed,1,[itm_practice_bow,itm_practice_arrows,itm_practice_horse,itm_arena_tunic_yellow, itm_gold_tourney_helmet]),

      (50, mtef_scene_source,af_override_horse|af_override_weapons|af_override_head,0,1,[]),
      (51, mtef_visitor_source,af_override_horse|af_override_weapons|af_override_head,0,1,[]),
      (52, mtef_scene_source,af_override_horse,0,1,[]),
#not used yet:
      (53, mtef_scene_source,af_override_horse,0,1,[]),(54, mtef_scene_source,af_override_horse,0,1,[]),(55, mtef_scene_source,af_override_horse,0,1,[]),
#used for torunament master scene

      (56, mtef_visitor_source|mtef_team_0, af_override_all, aif_start_alarmed, 1, [itm_practice_sword, itm_practice_shield, itm_padded_cloth, itm_segmented_helmet]),
      (57, mtef_visitor_source|mtef_team_0, af_override_all, aif_start_alarmed, 1, [itm_practice_sword, itm_practice_shield, itm_padded_cloth, itm_segmented_helmet]),
    ],
    tournament_triggers
  ),

At last, I put it in tournement_triggers with no satifying result.
My main problem is that I don't know where to put the first code since my knowledge of triggers isn't that great, haha. I probably implemented in triggers sources which of course creates errors. That's why I would like some help. :smile:
Thank you and I hope it is understandable!

Edit : fixed

Code:
	# TRIGGER 18: Player dies, round continues.  Warning of this feature to the player.
      common_init_deathcam,
      common_start_deathcam,
      common_move_deathcam,
      common_rotate_deathcam,	
           (0, 0, ti_once, [(main_hero_fallen),],
	   [(display_message, "@You have fallen during this round, but will be able to continue onto the next round when only one team remains."),
	    (troop_set_slot, "trp_tpe_presobj", tpe_time_of_death, "$g_wp_tpe_timer"),
	    # (try_begin),
			# (eq, MOD_PBOD_INSTALLED, 1), # (dependency) PBOD - Custom camera
			# (display_message, "@You may move your camera around using the arrow keys."),
			# # Sets up camera for free movement.
			# (call_script, "script_cust_cam_init_death_cam", cam_mode_free),
		# (try_end),
		]),