Free Camera after Death

Users who are viewing this thread

froggyluv

Grandmaster Knight
I've noticed a few mods have given the abilty to move the camera around the battlefield after PC has fallen, is there a released source on how this was done or is it priviledged information?
 
I have this link in my toolbox:

http://forums.taleworlds.com/index.php/topic,59637.msg1542126.html#msg1542126

Which can lead you to here:

http://forums.taleworlds.com/index.php/topic,60329.msg1559908.html#msg1559908

There are other approaches, but that should give you enough code to figure it out and do something else similar if you wish.
 
I've adapted that code so that it won't let you switch players but just jump the view through your surviving troops, a little like the way it works in Counter Strike after you're dead.

Let me know if you're interested, I can post it quite easily and it's a piece of piss to implement

[edit]

ok some ppl were interested so I'll go ahead and post my code:

this goes in module_scripts:

Code:
# script_dmod_cycle_forwards
  # Output: New $dmod_current_agent
  # Used to cycle forwards through valid agents
  ("dmod_cycle_forwards",[

            (assign, ":agent_moved", 0),
            (assign, ":first_agent", -1),
            (get_player_agent_no, ":player_agent"),
         (agent_get_team, ":player_team", ":player_agent"),
               
            (try_for_agents, ":agent_no"),
                (neq, ":agent_moved", 1),
                (neq, ":agent_no", ":player_agent"),
                (agent_is_human, ":agent_no"),
                (agent_is_alive, ":agent_no"),
            (agent_get_team, ":cur_team", ":agent_no"),
            (eq, ":cur_team", ":player_team"),
#                (agent_get_troop_id, ":agent_troop", ":agent_no"),
                (try_begin),
                    (lt, ":first_agent", 0),
                    (assign, ":first_agent", ":agent_no"),
                (try_end),
                (gt, ":agent_no", "$dmod_current_agent"),
                (assign, "$dmod_current_agent", ":agent_no"),
                (assign, ":agent_moved", 1),
            (try_end),

            (try_begin),
                (eq, ":agent_moved", 0),
                (neq, ":first_agent", -1),
                (assign, "$dmod_current_agent", ":first_agent"),
                (assign, ":agent_moved", 1),
            (else_try),
                (eq, ":agent_moved", 0),
                (eq, ":first_agent", -1),
                (display_message, "@No Troops Left."),
            (try_end),
   
            (try_begin),
                (eq, ":agent_moved", 1),
                (str_store_agent_name, 1, "$dmod_current_agent"),
                (display_message, "@Selected Troop: {s1}"),
            (try_end),
      (assign, "$dmod_move_camera", 1),
    ]),
   
  # script_dmod_cycle_backwards
  # Output: New $dmod_current_agent
  # Used to cycle backwards through valid agents
  ("dmod_cycle_backwards",[

            (assign, ":new_agent", -1),
            (assign, ":last_agent", -1),
            (get_player_agent_no, ":player_agent"),
         (agent_get_team, ":player_team", ":player_agent"),         
               
            (try_for_agents, ":agent_no"),
                (neq, ":agent_no", ":player_agent"),
                (agent_is_human, ":agent_no"),
                (agent_is_alive, ":agent_no"),
            (agent_get_team, ":cur_team", ":agent_no"),
            (eq, ":cur_team", ":player_team"),
 #               (agent_get_troop_id, ":agent_troop", ":agent_no"),
                (assign, ":last_agent", ":agent_no"),
                (lt, ":agent_no", "$dmod_current_agent"),
                (assign, ":new_agent", ":agent_no"),
            (try_end),

            (try_begin),
                (eq, ":new_agent", -1),
                (neq, ":last_agent", -1),
                (assign, ":new_agent", ":last_agent"),               
            (else_try),
                (eq, ":new_agent", -1),
                (eq, ":last_agent", -1),
                (display_message, "@No Troops Left."),
            (try_end),

            (try_begin),
                (neq, ":new_agent", -1),
                (assign, "$dmod_current_agent", ":new_agent"),
                (str_store_agent_name, 1, "$dmod_current_agent"),
                (display_message, "@Selected Troop: {s1}"),
            (try_end),
      (assign, "$dmod_move_camera", 1),
   ]),

