Designing a simple motion script [with video]

Users who are viewing this thread

EDIT:
What I've got so far
http://www.youtube.com/watch?v=McpxtSXAKnU
There's bug with the turret movement and it kind of shifts from left to right, but other than that things are working pretty well. (it also follows the slope of the ground, but you can't really see it in the vid since it's so flat.)

(tank model wasn't mine, from http://www.crazy3dsmax.com/).

Full Tank Part,
Code:
		(0, 0, 0, [(key_clicked, key_spawn_elemate),],[
		(get_player_agent_no, ":p_agent"),
		(agent_get_position, pos0, ":p_agent"),
		(position_move_y, pos0, 500),
		(position_set_z, pos0, 10000),
		(position_set_z_to_ground_level, pos0),							
		# Rotate y
		(position_get_rotation_around_y,":tilt", pos0),
		(val_mul, ":tilt", -1),
		(position_rotate_y, pos0, ":tilt"),
		# Rotate y
		## Get spawn position
		(set_spawn_position, pos0),				
		(spawn_scene_prop, "spr_tank_body"),
		(assign, ":instance", reg0),
		(assign, "$elemate", ":instance"),
		(call_script, "script_initialize_scene_prop_dynamics", ":instance", 0),
		(call_script, "script_set_scene_prop_abs_pos", ":instance"),
		(scene_prop_set_slot,":instance",scene_prop_set_z_ground,1),
		(scene_prop_set_slot,":instance",scene_prop_follow_slope,2),
		(scene_prop_set_slot,":instance",scene_prop_length,200),
		(scene_prop_set_slot,":instance",scene_prop_width,100),
		(position_move_z, pos0, 65, 1),
		(position_move_y, pos0, 15),
		(set_spawn_position, pos0),
		(spawn_scene_prop, "spr_turret"),
		(assign, ":instance", reg0),
		(assign, "$child", ":instance"),
		(call_script, "script_initialize_scene_prop_dynamics", ":instance", "$elemate"),
		(call_script, "script_set_scene_prop_abs_pos", ":instance"),
		#(assign, "$spawned", 1),
		(mission_cam_set_mode, 1),
		(mission_cam_set_position, pos0),
		]),
		(0, 0, 0, [],[
		(try_begin),## Cam Position ##
			(gt, "$elemate", 0),			
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", "$elemate"),
			(position_move_z, pos0, 200, 1),
			(position_move_y, pos0, -500),
			(position_rotate_x, pos0, -10),
			(mission_cam_set_position, pos0),
		(try_end),
		(try_begin),
			(gt, "$child", 0),
			(get_player_agent_no, ":p_agent"),
			(agent_get_look_position, pos0, ":p_agent"),
			(position_get_rotation_around_z, ":rot_z", pos0),
			(scene_prop_set_slot, "$child", scene_prop_rel_rot_z, ":rot_z"),
		(try_end),
		(try_begin),## Forward/Backward , Left/Right ##
			(gt, "$elemate", 0),
			(assign,":instance","$elemate"),
			(try_begin), 
				(key_is_down, key_elemate_forward),
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_y,5),
			(else_try),	
				(key_is_down, key_elemate_backward),
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_y,-5),
			(else_try),	
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_y,0),
			(try_end),	
		(try_end), ## Forward/Backward , Left/Right ##	
		(try_begin),
			(key_is_down, key_elemate_left),
			(gt, "$elemate", 0),
			(assign,":instance","$elemate"),
			(call_script, "script_rot_scene_prop_group_z", ":instance", 1),
		(try_end),	
		(try_begin),
			(key_is_down, key_elemate_right),
			(gt, "$elemate", 0),
			(assign,":instance","$elemate"),
			(call_script, "script_rot_scene_prop_group_z", ":instance", -1),
		(try_end), ## Forward/Backward , Left/Right ##
		]),

Needs the workhorse script,
Module Constants, which are the properties of the scene props.
Code:
scene_prop_slots 				= 0
scene_prop_enable_jl_dynamics	= 1   # enable = 1, disable = 0
scene_prop_parent 				= 2   # no parent (is parent itself) = -1, else = parent_id

scene_prop_abs_pos_x 			= 3   # absolute position determines movement
scene_prop_abs_pos_y 			= 4	  # ie, position_move_y uses the position of the prop's absolute position
scene_prop_abs_pos_z 			= 5			
scene_prop_abs_rot_x 			= 6			
scene_prop_abs_rot_y 			= 7			
scene_prop_abs_rot_z			= 8

scene_prop_rel_pos_x 			= 9	  # relative position are rendered for display only
scene_prop_rel_pos_y 			= 10  # they do NOT affect movement
scene_prop_rel_pos_z 			= 11			
scene_prop_rel_rot_x 			= 12
scene_prop_rel_rot_y 			= 13
scene_prop_rel_rot_z 			= 14

scene_prop_set_z_ground 		= 15  # always stick to ground (if enabled, disables gravity and vel_abs_z), = offset z - 1 (cm)
scene_prop_follow_slope			= 16  # follow slope only in y direction = 1, in both y and x direction = 2, none = 0
scene_prop_length 				= 17  # length and width only required if scene_prop_follow_slope is enabled
scene_prop_width 				= 18

scene_prop_gravity 				= 19  # no gravity = 0, else = gravity (in cm s-2)
scene_prop_vel_abs_z 			= 20  # speed downwards
scene_prop_vel_abs_y 			= 21  # speed forwards

scene_prop_is_wheel 			= 22
scene_prop_radius 				= 23
scene_prop_rel_ome_x			= 24  # relative angular velocity

# Used for calculations - Do not set #
scene_prop_group = 30

# Constants for iterations #
scene_prop_dynamics_start = 1
scene_prop_dynamics_end = 24
scene_prop_group_limit = 500
scene_prop_group_size_limit = 50

