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:
Used in:
Changelog:
Version 1.4
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
Replace common_battle_tab_press
With:
Replace any/all of these blocks of code for the relevant mission types (e.g lead_charge)
With:
Replace common_siege_check_defeat_condition
With:
Replace common_battle_check_victory_condition
With:
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:
Like this:
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
- 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
- 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
- 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),
]
)
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),
]
)
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),
]
)
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),
]
)
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),
])
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),
]
)
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)
]),
[
(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."),
]),
[
(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),
])
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."),
]
)
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),
])
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),
])
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,
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,
#....
"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,
#....