this goes in module_mission_templates:

Code:
sw_deathcam_follow_troop = (0, 0, 0,[(eq, "$dmod_move_camera", 2),
        (agent_get_position, 1, "$dmod_current_agent"),     
        (get_player_agent_no, ":player_agent"),
        (agent_set_position, ":player_agent", 1)

     ],[])
sw_deathcam_valkyrie_move_camera = (0, 1, 2.1,[(eq, "$dmod_move_camera", 1),
        (agent_get_position, 2, "$dmod_current_agent"),             
        (position_move_z, 2, 300),
        (mission_cam_set_mode,1),     
        (mission_cam_set_position, 2),
        (position_move_z, 2, 600),
        (mission_cam_animate_to_position, 2, 1000),
     ],[
        (mission_cam_set_mode, 0, 1000, 1),
        (assign, "$dmod_move_camera", 2),
     ])   
sw_deathcam_cycle_fowards =	 (0, 0, 0,[(key_clicked, key_m), (main_hero_fallen),
        (call_script, "script_dmod_cycle_forwards"),
        ], [])
		
sw_deathcam_cycle_backwards = (0, 0, 0,[(key_clicked, key_n), (main_hero_fallen),
        (call_script, "script_dmod_cycle_backwards"),
        ], [])

you can obviously change the names, these are from the Star Wars Calradia mod.

So that's the basics. Now for implementing it you'll need to do a few more things. If you already have the system like in SoD where the mission doesn't end when you get knocked out, you're good to go. Just put these constants in the mission templates you want to use them in and then after you're knocked out, you can use m and n to cycle through your troops and watch over their shoulder.

If not, there's a bit more work to be done. You'll have to implement the 'no-death' thing.

In the constant victory conditions, like common_ and custom_battle_check_victory_condition, you'll find stuff like:

    (neg|main_hero_fallen, 0),

You'll need to comment these out.


