Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/ONCC-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/ONCC-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/ONCC-.oni-patch	(revision 965)
@@ -1,10 +1,30 @@
 @XML_TOOLS Version "2.0"
 
-@ADD_INSIDE_NODES ElementName "Particles" ParentElementName "ONCP"
-<xml>
-	<ONCPParticle>
-		<Name>glass_break</Name>
-		<Type>glass_break</Type>
-		<BodyPart>None</BodyPart>
-	</ONCPParticle>
-</xml>
+@CUSTOM_CODE
+<code>
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+	var elements = myBuilder.elements[0];
+	
+	// If there are no attacks in this TRAM, ignore it
+	if (!elements.childElement("ONCP").childElement("Particles"))
+		return;
+						
+	// Check if glass_break is already registered for the character
+	var particles = elements.childElement("ONCP").childElement("Particles");
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Name").text == "glass_break")
+			return;
+	}
+
+	// If we're still here, register glass_break
+	myBuilder.addElementAt("ONCPParticle",
+				"",
+				"<Name>glass_break</Name>\
+                       		 <Type>glass_break</Type>\
+                 		 <BodyPart>None</BodyPart>",
+				particles.index + 1,
+				particles.level + 1);
+</code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-blownup-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-blownup-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-blownup-.oni-patch	(revision 965)
@@ -3,43 +3,62 @@
 @CUSTOM_CODE
 <code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
-	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
-	}
-
 	var myBuilder = new JSXMLBuilder();
 	myBuilder.load($xmlData);
 
 	var elements = myBuilder.elements[0];
+	var particles = elements.childElement("Animation").childElement("Particles");
+	var added_to_head = false, added_to_feet = false;
 	
-	var particles = elements.childElement("Animation").childElement("Particles");
-						
-	// Check if any of the existing particles contains a head bone
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(currElement.childElement("Bone").text=="Head"){
-			if(currElement.childElement("Name").text=="glass_break"){
-				return; // not necessary to add
-			}
-			else{
-				// gather all the necessary info
-				var int_start=currElement.childElement("Start").text;
-				var int_end=currElement.childElement("End").text;
-				
-				// Insert the new glass particle (for when he touches glass with head
-				myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>Head</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
-				break;
-			}
+	// Check if glass_break is assigned to Head and one of the feet;
+	// remove it from any other bones if present
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		var bone = particle.childElement("Bone").text;
+		var name = particle.childElement("Name").text;
+		if (name == "glass_break")
+		{
+			if (bone == "Head")
+				added_to_head = true;
+			else if (bone == "RightFoot")
+				added_to_feet = true;
+			else
+				myBuilder.removeElement(particle.index);
 		}
 	}
+
+	// Exit if we are past Oni's limit on TRAM particles
+	if (particles.length >= 16)
+		return;
+
+	// Add the glass_break particle to the desired bones if it's not there already
+	var heights = elements.childElement("Animation").childElement("Heights");
+	var anim_length;
+	for (anim_length = 0; (heights.childElement(anim_length)); anim_length++) {;}
+	if (!added_to_head)
+		myBuilder.addElementAt("Particle",
+				       "",
+			 	       "<Start>0</Start>\
+                			<End>" + (anim_length-1) + "</End>\
+                			<Bone>Head</Bone>\
+                			<Name>glass_break</Name>",
+				       particles.index + 1,
+				       particles.level + 1);
+
+	// Exit if we are past Oni's limit on TRAM particles
+	if (particles.length >= 16)
+		return;
+
+	if (!added_to_feet)
+		myBuilder.addElementAt("Particle",
+				       "",
+			 	       "<Start>0</Start>\
+                			<End>" + (anim_length-1) + "</End>\
+                			<Bone>RightFoot</Bone>\
+                			<Name>glass_break</Name>",
+				       particles.index + 1,
+				       particles.level + 1);
  
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
 </code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-comb-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-comb-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-comb-.oni-patch	(revision 965)
@@ -3,54 +3,148 @@
 @CUSTOM_CODE
 <code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
+	// |———————————————————————————————————Code best viewed at this width————————————————————————————————————————|
+
+	// Load XML data
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+	var elements = myBuilder.elements[0];
 	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
+	// If there are no attacks in this TRAM, ignore it
+	if (!elements.childElement("Animation").childElement("Attacks"))
+		return;
+	
+	// Gather all the necessary info
+	var particles   = elements.childElement("Animation").childElement("Particles");
+	var attack      = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
+	var hit_start   = attack.childElement("Start").text;
+	var hit_end     = attack.childElement("End").text;
+	var array_bones = attack.childElement("Bones").text.split(" ");
+						
+	// Remove glass_break if it is already assigned to any bones, because it's probably not been assigned the
+	// way we want it to be
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Name").text == "glass_break")
+			myBuilder.removeElement(particle.index);
 	}
 
