Index: AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-slide-.oni-patch
===================================================================
--- AE/packages/31000GlassBreakingMoves/patches/common/level0_Final/TRAM-slide-.oni-patch	(revision 959)
+++ 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>