Mission Templates, which does a order of calculations every frame. (i might change it to once every 1/30 of a second or something....)
The order of calculation is like this:
first, all parents are calculated first (this is done by the ordering of the arrays, thus, you should always initialize a "parent" before a "child" as a scene prop).
Then operations that change absolute position, ie velocity is calculated first.
Then operations that change other properties are calculated (ie gravity that changes velocity, wheel rotate determination, that changes omega).
Then after the "absolute" positions (ones that affect motion) are calculated, and the properties are changed, the "relative" position (ones that only have visual effects) are calculated. First, the parents movements are copied. Then, the object's own relative changes are done. Lastly the position is changed.
Code:
		(ti_before_mission_start, 0, ti_once, [], [
			(set_spawn_radius, 0), # make array for groups
			(spawn_around_party, 1, "pt_none"),
			(assign, "$dyn_groups", reg0),
			(try_for_range,":array_index",0,scene_prop_group_limit), # initialize array
				(party_set_slot,"$dyn_groups",":array_index",-1),
			(try_end),
			(assign, "$elemate", 0),
		]),
		(0, 0, 0, [],[
		(assign, ":end", scene_prop_group_limit),
		(try_for_range,":array_index",0,":end"), # try for all groups
			(assign, reg0, ":array_index"),
			#(display_debug_message, "@{reg0}"),
			(party_get_slot,":group","$dyn_groups",":array_index"),
			(try_begin),
				(eq, ":group", -1),
				(assign, ":end", ":array_index"),	
			(try_end),
			(neg|eq, ":group", -1),
			(assign, ":sub_end", 30),
			(try_for_range,":sub_array_index",0,":sub_end"), # try for group members		
				(party_get_slot,":instance",":group",":sub_array_index"),
				(try_begin),
					(eq, ":instance", -1),
					(assign, ":end", ":sub_array_index"),	
				(try_end),	
				(neg|eq, ":instance", -1),
				(scene_prop_get_slot,":enable",":instance",scene_prop_enable_jl_dynamics),
				(scene_prop_get_slot,":parent",":instance",scene_prop_parent),
				(ge, ":enable", 1),
				###########################################
				# Parent conditions that change abs value #
				###########################################
				(try_begin), #parent only conditions
					(eq, ":parent", -1),
					#(display_debug_message, "@is parent(abs)"),
					(try_begin), #try involving abs positions
						(scene_prop_get_slot,":vel_abs_z",":instance",scene_prop_vel_abs_z),	
						(scene_prop_get_slot,":enable",":instance",scene_prop_set_z_ground),
						(eq, ":enable", 0),
						(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),
						(position_get_distance_to_ground_level, ":distance", pos0),
						(store_mul,":neg_vel_abs_z",-1,":vel_abs_z"),
						(try_begin),
							(ge, ":neg_vel_abs_z", ":distance"), ##### NEED FIX ########
							(position_set_z_to_ground_level, pos0),
							(position_get_z, ":z", pos0),
							(call_script, "script_set_scene_prop_group_abs_z", ":instance", ":z"),				
						(else_try),
							(call_script, "script_move_scene_prop_group_abs_z", ":instance", ":vel_abs_z"),	
						(try_end),
					(end_try),
					(try_begin), 
						(scene_prop_get_slot,":vel_abs_y",":instance",scene_prop_vel_abs_y),	
						(call_script, "script_move_scene_prop_group_abs_y", ":instance", ":vel_abs_y"),						
					(end_try),
					(try_begin),
						(scene_prop_get_slot,":gravity",":instance",scene_prop_gravity), #### Needs to be MOVED ####
						(neg|eq, ":gravity", 0),		
						(scene_prop_get_slot,":vel_abs_z",":instance",scene_prop_vel_abs_z),
						(val_sub, ":vel_abs_z", ":gravity"),
						(scene_prop_set_slot,":instance",scene_prop_vel_abs_z,":vel_abs_z"),						
					(end_try),
					(try_begin), 
						(scene_prop_get_slot,":value",":instance",scene_prop_set_z_ground),
						(ge, ":value", 1),
						(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),	
						#(position_set_z, pos0, 10000),
						(position_get_distance_to_terrain, ":distance", pos0),
						(val_mul, ":distance", -1),
						(val_sub, ":value", 1),
						(val_add, ":distance", ":value"),
						(call_script, "script_move_scene_prop_group_abs_z", ":instance", ":distance"),
					(end_try),#try involving abs positions
				(end_try), #parent only conditions
				###########################################
				# Conditions that change other properties #
				###########################################		
				(try_begin), # Rotation
					(scene_prop_get_slot,":omega_x",":instance",scene_prop_rel_ome_x), 	
					(scene_prop_get_slot,":rel_rot_x",":instance",scene_prop_rel_rot_x),
					(val_add, ":rel_rot_x", ":omega_x"),
					(scene_prop_set_slot,":instance",scene_prop_rel_rot_x,":rel_rot_x"),						
				(end_try), # Rotation		 		
				(try_begin), # Wheel Rotation Speed determination
					(scene_prop_get_slot,":is_wheel",":instance",scene_prop_is_wheel),
					(eq, ":is_wheel", 1),
					(call_script, "script_scene_prop_get_master", ":instance"),
					(assign, ":master", reg0),
					(scene_prop_get_slot,":parent_v_y",":master",scene_prop_vel_abs_y),
					(scene_prop_get_slot,":radius_pi",":instance",scene_prop_radius),
					(val_mul, ":radius_pi", PI),
					(store_div, ":omega", 20000, ":radius_pi"),
					(val_mul, ":omega", ":parent_v_y"),
					(val_mul, ":omega", -1),
					(scene_prop_set_slot,":instance",scene_prop_rel_ome_x,":omega"),
				(end_try), # Wheel Rotation 
				################
				# START RENDER #
				################
				# pos30 is final position #
				(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),
				(copy_position, pos30, pos0),
				################################
				# Step 1: Render Slopes etc... #
				################################
				(try_begin), # parent-only renders
					(eq, ":parent", -1),
					#(display_debug_message, "@is parent(slope)"),
					(try_begin), 
						(scene_prop_get_slot,":slope_trigger",":instance",scene_prop_follow_slope),
						(ge, ":slope_trigger", 1),
						(scene_prop_get_slot,":length",":instance",scene_prop_length),
						(call_script, "script_get_slope_y_pos0", ":length"),
						(assign, ":slope_y", reg0),
						(position_rotate_x, pos30, ":slope_y"),			
						(try_begin),	
							(ge, ":slope_trigger", 2),
							(scene_prop_get_slot,":width",":instance",scene_prop_width),
							(call_script, "script_get_slope_x_pos0", ":width"),
							(assign, ":slope_x", reg0),
							(position_rotate_y, pos30, ":slope_x"),		
						(try_end),
					(try_end),
				(try_end), # parent-only renders
				################################
				# Step 2: Copy Parent's render #
				################################
				(try_begin), # child-only 
					(neg|eq, ":parent", -1),	
					(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":parent"),
					(copy_position, pos1, pos0), # pos 1: parent abs pos
					(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),
					(copy_position, pos2, pos0), # pos2: child abs pos		
					(position_transform_position_to_local, pos3, pos1, pos2), # pos 3: child in terms of parent
					(prop_instance_get_position, pos4, ":parent"), # pos4: parent rendered pos
					(position_transform_position_to_parent, pos30, pos4, pos3), #pos30: final							
				(try_end), # child-only				
				######################################
				# Step 3: Add oneself's rel. renders #
				######################################
				(scene_prop_get_slot,":rel_x",":instance",scene_prop_rel_pos_x),
				(scene_prop_get_slot,":rel_y",":instance",scene_prop_rel_pos_y),
				(scene_prop_get_slot,":rel_z",":instance",scene_prop_rel_pos_z),
				(scene_prop_get_slot,":rel_rot_x",":instance",scene_prop_rel_rot_x),
				(scene_prop_get_slot,":rel_rot_y",":instance",scene_prop_rel_rot_y),
				(position_move_x, pos30, ":rel_x"),
				(position_move_y, pos30, ":rel_y"),
				(position_move_z, pos30, ":rel_z"),
				(position_rotate_x, pos30, ":rel_rot_x"),
				(position_rotate_y, pos30, ":rel_rot_y"),
				# END RENDER #
				(prop_instance_set_position, ":instance", pos30),
				#(display_message, "@work"),
			(try_end),	# try for group members	 
		(try_end), # try for all groups
		]),