-	var myBuilder = new JSXMLBuilder();
-	myBuilder.load($xmlData);
-
-	var elements = myBuilder.elements[0];
-	
-	var particles = elements.childElement("Animation").childElement("Particles");
-	
-			
-	if(!elements.childElement("Animation").childElement("Attacks")){ // if no attacks found ignore file
-		return;
-	}
-	
-	var attackElement = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
-	
-	var int_start,int_end,array_bones;
-	
-	// gather all the necessary info
-	int_start=attackElement.childElement("Start").text;
-	int_end=attackElement.childElement("End").text;
-	array_bones=attackElement.childElement("Bones").text.split(" ");
-						
-	// Check if any of the existing particles correspond to the same bone and glass_break
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(contains(array_bones,currElement.childElement("Bone").text) && currElement.childElement("Name").text=="glass_break"){
-			removeFromArray(array_bones,currElement.childElement("Bone").text); // not necessary to add
+	// Find the outermost bone of each type
+	// The "type" in bone_type[] refers to the extremity of the body to which a bone belongs ("mid" counts as
+	// as an extremity because the head is part of "mid"); this is a "parallel array" with array_bones[]
+	var bone_type = new Array(19);
+	// The "ext" in bone_ext[] refers to the "outermostness" of the bone, that is, how far out on the extremity
+	// this bone is; this is a parallel array with array_bones[]
+	var bone_ext = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+	// The extremity_ arrays are parallel arrays which store the highest "outermostness" value found for each
+	// extremity, among all the bones in that extremity that are listed in the attack
+	var extremity_name = ["mid", "left_arm", "right_arm", "left_leg", "right_leg"];
+	var extremity_max = [0, 0, 0, 0, 0];
+	for (var i = 0; i < array_bones.length; i++)
+	{
+		var bone = array_bones[i];
+		if (bone == "Head" || bone == "Neck" || bone == "Chest" || bone == "Mid" || bone == "Pelvis")
+		{
+			bone_type[i] = "mid";
+			if (bone == "Neck")
+				bone_ext[i] = 1;
+			else if (bone == "Head")
+				bone_ext[i] = 2;
+			// The rest of these bones are extremity '0'
+		}
+		else if (bone == "LeftShoulder" || bone == "LeftArm" || bone == "LeftWrist" || bone == "LeftFist")
+		{
+			bone_type[i] = "left_arm";
+			if (bone == "LeftShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "LeftArm")
+				bone_ext[i] = 2;
+			else if (bone == "LeftWrist")
+				bone_ext[i] = 3;
+			else if (bone == "LeftFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "RightShoulder" || bone == "RightArm" || bone == "RightWrist" || bone == "RightFist")
+		{
+			bone_type[i] = "right_arm";
+			if (bone == "RightShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "RightArm")
+				bone_ext[i] = 2;
+			else if (bone == "RightWrist")
+				bone_ext[i] = 3;
+			else if (bone == "RightFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "LeftThigh" || bone == "LeftCalf" || bone == "LeftFoot")
+		{
+			bone_type[i] = "left_leg";
+			if (bone == "LeftThigh")
+				bone_ext[i] = 1;
+			else if (bone == "LeftCalf")
+				bone_ext[i] = 2;
+			else if (bone == "LeftFoot")
+				bone_ext[i] = 3;
+		}
+		else if (bone == "RightThigh" || bone == "RightCalf" || bone == "RightFoot")
+		{
+			bone_type[i] = "right_leg";
+			if (bone == "RightThigh")
+				bone_ext[i] = 1;
+			else if (bone == "RightCalf")
+				bone_ext[i] = 2;
+			else if (bone == "RightFoot")
+				bone_ext[i] = 3;
 		}
 	}
-	
-	// Insert the new glass particles
-	for (var i = 0; i < array_bones.length; i++) {
-		if( (contains(array_bones[i],"Foot")) && !contains(array_bones[i],"Calf") && !contains(array_bones[i],"Tight") 
-		||  (contains(array_bones[i],"Fist")) && !contains(array_bones[i],"Wrist")){
-		myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>"+array_bones[i]+"</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
+
+	// Find outermost bone for each extremity, among the bones listed in the Attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (extremity_name[b] == bone_type[a])
+			{
+				if (bone_ext[a] > extremity_max[b])
+					extremity_max[b] = bone_ext[a];
+			}
 		}
 	}
+
+	// Add a glass_break particle for every outermost bone in the attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		// Move to next bone if this is not the outermost attacking bone on this extremity
+		var add_this_bone = false;
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (bone_type[a] == extremity_name[b])
+			{
+				if (bone_ext[a] == extremity_max[b])
+					add_this_bone = true;
+			}
+		}
+		if (!add_this_bone)
+			continue;
+
+		// Exit if we are past Oni's limit on TRAM particles
+		if (particles.length >= 16)
+		{
+			echo("Reached maximum of 16 particles for this TRAM, exiting…");
+			return;
+		}
+
+		echo("Adding glass_break to " + array_bones[a]);
+		var par_string = "<Start>" + hit_start + "</Start><End>" + hit_end + "</End><Bone>" + array_bones[a] + "</Bone><Name>glass_break</Name>";
+
+		// Add glass_break to bone for time period that bone has collision status
+		myBuilder.addElementAt("Particle",
+				       "",
+				       par_string,
+				       particles.index + 1,
+				       particles.level + 1);
+	}
  
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
 </code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-getup_k-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-getup_k-.oni-patch	(revision 965)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-getup_k-.oni-patch	(revision 965)
@@ -0,0 +1,150 @@
+@XML_TOOLS Version "2.0"
+
+@CUSTOM_CODE
+<code>
+	// |———————————————————————————————————Code best viewed at this width————————————————————————————————————————|
+
+	// Load XML data
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+	var elements = myBuilder.elements[0];
+	
+	// If there are no attacks in this TRAM, ignore it
+	if (!elements.childElement("Animation").childElement("Attacks"))
+		return;
+	
+	// Gather all the necessary info
+	var particles   = elements.childElement("Animation").childElement("Particles");
+	var attack      = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
+	var hit_start   = attack.childElement("Start").text;
+	var hit_end     = attack.childElement("End").text;
+	var array_bones = attack.childElement("Bones").text.split(" ");
+						
+	// Remove glass_break if it is already assigned to any bones, because it's probably not been assigned the
+	// way we want it to be
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Name").text == "glass_break")
+			myBuilder.removeElement(particle.index);
+	}
+
+	// Find the outermost bone of each type
+	// The "type" in bone_type[] refers to the extremity of the body to which a bone belongs ("mid" counts as
+	// as an extremity because the head is part of "mid"); this is a "parallel array" with array_bones[]
+	var bone_type = new Array(19);
+	// The "ext" in bone_ext[] refers to the "outermostness" of the bone, that is, how far out on the extremity
+	// this bone is; this is a parallel array with array_bones[]
+	var bone_ext = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+	// The extremity_ arrays are parallel arrays which store the highest "outermostness" value found for each
+	// extremity, among all the bones in that extremity that are listed in the attack
+	var extremity_name = ["mid", "left_arm", "right_arm", "left_leg", "right_leg"];
+	var extremity_max = [0, 0, 0, 0, 0];
+	for (var i = 0; i < array_bones.length; i++)
+	{
+		var bone = array_bones[i];
+		if (bone == "Head" || bone == "Neck" || bone == "Chest" || bone == "Mid" || bone == "Pelvis")
+		{
+			bone_type[i] = "mid";
+			if (bone == "Neck")
+				bone_ext[i] = 1;
+			else if (bone == "Head")
+				bone_ext[i] = 2;
+			// The rest of these bones are extremity '0'
+		}
+		else if (bone == "LeftShoulder" || bone == "LeftArm" || bone == "LeftWrist" || bone == "LeftFist")
+		{
+			bone_type[i] = "left_arm";
+			if (bone == "LeftShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "LeftArm")
+				bone_ext[i] = 2;
+			else if (bone == "LeftWrist")
+				bone_ext[i] = 3;
+			else if (bone == "LeftFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "RightShoulder" || bone == "RightArm" || bone == "RightWrist" || bone == "RightFist")
+		{
+			bone_type[i] = "right_arm";
+			if (bone == "RightShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "RightArm")
+				bone_ext[i] = 2;
+			else if (bone == "RightWrist")
+				bone_ext[i] = 3;
+			else if (bone == "RightFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "LeftThigh" || bone == "LeftCalf" || bone == "LeftFoot")
+		{
+			bone_type[i] = "left_leg";
+			if (bone == "LeftThigh")
+				bone_ext[i] = 1;
+			else if (bone == "LeftCalf")
+				bone_ext[i] = 2;
+			else if (bone == "LeftFoot")
+				bone_ext[i] = 3;
+		}
+		else if (bone == "RightThigh" || bone == "RightCalf" || bone == "RightFoot")
+		{
+			bone_type[i] = "right_leg";
+			if (bone == "RightThigh")
+				bone_ext[i] = 1;
+			else if (bone == "RightCalf")
+				bone_ext[i] = 2;
+			else if (bone == "RightFoot")
+				bone_ext[i] = 3;
+		}
+	}
+
+	// Find outermost bone for each extremity, among the bones listed in the Attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (extremity_name[b] == bone_type[a])
+			{
+				if (bone_ext[a] > extremity_max[b])
+					extremity_max[b] = bone_ext[a];
+			}
+		}
+	}
+
+	// Add a glass_break particle for every outermost bone in the attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		// Move to next bone if this is not the outermost attacking bone on this extremity
+		var add_this_bone = false;
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (bone_type[a] == extremity_name[b])
+			{
+				if (bone_ext[a] == extremity_max[b])
+					add_this_bone = true;
+			}
+		}
+		if (!add_this_bone)
+			continue;
+
+		// Exit if we are past Oni's limit on TRAM particles
+		if (particles.length >= 16)
+		{
+			echo("Reached maximum of 16 particles for this TRAM, exiting…");
+			return;
+		}
+
+		echo("Adding glass_break to " + array_bones[a]);
+		var par_string = "<Start>" + hit_start + "</Start><End>" + hit_end + "</End><Bone>" + array_bones[a] + "</Bone><Name>glass_break</Name>";
+
+		// Add glass_break to bone for time period that bone has collision status
+		myBuilder.addElementAt("Particle",
+				       "",
+				       par_string,
+				       particles.index + 1,
+				       particles.level + 1);
+	}
+ 
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
+</code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-getupfront-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-getupfront-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-getupfront-.oni-patch	(revision 965)
@@ -3,53 +3,148 @@
 @CUSTOM_CODE
 <code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
+	// |———————————————————————————————————Code best viewed at this width————————————————————————————————————————|
+
+	// Load XML data
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+	var elements = myBuilder.elements[0];
 	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
+	// If there are no attacks in this TRAM, ignore it
+	if (!elements.childElement("Animation").childElement("Attacks"))
+		return;
+	
+	// Gather all the necessary info
+	var particles   = elements.childElement("Animation").childElement("Particles");
+	var attack      = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
+	var hit_start   = attack.childElement("Start").text;
+	var hit_end     = attack.childElement("End").text;
+	var array_bones = attack.childElement("Bones").text.split(" ");
+						
+	// Remove glass_break if it is already assigned to any bones, because it's probably not been assigned the
+	// way we want it to be
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Name").text == "glass_break")
+			myBuilder.removeElement(particle.index);
 	}
 
-	var myBuilder = new JSXMLBuilder();
-	myBuilder.load($xmlData);
-
-	var elements = myBuilder.elements[0];
-	
-	var particles = elements.childElement("Animation").childElement("Particles");
-	
-			
-	if(!elements.childElement("Animation").childElement("Attacks")){ // if no attacks found ignore file
-		return;
-	}
-	
-	var attackElement = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
-	
-	var int_start,int_end,array_bones;
-	
-	// gather all the necessary info
-	int_start=attackElement.childElement("Start").text;
-	int_end=attackElement.childElement("End").text;
-	array_bones=attackElement.childElement("Bones").text.split(" ");
-						
-	// Check if any of the existing particles correspond to the same bone and glass_break
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(contains(array_bones,currElement.childElement("Bone").text) && currElement.childElement("Name").text=="glass_break"){
-			removeFromArray(array_bones,currElement.childElement("Bone").text); // not necessary to add
+	// Find the outermost bone of each type
+	// The "type" in bone_type[] refers to the extremity of the body to which a bone belongs ("mid" counts as
+	// as an extremity because the head is part of "mid"); this is a "parallel array" with array_bones[]
+	var bone_type = new Array(19);
+	// The "ext" in bone_ext[] refers to the "outermostness" of the bone, that is, how far out on the extremity
+	// this bone is; this is a parallel array with array_bones[]
+	var bone_ext = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+	// The extremity_ arrays are parallel arrays which store the highest "outermostness" value found for each
+	// extremity, among all the bones in that extremity that are listed in the attack
+	var extremity_name = ["mid", "left_arm", "right_arm", "left_leg", "right_leg"];
+	var extremity_max = [0, 0, 0, 0, 0];
+	for (var i = 0; i < array_bones.length; i++)
+	{
+		var bone = array_bones[i];
+		if (bone == "Head" || bone == "Neck" || bone == "Chest" || bone == "Mid" || bone == "Pelvis")
+		{
+			bone_type[i] = "mid";
+			if (bone == "Neck")
+				bone_ext[i] = 1;
+			else if (bone == "Head")
+				bone_ext[i] = 2;
+			// The rest of these bones are extremity '0'
+		}
+		else if (bone == "LeftShoulder" || bone == "LeftArm" || bone == "LeftWrist" || bone == "LeftFist")
+		{
+			bone_type[i] = "left_arm";
+			if (bone == "LeftShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "LeftArm")
+				bone_ext[i] = 2;
+			else if (bone == "LeftWrist")
+				bone_ext[i] = 3;
+			else if (bone == "LeftFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "RightShoulder" || bone == "RightArm" || bone == "RightWrist" || bone == "RightFist")
+		{
+			bone_type[i] = "right_arm";
+			if (bone == "RightShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "RightArm")
+				bone_ext[i] = 2;
+			else if (bone == "RightWrist")
+				bone_ext[i] = 3;
+			else if (bone == "RightFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "LeftThigh" || bone == "LeftCalf" || bone == "LeftFoot")
+		{
+			bone_type[i] = "left_leg";
+			if (bone == "LeftThigh")
+				bone_ext[i] = 1;
+			else if (bone == "LeftCalf")
+				bone_ext[i] = 2;
+			else if (bone == "LeftFoot")
+				bone_ext[i] = 3;
+		}
+		else if (bone == "RightThigh" || bone == "RightCalf" || bone == "RightFoot")
+		{
+			bone_type[i] = "right_leg";
+			if (bone == "RightThigh")
+				bone_ext[i] = 1;
+			else if (bone == "RightCalf")
+				bone_ext[i] = 2;
+			else if (bone == "RightFoot")
+				bone_ext[i] = 3;
 		}
 	}
-	
-	// Insert the new glass particles
-	for (var i = 0; i < array_bones.length; i++) {
-		if(array_bones[i]=="RightFoot" || array_bones[i]=="LeftFoot" || array_bones[i]=="RightFist" || array_bones[i]=="LeftFist"){
-		myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>"+array_bones[i]+"</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
+
+	// Find outermost bone for each extremity, among the bones listed in the Attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (extremity_name[b] == bone_type[a])
+			{
+				if (bone_ext[a] > extremity_max[b])
+					extremity_max[b] = bone_ext[a];
+			}
 		}
 	}
+
+	// Add a glass_break particle for every outermost bone in the attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		// Move to next bone if this is not the outermost attacking bone on this extremity
+		var add_this_bone = false;
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (bone_type[a] == extremity_name[b])
+			{
+				if (bone_ext[a] == extremity_max[b])
+					add_this_bone = true;
+			}
+		}
+		if (!add_this_bone)
+			continue;
+
+		// Exit if we are past Oni's limit on TRAM particles
+		if (particles.length >= 16)
+		{
+			echo("Reached maximum of 16 particles for this TRAM, exiting…");
+			return;
+		}
+
+		echo("Adding glass_break to " + array_bones[a]);
+		var par_string = "<Start>" + hit_start + "</Start><End>" + hit_end + "</End><Bone>" + array_bones[a] + "</Bone><Name>glass_break</Name>";
+
+		// Add glass_break to bone for time period that bone has collision status
+		myBuilder.addElementAt("Particle",
+				       "",
+				       par_string,
+				       particles.index + 1,
+				       particles.level + 1);
+	}
  
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
 </code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-kick-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-kick-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-kick-.oni-patch	(revision 965)
@@ -3,53 +3,148 @@
 @CUSTOM_CODE
 <code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
+	// |———————————————————————————————————Code best viewed at this width————————————————————————————————————————|
+
+	// Load XML data
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+	var elements = myBuilder.elements[0];
 	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
+	// If there are no attacks in this TRAM, ignore it
+	if (!elements.childElement("Animation").childElement("Attacks"))
+		return;
+	
+	// Gather all the necessary info
+	var particles   = elements.childElement("Animation").childElement("Particles");
+	var attack      = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
+	var hit_start   = attack.childElement("Start").text;
+	var hit_end     = attack.childElement("End").text;
+	var array_bones = attack.childElement("Bones").text.split(" ");
+						
+	// Remove glass_break if it is already assigned to any bones, because it's probably not been assigned the
+	// way we want it to be
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Name").text == "glass_break")
+			myBuilder.removeElement(particle.index);
 	}
 
-	var myBuilder = new JSXMLBuilder();
-	myBuilder.load($xmlData);
-
-	var elements = myBuilder.elements[0];
-	
-	var particles = elements.childElement("Animation").childElement("Particles");
-	
-			
-	if(!elements.childElement("Animation").childElement("Attacks")){ // if no attacks found ignore file
-		return;
-	}
-	
-	var attackElement = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
-	
-	var int_start,int_end,array_bones;
-	
-	// gather all the necessary info
-	int_start=attackElement.childElement("Start").text;
-	int_end=attackElement.childElement("End").text;
-	array_bones=attackElement.childElement("Bones").text.split(" ");
-						
-	// Check if any of the existing particles correspond to the same bone and glass_break
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(contains(array_bones,currElement.childElement("Bone").text) && currElement.childElement("Name").text=="glass_break"){
-			removeFromArray(array_bones,currElement.childElement("Bone").text); // not necessary to add
+	// Find the outermost bone of each type
+	// The "type" in bone_type[] refers to the extremity of the body to which a bone belongs ("mid" counts as
+	// as an extremity because the head is part of "mid"); this is a "parallel array" with array_bones[]
+	var bone_type = new Array(19);
+	// The "ext" in bone_ext[] refers to the "outermostness" of the bone, that is, how far out on the extremity
+	// this bone is; this is a parallel array with array_bones[]
+	var bone_ext = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+	// The extremity_ arrays are parallel arrays which store the highest "outermostness" value found for each
+	// extremity, among all the bones in that extremity that are listed in the attack
+	var extremity_name = ["mid", "left_arm", "right_arm", "left_leg", "right_leg"];
+	var extremity_max = [0, 0, 0, 0, 0];
+	for (var i = 0; i < array_bones.length; i++)
+	{
+		var bone = array_bones[i];
+		if (bone == "Head" || bone == "Neck" || bone == "Chest" || bone == "Mid" || bone == "Pelvis")
+		{
+			bone_type[i] = "mid";
+			if (bone == "Neck")
+				bone_ext[i] = 1;
+			else if (bone == "Head")
+				bone_ext[i] = 2;
+			// The rest of these bones are extremity '0'
+		}
+		else if (bone == "LeftShoulder" || bone == "LeftArm" || bone == "LeftWrist" || bone == "LeftFist")
+		{
+			bone_type[i] = "left_arm";
+			if (bone == "LeftShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "LeftArm")
+				bone_ext[i] = 2;
+			else if (bone == "LeftWrist")
+				bone_ext[i] = 3;
+			else if (bone == "LeftFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "RightShoulder" || bone == "RightArm" || bone == "RightWrist" || bone == "RightFist")
+		{
+			bone_type[i] = "right_arm";
+			if (bone == "RightShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "RightArm")
+				bone_ext[i] = 2;
+			else if (bone == "RightWrist")
+				bone_ext[i] = 3;
+			else if (bone == "RightFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "LeftThigh" || bone == "LeftCalf" || bone == "LeftFoot")
+		{
+			bone_type[i] = "left_leg";
+			if (bone == "LeftThigh")
+				bone_ext[i] = 1;
+			else if (bone == "LeftCalf")
+				bone_ext[i] = 2;
+			else if (bone == "LeftFoot")
+				bone_ext[i] = 3;
+		}
+		else if (bone == "RightThigh" || bone == "RightCalf" || bone == "RightFoot")
+		{
+			bone_type[i] = "right_leg";
+			if (bone == "RightThigh")
+				bone_ext[i] = 1;
+			else if (bone == "RightCalf")
+				bone_ext[i] = 2;
+			else if (bone == "RightFoot")
+				bone_ext[i] = 3;
 		}
 	}
-	
-	// Insert the new glass particles
-	for (var i = 0; i < array_bones.length; i++) {
-		if(array_bones[i]=="RightFoot" || array_bones[i]=="LeftFoot" || array_bones[i]=="RightFist" || array_bones[i]=="LeftFist"){
-		myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>"+array_bones[i]+"</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
+
+	// Find outermost bone for each extremity, among the bones listed in the Attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (extremity_name[b] == bone_type[a])
+			{
+				if (bone_ext[a] > extremity_max[b])
+					extremity_max[b] = bone_ext[a];
+			}
 		}
 	}
+
+	// Add a glass_break particle for every outermost bone in the attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		// Move to next bone if this is not the outermost attacking bone on this extremity
+		var add_this_bone = false;
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (bone_type[a] == extremity_name[b])
+			{
+				if (bone_ext[a] == extremity_max[b])
+					add_this_bone = true;
+			}
+		}
+		if (!add_this_bone)
+			continue;
+
+		// Exit if we are past Oni's limit on TRAM particles
+		if (particles.length >= 16)
+		{
+			echo("Reached maximum of 16 particles for this TRAM, exiting…");
+			return;
+		}
+
+		echo("Adding glass_break to " + array_bones[a]);
+		var par_string = "<Start>" + hit_start + "</Start><End>" + hit_end + "</End><Bone>" + array_bones[a] + "</Bone><Name>glass_break</Name>";
+
+		// Add glass_break to bone for time period that bone has collision status
+		myBuilder.addElementAt("Particle",
+				       "",
+				       par_string,
+				       particles.index + 1,
+				       particles.level + 1);
+	}
  
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
 </code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-knockdown-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-knockdown-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-knockdown-.oni-patch	(revision 965)
@@ -3,43 +3,37 @@
 @CUSTOM_CODE
 <code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
-	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
-	}
-
 	var myBuilder = new JSXMLBuilder();
 	myBuilder.load($xmlData);
 
 	var elements = myBuilder.elements[0];
-	
 	var particles = elements.childElement("Animation").childElement("Particles");
 						
-	// Check if any of the existing particles contains a head bone
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
+	// Check to see if glass_break is already added to Head
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Bone").text == "Head" &&
+		    particle.childElement("Name").text == "glass_break")
+			return;
+	}
 
-		if(currElement.childElement("Bone").text=="Head"){
-			if(currElement.childElement("Name").text=="glass_break"){
-				return; // not necessary to add
-			}
-			else{
-				// gather all the necessary info
-				var int_start=currElement.childElement("Start").text;
-				var int_end=currElement.childElement("End").text;
+	// Exit if we are past Oni's limit on TRAM particles
+	if (particles.length >= 16)
+		return;
 				
-				// Insert the new glass particle (for when he touches glass with head
-				myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>Head</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
-				break;
-			}
-		}
-	}
+	// Add the glass_break particle to Head for duration of animation
+	var heights = elements.childElement("Animation").childElement("Heights");
+	var anim_length;
+	for (anim_length = 0; (heights.childElement(anim_length)); anim_length++) {;}
+	myBuilder.addElementAt("Particle",
+			       "",
+			       "<Start>0</Start>\
+                		<End>" + (anim_length-1) + "</End>\
+                		<Bone>Head</Bone>\
+                		<Name>glass_break</Name>",
+			       particles.index + 1,
+			       particles.level + 1);
  
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
 </code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-punch-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-punch-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-punch-.oni-patch	(revision 965)
@@ -3,53 +3,148 @@
 @CUSTOM_CODE
 <code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
+	// |———————————————————————————————————Code best viewed at this width————————————————————————————————————————|
+
+	// Load XML data
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+	var elements = myBuilder.elements[0];
 	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
+	// If there are no attacks in this TRAM, ignore it
+	if (!elements.childElement("Animation").childElement("Attacks"))
+		return;
+	
+	// Gather all the necessary info
+	var particles   = elements.childElement("Animation").childElement("Particles");
+	var attack      = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
+	var hit_start   = attack.childElement("Start").text;
+	var hit_end     = attack.childElement("End").text;
+	var array_bones = attack.childElement("Bones").text.split(" ");
+						
+	// Remove glass_break if it is already assigned to any bones, because it's probably not been assigned the
+	// way we want it to be
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Name").text == "glass_break")
+			myBuilder.removeElement(particle.index);
 	}
 
-	var myBuilder = new JSXMLBuilder();
-	myBuilder.load($xmlData);
-
-	var elements = myBuilder.elements[0];
-	
-	var particles = elements.childElement("Animation").childElement("Particles");
-	
-			
-	if(!elements.childElement("Animation").childElement("Attacks")){ // if no attacks found ignore file
-		return;
-	}
-	
-	var attackElement = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
-	
-	var int_start,int_end,array_bones;
-	
-	// gather all the necessary info
-	int_start=attackElement.childElement("Start").text;
-	int_end=attackElement.childElement("End").text;
-	array_bones=attackElement.childElement("Bones").text.split(" ");
-						
-	// Check if any of the existing particles correspond to the same bone and glass_break
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(contains(array_bones,currElement.childElement("Bone").text) && currElement.childElement("Name").text=="glass_break"){
-			removeFromArray(array_bones,currElement.childElement("Bone").text); // not necessary to add
+	// Find the outermost bone of each type
+	// The "type" in bone_type[] refers to the extremity of the body to which a bone belongs ("mid" counts as
+	// as an extremity because the head is part of "mid"); this is a "parallel array" with array_bones[]
+	var bone_type = new Array(19);
+	// The "ext" in bone_ext[] refers to the "outermostness" of the bone, that is, how far out on the extremity
+	// this bone is; this is a parallel array with array_bones[]
+	var bone_ext = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+	// The extremity_ arrays are parallel arrays which store the highest "outermostness" value found for each
+	// extremity, among all the bones in that extremity that are listed in the attack
+	var extremity_name = ["mid", "left_arm", "right_arm", "left_leg", "right_leg"];
+	var extremity_max = [0, 0, 0, 0, 0];
+	for (var i = 0; i < array_bones.length; i++)
+	{
+		var bone = array_bones[i];
+		if (bone == "Head" || bone == "Neck" || bone == "Chest" || bone == "Mid" || bone == "Pelvis")
+		{
+			bone_type[i] = "mid";
+			if (bone == "Neck")
+				bone_ext[i] = 1;
+			else if (bone == "Head")
+				bone_ext[i] = 2;
+			// The rest of these bones are extremity '0'
+		}
+		else if (bone == "LeftShoulder" || bone == "LeftArm" || bone == "LeftWrist" || bone == "LeftFist")
+		{
+			bone_type[i] = "left_arm";
+			if (bone == "LeftShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "LeftArm")
+				bone_ext[i] = 2;
+			else if (bone == "LeftWrist")
+				bone_ext[i] = 3;
+			else if (bone == "LeftFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "RightShoulder" || bone == "RightArm" || bone == "RightWrist" || bone == "RightFist")
+		{
+			bone_type[i] = "right_arm";
+			if (bone == "RightShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "RightArm")
+				bone_ext[i] = 2;
+			else if (bone == "RightWrist")
+				bone_ext[i] = 3;
+			else if (bone == "RightFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "LeftThigh" || bone == "LeftCalf" || bone == "LeftFoot")
+		{
+			bone_type[i] = "left_leg";
+			if (bone == "LeftThigh")
+				bone_ext[i] = 1;
+			else if (bone == "LeftCalf")
+				bone_ext[i] = 2;
+			else if (bone == "LeftFoot")
+				bone_ext[i] = 3;
+		}
+		else if (bone == "RightThigh" || bone == "RightCalf" || bone == "RightFoot")
+		{
+			bone_type[i] = "right_leg";
+			if (bone == "RightThigh")
+				bone_ext[i] = 1;
+			else if (bone == "RightCalf")
+				bone_ext[i] = 2;
+			else if (bone == "RightFoot")
+				bone_ext[i] = 3;
 		}
 	}
-	
-	// Insert the new glass particles
-	for (var i = 0; i < array_bones.length; i++) {
-		if(array_bones[i]=="RightFoot" || array_bones[i]=="LeftFoot" || array_bones[i]=="RightFist" || array_bones[i]=="LeftFist"){
-		myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>"+array_bones[i]+"</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
+
+	// Find outermost bone for each extremity, among the bones listed in the Attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (extremity_name[b] == bone_type[a])
+			{
+				if (bone_ext[a] > extremity_max[b])
+					extremity_max[b] = bone_ext[a];
+			}
 		}
 	}
+
+	// Add a glass_break particle for every outermost bone in the attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		// Move to next bone if this is not the outermost attacking bone on this extremity
+		var add_this_bone = false;
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (bone_type[a] == extremity_name[b])
+			{
+				if (bone_ext[a] == extremity_max[b])
+					add_this_bone = true;
+			}
+		}
+		if (!add_this_bone)
+			continue;
+
+		// Exit if we are past Oni's limit on TRAM particles
+		if (particles.length >= 16)
+		{
+			echo("Reached maximum of 16 particles for this TRAM, exiting…");
+			return;
+		}
+
+		echo("Adding glass_break to " + array_bones[a]);
+		var par_string = "<Start>" + hit_start + "</Start><End>" + hit_end + "</End><Bone>" + array_bones[a] + "</Bone><Name>glass_break</Name>";
+
+		// Add glass_break to bone for time period that bone has collision status
+		myBuilder.addElementAt("Particle",
+				       "",
+				       par_string,
+				       particles.index + 1,
+				       particles.level + 1);
+	}
  
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
 </code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-run_thw_fw_p_tgt-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-run_thw_fw_p_tgt-.oni-patch	(revision 963)
+++ 	(revision )
@@ -1,55 +1,0 @@
-@XML_TOOLS Version "2.0"
-
-@CUSTOM_CODE
-<code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
-	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
-	}
-
-	var myBuilder = new JSXMLBuilder();
-	myBuilder.load($xmlData);
-
-	var elements = myBuilder.elements[0];
-	
-	var particles = elements.childElement("Animation").childElement("Particles");
-	
-			
-	if(!elements.childElement("Animation").childElement("Attacks")){ // if no attacks found ignore file
-		return;
-	}
-	
-	var attackElement = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
-	
-	var int_start,int_end,array_bones;
-	
-	// gather all the necessary info
-	int_start=attackElement.childElement("Start").text;
-	int_end=attackElement.childElement("End").text;
-	array_bones=attackElement.childElement("Bones").text.split(" ");
-						
-	// Check if any of the existing particles correspond to the same bone and glass_break
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(contains(array_bones,currElement.childElement("Bone").text) && currElement.childElement("Name").text=="glass_break"){
-			removeFromArray(array_bones,currElement.childElement("Bone").text); // not necessary to add
-		}
-	}
-	
-	// Insert the new glass particles
-	for (var i = 0; i < array_bones.length; i++) {
-		if(array_bones[i]=="RightFoot" || array_bones[i]=="LeftFoot" || array_bones[i]=="RightFist" || array_bones[i]=="LeftFist"){
-		myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>"+array_bones[i]+"</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
-		}
-	}
- 
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
-</code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-slide-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-slide-.oni-patch	(revision 963)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-slide-.oni-patch	(revision 965)
@@ -3,53 +3,148 @@
 @CUSTOM_CODE
 <code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
+	// |———————————————————————————————————Code best viewed at this width————————————————————————————————————————|
+
+	// Load XML data
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+	var elements = myBuilder.elements[0];
 	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
+	// If there are no attacks in this TRAM, ignore it
+	if (!elements.childElement("Animation").childElement("Attacks"))
+		return;
+	
+	// Gather all the necessary info
+	var particles   = elements.childElement("Animation").childElement("Particles");
+	var attack      = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
+	var hit_start   = attack.childElement("Start").text;
+	var hit_end     = attack.childElement("End").text;
+	var array_bones = attack.childElement("Bones").text.split(" ");
+						
+	// Remove glass_break if it is already assigned to any bones, because it's probably not been assigned the
+	// way we want it to be
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		if (particle.childElement("Name").text == "glass_break")
+			myBuilder.removeElement(particle.index);
 	}
 
-	var myBuilder = new JSXMLBuilder();
-	myBuilder.load($xmlData);
-
-	var elements = myBuilder.elements[0];
-	
-	var particles = elements.childElement("Animation").childElement("Particles");
-	
-			
-	if(!elements.childElement("Animation").childElement("Attacks")){ // if no attacks found ignore file
-		return;
-	}
-	
-	var attackElement = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
-	
-	var int_start,int_end,array_bones;
-	
-	// gather all the necessary info
-	int_start=attackElement.childElement("Start").text;
-	int_end=attackElement.childElement("End").text;
-	array_bones=attackElement.childElement("Bones").text.split(" ");
-						
-	// Check if any of the existing particles correspond to the same bone and glass_break
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(contains(array_bones,currElement.childElement("Bone").text) && currElement.childElement("Name").text=="glass_break"){
-			removeFromArray(array_bones,currElement.childElement("Bone").text); // not necessary to add
+	// Find the outermost bone of each type
+	// The "type" in bone_type[] refers to the extremity of the body to which a bone belongs ("mid" counts as
+	// as an extremity because the head is part of "mid"); this is a "parallel array" with array_bones[]
+	var bone_type = new Array(19);
+	// The "ext" in bone_ext[] refers to the "outermostness" of the bone, that is, how far out on the extremity
+	// this bone is; this is a parallel array with array_bones[]
+	var bone_ext = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+	// The extremity_ arrays are parallel arrays which store the highest "outermostness" value found for each
+	// extremity, among all the bones in that extremity that are listed in the attack
+	var extremity_name = ["mid", "left_arm", "right_arm", "left_leg", "right_leg"];
+	var extremity_max = [0, 0, 0, 0, 0];
+	for (var i = 0; i < array_bones.length; i++)
+	{
+		var bone = array_bones[i];
+		if (bone == "Head" || bone == "Neck" || bone == "Chest" || bone == "Mid" || bone == "Pelvis")
+		{
+			bone_type[i] = "mid";
+			if (bone == "Neck")
+				bone_ext[i] = 1;
+			else if (bone == "Head")
+				bone_ext[i] = 2;
+			// The rest of these bones are extremity '0'
+		}
+		else if (bone == "LeftShoulder" || bone == "LeftArm" || bone == "LeftWrist" || bone == "LeftFist")
+		{
+			bone_type[i] = "left_arm";
+			if (bone == "LeftShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "LeftArm")
+				bone_ext[i] = 2;
+			else if (bone == "LeftWrist")
+				bone_ext[i] = 3;
+			else if (bone == "LeftFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "RightShoulder" || bone == "RightArm" || bone == "RightWrist" || bone == "RightFist")
+		{
+			bone_type[i] = "right_arm";
+			if (bone == "RightShoulder")
+				bone_ext[i] = 1;
+			else if (bone == "RightArm")
+				bone_ext[i] = 2;
+			else if (bone == "RightWrist")
+				bone_ext[i] = 3;
+			else if (bone == "RightFist")
+				bone_ext[i] = 4;
+		}
+		else if (bone == "LeftThigh" || bone == "LeftCalf" || bone == "LeftFoot")
+		{
+			bone_type[i] = "left_leg";
+			if (bone == "LeftThigh")
+				bone_ext[i] = 1;
+			else if (bone == "LeftCalf")
+				bone_ext[i] = 2;
+			else if (bone == "LeftFoot")
+				bone_ext[i] = 3;
+		}
+		else if (bone == "RightThigh" || bone == "RightCalf" || bone == "RightFoot")
+		{
+			bone_type[i] = "right_leg";
+			if (bone == "RightThigh")
+				bone_ext[i] = 1;
+			else if (bone == "RightCalf")
+				bone_ext[i] = 2;
+			else if (bone == "RightFoot")
+				bone_ext[i] = 3;
 		}
 	}
-	
-	// Insert the new glass particles
-	for (var i = 0; i < array_bones.length; i++) {
-		if(array_bones[i]=="RightFoot" || array_bones[i]=="LeftFoot" || array_bones[i]=="RightFist" || array_bones[i]=="LeftFist"){
-		myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>"+array_bones[i]+"</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
+
+	// Find outermost bone for each extremity, among the bones listed in the Attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (extremity_name[b] == bone_type[a])
+			{
+				if (bone_ext[a] > extremity_max[b])
+					extremity_max[b] = bone_ext[a];
+			}
 		}
 	}
+
+	// Add a glass_break particle for every outermost bone in the attack
+	for (var a = 0; a < array_bones.length; a++)
+	{
+		// Move to next bone if this is not the outermost attacking bone on this extremity
+		var add_this_bone = false;
+		for (var b = 0; b < extremity_name.length; b++)
+		{
+			if (bone_type[a] == extremity_name[b])
+			{
+				if (bone_ext[a] == extremity_max[b])
+					add_this_bone = true;
+			}
+		}
+		if (!add_this_bone)
+			continue;
+
+		// Exit if we are past Oni's limit on TRAM particles
+		if (particles.length >= 16)
+		{
+			echo("Reached maximum of 16 particles for this TRAM, exiting…");
+			return;
+		}
+
+		echo("Adding glass_break to " + array_bones[a]);
+		var par_string = "<Start>" + hit_start + "</Start><End>" + hit_end + "</End><Bone>" + array_bones[a] + "</Bone><Name>glass_break</Name>";
+
+		// Add glass_break to bone for time period that bone has collision status
+		myBuilder.addElementAt("Particle",
+				       "",
+				       par_string,
+				       particles.index + 1,
+				       particles.level + 1);
+	}
  
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
 </code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-tgt-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-tgt-.oni-patch	(revision 965)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-tgt-.oni-patch	(revision 965)
@@ -0,0 +1,64 @@
+@XML_TOOLS Version "2.0"
+
+@CUSTOM_CODE
+<code>
+	var myBuilder = new JSXMLBuilder();
+	myBuilder.load($xmlData);
+
+	var elements = myBuilder.elements[0];
+	var particles = elements.childElement("Animation").childElement("Particles");
+	var added_to_head = false, added_to_feet = false;
+	
+	// Check if glass_break is assigned to Head and one of the feet;
+	// remove it from any other bones if present
+	for (var i = 0; (particles.childElement(i)); i++)
+	{
+		var particle = particles.childElement(i);
+		var bone = particle.childElement("Bone").text;
+		var name = particle.childElement("Name").text;
+		if (name == "glass_break")
+		{
+			if (bone == "Head")
+				added_to_head = true;
+			else if (bone == "RightFoot")
+				added_to_feet = true;
+			else
+				myBuilder.removeElement(particle.index);
+		}
+	}
+
+	// Exit if we are past Oni's limit on TRAM particles
+	if (particles.length >= 16)
+		return;
+
+	// Add the glass_break particle to the desired bones if it's not there already
+	var heights = elements.childElement("Animation").childElement("Heights");
+	var anim_length;
+	for (anim_length = 0; (heights.childElement(anim_length)); anim_length++) {;}
+	if (!added_to_head)
+		myBuilder.addElementAt("Particle",
+				       "",
+			 	       "<Start>0</Start>\
+                			<End>" + (anim_length-1) + "</End>\
+                			<Bone>Head</Bone>\
+                			<Name>glass_break</Name>",
+				       particles.index + 1,
+				       particles.level + 1);
+
+	// Exit if we are past Oni's limit on TRAM particles
+	if (particles.length >= 16)
+		return;
+
+	if (!added_to_feet)
+		myBuilder.addElementAt("Particle",
+				       "",
+			 	       "<Start>0</Start>\
+                			<End>" + (anim_length-1) + "</End>\
+                			<Bone>RightFoot</Bone>\
+                			<Name>glass_break</Name>",
+				       particles.index + 1,
+				       particles.level + 1);
+ 
+	// Update the global variable with the new XML
+	$xmlData = myBuilder.generateXML();
+</code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-throw-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-throw-.oni-patch	(revision 963)
+++ 	(revision )
@@ -1,55 +1,0 @@
-@XML_TOOLS Version "2.0"
-
-@CUSTOM_CODE
-<code>
-	function contains(fullStringOrArray, subString){
-		return fullStringOrArray.indexOf(subString)!=-1;
-	}
-	
-	function removeFromArray(_array, _value){
-		_array.splice(_array.indexOf(_value), 1);
-	}
-
-	var myBuilder = new JSXMLBuilder();
-	myBuilder.load($xmlData);
-
-	var elements = myBuilder.elements[0];
-	
-	var particles = elements.childElement("Animation").childElement("Particles");
-	
-			
-	if(!elements.childElement("Animation").childElement("Attacks")){ // if no attacks found ignore file
-		return;
-	}
-	
-	var attackElement = elements.childElement("Animation").childElement("Attacks").childElement("Attack");
-	
-	var int_start,int_end,array_bones;
-	
-	// gather all the necessary info
-	int_start=attackElement.childElement("Start").text;
-	int_end=attackElement.childElement("End").text;
-	array_bones=attackElement.childElement("Bones").text.split(" ");
-						
-	// Check if any of the existing particles correspond to the same bone and glass_break
-	for (var i=0; (particles.childElement(i)); i++){ // the condition is to check if the child element exists (!= undefined)
-		var currElement=particles.childElement(i);
-
-		if(contains(array_bones,currElement.childElement("Bone").text) && currElement.childElement("Name").text=="glass_break"){
-			removeFromArray(array_bones,currElement.childElement("Bone").text); // not necessary to add
-		}
-	}
-	
-	// Insert the new glass particles
-	for (var i = 0; i < array_bones.length; i++) {
-		if(array_bones[i]=="RightFoot" || array_bones[i]=="LeftFoot" || array_bones[i]=="RightFist" || array_bones[i]=="LeftFist"){
-		myBuilder.addElementAt("Particle","",
-				"<Start>"+int_start+"</Start>\
-                <End>"+int_end+"</End>\
-                <Bone>"+array_bones[i]+"</Bone>\
-                <Name>glass_break</Name>",particles.index+1,particles.level+1);
-		}
-	}
- 
-	$xmlData=myBuilder.generateXML(); // update the global variable with the new XML
-</code>
Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAMKONCOMrun_throw_fw.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAMKONCOMrun_throw_fw.oni-patch	(revision 965)
+++ AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAMKONCOMrun_throw_fw.oni-patch	(revision 965)
@@ -0,0 +1,11 @@
+@XML_TOOLS Version "2.0"
+
+@ADD_INSIDE_NODES ElementName "Particles"
+<xml>
+    <Particle>
+        <Start>29</Start>
+        <End>39</End>
+        <Bone>LeftFoot</Bone>
+        <Name>glass_break</Name>
+    </Particle>
+</xml>
