OSP Code Combat Crude fragmentation grenade

Users who are viewing this thread

Urist

Master Knight
For fun I made a crappy excuse for an impact-triggered frag nade using the new add_missile operation and I thought I can as well share it. It's done as an item trigger in the items.py and uses 3 entries there, one for the fragments, one for the launcher of the fragments and finally the actual grenade that has to be equipped and thrown(in this case simple stones). I don't provide models, sounds or particle effects for the grenade, fragments or explosion, just the code for item.py.

The grenade effect starts after it is thrown and hits something. Then first a blast damage is dealt to agents within a certain radius and unmounted agents that receive enough damage are eventually knocked over. The second effect is the launching of an customisable amount of fragments radially from the explosion, being able to damage agents as seperate projectiles.

This code is for single player. In multiplayer certain stuff like the knockover animations or particle/sound effects has to be sent as events to the clients to make them see or hear it. Another gripe is that it seems that an agent can only be hit once per frame so that multible fragments hitting at the same time are ignored. I am trying prevent that with randomising starting position and speed of the fragments by a certain degree. Hoping for WSE2 there.

Code(item entries in the item.py):

Fragment entry:
Code:
#item entry of the fragments, one could give an invisible inflight model to them
#changing damage doesn't do anything here
["fragmentation_grenade_fragment","Fragment(do not use)", [(0,0)], itp_type_bullets|itp_merchandise|itp_can_penetrate_shield|itp_default_ammo, 0, 41,weight(2.25)|abundance(0)|weapon_length(3)|thrust_damage(0,pierce)|max_ammo(1),imodbits_missile, 
 [
 (ti_on_missile_hit, 
	[	
	#play sound and dust effect at fragment location
	#it is advisable use a custom particle effect and sound here instead
	(play_sound_at_position, "snd_blunt_hit", pos1),	
	#(particle_system_burst, "psys_fragmentation_grenade_fragment_dust", pos1, 1),		
	(particle_system_burst, "psys_game_hoof_dust", pos1, 1),		
	]
)	
]],

Fragment launcher entry:
Code:
#the launcher determines the damage of the fragments, changing fracment damage in the other entry someohow doesnt effect damage
#if you change the fragment shot speed in the add_missile op, then change it here too or the damage might change (not sure)
["fragmentation_grenade_fragment_launcher", "Fragment Launcher(do not use)", [("flintlock_pistol",0)], itp_type_pistol |itp_merchandise|itp_primary ,itcf_shoot_pistol|itcf_reload_pistol, 230 , weight(1.5)|abundance(0)|difficulty(0)|spd_rtng(100) | shoot_speed(9) | thrust_damage(80 ,pierce)|max_ammo(1)|accuracy(80),imodbits_none,
],