Here are the scripts,
every time a new scene prop is initialized to have dynamics, it will be allocated automatically into it's parent array, or if it is a top-level-parent itself, a new array will be created.
Code:
("get_slope_y_pos0",
	[
		# pos0 is position passed in from caller
		(store_script_param_1,":dimension"), 
		(copy_position,pos60,pos0),
		(store_div, ":half_dimension",":dimension", 2),
		(store_mul, ":neg_dimension",":dimension", -1),
		(position_get_rotation_around_z,":z_rot",pos60),
		(init_position, pos1),
		(position_copy_rotation,pos60,pos1),
		(position_rotate_z,pos60,":z_rot"),
		(position_move_y,pos60,":half_dimension"),
		(position_set_z,pos60,10000),
		(position_get_distance_to_terrain, ":d1", pos60), 
		(position_move_y,pos60,":neg_dimension"),
		(position_get_distance_to_terrain, ":d2", pos60),
		(assign, reg20, ":d1"),
		(assign, reg21, ":d2"),	
		(store_sub, ":delta_d", ":d2", ":d1"),
		(store_atan2, ":slope", ":delta_d", ":dimension"),
		(val_div, ":slope", 100),
		(assign, reg0, ":slope"),
	]),
	("get_slope_x_pos0",
	[
		# pos0 is position passed in from caller
		(store_script_param_1,":dimension"), 
		(copy_position,pos60,pos0),
		(store_div, ":half_dimension",":dimension", 2),
		(store_mul, ":neg_dimension",":dimension", -1),
		(position_get_rotation_around_z,":z_rot",pos60),
		(init_position, pos1),
		(position_copy_rotation,pos60,pos1),
		(position_rotate_z,pos60,":z_rot"),
		(position_move_x,pos60,":half_dimension"),
		(position_set_z,pos60,10000),
		(position_get_distance_to_terrain, ":d1", pos60), 		
		(position_move_x,pos60,":neg_dimension"),
		(position_get_distance_to_terrain, ":d2", pos60),
		(store_sub, ":delta_d", ":d1", ":d2"),
		(store_atan2, ":slope", ":delta_d", ":dimension"),
		(val_div, ":slope", 100),
		(assign, reg0, ":slope"),
	]),
	("rotate_pos2_around_pos1",
	[
		(store_script_param_1,":rot"),
		(position_transform_position_to_local, pos3, pos1, pos2),
		(position_rotate_z, pos1, ":rot"),
		(position_transform_position_to_parent, pos0, pos1, pos3),
	]),
	# Dynamics Scripts - Get Scene Prop Information
	("store_scene_prop_abs_pos_to_pos0",
	[
		(store_script_param_1,":instance"),
		(set_fixed_point_multiplier, 100),
		(init_position, pos0),
		(scene_prop_get_slot,":x",":instance",scene_prop_abs_pos_x),
		(scene_prop_get_slot,":y",":instance",scene_prop_abs_pos_y),
		(scene_prop_get_slot,":z",":instance",scene_prop_abs_pos_z),
		(scene_prop_get_slot,":rot_z",":instance",scene_prop_abs_rot_z),
		(scene_prop_get_slot,":rot_x",":instance",scene_prop_abs_rot_x),
		#(scene_prop_get_slot,":rot_x",":instance",scene_prop_abs_rot_x),
		#(scene_prop_get_slot,":rot_y",":instance",scene_prop_abs_rot_y),
		#(scene_prop_get_slot,":rot_z",":instance",scene_prop_abs_rot_z),	
		(position_set_x, pos0, ":x"),
		(position_set_y, pos0, ":y"),
		(position_set_z, pos0, ":z"),
		(position_rotate_z, pos0, ":rot_z"),
		(position_rotate_x, pos0, ":rot_x"),
	]),
	("scene_prop_get_master",
	[
		(store_script_param_1,":instance"),
		(scene_prop_get_slot,":group",":instance",scene_prop_group),	
		(party_get_slot,reg0,":group",0),
	]),	
	# Dynamics Scripts - Set Scene Prop Information
	("initialize_scene_prop_dynamics",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":parent_id"),
		(assign, reg0, ":parent_id"),
		#(display_debug_message, "@{reg0} "),
		(scene_prop_set_slot,":instance",scene_prop_enable_jl_dynamics,1),
		(try_begin),
			(gt, ":parent_id", 0), # has parent
			(scene_prop_set_slot,":instance",scene_prop_parent,":parent_id"),
			(scene_prop_get_slot,":party_id",":parent_id",scene_prop_group),
			(assign, ":stop", -1),
			(try_for_range,":array_index",0,scene_prop_group_size_limit), # find end index				
				(eq, ":stop", -1),
				(party_get_slot,":value",":party_id",":array_index"),
				(eq, ":value", -1),
				(party_set_slot, ":party_id", ":array_index", ":instance"), # replace as end					
				(assign, ":stop", 1),
			(try_end),
			#(try_for_range,":array_index",0,scene_prop_group_size_limit), # show array
			#	(party_get_slot,":value", ":party_id",":array_index"),
			#	(assign, reg0, ":value"),
			#	(display_debug_message, "@{reg0} "),
			#(try_end),
		(else_try),
			(eq, ":parent_id", 0), # no parent, ie IS parent
			(scene_prop_set_slot,":instance",scene_prop_parent,-1),
			(set_spawn_radius, 0), # make array for group
			(spawn_around_party, 1, "pt_none"),
			(assign, ":array", reg0),
			(try_for_range,":array_index",0,scene_prop_group_size_limit), # initialize array
				(party_set_slot,":array",":array_index",-1),
			(try_end),
			(scene_prop_set_slot, ":instance", scene_prop_group, ":array"),
			(party_set_slot, ":array", 0, ":instance"),
			(assign, ":end", scene_prop_group_limit),
			(try_for_range,":array_index",0,":end"), 
				(party_get_slot,":group", "$dyn_groups",":array_index"),
				(try_begin),
					(eq,":group",-1),
					(assign, ":end", ":array_index"),
					(party_set_slot, "$dyn_groups", ":array_index", ":array"),
					#(display_debug_message, "@hey, 1"),
				(try_end),				
			(try_end),	
			#(try_for_range,":array_index",0,scene_prop_group_size_limit), # show array
			#	(party_get_slot,":value","$dyn_groups",":array_index"),
			#	(assign, reg0, ":value"),
			#	(display_debug_message, "@{reg0} "),
			#(try_end),
		(try_end),		
		(try_for_range,":loop",scene_prop_dynamics_start+2,scene_prop_dynamics_end+1),
			(scene_prop_set_slot,":instance",":loop",0),		
		(try_end),
	]),
	("set_scene_prop_abs_pos",
	[
		(store_script_param_1,":instance"),
		(set_fixed_point_multiplier, 100),
		(position_get_x,":x",pos0),
		(position_get_y,":y",pos0),
		(position_get_z,":z",pos0),
		(position_get_rotation_around_x,":rot_x",pos0),
		(position_get_rotation_around_y,":rot_y",pos0),
		(position_get_rotation_around_z,":rot_z",pos0),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_x,":x"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_y,":y"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_z,":z"),
		(scene_prop_set_slot,":instance",scene_prop_abs_rot_x,":rot_x"),
		(scene_prop_set_slot,":instance",scene_prop_abs_rot_y,":rot_y"),
		(scene_prop_set_slot,":instance",scene_prop_abs_rot_z,":rot_z"),
	]),
	("set_scene_prop_group_abs_x",  ### NEEDS TO BE COMPLETED ###
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":x"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_x,":x"),
	]),
	("set_scene_prop_group_abs_y", ### NEEDS TO BE COMPLETED ###
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":y"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_y,":y"),		
	]),
	("set_scene_prop_group_abs_z", ### NEEDS TO BE COMPLETED ###
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":z"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_z,":z"),		
	]),
	# Dynamics Scripts - Move Secene Prop
	("move_scene_prop_group_abs_y",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":distance"),
		#(val_mul,":distance", 100), 
		(scene_prop_get_slot,":array",":instance",scene_prop_group),
		(assign, ":end", scene_prop_group_size_limit),
		(try_for_range,":array_index",0,":end"), # find end index				
			(try_begin),
				(party_get_slot,":prop_id",":array",":array_index"),
				(eq, ":prop_id", -1),
				(assign, ":end", ":array_index"),
			(try_end),
			(neg|eq, ":prop_id", -1),
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":prop_id"),
			(position_move_y, pos0, ":distance"),
			(call_script, "script_set_scene_prop_abs_pos", ":prop_id"),				
		(try_end),			
	]),
	("move_scene_prop_group_abs_z",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":distance"),
		#(val_mul,":distance", 100), 
		(scene_prop_get_slot,":array",":instance",scene_prop_group),
		(assign, ":end", scene_prop_group_size_limit),
		(try_for_range,":array_index",0,":end"), # find end index				
			(try_begin),
				(party_get_slot,":prop_id",":array",":array_index"),
				(eq, ":prop_id", -1),
				(assign, ":end", ":array_index"),
				#(display_debug_message, "@hey, 2"),
			(try_end),
			(neg|eq, ":prop_id", -1),
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":prop_id"),
			(position_move_z, pos0, ":distance"),
			(call_script, "script_set_scene_prop_abs_pos", ":prop_id"),				
		(try_end),					
	]),
	("rot_scene_prop_group_z",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":rot"),
		#(val_mul,":distance", 100), 
		(scene_prop_get_slot,":array",":instance",scene_prop_group),
		(party_get_slot, ":master", ":array", 0),
		(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":master"),
		(copy_position, pos1, pos0),
		(assign, ":end", scene_prop_group_size_limit),
		(try_for_range,":array_index",0,":end"), # find end index				
			(try_begin),
				(party_get_slot,":prop_id",":array",":array_index"),
				(eq, ":prop_id", -1),
				(assign, ":end", ":array_index"),
			(try_end),
			(neg|eq, ":prop_id", -1),
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":prop_id"),
			(copy_position, pos2, pos0),
			(call_script, "script_rotate_pos2_around_pos1", ":rot"),
			#(position_transform_position_to_local, pos3, pos1, pos2),
			#(position_rotate_z, pos1, ":rot"),
			#(position_transform_position_to_parent, pos0, pos1, pos3),
			(call_script, "script_set_scene_prop_abs_pos", ":prop_id"),		
			#(display_message, "@bye"),
		(try_end),		
	]),