Then there is common_siege_check_defeat_condition = ( which you'll have to change so it looks something like this:

Code:
common_siege_check_defeat_condition = (
  1, 4, ti_once,
  [
    (main_hero_fallen)
    ],
  [
    (assign, "$pin_player_fallen", 1),
	(display_message, "@You have been knocked out by the enemy. Watch your men continue the fight without you or press Tab to retreat."),
	(display_message, "@If you choose to watch the fight you can use the M and N keys to change your camera view."),
    # (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),
    # (else_try),
      # (str_store_string, s5, "str_retreat"),
      # (call_script, "script_simulate_retreat", 5, 20),
    # (try_end),
    # (assign, "$g_battle_result", -1),
    # (set_mission_result,-1),
    # (call_script, "script_count_mission_casualties_from_agents"),
    # (finish_mission,0),
    ])

Finally, you'll have to initialize the global variables in every template. This is an example from lead_charge, most templates look slightly different but the basics are the same:

Code:
      (0, 0, ti_once, [], [(assign,"$battle_won",0),
                           (assign,"$defender_reinforcement_stage",0),
                           (assign,"$attacker_reinforcement_stage",0),
                           (assign,"$g_presentation_battle_active", 0),
                           (call_script, "script_place_player_banner_near_inventory"),
                           (call_script, "script_combat_music_set_situation_with_culture"),
						   #SW Deathcam
						   (assign, "$dmod_current_agent", -1),
						   (assign, "$dmod_move_camera", -1),
                           ]),

These three basics apply to all templates. So go through all of them and every trigger that fires on [main_hero_fallen] will have to be modified like above one. So change the code so it doesn't end the mission after you die. One more example from the lead_charge template:

Code:
      (1, 4, ti_once, [(main_hero_fallen)],
          [
              (assign, "$pin_player_fallen", 1),
			  (display_message, "@You have been knocked out by the enemy. Watch your men continue the fight without you or press Tab to retreat."),
			  (display_message, "@If you choose to watch the fight you can use the M and N keys to change your camera view."),
              # (str_store_string, s5, "str_retreat"),
              # (call_script, "script_simulate_retreat", 10, 20),
              # (assign, "$g_battle_result", -1),
              # (set_mission_result,-1),
              # (call_script, "script_count_mission_casualties_from_agents"),
              # (finish_mission,0)
			  ]),

You'll also have to change the common_battle_tab_press constant, otherwise you won't be able to get out of the mission properly anymore. Mine looks like this:

Code:
common_battle_tab_press = (
  ti_tab_pressed, 0, 0, [],
  [
    (try_begin),
      (eq, "$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", 5, 20),
		(str_store_string, s5, "str_retreat"),
		(call_script, "script_count_mission_casualties_from_agents"),
		(set_mission_result, -1),
		(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),
    ])


If you're having trouble with this, a good option would be to get the source code for Sword of Damocles and look at how they changed their mission_templates, as they already have the 'stay in the fight after death' feature in there. Then you can just add the extra triggers and global variables in and it will work.

Now this feature still needs to be tweaked a little bit in my opinion. Right now the camera soars up into the sky, moves over the troop and then sinks down. This takes a bit long. One way around it, is to only use the 'dmod_follow_troop' trigger (the first one). You can do this by changing the condition block to ,(eq, "$dmod_move_camera", 1), and then commenting out the second trigger (move_camera). Problem with this is that your camera will stay looking in the same direction, it won't look towards where the troop is looking. I was still working on that but haven't had much time to code lately (sorry Hokie..)

I've been playing around with various camera settings and different ways of doing it but haven't found anything I really liked yet.

This might not be something for the total newb at modding, but with a bit of thinking it's really pretty basic stuff.

Kudos for this don't go to me, but to silverkatana and his Valkyrie minmod, I just changed it around.
 
Damn if I'll ever wrap my head around this stuff  :evil:

MartinF, I've got the basic 'no die' code worked and stuck in the first two spoilers in both scripts and mission template as well as the 'press N/M' dialogue. The fourth spoiler, the one that initilizes the global variable - well, lets just say I must be guessing wrong where to put:
                                                                                                      #SW Deathcam
  (assign, "$dmod_current_agent", -1),
  (assign, "$dmod_move_camera", -1),

as I'm getting "Global variable dmod_move_camera is never used".
 
well it's a bit different in each mission template, but the example I gave is from lead_charge

most of the templates have a (0,0, ti_once) trigger, somewhere near the top where some global vars are initialized. such as (assign,"$battle_won",0), and also where the script is called for the banner near inventory and the culture specific music. That's the one.

It doesn't really matter, you can also just make a whole new (0,0, ti_once) trigger, as long as the vars get initialized.

But if you get the global var never used, I'm guessing it's not this problem.

Did you add the constants to the mission template? The bit I posted goes in the top, before the actual mission templates (where the common_ stuff is declared) and then in each mission template where you want to use it, you have to add

sw_deathcam_follow_troop,
sw_deathcam_valkyrie_move_camera,
sw_deathcam_cycle_fowards,
sw_deathcam_cycle_backwards,

In lead_charge you can put it right under

      common_battle_victory_display,

for instance. Doesn't really matter, as long as it's in the triggers part of the mission template
 
Is it possible to move the camera back, and take away the ability to move the player agent?

The reason I ask this is it might be cool to (after striking/missing) in the joust to have the camera zoom back so you can see the outcome.  Even if the player's agent is not dead/KOed.
 
sure, you just have to store the original player agent.

Only potential problem might be that you're actually physically moving the player agent with this method.. which you would obviously not want with the jousting.

But you can move the mission cam and then put it back where you want it (on the player) afterwards. You'll also have to experiment with the mission cam modes, I had some dodgy results. It's supposed to be possible to set it to free or to lock it, but somehow whatever I do if I move it, it locks, so you can't mouse-look anymore.

What you could also do is something similar to what happens here when you 'switch' to a new player. As soon as you initiate the strike for the joust, the camera zooms up and out so you can see the result, then settles back on the player.
 
good idea.  I just have to put an agent in a good viewing spot.  I can trigger it if
A) the player swings
b) the player is unhorsed
c) after the distance is less than 100 between jousters (pretty much passed at this point)


Can I prevent the player from moving around at this time?
 
Big thanks again MartinF I finally got it working! Yes, I needed to place the:

                                                  sw_deathcam_follow_troop,
                                                  sw_deathcam_valkyrie_move_camera,
                                                  sw_deathcam_cycle_fowards,
                                                  sw_deathcam_cycle_backwards,