Grenade entry:
Code:
["fragmentation_grenade",         "Fragmentation Grenade", [("throwing_stone",0)], itp_type_thrown |itp_merchandise|itp_primary ,itcf_throw_stone, 1 , weight(4)|difficulty(0)|spd_rtng(97) | shoot_speed(15) | thrust_damage(4 ,  blunt)|max_ammo(100)|weapon_length(8),imodbit_large_bag,
[
(ti_on_missile_hit, 
	[		
	(store_trigger_param_1, ":frag_thrower_agent"),
	(set_fixed_point_multiplier, 100),
	#play sound and dust effect at fragment location
	#one should use a custom explosion particle effect and explosion sound here instead	
	#(play_sound_at_position,"snd_frag_explode", pos1),
	#(particle_system_burst, "psys_frag_explosion", pos1, 10),	
	(play_sound_at_position,"snd_pistol_shot", pos1),
	(particle_system_burst, "psys_village_fire_big", pos1, 6),	
	(particle_system_burst, "psys_dummy_smoke_big", pos1, 24),		
	#blast effect part
    (try_for_agents, ":cur_agent"), #check every agent if he is close enough to the nade to directly suffer from the detonation, ignoring armour
		(agent_is_alive, ":cur_agent"),
		(agent_get_position, pos4, ":cur_agent"),
		(get_sq_distance_between_positions,":blast_distance",pos1, pos4), 
		#(assign, reg10, ":blast_distance"), 
		#(display_message, "@Distance2={reg10}cm2.", 0xCCCCCC),		
		(lt, ":blast_distance", 3600), #within 6m radius(using squared distance)
		(store_random_in_range, ":blast_damage", 3200,4000),#randomised damage part			
		(val_sub, ":blast_damage", ":blast_distance"),
		(val_div, ":blast_damage", 100),		
		(gt, ":blast_damage", 0),#max dam at distance 0= 40; max dam at 6m = 4;	min dam at distance 0 = 34; min dam at 6m = 0;		
		(agent_deliver_damage_to_agent, ":frag_thrower_agent", ":cur_agent", ":blast_damage"),		
		(gt, ":blast_damage", 5),#if blast damage is big enough, knock agent down	
        (agent_is_human, ":cur_agent"),	#prevent horses from knockdown
		(agent_get_horse, ":cur_agent_mount_id",":cur_agent"),#prevent mounted agents form knockdown
		(lt, ":cur_agent_mount_id", 0),		
		(try_begin),
			(position_is_behind_position,pos1,pos4),#blast from behind ->fall forward
			(agent_set_animation, ":cur_agent", "anim_rider_fall_roll"), 			
		(else_try),
			(agent_set_animation, ":cur_agent", "anim_strike_fall_back_rise"), 	#blast infront ->fall backwards	
			(agent_set_animation, ":cur_agent", "anim_strike_fall_back_rise_upper"), 				
		(try_end),
	(try_end),	
	#fragmentation part
	(assign, ":fragment_number", 192), #number of fragments, dont go above 2000, never go full retard  			
	(position_copy_origin, pos2, pos1),#take xyz of the nade landing point
	(init_position, pos3), 
	(position_copy_rotation,pos2,pos3),#give standard orientation of the axis, with z axis looking up
	(position_rotate_x_floating, pos2, 9000),#turn y axis up, the fire direction of the add_missile operation		
	#fire x(=fragment_number) fragments , 1 each loop run
    (try_for_range, ":fragment_no", 1,  ":fragment_number"),	
		#randomise speed of fragments, should help with the problem that an agent can only hit once per frame
		(store_random_in_range,":fragment_speed",-450,450),	
		(val_add,":fragment_speed",900),#average speed of a fragment, determines max fragment range 
		#vary the starting position of the fragments a bit, should help with the problem that an agent can only hit once per frame
		(store_random_in_range,":fragment_random_pos_x",0,10),
		(store_random_in_range,":fragment_random_pos_y",0,10),
		(store_random_in_range,":fragment_random_pos_z",0,40),		
		#fragment fanning, no fragments should be released with downward component(would be wasted)	
		(copy_position, pos3, pos2), #pos3 is used for emiting the missile later on, 	
		(position_move_x,pos3,":fragment_random_pos_x",1),# move x for better fragment	spread			
		(position_move_y,pos3,":fragment_random_pos_y",1),# move y for better fragment	spread			
		(position_move_z,pos3,":fragment_random_pos_z",1),# move z for better fragment	spread	
		(store_random_in_range,":fragmentation_rot_x", -9000,-3000), #don't release fragments too vertically	up, for complete hemisphere change -3000 to 0
		(position_rotate_x_floating, pos3, ":fragmentation_rot_x"),				
		(store_random_in_range,":fragmentation_rot_z", 0, 359),	#not in fixed point, so it's 0-359 degree
		(position_rotate_z, pos3, ":fragmentation_rot_z", 1),#use global z axis, not the already randomised one of the nade			
		(add_missile, ":frag_thrower_agent", pos3, ":fragment_speed", "itm_fragmentation_grenade_fragment_launcher", 0, "itm_fragmentation_grenade_fragment", 0),			
	(try_end),
	]
)	
]],

GIF:
df24e7641818527df577fc96d7a7b36b.gif

 
You have alot of stuff in the code which will probably cause lag if used on more than one agent on the field at a time, but nice nonetheless. :wink:
 
You can do it with just removing/commenting out the blast damage part. Then only the fragments do damage. A bit of an limitation still is that only once per frame damage can be dealt to an agent so multible fragments hitting at the same time won't work. Hoping for WSE2 to change that but for now I like combining classic grenade blast damage and fragments.
 
Back
Top Bottom