OSP Code Driven Cart OSP

Users who are viewing this thread

This is code from The Vision related to "chariot". I share it here so anyone can use it and help me to solve my problem with collision detection (the only reason why I don't put it on single player campaign of my mods).
As The Vision is SP only, then my code is, but I think it's not hard to convert it to MP code.

It needs pavise.brf of The Vision to work. The file contains meshes for the cart and it's wheels.  The meshes are based on native's cart model. I removed the wheels as separated meshes and repositioned them to simplify the transformation computations.

Code:
scene_prop_attached_left  = 3 # left wheel
scene_prop_attached_right = 4 # right wheel
scene_prop_attached_horse = 5 # horse
scene_prop_rotation       = 6 # wheel's angle

scene_prop_destroyed      = 7 # status (check if it's destroyed already)

slot_horse_cart    = 26  # agent slots to get the cart instance id form the horse
slot_horse_forward = 27  # horse's relative destination (distance and angle)
slot_horse_angle   = 28

maximum_turn_angle         = 45
maximum_forward_range      = 15

Code:
("moving_wheel_left",sokf_moveable,"wheel_left",0,[]),    
("moving_wheel_right",sokf_moveable,"wheel_right",0,[]),

# notes : cart_barriers related was my trial to attach dummy scene prop to detect collisions. If anyone has a better idea, please tell me
#("cart_barrier",sokf_moveable,0,"bobo",[]),    
    
("moving_cart",sokf_moveable|sokf_destructible,"moving_cart","bo_moving_cart",
 [(ti_on_init_scene_prop, 
   [(set_fixed_point_multiplier, 100),
    (store_trigger_param_1, ":instance_no"),        
    (prop_instance_get_position, pos1, ":instance_no"),    
    (set_spawn_position, pos1),
    (spawn_scene_prop, "spr_moving_wheel_left"),
    (assign, ":wheel_left", reg0),
    (spawn_scene_prop, "spr_moving_wheel_right"),
    (assign, ":wheel_right", reg0),
    
    #(copy_position, pos3, pos1), (copy_position, pos2, pos1),
    #(position_move_x, pos3, 150, 0), (position_move_x, pos2, -150, 0),
    #(set_spawn_position, pos3), (spawn_scene_prop, "spr_cart_barrier"),
    #(assign, ":phy_right", reg0),
    #(set_spawn_position, pos2), (spawn_scene_prop, "spr_cart_barrier"),
    #(assign, ":phy_left", reg0),
    
    (scene_prop_set_slot,":instance_no", scene_prop_attached_left,  ":wheel_left"),
    (scene_prop_set_slot,":instance_no", scene_prop_attached_right, ":wheel_right"),
    
    #(scene_prop_set_slot,":instance_no", scene_prop_phy_left,  ":phy_left"),
    #(scene_prop_set_slot,":instance_no", scene_prop_phy_right, ":phy_right"),
    
    (scene_prop_set_slot, ":wheel_left", scene_prop_rotation, 0),
    (scene_prop_set_slot, ":wheel_right",scene_prop_rotation, 0),
    (assign, ":horse", reg1),    
    (try_begin),
       (ge, ":horse", 0),
       (position_move_z, pos1, -72,0),
       (position_move_y, pos1, 239,0),
       (set_spawn_position, pos1),
       (spawn_horse, ":horse"),
       (scene_prop_set_slot, ":instance_no",scene_prop_attached_horse, reg0),
       (agent_set_slot, reg0, slot_horse_cart, ":instance_no"),
    (else_try),
       (scene_prop_set_slot, ":instance_no",scene_prop_attached_horse, -1),
    (try_end),    
    ]),
  (ti_on_scene_prop_destroy,
   [(store_trigger_param_1, ":instance_no"),      
    (store_trigger_param_2, ":attacker_agent_no"),
    (set_fixed_point_multiplier, 100),
    (prop_instance_get_position, pos1, ":instance_no"),
    (play_sound_at_position,"snd_dummy_destroyed", pos1),
    (assign, ":rotate_side", 86),
    (try_begin),
      (ge, ":attacker_agent_no", 0),
      (agent_get_position, pos2, ":attacker_agent_no"),
      (try_begin),
         (position_is_behind_position, pos2, pos1),
         (val_mul, ":rotate_side", -1),
      (try_end),
    (try_end), 
    (init_position, pos3),
    (try_begin),
       (ge, ":rotate_side", 0),
       (position_move_y, pos3, -100),
    (else_try),
       (position_move_y, pos3, 100),
    (try_end),
    (position_move_x, pos3, -50),
    (position_transform_position_to_parent, pos4, pos1, pos3),
    (position_move_z, pos4, 100),
    (position_get_distance_to_ground_level, ":height_to_terrain", pos4),
    (val_sub, ":height_to_terrain", 100),
    (assign, ":z_difference", ":height_to_terrain"),
    (val_div, ":z_difference", 3),
    (try_begin),
      (ge, ":rotate_side", 0),
      (val_add, ":rotate_side", ":z_difference"),
    (else_try),
      (val_sub, ":rotate_side", ":z_difference"),
    (try_end),
    (position_rotate_x, pos1, ":rotate_side"),
    (prop_instance_animate_to_position, ":instance_no", pos1, 70),  ]),#animate to position 1 in 0.7 second
  (ti_on_scene_prop_hit,
   [(play_sound_at_position,"snd_dummy_hit", pos1),
    (particle_system_burst, "psys_dummy_smoke", pos1, 3),
    (particle_system_burst, "psys_dummy_straw", pos1, 10), ]), ]), 
   
Code:
delay_for_spawn = 0.2

# MST03c. Moving Cart  

# Key reading to control
cart_control = (0.1, 0, 0, 
 [(neg|main_hero_fallen), (ge, "$player_cart", 0), (assign, ":cart_command", 0),
  (try_begin),
     (key_is_down, "$key_cart_right"), (assign, ":cart_command", 3), # Turn Right
  (else_try),   
     (key_is_down, "$key_cart_left"), (assign, ":cart_command", 4), # Turn Left
  (else_try),   
     (key_is_down,  "$key_cart_forward"), (assign, ":cart_command", 1), # Accelerate
  (else_try),   
     (key_is_down,  "$key_cart_brake"), (assign, ":cart_command", 2), # Deccelerate
  (try_end),
  (scene_prop_get_slot, ":horse",  "$player_cart", scene_prop_attached_horse),
  (call_script, "script_control_cart_horse", ":cart_command", ":horse"),],  [])

# Safety, clear the global var first  
cart_init = (ti_before_mission_start, 0, 0, [], [(assign, "$player_cart", -1),])  

# if player has itm_cart, then deploy it
cart_spawn = (0, delay_for_spawn, ti_once, 
   [(player_has_item, itm_cart),(call_script, "script_deploy_cart", -1, itm_hunter),], [])
   
# Scanning   
cart_scan  = (0.1, 0, 0,  [(call_script, "script_cart_scan"),], []) 
carts = [cart_init,cart_spawn, cart_control, cart_scan]
Code:
] + carts, ),
   
