A script that enables you to pick up scene props and throw them to ppl with lethal consequences.
Includes great deal of real physics (flight and bouncing). Does not include weight considerations yet, but can be easily programmed to include those. Just needs some constants definition for different scene props and their relative visual sizes.
So far it uses two scene props, spr_stoneball (Native one) and spr_throwing_stone (new one). Can be easily reprogrammed to use any scene prop - like picking up and throwing a stool in a bar brawl Or a castle, if you really feel like it...
Feel free to use and modify it however you like. Mention me in the credits afterwards.
This code goes to a mission in module_mission_templates.py, where you want to be able to lob stones
You will need to add props with Edit mode to scenes, or you will have nothing to lob
And a new prop made of Native throwing stone model.
Code goes at the end of the module_scene_props.py.
Script limitations:
1) you can't pick up another stone while first one is flying. CBA to write more script to handle this
2) I yet to find a way to keep player's arms up when carrying a stone, and preserve mobility
Engine limitations:
1) stone can only bounce from ground or non-vertical collision meshes. It will fly through vertical walls, nothing can be done about it
2) also, bouncing from horizontal surfaces looks best. The more vertical the obstacle, the more unnatural is the bouncing
3) you can equip back weapon & shield when you picked up a stone. I yet to find a way to forbid equipping
Includes great deal of real physics (flight and bouncing). Does not include weight considerations yet, but can be easily programmed to include those. Just needs some constants definition for different scene props and their relative visual sizes.
So far it uses two scene props, spr_stoneball (Native one) and spr_throwing_stone (new one). Can be easily reprogrammed to use any scene prop - like picking up and throwing a stool in a bar brawl Or a castle, if you really feel like it...
Feel free to use and modify it however you like. Mention me in the credits afterwards.
This code goes to a mission in module_mission_templates.py, where you want to be able to lob stones
Code:
################## STONELOBBING BEGIN ########################################
################## uses spr_stoneball and spr_throwing_stone (new one) props #
################## pos49 is used globally for stone tracking! ################
(0, 0, ti_once, [], [
(assign,"$stonelobbing_state",0), ###### 0 no stones, 1 stone picked, 2,3,4 stone flying & bouncing
(assign,"$stone_initial_velocity",35),
(assign,"$stone_horizontal_velocity",0),
(assign,"$stone_vertical_velocity",0),
(assign,"$stone_rotation_x",20), ###### stone rotation speed in flight
(assign,"$stone_rotation_y",30),
(assign,"$stone_rotation_z",30),
]),
(0,0,1, [
(key_clicked, key_e), ###### picking up a stone
(eq,"$stonelobbing_state",0),
(get_player_agent_no,":player_agent"),
(agent_get_wielded_item,reg1,":player_agent",0), ###### should be emptyhanded to pick up a stone, duh
(agent_get_wielded_item,reg2,":player_agent",1),
# (display_message, "@DEBUG:STONE: Pick stone E, throw F, should be emptyhanded to pick"),
(eq,reg1,-1),
(eq,reg2,-1),
],[
(get_player_agent_no,":player_agent"),
(agent_get_position,pos1,":player_agent"),
(position_move_z,pos1,50),
(scene_prop_get_num_instances,":num_stones","spr_stone_ball"), ### pick stone ball prop
(try_for_range,":count",0,":num_stones"),
(scene_prop_get_instance,":stone_instance", "spr_stone_ball", ":count"),
(prop_instance_get_position,pos2,":stone_instance"),
(get_distance_between_positions,":distance",pos1,pos2),
(lt,":distance",150),
(assign,"$stonelobbing_state",1),
(assign,"$stone_picked_instance",":stone_instance"),
(agent_set_walk_forward_animation,":player_agent", "anim_reload_crossbow"),
(play_sound, "snd_man_grunt"),
(try_end),
(scene_prop_get_num_instances,":num_stones","spr_throwing_stone"),# or pick throwing stone prop
(try_for_range,":count",0,":num_stones"),
(scene_prop_get_instance,":stone_instance", "spr_throwing_stone", ":count"),
(prop_instance_get_position,pos2,":stone_instance"),
(get_distance_between_positions,":distance",pos1,pos2),
(lt,":distance",150),(eq,"$stonelobbing_state",0),
(assign,"$stonelobbing_state",1),
(assign,"$stone_picked_instance",":stone_instance"),
(agent_set_animation,":player_agent", "anim_reload_crossbow"),
(play_sound, "snd_man_grunt"),
(try_end),
]),
(0,0,5, [
(key_clicked, key_f),
(eq,"$stonelobbing_state",1), ###### throwing a stone
],[
(get_player_agent_no,":player_agent"),
(agent_get_position,pos1,":player_agent"),
(agent_get_look_position,pos2,":player_agent"),
(copy_position,pos3,pos2), ####### get stone initial velocities
(position_move_y,pos3,"$stone_initial_velocity"),
(position_transform_position_to_local, pos4, pos1,pos3),
(position_get_y,"$stone_horizontal_velocity",pos4),
(position_get_z,"$stone_vertical_velocity",pos4),
(agent_get_position,pos49,":player_agent"), ###### orient stone with horizontal y for easier flight later
(position_move_z,pos49,170),
(position_move_x,pos49,25),
(prop_instance_set_position,"$stone_picked_instance",pos49),
(agent_set_animation,":player_agent","anim_release_overswing_twohanded"),
(play_sound, "snd_man_grunt"),
(assign,"$stonelobbing_state",2),
]),
(0,0,0, [
(ge,"$stonelobbing_state",2), ###### stone flight
],[
(prop_instance_get_position,pos1,"$stone_picked_instance"),
(copy_position,pos2,pos49),
(position_set_z_to_ground_level, pos2),
(position_transform_position_to_local,pos4, pos49,pos2),
(position_get_z,":z_missile",pos4),
(try_begin),
(this_or_next|lt,":z_missile",-20), ###### when ground is far away or flying up, fly stone
(gt,"$stone_vertical_velocity",0),
(position_move_y,pos49,"$stone_horizontal_velocity"),
(position_move_z,pos49,"$stone_vertical_velocity"),
(val_sub,"$stone_vertical_velocity",1), ###### gravity
(copy_position,pos2,pos49), ###### stone rotation
(position_copy_rotation,pos2,pos1),
(position_rotate_x,pos2,"$stone_rotation_x"),
(position_rotate_y,pos2,"$stone_rotation_y"),
(try_begin), ###### add spin when bounced
(gt,"$stonelobbing_state",2),
(position_rotate_z,pos2,"$stone_rotation_z"),
(try_end),
(prop_instance_animate_to_position,"$stone_picked_instance",pos2,5),
(get_player_agent_no,":player_agent"), ###### when stone close to the agent
(try_for_agents,":agent"),
(agent_is_alive, ":agent"),
(neq,":agent",":player_agent"),
(agent_get_position,pos3,":agent"),
(position_move_z,pos3,70),
(get_distance_between_positions,":stone_hit",pos2,pos3),
(try_begin),
(lt,":stone_hit",100),
(agent_play_sound,":agent","snd_blunt_hit"),
(store_mul,":v","$stone_vertical_velocity", "$stone_vertical_velocity" ),
(store_mul,":h","$stone_horizontal_velocity","$stone_horizontal_velocity"),
(val_add,":v",":h"),
(store_sqrt,":velocity",":v"),
(try_begin), ###### kill the agent if stone is fast
(gt,":velocity",40),
(agent_set_hit_points,":agent",0,0),
(agent_deliver_damage_to_agent,":player_agent",":agent"),
(agent_play_sound,":agent","snd_man_die"),
(val_sub,"$stone_horizontal_velocity",5),
(else_try), ###### ko agent and deliver some damage if stone is slow
(store_agent_hit_points,":hp",":agent",1),
(val_div,":velocity",2),
(val_sub,":hp",":velocity"),
(try_begin),
(lt,":hp",0),
(assign,":hp",0),
(try_end),
(agent_set_hit_points,":agent",":hp",1),
(agent_deliver_damage_to_agent,":player_agent",":agent"),
(agent_set_animation,":agent","anim_strike_fall_back_rise"),
(agent_play_sound,":agent","snd_man_grunt"),
(val_sub,"$stone_horizontal_velocity",2),
(try_end),
(try_end),
(try_end),
(else_try),
(play_sound,"snd_body_fall_small"),
(prop_instance_get_position,pos1,"$stone_picked_instance"),
(position_set_z_to_ground_level,pos1),
(position_move_z,pos1,30),
(prop_instance_set_position,"$stone_picked_instance",pos1),
(try_begin),
(lt,"$stonelobbing_state",4), ###### bouncing stone
(val_div,"$stone_vertical_velocity",-2),
(val_div,"$stone_horizontal_velocity",2),
(val_add,"$stonelobbing_state",1),
(else_try), ###### stone reached final rest
# (display_message,"@DEBUG:STONE: missile hit final ground"),
(assign,"$stonelobbing_state",0),
(try_end),
(try_end),
]),
(0,0,0, [
(eq,"$stonelobbing_state",1), ###### carrying stone sync
],[
(get_player_agent_no,":player_agent"),
(agent_get_position,pos6,":player_agent"),
(position_move_z,pos6,170),
(position_move_x,pos6,25),
(prop_instance_animate_to_position,"$stone_picked_instance",pos6,3),
# (agent_set_walk_forward_animation,":player_agent","anim_ready_overswing_twohanded"),# dont know how to assign upperbody animation yet :(
]),
################## STONELOBBING END ########################################
And a new prop made of Native throwing stone model.
Code goes at the end of the module_scene_props.py.
Code:
("throwing_stone",0,"throwing_stone","0",[]),
Script limitations:
1) you can't pick up another stone while first one is flying. CBA to write more script to handle this
2) I yet to find a way to keep player's arms up when carrying a stone, and preserve mobility
Engine limitations:
1) stone can only bounce from ground or non-vertical collision meshes. It will fly through vertical walls, nothing can be done about it
2) also, bouncing from horizontal surfaces looks best. The more vertical the obstacle, the more unnatural is the bouncing
3) you can equip back weapon & shield when you picked up a stone. I yet to find a way to forbid equipping