Working compass in battle map

Users who are viewing this thread

shokkueibu

Knight
I want to use the compass in the battle map.
So far I've managed to use the mesh from the one in world map and make it rotate as I do. Obviously, I want it to work like a real compass except I don't have the necessary mathematical knowledge to do so. (arctangent?  :neutral:)
I take it [font=Consolas,Fixedsys]overlay_set_mesh_rotation[/font] is a good start, along with [font=Consolas,Fixedsys]agent_get_look_position[/font]?

How can I make it point towards a single point?
Can I define where in the scene that point is?


Working code:

Code:
("multiplayer_compass", prsntf_read_only|prsntf_manual_end_only, 0, [
    (ti_on_presentation_load, [
      (set_fixed_point_multiplier, 1000),
      (create_mesh_overlay, "$bi_compass", "mesh_compass"),
      (position_set_x, pos1, 50),
      (position_set_y, pos1, 550),
      (overlay_set_position, "$bi_compass", pos1),
      (position_set_x, pos1, 500),
      (position_set_y, pos1, 500),
      (overlay_set_size, "$bi_compass", pos1),
      
      (store_current_scene, ":cur_scene"),      
      (try_begin),
        (is_between, ":cur_scene", multiplayer_scenes_begin, multiplayer_scenes_end),
        (try_begin),
          (this_or_next|eq, ":cur_scene", scn_multi_scene_1), #Ruins
          (eq, ":cur_scene", scn_multi_scene_14), #Battle on Ice
          (assign, "$bi_compass_north", 135),
          
        (else_try),
          (eq, ":cur_scene", scn_multi_scene_2), #Village
          (assign, "$bi_compass_north", 180),
        (else_try),
          (this_or_next|eq, ":cur_scene", scn_multi_scene_4),   #Ruined Fort
          (this_or_next|eq, ":cur_scene", scn_multi_scene_12),  #Port Assault
          (eq, ":cur_scene", scn_multi_scene_18),               #Forest Hideout
          (assign, "$bi_compass_north", 0),
        (else_try),
          (eq, ":cur_scene", scn_multi_scene_7),    #Field by the River
          (assign, "$bi_compass_north", 225),
        (else_try),
          (eq, ":cur_scene", scn_multi_scene_9),    #Snowy Village
          (assign, "$bi_compass_north", 45),
        (else_try),
          (eq, ":cur_scene", scn_multi_scene_11),   #Nord Town
          (assign, "$bi_compass_north", 315),
        (else_try),
          (eq, ":cur_scene", scn_multi_scene_17),   #The Arena
          (assign, "$bi_compass_north", 20),          #The map isn't aligned to its borders 
        (try_end),
      (else_try),
        (entry_point_get_position, pos1, multi_initial_spawn_point_team_1),
        (entry_point_get_position, pos2, multi_initial_spawn_point_team_2),
        (get_angle_between_positions, "$bi_compass_north", pos2, pos1),
      (try_end),
      
      (assign, "$bi_compass_active", 1), #TODO: Let the user toggle this from
      (assign, "$bi_compass_3d", 1),      #              a menu or with a key
      (presentation_set_duration, 999999),
      ]),
    (ti_on_presentation_run, [
      (try_begin),
        (eq, "$bi_compass_active", 1),
        (set_fixed_point_multiplier, 1),
       
        (init_position, pos3),
        (position_rotate_z, pos3, "$bi_compass_north"),
        
        (mission_cam_get_position, pos1),
        (position_get_rotation_around_z, ":view_angle", pos1),
        
        (init_position, pos2),
        (val_mul, ":view_angle", -1), #Invert the angle
        (position_rotate_z, pos2, ":view_angle"),
        
        #Here we get the angle between the player and north
        (set_fixed_point_multiplier, 1),
        (get_angle_between_positions, ":angle", pos3, pos2),

        (init_position, pos10),
        (try_begin), #by dunde
           (eq, "$bi_compass_3d", 1),
           (position_get_rotation_around_x, ":pitch", pos1),
           (store_sub, ":pitch", -90, ":pitch"),
           (try_begin),
              (gt, ":pitch", 360),
              (val_mod, ":pitch", 360),
           (else_try),
              (lt, ":pitch", -360),
              (val_abs, ":pitch"),
              (val_mod, ":pitch", 360),
              (val_mul, ":pitch", -1),
           (try_end),
           (try_begin),
              (is_between, ":pitch", 180, 361),
              (val_sub, ":pitch", 360),
           (try_end),   
          (val_clamp, ":pitch", -90, 1),     
          (position_rotate_x, pos10, ":pitch"),         
        (try_end),
        
        (position_rotate_z, pos10, ":angle"),
        (overlay_set_mesh_rotation, "$bi_compass", pos10),
      (else_try),
        (presentation_set_duration, 0),
      (try_end),
      ]),
    ]),