Code:
# Deploy the cart. If agent=-1 then use entry point o position that usually is player initial position.
("deploy_cart",
 [(store_script_param, ":agent_no", 1),  
  (store_script_param, ":horse", 2),  
  (set_fixed_point_multiplier, 100),
  (try_begin),
    (ge, ":agent_no", 0),  
    (agent_get_position, pos2, ":agent_no"),
  (else_try),
    (entry_point_get_position, pos2, 0), 
  (try_end),  
  (position_move_y, pos2, 75, 0),
  (position_move_z, pos2, 72, 0),
  (set_spawn_position, pos2),
  (assign, reg1, ":horse"), 
  (spawn_scene_prop, "spr_moving_cart"),  ]),
  
("cart_scan",
 [(set_fixed_point_multiplier, 100),
  (get_player_agent_no, ":player_agent"),
  (try_begin), # If we have a cart already, check if it's valid
    (ge, "$player_cart", 0),
    (prop_instance_is_valid, "$player_cart"),
    (try_begin), # If we still on it?
      (neg|scene_prop_has_agent_on_it, "$player_cart", ":player_agent"),
      (assign, "$player_cart", -1),
    (try_end),
  (else_try),
    (assign, "$player_cart", -1),
  (try_end),  
  (scene_prop_get_num_instances, ":num_of_props", "spr_moving_cart"), 
  (try_for_range, ":props_no", 0, ":num_of_props"), # Multiple Cart? Why not. If only we have good collisions detection among them
    (scene_prop_get_instance, ":cart", "spr_moving_cart", ":props_no"),
    (try_begin),      
      (scene_prop_has_agent_on_it, ":cart", ":player_agent"), 
      (assign, "$player_cart", ":cart"),
    (try_end),  
    (scene_prop_get_slot, ":horse", ":cart", scene_prop_attached_horse),      # get the horse 
    (scene_prop_get_slot, ":wheel_left",  ":cart", scene_prop_attached_left), # get the wheels
    (scene_prop_get_slot, ":wheel_right", ":cart", scene_prop_attached_right),
    
    #(scene_prop_get_slot, ":phy_right", ":cart", scene_prop_phy_right),      # get dummy spr to detect collision (?)
    #(scene_prop_get_slot, ":phy_left", ":cart", scene_prop_phy_left),
    
    (try_begin),
      (ge, ":horse", 0),          # validating the horse is alive
      (agent_is_alive, ":horse"),
      (prop_instance_get_position, pos5, ":cart"), (agent_get_position, pos2, ":horse"),
     
      #(try_begin),
      #   (prop_instance_intersects_with_prop_instance,  ":phy_right", -1),
      #   (display_message, "@right"),
      #   (prop_instance_get_position, pos1, ":wheel_left"),
      #   (prop_instance_get_position, pos2, ":wheel_right"),
      #   (prop_instance_get_position, pos3, ":wheel_left"),
      #   (prop_instance_get_position, pos4, ":phy_right"),
      #   (position_move_x, pos1, -10), (position_move_x, pos2, -10), (position_move_x, pos3, -10), (position_move_x, pos4, -10), (position_move_x, pos5, -10),
      #   (prop_instance_set_position,  ":wheel_left", pos1),
      #   (prop_instance_set_position,  ":wheel_right", pos2),
      #   (prop_instance_set_position,  ":phy_left", pos3),
      #   (prop_instance_set_position,  ":phy_right", pos4),
      #   (prop_instance_set_position,  ":cart", pos5),
      #(else_try),
      #   (prop_instance_intersects_with_prop_instance,  ":phy_left", -1),
      #   (display_message, "@left"),
      #   (prop_instance_get_position, pos1, ":wheel_left"),
      #   (prop_instance_get_position, pos2, ":wheel_right"),
      #   (prop_instance_get_position, pos3, ":wheel_left"),
      #   (prop_instance_get_position, pos4, ":phy_right"),
      #   (position_move_x, pos1, 10), (position_move_x, pos2, 10), (position_move_x, pos3, 10), (position_move_x, pos4, 10), (position_move_x, pos5, 10),
      #   (prop_instance_set_position,  ":wheel_left", pos1),
      #   (prop_instance_set_position,  ":wheel_right", pos2),
      #   (prop_instance_set_position,  ":phy_left", pos3),
      #   (prop_instance_set_position,  ":phy_right", pos4),
      #   (prop_instance_set_position,  ":cart", pos5),
      #(try_end),    
      
      # terrain adjustments
      (position_get_distance_to_terrain, ":horse_level", pos2),
      (copy_position, pos3, pos2),        
      (position_move_y, pos3, -239,0),
      (position_move_x, pos3, 100,0),
      (position_get_distance_to_terrain, ":right_level", pos3),
      (position_move_x, pos3, -200,0),
      (position_get_distance_to_terrain, ":left_level", pos3),
      (store_add, ":average", ":right_level", ":left_level"),
      (val_div,  ":average", 2), (val_sub, ":average", ":horse_level"), (val_mul, ":average", 25),
      (store_sub, ":different", ":right_level", ":left_level"), (val_mul, ":different", 25),
      (copy_position, pos1, pos2),
      (position_rotate_x_floating, pos1,":average"),
      (position_rotate_y_floating, pos1,":different"),
      (position_move_y, pos1, -239,0),
      (position_move_z, pos1, 72,0),
      (position_get_rotation_around_z, ":speedx", pos1),     
      (position_get_rotation_around_z, ":angle", pos5),     
      (val_sub, ":speedx", ":angle"),
      (val_clamp, ":speedx", -100, 101),
      (agent_get_speed, pos3, ":horse"),
      (position_get_y, ":speedy", pos3),
      (copy_position, pos2, pos1),
      (copy_position, pos4, pos1),
      (scene_prop_get_slot, ":rotation_left", ":wheel_left",   scene_prop_rotation),
      (scene_prop_get_slot, ":rotation_right", ":wheel_right", scene_prop_rotation),    
    
      # wheels rotaring adjustments
      (try_begin),
        (assign, ":stop", 0),
        (try_begin),
          (eq, ":speedx", 0), (is_between, ":speedy", -20, 21),
          (assign, ":stop", 1),          
        (try_end),
        (eq, ":stop", 0),
        (val_div, ":speedy", 20),
        (val_sub, ":rotation_left", ":speedy"), (val_sub, ":rotation_right", ":speedy"),
        (val_add, ":rotation_left", ":speedx"), (val_sub, ":rotation_right",  ":speedx"),
        (val_mod, ":rotation_left", 36000), (val_mod, ":rotation_right", 36000),       
        (scene_prop_set_slot, ":wheel_left",  scene_prop_rotation, ":rotation_left"),
        (scene_prop_set_slot, ":wheel_right", scene_prop_rotation, ":rotation_right"),       
      (try_end),   
      (position_rotate_x, pos2, ":rotation_left"), (position_rotate_x, pos4, ":rotation_right"),
    
      #(copy_position, pos3, pos1), (copy_position, pos5, pos1),
      #(position_move_x, pos3, 150, 0), (position_move_x, pos5, -150, 0),
      
      # Executing the following the horse animation
      (prop_instance_animate_to_position, ":cart",  pos1, 12),
    
      #(prop_instance_animate_to_position, ":phy_left",  pos5, 12),
      #(prop_instance_animate_to_position, ":phy_right",  pos3, 12),
    
      (prop_instance_animate_to_position, ":wheel_left",  pos2, 12),
      (prop_instance_animate_to_position, ":wheel_right", pos4, 12),
    (try_end),
  (try_end), ]),  
 