Original Post,
I've been thinking of writing an open source, easy to use multi-piece scene prop motion engine that supports basic physics and very very basic animations. It would mainly use the scene prop slots to store various information.

After completion, I hope it could be used to build cool stuff easier, for example, a tank's puesdo-code would be like:
Tank (contains two parts, the body and the turret)
- Press spawn tank
  - Spawn Turret, Body in position
  - Set "Turret's" parent as "Body"
  - Set auto-adjust relative position to slope of terrain
- Press tank_forward/tank_backward/tank_left/tank_right
  - "Body" goes forward/ backward/ left/ right (turret follows automatically, using body's origins)
- Mouse movement
  - Rotate turret

Currently, I've defined the following slots:
Code:
scene_prop_enable_dynamics
scene_prop_parent
scene_prop_abs_pos_x
scene_prop_abs_pos_y
scene_prop_abs_pos_z
scene_prop_abs_rot_x
scene_prop_abs_rot_y
scene_prop_abs_rot_z
scene_prop_rel_pos_x
scene_prop_rel_pos_y
scene_prop_rel_pos_z
scene_prop_rel_rot_x
scene_prop_rel_rot_y
scene_prop_rel_rot_z
scene_prop_gravity
scene_prop_velocity_global_z
scene_prop_acceleration_forward
scene_prop_velocity_forward

The absolute values, are the actually position values that affect the movement of the object, ie, when the tank moves, the absolute values of the tanks and turret changes.
But when the turret moves, only the relative values of the turret moves. This way, basic animations could be made without disrupting the movement of the object.

If even more animation control is needed I might add:
Code:
scene_prop_abs_vel_x
scene_prop_abs_vel_z
scene_prop_abs_omega_x
scene_prop_abs_omega_y
scene_prop_abs_omega_z
scene_prop_abs_acc_x
scene_prop_abs_acc_z
scene_prop_abs_alpha_x # angular acceleration
scene_prop_abs_alpha_y
scene_prop_abs_alpha_z
scene_prop_rel_vel_x
scene_prop_rel_vel_y
scene_prop_rel_vel_z
scene_prop_rel_omega_x
scene_prop_rel_omega_y
scene_prop_rel_omega_z
scene_prop_rel_acc_x
scene_prop_rel_acc_y
scene_prop_rel_acc_z
scene_prop_rel_alpha_x # angular acceleration
scene_prop_rel_alpha_y
scene_prop_rel_alpha_z

Do you think such a script is useful? And the second set of slots, do you think it's needed? (personally, if someone needed such complex stuff, I'd suggest the person to use the physics engine :razz:)
Any other slots/functions are needed?
 
I actually coded something similar to what you suggest...
It is certainly doable  :smile:

Example:
http://www.youtube.com/watch?v=lPPUhpxK00g

You can't use the physics engine of warband because it is only usable in single player.
I suggest you write your own one like I did..

If your stuck somewhere just ask. Good luck.
 