...and that seemed to do the trick. I'm getting the "pess/N/M" dialogue after the entire battle is over as well so I'll have to go thru and find where I misplaced those entries. You guys down here in the forge are a big help to 'baby-steppers' like me who really want to understand the MS but aren't quite as naturally gifted  :mrgreen:
 
haha naturally gifted.. yeah.. I only spent a couple hundred hours trying to figure it all out :wink:

It's strange that you're getting the m/n message.. make sure you corrected the victory condition to comment out the (neg|main_hero_fallen) because otherwise it won't trigger.

Basically all my triggers relating to this should have (main_hero_fallen) as conditions so they should only show up when you're knocked on your ass
 
MartinF said:
I've adapted that code so that it won't let you switch players but just jump the view through your surviving troops, a little like the way it works in Counter Strike after you're dead.

thanks a lot for the tutorial Martin, saved me lots of time!
 
Hi folks,

This blew my mind trying to figure it out but now I think I got it.

Two things:

1. I cannot figure out why, but your common_battle_tab_press constant has a flaw in which it allows the player to retreat from battle regardless of having enemies nearby also while being alive (which I don't understand since "(eq, "$pin_player_fallen", 1)," as far as I know (which is quite close after all) should take care of it but apparently it doesn't).

2. I am seeking to get upon death a total free-cam view as the one you get in edit mode by pressing ctrl+e. kt0 has guided me in that direction here, but I think that setting the camera as agent is preventing it to move on the z axis aswell, which is the main point of it.

Does any of you guys have any insights about it? It wold be cool.
 
Martinf I found what might be a bug in the code. Due to removing the check that your player is dead what is there to check that your team has actually lost the battle. I went to a battle alone died and the mission wouldn't end. When I "retreated" the game crashed. I couldn't find a common battle check defeat condition maybe it just checks for your death at the end of all the mission templates? Do I need to modify the MT's to count your team and see if they are all dead?

EDIT: The crash was due to something else but that still means that if you lose by yourself you "retreat" and get to fight again or run? I've been looking in module operations but haven't found an operation to count your teams remaining agents. Its probably there somewhere though.
 
jik said:
Is it possible to move the camera back, and take away the ability to move the player agent?

The reason I ask this is it might be cool to (after striking/missing) in the joust to have the camera zoom back so you can see the outcome.  Even if the player's agent is not dead/KOed.

hmm.. did you manage to come up with the code for moving the camera back/zooming backwards??

i've been trying to do that for awhile now.. but i still can't figure it out..  :???:
 
Berserker Pride said:
Martinf I found what might be a bug in the code. Due to removing the check that your player is dead what is there to check that your team has actually lost the battle. I went to a battle alone died and the mission wouldn't end. When I "retreated" the game crashed. I couldn't find a common battle check defeat condition maybe it just checks for your death at the end of all the mission templates? Do I need to modify the MT's to count your team and see if they are all dead?

EDIT: The crash was due to something else but that still means that if you lose by yourself you "retreat" and get to fight again or run? I've been looking in module operations but haven't found an operation to count your teams remaining agents. Its probably there somewhere though.

May be it will something like this :
Code:
(1, 4, ti_once, [(main_hero_fallen)],
          [
              (assign, "$pin_player_fallen", 1),
              (display_message, "@You have fallen in battle!"),
              (assign, ":num_allies", 0),
              (try_for_agents, ":agent"),
               (agent_is_ally, ":agent"),
               (agent_is_alive, ":agent"),
               (val_add, ":num_allies", 1),
             (try_end),
             (try_begin),
                (eq, ":num_allies", 0),
                (assign, "$g_battle_result", -1),
                (set_mission_result,-1),
                (call_script, "script_count_mission_casualties_from_agents"),
                (finish_mission,0),
             (else_try),
                (display_message, "@You have been knocked out by the enemy. Watch your men continue the fight without you or press Tab to retreat."),
                (display_message, "@If you choose to watch the fight you can use the M and N keys to change your camera view."), 
             (try_end),
          ]),
 
More DeathCam necro!

Tried this for WB and everything works except now the camera (upon pressing N/M) starts at the troop and does a flyover back to you.
 
Back
Top Bottom