("control_cart_horse",
 [(store_script_param, ":command", 1),
  (store_script_param, ":horse", 2),
  (agent_get_slot, ":forward", ":horse", slot_horse_forward),
  (agent_get_slot, ":angle", ":horse", slot_horse_angle),
  (try_begin),
    (eq, ":command", 0),
    (val_sub, ":forward", 5),
    (assign, ":angle", 0),
  (else_try),
    (eq, ":command", 1), (val_add, ":forward", 100),
  (else_try),
    (eq, ":command", 2), (val_sub, ":forward", 100),
  (else_try),   
    (eq, ":command", 3), (val_sub, ":angle", 5),
  (else_try),   
    (eq, ":command", 4), (val_add, ":angle", 5),     
  (try_end),
  (val_clamp, ":forward", 0, maximum_forward_range*100),
  (val_clamp, ":angle", -maximum_turn_angle, maximum_turn_angle + 1),
  (agent_set_slot, ":horse", slot_horse_forward, ":forward"),
  (agent_set_slot, ":horse", slot_horse_angle, ":angle"),
  (set_fixed_point_multiplier, 100),
  (agent_get_position, pos1, ":horse"),
  (position_rotate_z, pos1, ":angle"),
  (position_move_y, pos1, ":forward"),
  (agent_set_scripted_destination, ":horse", pos1, 1), ]),
 