Vincenzo said:
I actually coded something similar to what you suggest...
It is certainly doable  :smile:

Example:
http://www.youtube.com/watch?v=lPPUhpxK00g

You can't use the physics engine of warband because it is only usable in single player.
I suggest you write your own one like I did..

If your stuck somewhere just ask. Good luck.

:shock:
It's just.. Great!!!
 
Vincenzo said:
I actually coded something similar to what you suggest...
It is certainly doable  :smile:

Example:
http://www.youtube.com/watch?v=lPPUhpxK00g

You can't use the physics engine of warband because it is only usable in single player.
I suggest you write your own one like I did..

If your stuck somewhere just ask. Good luck.

Just... amazing!!

*hurries back to coding* :razz:
 
A standardized system would be great. We could do things like rams, moving catapults and inspirational moving objects.
 
Here's my progress so far for those who're interested:


Module Constants, which are the properties of the scene props.
Code:
scene_prop_slots 				= 0
scene_prop_enable_jl_dynamics	= 1   # enable = 1, disable = 0
scene_prop_parent 				= 2   # no parent (is parent itself) = -1, else = parent_id

scene_prop_abs_pos_x 			= 3   # absolute position determines movement
scene_prop_abs_pos_y 			= 4	  # ie, position_move_y uses the position of the prop's absolute position
scene_prop_abs_pos_z 			= 5			
scene_prop_abs_rot_x 			= 6			
scene_prop_abs_rot_y 			= 7			
scene_prop_abs_rot_z			= 8

scene_prop_rel_pos_x 			= 9	  # relative position are rendered for display only
scene_prop_rel_pos_y 			= 10  # they do NOT affect movement
scene_prop_rel_pos_z 			= 11			
scene_prop_rel_rot_x 			= 12
scene_prop_rel_rot_y 			= 13
scene_prop_rel_rot_z 			= 14

scene_prop_set_z_ground 		= 15  # always stick to ground (if enabled, disables gravity and vel_abs_z), = offset z - 1 (cm)
scene_prop_follow_slope			= 16  # follow slope only in y direction = 1, in both y and x direction = 2, none = 0
scene_prop_length 				= 17  # length and width only required if scene_prop_follow_slope is enabled
scene_prop_width 				= 18

scene_prop_gravity 				= 19  # no gravity = 0, else = gravity (in cm s-2)
scene_prop_vel_abs_z 			= 20  # speed downwards
scene_prop_vel_abs_y 			= 21  # speed forwards

scene_prop_is_wheel 			= 22
scene_prop_radius 				= 23
scene_prop_rel_ome_x			= 24  # relative angular velocity

# Used for calculations - Do not set #
scene_prop_group = 30

# Constants for iterations #
scene_prop_dynamics_start = 1
scene_prop_dynamics_end = 24
scene_prop_group_limit = 500
scene_prop_group_size_limit = 50