Code:
  ("compass", 0, "compass", 0, 0, 0, 0, 0, 0, 1, 1, 1),
Code:
multiplayer_compass = (
  ti_battle_window_opened, 0, 0, [], [
    (start_presentation, "prsnt_multiplayer_compass"),
    ])   

Still in [font=consolas,fixedsys]module_mission_templates.py[/font], add
[font=consolas,fixedsys]multiplayer_compass,[/font]
by the end of any gametype you wish (multiplayer_bt, multiplayer_dm, etc).


Many thanks to Caba`drin, dunde and Somebody!

EDIT: Turns out I was wrong. The angle calculations aren't really working, it was a coincidence it pointed at the right place in Ruins. Yeah I know, bad testing from my part :/
As a workaround I set North manually for each stock map, excluding Siege  and random maps. If someone knows how to fix it please do say so.
 
I don't think you'll be needing any fancy trigonometric operations, actually.

Something else that will come in handy is
get_angle_between_positions

Pick a point in the scene that you want it to point to X, Y. Initialize a new position and then use position_set_x and position_set_y to make that position contain the point you want. So if that was pos45, and you used agent_get_look_position and stored it to pos1..

(set_fixed_point_multiplier, 1),
(get_angle_between_positions, ":theta", pos45, pos1),
(overlay_set_mesh_rotation, ":eek:verlay", ":theta"),

would be what I would start toying around with.



 
Caba`drin said:
(overlay_set_mesh_rotation, ":eek:verlay", ":theta"),
I don't think this works because it needs a position, not an angle. :neutral:

Code:
(overlay_set_mesh_rotation, <overlay_id>, <position_no>), #position's rotation values are used for rotations around x, y and z axis
Even with that in mind it doesn't work. The compass mimics my movement instead of always pointing towards the coordinates I set.

Code:
      (set_fixed_point_multiplier, 1000),
      (create_mesh_overlay, "$g_multiplayer_compass", "mesh_compass"),
      (position_set_x, pos1, 50),
      (position_set_y, pos1, 550),
      (overlay_set_position, "$g_multiplayer_compass", pos1),
      (position_set_x, pos1, 500),
      (position_set_y, pos1, 500),
      (overlay_set_size, "$g_multiplayer_compass", pos1),
      
      (multiplayer_get_my_player, ":player"),
      (player_get_agent_id, ":player_agent", ":player"),
      (try_begin),
        (agent_is_active,":player_agent"),
        (agent_is_alive,":player_agent"),
        
        (init_position, pos10),
        (position_set_x, pos10, 100),  #random coordinates
        (position_set_y, pos10, 100),
        
        (agent_get_look_position, pos1, ":player_agent"),
        
        (set_fixed_point_multiplier, 1),
        (get_angle_between_positions, ":angle", pos10, pos1),
        
        (init_position, pos1),
        (position_rotate_z, pos1, ":angle"),
        
        (overlay_set_display, "$g_multiplayer_compass", 1),
        (overlay_set_mesh_rotation, "$g_multiplayer_compass", pos1),
      (else_try),
        (overlay_set_display, "$g_multiplayer_compass", 0),
      (try_end),


This is what happens in-game


dunde said:
camera position will be better choice than agent_look_position, in case player use custom camera.
Thanks for the tip, might come in handy when it works.
 