Code:
["items_end", "Items End", [("shield_round_a",0)], 0, 0, 1, 0, 0],
# LIMIT VALID ITEM ###############################################################################
# I put it below items_end so it will never be on marketplace, so it should be given to player via script
["cart","Carts", [("cart",0)], itp_type_goods, 0, 410,weight(200)|abundance(1),imodbits_none],
 

Edit1 : Adding missing constants (maximum_turn_angle & maximum_forward_range) at module_constants.py
Edit2 : Adding missing constant (delay_for_spawn) at module_mission_templates.py
 
I have a collision script (with detection w/ group, agents, and scene props) for a cannon. It was one of my favorite pieces of scripts, but was rendered useless by WSE and the new 1.154 missile operation :grin:. Oh well.

So I thought I would share it here to see if it would be useful for you.

Code:
			(scene_prop_get_instance, ":instance", "spr_cannon", ":prop_no"),
			(scene_prop_slot_eq,":instance",scene_prop_active,1),
			(assign, ":explode", 0),
			(prop_instance_get_position, pos5, ":instance"), # pos5 - to-be pos 
			(copy_position, pos6, pos5), # pos6 - inital
			(copy_position, pos8, pos5), # pos8 - collison check
			(scene_prop_get_slot,":dx",":instance",scene_prop_x_vel),
			(scene_prop_get_slot,":dy",":instance",scene_prop_y_vel),
			(scene_prop_get_slot,":dz",":instance",scene_prop_z_vel),
			(scene_prop_get_slot,":shooter",":instance",scene_prop_shooter),			
			(store_div, ":s_dx",":dx", 250),
			(store_div, ":s_dy",":dy", 250),
			(store_div, ":s_dz",":dz", 250),
			(position_move_x,pos8,":s_dx",1),
			(position_move_y,pos8,":s_dy",1),
			(position_move_z,pos8,":s_dz",1),
			(try_begin), # No line of sight => Explode #
				(neg|position_has_line_of_sight_to_position, pos6, pos8),
				(assign, ":explode", 1),
			(else_try),  # Hit terrian => Explode #
				(position_get_distance_to_terrain, ":distance", pos6),
				(store_mul,":neg_s_dy",-1,":s_dy"),
				(ge, ":neg_s_dy", ":distance"),
				(assign, ":explode", 1),
			(else_try),  # Hit agent => Explode #
				(try_for_agents,":a"), # Agents
					(agent_is_alive,":a"),
					(neg|eq, ":shooter", ":a"), # Disclude Shooter
					(agent_get_horse,":horse",":shooter"),
					(neg|eq, ":horse", ":a"), # Disclude Shooter's Horse
					(agent_get_position,pos9,":a"),
					(get_distance_between_positions_in_meters,":distance_m",pos9,pos8),
					(lt, ":distance_m", 3), # Optimization, only have agent collision detection if agent is close-by 
					(position_transform_position_to_local, pos10, pos9, pos8),
					(try_begin), # Humans
						(agent_is_human, ":a"),
						(try_begin), # Dismounted
							(eq, ":horse", -1),
							(position_get_x,":x_ori",pos10),
							(is_between,":x_ori",-70,70),
							(position_get_z,":z_ori",pos10),	
							(is_between,":z_ori",0,180),	
							(position_get_y,":y_ori",pos10),
							(is_between,":y_ori",-40,40),						
							(assign, ":explode", 1),
						(else_try), # Mounted
							(position_get_x,":x_ori",pos10),
							(is_between,":x_ori",-70,70),
							(position_get_z,":z_ori",pos10),	
							(is_between,":z_ori",180,280),	
							(position_get_y,":y_ori",pos10),
							(is_between,":y_ori",-40,40),				
							(assign, ":explode", 1),
						(try_end),
					(else_try), # Horse (body)
						(position_get_x,":x_ori",pos10),
						(is_between,":x_ori",-70,70),
						(position_get_z,":z_ori",pos10),	
						(is_between,":z_ori",50,180),	
						(position_get_y,":y_ori",pos10),
						(is_between,":y_ori",-170,170),						
						(assign, ":explode", 1),
					(try_end), 
				(try_end),
			(try_end),
 
Back
Top Bottom