Mission Templates, which does a order of calculations every frame. (i might change it to once every 1/30 of a second or something....)
The order of calculation is like this:
first, all parents are calculated first (this is done by the ordering of the arrays, thus, you should always initialize a "parent" before a "child" as a scene prop).
Then operations that change absolute position, ie velocity is calculated first.
Then operations that change other properties are calculated (ie gravity that changes velocity, wheel rotate determination, that changes omega).
Then after the "absolute" positions (ones that affect motion) are calculated, and the properties are changed, the "relative" position (ones that only have visual effects) are calculated. First, the parents movements are copied. Then, the object's own relative changes are done. Lastly the position is changed.
Code:
		(ti_before_mission_start, 0, ti_once, [], [
			(set_spawn_radius, 0), # make array for groups
			(spawn_around_party, 1, "pt_none"),
			(assign, "$dyn_groups", reg0),
			(try_for_range,":array_index",0,scene_prop_group_limit), # initialize array
				(party_set_slot,"$dyn_groups",":array_index",-1),
			(try_end),
			(assign, "$elemate", 0),
		]),
		(0, 0, 0, [],[
		(assign, ":end", scene_prop_group_limit),
		(try_for_range,":array_index",0,":end"), # try for all groups
			(assign, reg0, ":array_index"),
			#(display_debug_message, "@{reg0}"),
			(party_get_slot,":group","$dyn_groups",":array_index"),
			(try_begin),
				(eq, ":group", -1),
				(assign, ":end", ":array_index"),	
			(try_end),
			(neg|eq, ":group", -1),
			(assign, ":sub_end", 30),
			(try_for_range,":sub_array_index",0,":sub_end"), # try for group members		
				(party_get_slot,":instance",":group",":sub_array_index"),
				(try_begin),
					(eq, ":instance", -1),
					(assign, ":end", ":sub_array_index"),	
				(try_end),	
				(neg|eq, ":instance", -1),
				(scene_prop_get_slot,":enable",":instance",scene_prop_enable_jl_dynamics),
				(scene_prop_get_slot,":parent",":instance",scene_prop_parent),
				(ge, ":enable", 1),
				###########################################
				# Parent conditions that change abs value #
				###########################################
				(try_begin), #parent only conditions
					(eq, ":parent", -1),
					#(display_debug_message, "@is parent(abs)"),
					(try_begin), #try involving abs positions
						(scene_prop_get_slot,":vel_abs_z",":instance",scene_prop_vel_abs_z),	
						(scene_prop_get_slot,":enable",":instance",scene_prop_set_z_ground),
						(eq, ":enable", 0),
						(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),
						(position_get_distance_to_ground_level, ":distance", pos0),
						(store_mul,":neg_vel_abs_z",-1,":vel_abs_z"),
						(try_begin),
							(ge, ":neg_vel_abs_z", ":distance"), ##### NEED FIX ########
							(position_set_z_to_ground_level, pos0),
							(position_get_z, ":z", pos0),
							(call_script, "script_set_scene_prop_group_abs_z", ":instance", ":z"),				
						(else_try),
							(call_script, "script_move_scene_prop_group_abs_z", ":instance", ":vel_abs_z"),	
						(try_end),
					(end_try),
					(try_begin), 
						(scene_prop_get_slot,":vel_abs_y",":instance",scene_prop_vel_abs_y),	
						(call_script, "script_move_scene_prop_group_abs_y", ":instance", ":vel_abs_y"),						
					(end_try),
					(try_begin),
						(scene_prop_get_slot,":gravity",":instance",scene_prop_gravity), #### Needs to be MOVED ####
						(neg|eq, ":gravity", 0),		
						(scene_prop_get_slot,":vel_abs_z",":instance",scene_prop_vel_abs_z),
						(val_sub, ":vel_abs_z", ":gravity"),
						(scene_prop_set_slot,":instance",scene_prop_vel_abs_z,":vel_abs_z"),						
					(end_try),
					(try_begin), 
						(scene_prop_get_slot,":value",":instance",scene_prop_set_z_ground),
						(ge, ":value", 1),
						(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),	
						#(position_set_z, pos0, 10000),
						(position_get_distance_to_terrain, ":distance", pos0),
						(val_mul, ":distance", -1),
						(val_sub, ":value", 1),
						(val_add, ":distance", ":value"),
						(call_script, "script_move_scene_prop_group_abs_z", ":instance", ":distance"),
					(end_try),#try involving abs positions
				(end_try), #parent only conditions
				###########################################
				# Conditions that change other properties #
				###########################################		
				(try_begin), # Rotation
					(scene_prop_get_slot,":omega_x",":instance",scene_prop_rel_ome_x), 	
					(scene_prop_get_slot,":rel_rot_x",":instance",scene_prop_rel_rot_x),
					(val_add, ":rel_rot_x", ":omega_x"),
					(scene_prop_set_slot,":instance",scene_prop_rel_rot_x,":rel_rot_x"),						
				(end_try), # Rotation		 		
				(try_begin), # Wheel Rotation Speed determination
					(scene_prop_get_slot,":is_wheel",":instance",scene_prop_is_wheel),
					(eq, ":is_wheel", 1),
					(call_script, "script_scene_prop_get_master", ":instance"),
					(assign, ":master", reg0),
					(scene_prop_get_slot,":parent_v_y",":master",scene_prop_vel_abs_y),
					(scene_prop_get_slot,":radius_pi",":instance",scene_prop_radius),
					(val_mul, ":radius_pi", PI),
					(store_div, ":omega", 20000, ":radius_pi"),
					(val_mul, ":omega", ":parent_v_y"),
					(val_mul, ":omega", -1),
					(scene_prop_set_slot,":instance",scene_prop_rel_ome_x,":omega"),
				(end_try), # Wheel Rotation 
				################
				# START RENDER #
				################
				# pos30 is final position #
				(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),
				(copy_position, pos30, pos0),
				################################
				# Step 1: Render Slopes etc... #
				################################
				(try_begin), # parent-only renders
					(eq, ":parent", -1),
					#(display_debug_message, "@is parent(slope)"),
					(try_begin), 
						(scene_prop_get_slot,":slope_trigger",":instance",scene_prop_follow_slope),
						(ge, ":slope_trigger", 1),
						(scene_prop_get_slot,":length",":instance",scene_prop_length),
						(call_script, "script_get_slope_y_pos0", ":length"),
						(assign, ":slope_y", reg0),
						(position_rotate_x, pos30, ":slope_y"),			
						(try_begin),	
							(ge, ":slope_trigger", 2),
							(scene_prop_get_slot,":width",":instance",scene_prop_width),
							(call_script, "script_get_slope_x_pos0", ":width"),
							(assign, ":slope_x", reg0),
							(position_rotate_y, pos30, ":slope_x"),		
						(try_end),
					(try_end),
				(try_end), # parent-only renders
				################################
				# Step 2: Copy Parent's render #
				################################
				(try_begin), # child-only 
					(neg|eq, ":parent", -1),	
					(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":parent"),
					(copy_position, pos1, pos0), # pos 1: parent abs pos
					(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),
					(copy_position, pos2, pos0), # pos2: child abs pos		
					(position_transform_position_to_local, pos3, pos1, pos2), # pos 3: child in terms of parent
					(prop_instance_get_position, pos4, ":parent"), # pos4: parent rendered pos
					(position_transform_position_to_parent, pos30, pos4, pos3), #pos30: final							
				(try_end), # child-only				
				######################################
				# Step 3: Add oneself's rel. renders #
				######################################
				(scene_prop_get_slot,":rel_x",":instance",scene_prop_rel_pos_x),
				(scene_prop_get_slot,":rel_y",":instance",scene_prop_rel_pos_y),
				(scene_prop_get_slot,":rel_z",":instance",scene_prop_rel_pos_z),
				(scene_prop_get_slot,":rel_rot_x",":instance",scene_prop_rel_rot_x),
				(scene_prop_get_slot,":rel_rot_y",":instance",scene_prop_rel_rot_y),
				(position_move_x, pos30, ":rel_x"),
				(position_move_y, pos30, ":rel_y"),
				(position_move_z, pos30, ":rel_z"),
				(position_rotate_x, pos30, ":rel_rot_x"),
				(position_rotate_y, pos30, ":rel_rot_y"),
				# END RENDER #
				(prop_instance_set_position, ":instance", pos30),
				#(display_message, "@work"),
			(try_end),	# try for group members	 
		(try_end), # try for all groups
		]),