What if you got the player's position, rather than their look position. Then take the player's rotation around Z and subtract the angle between the player's position and the target position and set that as the rotation for the overlay?

I can't tell if I'm thinking this through well or not...
 
Somebody said:
You might want to get the position of an in-game object instead of arbitrarily defining a point. Also, what did you set the point multiplier to before setting pos10?
I can try with the spawn point of Team 1. Any way to obtain it?

Somebody said:
Also, how is the presentation run in the mission template?

Code:
multiplayer_compass = (
  ti_battle_window_opened, 0, 0, [], [
    (start_presentation, "prsnt_multiplayer_compass"),
    ]) 

Which is then used at the end of the Deathmatch mission template, right after [font=consolas,fixedsys]multiplayer_once_at_the_first_frame[/font]


Caba`drin said:
What if you got the player's position, rather than their look position. Then take the player's rotation around Z and subtract the angle between the player's position and the target position and set that as the rotation for the overlay?

I can't tell if I'm thinking this through well or not...

I'm going to try that.
 
That not only makes sense but it works perfectly. At least as far as a quick test can reveal:


Don't mind my buddies on TS, they're trying out Barfight :razz:
 
And this is the SP version :
Code:
# Compass
("compass", prsntf_read_only|prsntf_manual_end_only, 0, [
    (ti_on_presentation_load, [
      (set_fixed_point_multiplier, 1000),
      (create_mesh_overlay, "$compass", "mesh_compass"),
      (position_set_x, pos1, 50),
      (position_set_y, pos1, 50),
      (overlay_set_position, "$compass", pos1),
      (position_set_x, pos1, 500),
      (position_set_y, pos1, 500),
      (overlay_set_size, "$compass", pos1),      
      (presentation_set_duration, 999999),
      ]),
    (ti_on_presentation_run, 
    [(try_begin),
        (eq, "$compass_active", 1),
        (set_fixed_point_multiplier, 1),
        (mission_cam_get_position, pos1),                  #Or camera view; pick whichever you prefer 
        (init_position, pos2),        
        (try_begin),
           (eq, "$compass_3d", 1),
           (position_get_rotation_around_x, ":angle", pos1),
           (store_sub, ":angle", -90, ":angle"),
           (try_begin),
              (gt, ":angle", 360),
              (val_mod, ":angle", 360),
           (else_try),
              (lt, ":angle", -360),
              (val_abs, ":angle"),
              (val_mod, ":angle", 360),
              (val_mul, ":angle", -1),
           (try_end),
           (try_begin),
              (is_between, ":angle", 180, 361),
              (val_sub, ":angle", 360),
           (try_end),   
          (val_clamp, ":angle", -90, 1),     
          (position_rotate_x, pos2, ":angle"),         
        (try_end),
        (position_get_rotation_around_z, ":angle", pos1),
        (val_mul, ":angle", -1),     
        (position_rotate_z, pos2, ":angle"),                 
        (overlay_set_mesh_rotation, "$compass", pos2),
     (else_try),
        (presentation_set_duration, 0),     
     (try_end), ]),
    ]),

Code:
# 2D/3D Compass begin
compass_init = (ti_before_mission_start, 0, 0, [], [(assign,  "$compass_active", 0),])
compass_run  = (0, 0, 0, [(key_clicked, 0x2e),],   # key_c 
[(try_begin),
   (eq, "$compass_active", 0),
   (assign,  "$compass_active", 1),   
   (start_presentation, "prsnt_compass"),
 (else_try),
   (assign,  "$compass_active", 0),
 (try_end),  ])

compas_3d    = (0, 0, 0, [(key_clicked, 0x2f),],  # key_v
[(try_begin),
   (eq, "$compass_3d", 0),
   (assign, "$compass_3d", 1),   
   (start_presentation, "prsnt_compass"),
 (else_try),
   (assign, "$compass_3d", 0), 
 (try_end),  ])  
# 2D/3D Compass end

Code:
   compass_init, compass_run, compass_3d,

Press C : Toggle Compass On/Off
Press V : Toggle Compass 3D/2D
 
Back
Top Bottom