OSP Code QoL Mouse-controlled, after-death, free-roaming camera

Users who are viewing this thread

MadVader said:
This was developed for Warband only. The POP MB version uses entirely different code (see first post and follow kt0's link) - that code can't be used in WB, as WB doesn't allow moving the dead player.

Okay, thanks for clearing up.
 
I love the code, but would it be possible to take the "Spectator" codes from MP and convert them to SP? That way you could go into battle (once cheat mode was enabled) as a spectator for taking screens and making videos, etc, but not having to die to do it. If it's possible, I may be looking into converting it..... :smile:
 
Specialist said:
I love the code, but would it be possible to take the "Spectator" codes from MP and convert them to SP? That way you could go into battle (once cheat mode was enabled) as a spectator for taking screens and making videos, etc, but not having to die to do it. If it's possible, I may be looking into converting it..... :smile:
Not familar with MP code, but aren't there some cheat keys already available for taking screenshots? Like pausing the game (ctrl+f11) and entering edit mode to move around the camera? People who post shots and videos would know more.
Otherwise feel free to take the code and abuse it for any needs (like piloting flying troops.. haha).
 
My code's based on this, but it's considerably different in many areas.  I'm not sure what you say about "it doesn't work", though; I haven't had any complaints about it working in Blood and Steel in a long time.  Keep in mind that it uses a different approach, though, and it's not really designed for copy-pasta into Native's code.  You'll have to read it and spend some time actually understanding it to apply it.
 
xenoargh said:
My code's based on this, but it's considerably different in many areas.  I'm not sure what you say about "it doesn't work", though; I haven't had any complaints about it working in Blood and Steel in a long time.  Keep in mind that it uses a different approach, though, and it's not really designed for copy-pasta into Native's code.  You'll have to read it and spend some time actually understanding it to apply it.

it works fine in Blood and steal, and yes i looked at that code, wow...  :shock:  i see what you mean by understanding it.


so i tried this....
MadVader said:
Here's the code for a WASD+mouse-controlled free-roaming camera. (I know you want it!)
I couldn't find any camera code I liked, so I wrote one for POP3 for Warband. The cameras I found either had clumsy extra keys for control, a limited camera, or didn't work for Warband.

It was based on kt0's simple after-death camera, but is much expanded:
http://forums.taleworlds.com/index.php/topic,63178.msg1641483.html#msg1641483

At the top of mission templates, add these declarations:
Code:
## MadVader deathcam begin
common_init_deathcam = (
   0, 0, ti_once,
   [],
   [
      (assign, "$pop_camera_on", 0),
      # mouse center coordinates (non-windowed)
      (assign, "$pop_camera_mouse_center_x", 500),
      (assign, "$pop_camera_mouse_center_y", 375),
      # last recorded mouse coordinates
      (assign, "$pop_camera_mouse_x", "$pop_camera_mouse_center_x"),
      (assign, "$pop_camera_mouse_y", "$pop_camera_mouse_center_y"),
      # counts how many cycles the mouse stays in the same position, to determine new center in windowed mode
      (assign, "$pop_camera_mouse_counter", 0),
   ]
)

common_start_deathcam = (
   0, 4, ti_once, # 4 seconds delay before the camera activates
   [
     (main_hero_fallen),
     (eq, "$pop_camera_on", 0),
   ],
   [
      (get_player_agent_no, ":player_agent"),
      (agent_get_position, pos1, ":player_agent"),
      (position_get_x, ":pos_x", pos1),
      (position_get_y, ":pos_y", pos1),
      (init_position, pos47),
      (position_set_x, pos47, ":pos_x"),
      (position_set_y, pos47, ":pos_y"),
      (position_set_z_to_ground_level, pos47),
      (position_move_z, pos47, 250),
      (mission_cam_set_mode, 1, 0, 0),
      (mission_cam_set_position, pos47),
      (assign, "$pop_camera_rotx", 0),
      (assign, "$pop_camera_on", 1),
   ]
)

common_move_deathcam = (
   0, 0, 0,
   [
      (eq, "$pop_camera_on", 1),
      (this_or_next|game_key_clicked, gk_move_forward),
      (this_or_next|game_key_is_down, gk_move_forward),
      (this_or_next|game_key_clicked, gk_move_backward),
      (this_or_next|game_key_is_down, gk_move_backward),
      (this_or_next|game_key_clicked, gk_move_left),
      (this_or_next|game_key_is_down, gk_move_left),
      (this_or_next|game_key_clicked, gk_move_right),
      (game_key_is_down, gk_move_right),
   ],
   [
      (mission_cam_get_position, pos47),
      (assign, ":move_x", 0),
      (assign, ":move_y", 0),
      (try_begin), #forward
        (this_or_next|game_key_clicked, gk_move_forward),
        (game_key_is_down, gk_move_forward),
        (assign, ":move_y", 10),
      (try_end),
      (try_begin), #backward
        (this_or_next|game_key_clicked, gk_move_backward),
        (game_key_is_down, gk_move_backward),
        (assign, ":move_y", -10),
      (try_end),
      (try_begin), #left
        (this_or_next|game_key_clicked, gk_move_left),
        (game_key_is_down, gk_move_left),
        (assign, ":move_x", -10),
      (try_end),
      (try_begin), #right
        (this_or_next|game_key_clicked, gk_move_right),
        (game_key_is_down, gk_move_right),
        (assign, ":move_x", 10),
      (try_end),
      (position_move_x, pos47, ":move_x"),
      (position_move_y, pos47, ":move_y"),
      (mission_cam_set_position, pos47),      
   ]
)

deathcam_mouse_deadzone = 2 #set this to a positive number (MV: 2 or 3 works well for me, but needs testing on other people's PCs)

common_rotate_deathcam = (
   0, 0, 0,
   [
      (eq, "$pop_camera_on", 1),
      (neg|is_presentation_active, "prsnt_battle"),
      (mouse_get_position, pos1),
      (set_fixed_point_multiplier, 1000),
      (position_get_x, reg1, pos1),
      (position_get_y, reg2, pos1),
      (this_or_next|neq, reg1, "$pop_camera_mouse_center_x"),
      (neq, reg2, "$pop_camera_mouse_center_y"),
   ],
   [
      # fix for windowed mode: recenter the mouse
      (assign, ":continue", 1),
      (try_begin),
        (eq, reg1, "$pop_camera_mouse_x"),
        (eq, reg2, "$pop_camera_mouse_y"),
        (val_add, "$pop_camera_mouse_counter", 1),
        (try_begin), #hackery: if the mouse hasn't moved for X cycles, recenter it
          (gt, "$pop_camera_mouse_counter", 50),
          (assign, "$pop_camera_mouse_center_x", reg1),
          (assign, "$pop_camera_mouse_center_y", reg2),
          (assign, "$pop_camera_mouse_counter", 0),
        (try_end),
        (assign, ":continue", 0),
      (try_end),
      (eq, ":continue", 1), #continue only if mouse has moved
      (assign, "$pop_camera_mouse_counter", 0), # reset recentering hackery
      
      # update recorded mouse position
      (assign, "$pop_camera_mouse_x", reg1),
      (assign, "$pop_camera_mouse_y", reg2),
      
      (mission_cam_get_position, pos47),
      (store_sub, ":shift", "$pop_camera_mouse_center_x", reg1), #horizontal shift for pass 0
      (store_sub, ":shift_vertical", reg2, "$pop_camera_mouse_center_y"), #for pass 1
      
      (try_for_range, ":pass", 0, 2), #pass 0: check mouse x movement (left/right), pass 1: check mouse y movement (up/down)
        (try_begin),
          (eq, ":pass", 1),
          (assign, ":shift", ":shift_vertical"), #get ready for the second pass
        (try_end),
        (this_or_next|lt, ":shift", -deathcam_mouse_deadzone), #skip pass if not needed (mouse deadzone)
        (gt, ":shift", deathcam_mouse_deadzone),
        
        (assign, ":sign", 1),
        (try_begin),
          (lt, ":shift", 0),
          (assign, ":sign", -1),
        (try_end),
        # square root calc
        (val_abs, ":shift"),
        (val_sub, ":shift", deathcam_mouse_deadzone), # ":shift" is now 1 or greater
        (convert_to_fixed_point, ":shift"),
        (store_sqrt, ":shift", ":shift"),
        (convert_from_fixed_point, ":shift"),
        (val_clamp, ":shift", 1, 6), #limit rotation speed
        (val_mul, ":shift", ":sign"),
        (try_begin),
          (eq, ":pass", 0), # rotate around z (left/right)
          (store_mul, ":minusrotx", "$pop_camera_rotx", -1),
          (position_rotate_x, pos47, ":minusrotx"), #needed so camera yaw won't change
          (position_rotate_z, pos47, ":shift"),
          (position_rotate_x, pos47, "$pop_camera_rotx"), #needed so camera yaw won't change
        (try_end),
        (try_begin),
          (eq, ":pass", 1), # rotate around x (up/down)
          (position_rotate_x, pos47, ":shift"),
          (val_add, "$pop_camera_rotx", ":shift"),
        (try_end),
      (try_end), #try_for_range ":pass"
      (mission_cam_set_position, pos47),
   ]
)
## MadVader deathcam end
In each mission you want to have the camera, add the triggers:
Code:
## MadVader deathcam begin
      common_init_deathcam,
      common_start_deathcam,
      common_move_deathcam,
      common_rotate_deathcam,
## MadVader deathcam end

You also need to disable Warband ending the battle after death, but you can do this yourself (or read kt0's post).

If you use the code, some credit would be nice.

EDIT: added "(neg|is_presentation_active, "prsnt_battle")," in the rotate triggers conditions, so the camera would not rotate wildly when you press Backspace.

EDIT2: lowered the number of triggers (from 8 to 4) and increased mouse sensitivity

FINAL EDIT: fixed spinning in windowed mode

and then added it to a mission (i was not sure where so i tried a ton of different ones, none worked)

my code snippet:

custom_battle_check_defeat_condition = (
  1, 4, ti_once,
  [
    (main_hero_fallen),
    (assign,"$g_battle_result",-1),
    ],
  [
  ## MadVader deathcam begin
      common_init_deathcam,
      common_start_deathcam,
      common_move_deathcam,
      common_rotate_deathcam,
## MadVader deathcam end
    (call_script, "script_custom_battle_end"),
    (finish_mission),
    ])

and got this error: (this is way less then i had through the first few hours of trial and error)

 
dunde said:
Oh no, you put MadVader's triggers into another trigger. You should put them into the mission templates, like lead_charge.

:/ goodness...
but it still gives errors like the one i had... do you add it into (or at the end) the lead_charge for example, i tried a few places but alas no luck....

"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,[]),
    ],
    [
      (ti_on_agent_spawn, 0, 0, [],
      [
        (store_trigger_param_1, ":agent_no"),
        (call_script, "script_agent_reassign_team", ":agent_no"),

        (assign, ":initial_courage_score", 5000),
                 
        (agent_get_troop_id, ":troop_id", ":agent_no"),
        (store_character_level, ":troop_level", ":troop_id"),
        (val_mul, ":troop_level", 35),
        (val_add, ":initial_courage_score", ":troop_level"), #average : 20 * 35 = 700
       
        (store_random_in_range, ":randomized_addition_courage", 0, 3000), #average : 1500
        (val_add, ":initial_courage_score", ":randomized_addition_courage"),
                 
        (agent_get_party_id, ":agent_party", ":agent_no"),       
        (party_get_morale, ":cur_morale", ":agent_party"),
       
        (store_sub, ":morale_effect_on_courage", ":cur_morale", 70),
        (val_mul, ":morale_effect_on_courage", 30), #this can effect morale with -2100..900
        (val_add, ":initial_courage_score", ":morale_effect_on_courage"),
       
        #average = 5000 + 700 + 1500 = 7200; min : 5700, max : 8700
        #morale effect = min : -2100(party morale is 0), average : 0(party morale is 70), max : 900(party morale is 100)
        #min starting : 3600, max starting  : 9600, average starting : 7200
        (agent_set_slot, ":agent_no", slot_agent_courage_score, ":initial_courage_score"),
## MadVader deathcam begin
      common_init_deathcam,
      common_start_deathcam,
      common_move_deathcam,
      common_rotate_deathcam,
## MadVader deathcam end

error...

 
You did it again.
(ti_on_agent_spawn, 0, 0, [],
      [
        (store_trigger_param_1, ":agent_no"),
        (call_script, "script_agent_reassign_team", ":agent_no"),

        (assign, ":initial_courage_score", 5000),
      ........
      ]),
is another trigger.

It should be like this :
Code:
"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,[]),
     ],
    [
## MadVader deathcam begin
      common_init_deathcam,
      common_start_deathcam,
      common_move_deathcam,
      common_rotate_deathcam,
## MadVader deathcam end
      
      (ti_on_agent_spawn, 0, 0, [],
       [
         (store_trigger_para

A mission template consist of :
  • Mission template ID
  • flags
  • type
  • description
  • entry points
  • triggers

("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,[]),

    ],
    [
    triggers
  ]),

 
thank you!!!  ive been at that for the 8 hours today.
and it works ... NO ERRORS!!!!!!!!!! i was going crazy  :shock:

You did it again.
(ti_on_agent_spawn, 0, 0, [],
      [
        (store_trigger_param_1, ":agent_no"),
        (call_script, "script_agent_reassign_team", ":agent_no"),

        (assign, ":initial_courage_score", 5000),
      ........
      ]),
is another trigger.

my bad... i wasn't focused anymore.
 
@dunde

And how to make it on Warband? there are just Numbers i can't rly find out the place to put this in under missions.
 
madmaximillian said:
Does this also allow you to control your troops after death, via the backspace menu? If not, can you point me in the right direction. Thanks.

It doesn't. I've never seen that feature before, which mod was it in?
 
Fellow noob warriors, don't forget to change «common_battle_tab_press» on module_mission_templates.py or you will never be able to leave the battle if you lose!

This issue wasn't fixed on kt's version. So, here is how I made it work. You can add the green text or you can replace the whole thing :wink:

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),
      (num_active_teams_le, 1),
      (main_hero_fallen),
      (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),
      (main_hero_fallen),
      (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),
])
 
Back
Top Bottom