Here are the scripts,
every time a new scene prop is initialized to have dynamics, it will be allocated automatically into it's parent array, or if it is a top-level-parent itself, a new array will be created.
Code:
("get_slope_y_pos0",
	[
		# pos0 is position passed in from caller
		(store_script_param_1,":dimension"), 
		(copy_position,pos60,pos0),
		(store_div, ":half_dimension",":dimension", 2),
		(store_mul, ":neg_dimension",":dimension", -1),
		(position_get_rotation_around_z,":z_rot",pos60),
		(init_position, pos1),
		(position_copy_rotation,pos60,pos1),
		(position_rotate_z,pos60,":z_rot"),
		(position_move_y,pos60,":half_dimension"),
		(position_set_z,pos60,10000),
		(position_get_distance_to_terrain, ":d1", pos60), 
		(position_move_y,pos60,":neg_dimension"),
		(position_get_distance_to_terrain, ":d2", pos60),
		(assign, reg20, ":d1"),
		(assign, reg21, ":d2"),	
		(store_sub, ":delta_d", ":d2", ":d1"),
		(store_atan2, ":slope", ":delta_d", ":dimension"),
		(val_div, ":slope", 100),
		(assign, reg0, ":slope"),
	]),
	("get_slope_x_pos0",
	[
		# pos0 is position passed in from caller
		(store_script_param_1,":dimension"), 
		(copy_position,pos60,pos0),
		(store_div, ":half_dimension",":dimension", 2),
		(store_mul, ":neg_dimension",":dimension", -1),
		(position_get_rotation_around_z,":z_rot",pos60),
		(init_position, pos1),
		(position_copy_rotation,pos60,pos1),
		(position_rotate_z,pos60,":z_rot"),
		(position_move_x,pos60,":half_dimension"),
		(position_set_z,pos60,10000),
		(position_get_distance_to_terrain, ":d1", pos60), 		
		(position_move_x,pos60,":neg_dimension"),
		(position_get_distance_to_terrain, ":d2", pos60),
		(store_sub, ":delta_d", ":d1", ":d2"),
		(store_atan2, ":slope", ":delta_d", ":dimension"),
		(val_div, ":slope", 100),
		(assign, reg0, ":slope"),
	]),
	("rotate_pos2_around_pos1",
	[
		(store_script_param_1,":rot"),
		(position_transform_position_to_local, pos3, pos1, pos2),
		(position_rotate_z, pos1, ":rot"),
		(position_transform_position_to_parent, pos0, pos1, pos3),
	]),
	# Dynamics Scripts - Get Scene Prop Information
	("store_scene_prop_abs_pos_to_pos0",
	[
		(store_script_param_1,":instance"),
		(set_fixed_point_multiplier, 100),
		(init_position, pos0),
		(scene_prop_get_slot,":x",":instance",scene_prop_abs_pos_x),
		(scene_prop_get_slot,":y",":instance",scene_prop_abs_pos_y),
		(scene_prop_get_slot,":z",":instance",scene_prop_abs_pos_z),
		(scene_prop_get_slot,":rot_z",":instance",scene_prop_abs_rot_z),
		(scene_prop_get_slot,":rot_x",":instance",scene_prop_abs_rot_x),
		#(scene_prop_get_slot,":rot_x",":instance",scene_prop_abs_rot_x),
		#(scene_prop_get_slot,":rot_y",":instance",scene_prop_abs_rot_y),
		#(scene_prop_get_slot,":rot_z",":instance",scene_prop_abs_rot_z),	
		(position_set_x, pos0, ":x"),
		(position_set_y, pos0, ":y"),
		(position_set_z, pos0, ":z"),
		(position_rotate_z, pos0, ":rot_z"),
		(position_rotate_x, pos0, ":rot_x"),
	]),
	("scene_prop_get_master",
	[
		(store_script_param_1,":instance"),
		(scene_prop_get_slot,":group",":instance",scene_prop_group),	
		(party_get_slot,reg0,":group",0),
	]),	
	# Dynamics Scripts - Set Scene Prop Information
	("initialize_scene_prop_dynamics",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":parent_id"),
		(assign, reg0, ":parent_id"),
		#(display_debug_message, "@{reg0} "),
		(scene_prop_set_slot,":instance",scene_prop_enable_jl_dynamics,1),
		(try_begin),
			(gt, ":parent_id", 0), # has parent
			(scene_prop_set_slot,":instance",scene_prop_parent,":parent_id"),
			(scene_prop_get_slot,":party_id",":parent_id",scene_prop_group),
			(assign, ":stop", -1),
			(try_for_range,":array_index",0,scene_prop_group_size_limit), # find end index				
				(eq, ":stop", -1),
				(party_get_slot,":value",":party_id",":array_index"),
				(eq, ":value", -1),
				(party_set_slot, ":party_id", ":array_index", ":instance"), # replace as end					
				(assign, ":stop", 1),
			(try_end),
			#(try_for_range,":array_index",0,scene_prop_group_size_limit), # show array
			#	(party_get_slot,":value", ":party_id",":array_index"),
			#	(assign, reg0, ":value"),
			#	(display_debug_message, "@{reg0} "),
			#(try_end),
		(else_try),
			(eq, ":parent_id", 0), # no parent, ie IS parent
			(scene_prop_set_slot,":instance",scene_prop_parent,-1),
			(set_spawn_radius, 0), # make array for group
			(spawn_around_party, 1, "pt_none"),
			(assign, ":array", reg0),
			(try_for_range,":array_index",0,scene_prop_group_size_limit), # initialize array
				(party_set_slot,":array",":array_index",-1),
			(try_end),
			(scene_prop_set_slot, ":instance", scene_prop_group, ":array"),
			(party_set_slot, ":array", 0, ":instance"),
			(assign, ":end", scene_prop_group_limit),
			(try_for_range,":array_index",0,":end"), 
				(party_get_slot,":group", "$dyn_groups",":array_index"),
				(try_begin),
					(eq,":group",-1),
					(assign, ":end", ":array_index"),
					(party_set_slot, "$dyn_groups", ":array_index", ":array"),
					#(display_debug_message, "@hey, 1"),
				(try_end),				
			(try_end),	
			#(try_for_range,":array_index",0,scene_prop_group_size_limit), # show array
			#	(party_get_slot,":value","$dyn_groups",":array_index"),
			#	(assign, reg0, ":value"),
			#	(display_debug_message, "@{reg0} "),
			#(try_end),
		(try_end),		
		(try_for_range,":loop",scene_prop_dynamics_start+2,scene_prop_dynamics_end+1),
			(scene_prop_set_slot,":instance",":loop",0),		
		(try_end),
	]),
	("set_scene_prop_abs_pos",
	[
		(store_script_param_1,":instance"),
		(set_fixed_point_multiplier, 100),
		(position_get_x,":x",pos0),
		(position_get_y,":y",pos0),
		(position_get_z,":z",pos0),
		(position_get_rotation_around_x,":rot_x",pos0),
		(position_get_rotation_around_y,":rot_y",pos0),
		(position_get_rotation_around_z,":rot_z",pos0),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_x,":x"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_y,":y"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_z,":z"),
		(scene_prop_set_slot,":instance",scene_prop_abs_rot_x,":rot_x"),
		(scene_prop_set_slot,":instance",scene_prop_abs_rot_y,":rot_y"),
		(scene_prop_set_slot,":instance",scene_prop_abs_rot_z,":rot_z"),
	]),
	("set_scene_prop_group_abs_x",  ### NEEDS TO BE COMPLETED ###
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":x"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_x,":x"),
	]),
	("set_scene_prop_group_abs_y", ### NEEDS TO BE COMPLETED ###
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":y"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_y,":y"),		
	]),
	("set_scene_prop_group_abs_z", ### NEEDS TO BE COMPLETED ###
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":z"),
		(scene_prop_set_slot,":instance",scene_prop_abs_pos_z,":z"),		
	]),
	# Dynamics Scripts - Move Secene Prop
	("move_scene_prop_group_abs_y",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":distance"),
		#(val_mul,":distance", 100), 
		(scene_prop_get_slot,":array",":instance",scene_prop_group),
		(assign, ":end", scene_prop_group_size_limit),
		(try_for_range,":array_index",0,":end"), # find end index				
			(try_begin),
				(party_get_slot,":prop_id",":array",":array_index"),
				(eq, ":prop_id", -1),
				(assign, ":end", ":array_index"),
			(try_end),
			(neg|eq, ":prop_id", -1),
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":prop_id"),
			(position_move_y, pos0, ":distance"),
			(call_script, "script_set_scene_prop_abs_pos", ":prop_id"),				
		(try_end),			
	]),
	("move_scene_prop_group_abs_z",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":distance"),
		#(val_mul,":distance", 100), 
		(scene_prop_get_slot,":array",":instance",scene_prop_group),
		(assign, ":end", scene_prop_group_size_limit),
		(try_for_range,":array_index",0,":end"), # find end index				
			(try_begin),
				(party_get_slot,":prop_id",":array",":array_index"),
				(eq, ":prop_id", -1),
				(assign, ":end", ":array_index"),
				#(display_debug_message, "@hey, 2"),
			(try_end),
			(neg|eq, ":prop_id", -1),
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":prop_id"),
			(position_move_z, pos0, ":distance"),
			(call_script, "script_set_scene_prop_abs_pos", ":prop_id"),				
		(try_end),					
	]),
	("rot_scene_prop_group_z",
	[
		(store_script_param_1,":instance"),
		(store_script_param_2,":rot"),
		#(val_mul,":distance", 100), 
		(scene_prop_get_slot,":array",":instance",scene_prop_group),
		(party_get_slot, ":master", ":array", 0),
		(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":master"),
		(copy_position, pos1, pos0),
		(assign, ":end", scene_prop_group_size_limit),
		(try_for_range,":array_index",0,":end"), # find end index				
			(try_begin),
				(party_get_slot,":prop_id",":array",":array_index"),
				(eq, ":prop_id", -1),
				(assign, ":end", ":array_index"),
			(try_end),
			(neg|eq, ":prop_id", -1),
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":prop_id"),
			(copy_position, pos2, pos0),
			(call_script, "script_rotate_pos2_around_pos1", ":rot"),
			#(position_transform_position_to_local, pos3, pos1, pos2),
			#(position_rotate_z, pos1, ":rot"),
			#(position_transform_position_to_parent, pos0, pos1, pos3),
			(call_script, "script_set_scene_prop_abs_pos", ":prop_id"),		
			#(display_message, "@bye"),
		(try_end),		
	]),

For testing:
(this also demonstrates how the script is used, the main part is actually very simple)
like:
Code:
				(spawn_scene_prop, "spr_place_holder"),
				(assign, ":instance", reg0),
				(assign, "$elemate", ":instance"),
				(call_script, "script_initialize_scene_prop_dynamics", ":instance", 0),
				(call_script, "script_set_scene_prop_abs_pos", ":instance"),
				(scene_prop_set_slot,":instance",scene_prop_set_z_ground,1),
				(scene_prop_set_slot,":instance",scene_prop_follow_slope,2),
				(scene_prop_set_slot,":instance",scene_prop_length,424),
				(scene_prop_set_slot,":instance",scene_prop_width,100),
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_z,0),
				(scene_prop_set_slot,":instance",scene_prop_gravity,0),
Code:
(try_begin),
			(this_or_next|key_clicked, key_m),
			(this_or_next|key_clicked, key_o),
			(key_clicked, key_p),
			## Get spawn position
			(get_player_agent_no, ":p_agent"),
			(agent_get_position, pos0, ":p_agent"),
			(position_move_y, pos0, 500),
			(position_set_z, pos0, 10000),
			(position_set_z_to_ground_level, pos0),							
			# Rotate y
			(position_get_rotation_around_y,":tilt", pos0),
			(val_mul, ":tilt", -1),
			(position_rotate_y, pos0, ":tilt"),
			# Rotate y
			## Get spawn position
			(set_spawn_position, pos0),				
			(try_begin), # Spawn Elemate #
				(key_clicked, key_m),
				(spawn_scene_prop, "spr_place_holder"),
				(assign, ":instance", reg0),
				(assign, "$elemate", ":instance"),
				(call_script, "script_initialize_scene_prop_dynamics", ":instance", 0),
				(call_script, "script_set_scene_prop_abs_pos", ":instance"),
				(scene_prop_set_slot,":instance",scene_prop_set_z_ground,1),
				(scene_prop_set_slot,":instance",scene_prop_follow_slope,2),
				(scene_prop_set_slot,":instance",scene_prop_length,424),
				(scene_prop_set_slot,":instance",scene_prop_width,100),
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_z,0),
				(scene_prop_set_slot,":instance",scene_prop_gravity,0),
			(try_end), # Spawn Elemate #
			(try_begin), # Spawn Child #	
				(key_clicked, key_o),
				(spawn_scene_prop, "spr_place_holder"),
				(assign, ":instance", reg0),
				(assign, "$child", ":instance"),
				(call_script, "script_initialize_scene_prop_dynamics", ":instance", "$elemate"),
				(call_script, "script_set_scene_prop_abs_pos", ":instance"),			
			(try_end), # Spawn Child #
			(try_begin), # Spawn Wheel #	
				(key_clicked, key_p),
				(spawn_scene_prop, "spr_wheel"),
				(assign, ":instance", reg0),
				(assign, "$elemate", ":instance"),
				(call_script, "script_initialize_scene_prop_dynamics", ":instance", 0),
				(call_script, "script_set_scene_prop_abs_pos", ":instance"),
				(scene_prop_set_slot,":instance",scene_prop_set_z_ground,40),
				(scene_prop_set_slot,":instance",scene_prop_follow_slope,2),
				(scene_prop_set_slot,":instance",scene_prop_length,0),
				(scene_prop_set_slot,":instance",scene_prop_width,10),
				(scene_prop_set_slot,":instance",scene_prop_is_wheel,1),
				(scene_prop_set_slot,":instance",scene_prop_radius,41),
			(try_end), # Spawn Elemate #
		(try_end),
		(try_begin),## Forward/Backward , Left/Right ##
			(gt, "$elemate", 0),
			(assign,":instance","$elemate"),	
			(try_begin), 
				(key_is_down, key_i),
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_y,5),
			(else_try),	
				(key_is_down, key_k),
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_y,-5),
			(else_try),	
				(scene_prop_set_slot,":instance",scene_prop_vel_abs_y,0),
			(try_end),	
		(try_end), ## Forward/Backward , Left/Right ##	
		(try_begin),
			(key_is_down, key_j),
			(gt, "$elemate", 0),
			(assign,":instance","$elemate"),
			(call_script, "script_rot_scene_prop_group_z", ":instance", 1),
		(try_end),	
		(try_begin),
			(key_is_down, key_l),
			(gt, "$elemate", 0),
			(assign,":instance","$elemate"),
			(call_script, "script_rot_scene_prop_group_z", ":instance", -1),
		(try_end), ## Forward/Backward , Left/Right ##
		(try_begin),
			(key_is_down, key_n),
			(gt, "$elemate", 0),
			(assign,":instance","$elemate"),
			(call_script, "script_store_scene_prop_abs_pos_to_pos0", ":instance"),	
			(position_move_z, pos0, 500),
			(get_player_agent_no, ":p_agent"),
			(agent_set_position,":p_agent",pos0),
		(try_end), ## Forward/Backward , Left/Right ##

There are a few things that I haven't finished yet, such as the child following the parent when dropping due to gravity etc... it is commented in the code if it hasn't been finished.

Bugs are expected.

In theory, it should also support, children of children of children etc... (so you could almost have a whole bone like structure) but I haven't tested it yet.
 
Quick question, why did you set the positive reference direction for the Z axis's speed to be downwards? Since a prop moving downwards has a decreasing position, wouldn't it make more sense to make upwards positive?
 
you could easily implant that yourself.
Also becouse it would be for every object their own acceleration and top speed.
 
I guess so :smile:.

But I think I might rewrite quite a bit how it works to fix that spinning bug and make it easier to use.

But... after Monday, when I finish my exams :grin:.
 
Back
Top Bottom