private void ChangeObjectCapability(CapabilityValue newCapabilitySet, string objectID) { SimulationObjectProxy obj = objectProxies[objectID]; if (obj == null) { return; } CapabilityValue previousCapabilityValue = obj["Capability"].GetDataValue() as CapabilityValue; List <string> previousCapabilityNames = previousCapabilityValue.GetCapabilityNames(); List <string> newCapabilityNames = newCapabilitySet.GetCapabilityNames(); List <string> missingCapabilities = new List <string>(); foreach (string capName in previousCapabilityNames) { if (!newCapabilityNames.Contains(capName)) { if (!missingCapabilities.Contains(capName)) { missingCapabilities.Add(capName); } } } foreach (string capName in missingCapabilities) { CancelCapabilityAttack(capName, objectID); } obj["Capability"].SetDataValue(newCapabilitySet); missingCapabilities.Clear(); newCapabilityNames.Clear(); previousCapabilityNames.Clear(); }
public void GetOrderedEffectsByCapabilityTest() { CapabilityValue target = new CapabilityValue(); // TODO: Initialize to an appropriate value CapabilityValue.Effect ef = new CapabilityValue.Effect("Capability1", 1000.0, 10, 1); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability2", 2000.0, 20, 1); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability1", 2000.0, 20, 1); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability1", 500.0, 5, 0.5); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability2", 555.0, 6, 0.6); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability1", 5000.0, 50, 1); target.effects.Add(ef); //this shows that the function returns the correctly ordered list for Capability1 List <CapabilityValue.Effect> actual; actual = target.GetOrderedEffectsByCapability("Capability1"); Assert.AreEqual(actual.Count, 4); Assert.AreEqual(actual[0].range, 500.0); Assert.AreEqual(actual[1].range, 1000.0); Assert.AreEqual(actual[0].intensity, 5); Assert.AreEqual(actual[1].intensity, 10); //this shows that the function returns the correctly ordered list for Capability2 actual = target.GetOrderedEffectsByCapability("Capability2"); Assert.AreEqual(actual.Count, 2); Assert.AreEqual(actual[0].range, 555.0); Assert.AreEqual(actual[1].range, 2000.0); Assert.AreEqual(actual[0].intensity, 6); Assert.AreEqual(actual[1].intensity, 20); //this shows that removal from the returned list doesn't affect the structure of the internal list. actual.RemoveAt(1); actual = target.effects; Assert.AreEqual(actual.Count, 6); Assert.AreEqual(actual[0].range, 1000.0); Assert.AreEqual(actual[1].range, 2000.0); Assert.AreEqual(actual[0].intensity, 10); Assert.AreEqual(actual[1].intensity, 20); }
/* * static public void SkipToReset(ref List<SimulationEvent> eventList) * { * bool resetFound = false; * * foreach (SimulationEvent e in eventList) * { * if (e.eventType == "ResetSimulation") * { * resetFound = true; * } * } * * if (resetFound) * { * while (eventList.Count > 0 && eventList[0].eventType != "ResetSimulation") * { * eventList.Remove(eventList[0]); * } * } * } */ static public CapabilityValue.Effect FindCapabilityEffect(CapabilityValue cap, VulnerabilityValue vuln) { List <string> vulnNames = new List <string>(); foreach (VulnerabilityValue.Transition t in vuln.transitions) { foreach (VulnerabilityValue.TransitionCondition tc in t.conditions) { if (!vulnNames.Contains(tc.capability)) { vulnNames.Add(tc.capability); } } } foreach (CapabilityValue.Effect e in cap.effects) { if (vulnNames.Contains(e.name)) { return(e); } } return(null); }
/// <summary> /// Similar to CalculateRangeRings, this is done with ABSOLUTE data, not detected values. /// This method is called in a ViewProAttributeUpdate call, which only contains attributes /// which have CHANGED, and will determine if either the sensors, vulnerabilties, or capabilities (including docked weapons) has /// changed. If so, then new attributes will be added to the attribute collection value. /// </summary> /// <param name="acv"></param> /// <param name="fullObjectView"></param> /// <returns></returns> private void AddRangeRings(ref AttributeCollectionValue acv, ref SimulationObjectProxy fullObjectView) { if (acv.attributes.ContainsKey("Sensors")) { //detected contains a sensor array type CustomAttributesValue sensorCollection = DataValueFactory.BuildCustomAttributes(new Dictionary <string, DataValue>()) as CustomAttributesValue; RangeRingDisplayValue sensorRing; SensorArrayValue detectedSensors = acv["Sensors"] as SensorArrayValue; foreach (SensorValue sv in detectedSensors.sensors) { sensorRing = DataValueFactory.BuildRangeRingDisplayValue(sv.sensorName, "Sensors", false, new Dictionary <int, int>()) as RangeRingDisplayValue; sensorRing.rangeIntensities.Add(Convert.ToInt32(sv.maxRange), -1); sensorCollection.attributes.Add(sv.sensorName, sensorRing); } if (sensorCollection.attributes.Count > 0) { acv.attributes.Add("SensorRangeRings", sensorCollection); } else { Console.WriteLine("No SensorRangeRings added to ACV"); } } if (acv.attributes.ContainsKey("Vulnerability")) { //gets detected values, containing a vulnerability type CustomAttributesValue vulnerabilityCollection = DataValueFactory.BuildCustomAttributes(new Dictionary <string, DataValue>()) as CustomAttributesValue; RangeRingDisplayValue vulnerabilityRing; VulnerabilityValue detectedVulnerability = acv["Vulnerability"] as VulnerabilityValue; Dictionary <string, int> longestRange = new Dictionary <string, int>();//[Capability],[Range] foreach (VulnerabilityValue.Transition tr in detectedVulnerability.transitions) { foreach (VulnerabilityValue.TransitionCondition tc in tr.conditions) { if (!longestRange.ContainsKey(tc.capability)) { longestRange.Add(tc.capability, -1); } if (longestRange[tc.capability] < Convert.ToInt32(tc.range)) { longestRange[tc.capability] = Convert.ToInt32(tc.range); } } } foreach (KeyValuePair <string, int> kvp in longestRange) { vulnerabilityRing = DataValueFactory.BuildRangeRingDisplayValue(kvp.Key, "Vulnerability", false, new Dictionary <int, int>()) as RangeRingDisplayValue; vulnerabilityRing.rangeIntensities.Add(kvp.Value, -1); vulnerabilityCollection.attributes.Add(kvp.Key, vulnerabilityRing); } if (vulnerabilityCollection.attributes.Count > 0) { acv.attributes.Add("VulnerabilityRangeRings", vulnerabilityCollection); } else { Console.WriteLine("No VulnerabilityRangeRings added to ACV"); } } if (acv.attributes.ContainsKey("Capability") || acv.attributes.ContainsKey("DockedWeapons")) { CustomAttributesValue capabilityCollection = DataValueFactory.BuildCustomAttributes(new Dictionary <string, DataValue>()) as CustomAttributesValue; RangeRingDisplayValue capabilityRing; Dictionary <string, int> longestWeaponRange = new Dictionary <string, int>();//[Capability],[Range] //docked weapons gets string list of IDs if (acv.attributes.ContainsKey("DockedWeapons")) { StringListValue dockedWeapons = acv["DockedWeapons"] as StringListValue; foreach (String weaponID in dockedWeapons.strings) { //get weapon id //get proxy info for weapon SimulationObjectProxy weapon = objectProxies[weaponID]; string species = ((StringValue)weapon["ClassName"].GetDataValue()).value; if (longestWeaponRange.ContainsKey(species)) { continue; //For now, assume that all weapons of the same species type have the same ranges. //this will cut back on unneccessary loops, and for the most part is 100% true. } //get max speed, maxfuel or current fuel, get fuel consumption rate, get SHORTEST capability range double maxSpeed = ((DoubleValue)weapon["MaximumSpeed"].GetDataValue()).value; double maxFuel = ((DoubleValue)weapon["FuelCapacity"].GetDataValue()).value; double fuelConsumptionRate = ((DoubleValue)weapon["FuelConsumptionRate"].GetDataValue()).value; double shortCapabilityRange = -1; CapabilityValue weaponCV = (CapabilityValue)weapon["Capability"].GetDataValue(); Dictionary <string, double> capRanges = new Dictionary <string, double>(); foreach (CapabilityValue.Effect ef in weaponCV.effects) { if (!capRanges.ContainsKey(ef.name)) { capRanges.Add(ef.name, ef.range); } else { if (capRanges[ef.name] > ef.range) {//You want the smaller range here because that's how weapons work. Auto-attacks use the SHORTEST range to trigger. capRanges[ef.name] = ef.range; } } } //but here, you want the LONGEST of the ranges that could trigger an auto-attack. foreach (KeyValuePair <string, double> kvp in capRanges) { if (kvp.Value > shortCapabilityRange) { shortCapabilityRange = kvp.Value; } } double thisRange = maxSpeed * maxFuel * fuelConsumptionRate + shortCapabilityRange; longestWeaponRange.Add(species, Convert.ToInt32(thisRange)); } // } Dictionary <string, Dictionary <double, double> > capabilityRanges = new Dictionary <string, Dictionary <double, double> >(); if (acv.attributes.ContainsKey("Capability")) { CapabilityValue detectedCapability = acv["Capability"] as CapabilityValue; foreach (CapabilityValue.Effect ef in detectedCapability.effects) { if (!capabilityRanges.ContainsKey(ef.name)) { capabilityRanges.Add(ef.name, new Dictionary <double, double>()); } capabilityRanges[ef.name].Add(ef.range, ef.intensity); } } //add all capabilities to ring collection foreach (string capName in capabilityRanges.Keys) { if (!capabilityCollection.attributes.ContainsKey(capName)) { capabilityRing = DataValueFactory.BuildRangeRingDisplayValue(capName, "Capability", false, new Dictionary <int, int>()) as RangeRingDisplayValue; Dictionary <int, int> convertedRanges = new Dictionary <int, int>(); foreach (KeyValuePair <double, double> kvp in capabilityRanges[capName]) { convertedRanges.Add(Convert.ToInt32(kvp.Key), Convert.ToInt32(kvp.Value)); } capabilityRing.AddAndSortRanges(convertedRanges); //this sorts as well capabilityCollection.attributes.Add(capName, capabilityRing); } else { Console.WriteLine("Failed to add duplicate capability to collection, {0}", capName); } } foreach (string weaponSpeciesName in longestWeaponRange.Keys) { if (!capabilityCollection.attributes.ContainsKey(weaponSpeciesName)) { capabilityRing = DataValueFactory.BuildRangeRingDisplayValue(weaponSpeciesName, "Capability", true, new Dictionary <int, int>()) as RangeRingDisplayValue; capabilityRing.rangeIntensities.Add(longestWeaponRange[weaponSpeciesName], -1); //TODO: Maybe add intensity above? capabilityCollection.attributes.Add(weaponSpeciesName, capabilityRing); } else { Console.WriteLine("Failed to add duplicate capability(Weapon species) to collection, {0}", weaponSpeciesName); } } if (capabilityCollection.attributes.Count > 0) { acv.attributes.Add("CapabilityRangeRings", capabilityCollection); } else { Console.WriteLine("No CapabilityRangeRings added to ACV"); } } }
public void TestAttackProcessorSimAttackObjectLogic() { //SETUP CapabilityValue target = new CapabilityValue(); CapabilityValue.Effect ef = new CapabilityValue.Effect("Capability1", 1000.0, 10, 1); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability2", 2000.0, 20, 1); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability1", 2000.0, 20, 1); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability1", 500.0, 5, 0.5); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability2", 555.0, 6, 0.6); target.effects.Add(ef); ef = new CapabilityValue.Effect("Capability1", 5000.0, 50, 1); target.effects.Add(ef); double[] ranges = { 200.0, 800.0, 1500.0, 5000.0 }; int[] expectedIntensities = { 5, 10, 20, 50 }; //TEST for (int x = 0; x < ranges.Length; x++)//double distance in ranges) { List <CapabilityValue.Effect> capabilities = target.GetOrderedEffectsByCapability("Capability1"); bool testComplete = false; foreach (CapabilityValue.Effect eff in capabilities) { if (eff.name == "Capability1" && ranges[x] <= eff.range) { //int r = random.Next(0, 100); //if (r <= ((int)(eff.probability * 100))) //{ //appliedIntensity = (int)(eff.intensity * newAttack.percentageApplied / 100); //newAttack.appliedIntensity = appliedIntensity; //targetVul.ApplyEffect(eff.name, appliedIntensity, distance, ref random); //} //break outside of the if because if the probability failed, you dont want a second chance with a different range. Assert.AreEqual(eff.intensity, expectedIntensities[x]); testComplete = true; break; //break because we only want to apply the first range found that satisfied the distance restraint } } Assert.IsTrue(testComplete, System.String.Format("Incorrect value when testing for range {0}", ranges[x])); } List <CapabilityValue.Effect> capability = target.GetOrderedEffectsByCapability("Capability1"); bool testCompleted = false; foreach (CapabilityValue.Effect eff in capability) { if (eff.name == "Capability1" && 6000 <= eff.range) { //int r = random.Next(0, 100); //if (r <= ((int)(eff.probability * 100))) //{ //appliedIntensity = (int)(eff.intensity * newAttack.percentageApplied / 100); //newAttack.appliedIntensity = appliedIntensity; //targetVul.ApplyEffect(eff.name, appliedIntensity, distance, ref random); //} //break outside of the if because if the probability failed, you dont want a second chance with a different range. testCompleted = true; break; //break because we only want to apply the first range found that satisfied the distance restraint } } Assert.IsFalse(testCompleted, System.String.Format("Incorrect value when testing for range {0}", 6000)); }
private void AttackObject(string attackerID, string targetID, string capabilityName, int percentageApplied, bool isSelfDefense) { DataValue dv = null; //AD Note: on 9/23/09, we decided that Vulnerabilities would now have an "EngagementDuration", which is the Vulnerability // version of Capability's "AttackDuration". If an EngagementDuration exists, it will override a Capability's AttackDuration. SimulationObjectProxy attackerProx = objectProxies[attackerID]; SimulationObjectProxy targetProx = objectProxies[targetID]; CapabilityValue attackerCap = (CapabilityValue)attackerProx["Capability"].GetDataValue(); VulnerabilityValue targetVul = (VulnerabilityValue)targetProx["Vulnerability"].GetDataValue(); // Check to see if this attack can start if (((StringValue)attackerProx["AttackState"].GetDataValue()).value == "BEING_ATTACKED") { distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(attackerProx["OwnerID"].GetDataValue())).value, attackerID + " is being engaged -- it can't initiate an engagement.")); return; } if (targetVul.transitions.Count == 0) { distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(attackerProx["OwnerID"].GetDataValue())).value, attackerID + " can't engage " + targetID + " -- object has no vulnerabilities.")); return; } //AD 11/16/2009: New Attack Logic: Allow for partial capabilities to be applied to attacks. AttackCollectionValue attackCollection = (AttackCollectionValue)attackerProx["CurrentAttacks"].GetDataValue(); int attackDuration = -1; AttackCollectionValue.AttackValue newAttack = new AttackCollectionValue.AttackValue(time, attackDuration, targetID, attackerID, capabilityName, percentageApplied, isSelfDefense); string errMsg = String.Empty; attackDuration = ((IntegerValue)attackerProx["AttackDuration"].GetDataValue()).value; int defenseDuration = ((IntegerValue)targetProx["EngagementDuration"].GetDataValue()).value; int attackTimeWindow = attackDuration; bool attackSuccess = true; if (defenseDuration > 0) { attackTimeWindow = defenseDuration; } Console.WriteLine("AttackObject: Attack duration for " + attackerID + " is " + attackDuration.ToString()); Console.WriteLine("AttackObject: Attack duration for attack is " + attackTimeWindow.ToString()); newAttack.attackTimeWindow = attackTimeWindow; if (attackCollection.AddAttack(newAttack, out errMsg) == false) { string msg = "The attack between " + attackerID + " and " + targetID + " encountered the following problem: " + errMsg; distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(attackerProx["OwnerID"].GetDataValue())).value, msg)); attackSuccess = false; } else if (errMsg != String.Empty) { string msg = "The attack between " + attackerID + " and " + targetID + " encountered the following problem: " + errMsg; distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(attackerProx["OwnerID"].GetDataValue())).value, msg)); } else //success { dv = targetProx["AttackState"].GetDataValue(); ((StringValue)dv).value = "BEING_ATTACKED"; targetProx["AttackState"].SetDataValue(dv); dv = targetProx["AttackerList"].GetDataValue(); ((StringListValue)dv).strings.Add(attackerID); targetProx["AttackerList"].SetDataValue(dv); } if (!attackSuccess) { attackerProx["CurrentAttacks"].SetDataValue(attackCollection); //set below if attackSuccess is true return; } //End new attack logic. // Vec3D attackerPosition = new Vec3D((LocationValue)attackerProx["Location"].GetDataValue()); Vec3D targetPosition = new Vec3D((LocationValue)targetProx["Location"].GetDataValue()); double distance = attackerPosition.ScalerDistanceTo(targetPosition); //FIX find actual diatance int appliedIntensity = -1; List <CapabilityValue.Effect> capabilities = attackerCap.GetOrderedEffectsByCapability(capabilityName); foreach (CapabilityValue.Effect eff in capabilities) { if (eff.name == capabilityName && distance <= eff.range) { int r = random.Next(0, 100); if (r <= ((int)(eff.probability * 100))) { appliedIntensity = Convert.ToInt32(Math.Round(((double)eff.intensity * (double)newAttack.percentageApplied / 100), MidpointRounding.AwayFromZero)); newAttack.appliedIntensity = appliedIntensity; targetVul.ApplyEffect(eff.name, appliedIntensity, distance, ref random); } //break outside of the if because if the probability failed, you dont want a second chance with a different range. break; //break because we only want to apply the first range found that satisfied the distance restraint } } attackerProx["CurrentAttacks"].SetDataValue(attackCollection); targetProx["Vulnerability"].SetDataValue((DataValue)targetVul); distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(attackerProx["OwnerID"].GetDataValue())).value, attackerID + " has engaged " + targetID)); distClient.PutEvent(SimUtility.BuildSystemMessageEvent(ref simModel, time, ((StringValue)(targetProx["OwnerID"].GetDataValue())).value, targetID + " has been engaged by " + attackerID)); distClient.PutEvent(SimUtility.BuildHistory_AttackerObjectReportEvent(ref simModel, time, attackerID, attackerPosition, targetID, targetPosition, capabilityName, appliedIntensity)); }
private void ForceUpdateObjectAttribute(SimulationEvent e) { string objectId = ((StringValue)e["ObjectID"]).value; string attributeName = ((StringValue)e["AttributeName"]).value; if (!objectProxies.ContainsKey(objectId)) { return; } try { if (!objectProxies[objectId][attributeName].IsOwner()) { return; } } catch (Exception ex) { return; } DataValue attributeValue = e["AttributeValue"]; if (attributeValue.dataType != "WrapperType") { return; } attributeValue = ((WrapperValue)attributeValue).value; SimulationObjectProxy obj = null; //depending on the attribute, you might have specific functionality //Capability //Vulnerability //Attack State //Current Attacks //Attacker List switch (attributeName) { case "Capability": //change object's capability set, update attacks CapabilityValue capVal = attributeValue as CapabilityValue; ChangeObjectCapability(capVal, objectId); return; break; case "Vulnerability": //change object's vulnerability set, update attacks VulnerabilityValue vulValue = attributeValue as VulnerabilityValue; ChangeObjectVulnerability(vulValue, objectId); return; break; case "AttackState": //if changing from "BEING_ATTACKED" to not, then cancel all attacks return; break; case "CurrentAttacks": //for now, do not let them modify this return; break; case "AttackerList": //any missing attackers should have their attacks cancelled return; break; default: //somehow you are able to publish, but it's not one of the current attributes as of 12/9 return; break; } try { obj[attributeName].SetDataValue(attributeValue); } catch (Exception ex) { return; } attributeValue = null; obj = null; }
private void TimeTick(SimulationEvent e) { int oldTime = time; DataValue dv = null; //Vec3D curVec = new Vec3D(0, 0, 0); //Vec3D destVec = new Vec3D(0, 0, 0); //Vec3D velVec = new Vec3D(0, 0, 0); Vec3D loc1 = new Vec3D(0, 0, 0); Vec3D loc2 = new Vec3D(0, 0, 0); Vec3D next1 = new Vec3D(0, 0, 0); Vec3D next2 = new Vec3D(0, 0, 0); Vec3D vel1 = new Vec3D(0, 0, 0); Vec3D vel2 = new Vec3D(0, 0, 0); dv = e["Time"]; time = ((IntegerValue)dv).value; double dTime = ((double)(time - oldTime)) / 1000; SimulationObjectProxy obProx1 = null; SimulationObjectProxy obProx2 = null; List <string> ids = new List <string>(objectProxies.Keys); string id1; SimulationEvent collision = null; double distance; double? d; while (ids.Count > 0) { id1 = ids[0]; ids.Remove(id1); foreach (string id2 in ids) { d = ObjectDistances.GetScalarDistanceBetweenObjects(id1, id2); if (d == null) { // Don't look for collisions if they aren't on the screen continue; } distance = d.Value; double objectSize1 = 0; double objectSize2 = 0; obProx1 = objectProxies[id1]; obProx2 = objectProxies[id2]; //// Don't look for collisions if they aren't on the screen dv = obProx1["Location"].GetDataValue(); //if (!((LocationValue)dv).exists) //{ // continue; //} loc1.Set((LocationValue)dv); dv = obProx2["Location"].GetDataValue(); //if (!((LocationValue)dv).exists) //{ // continue; //} loc2.Set((LocationValue)dv); if (((BooleanValue)obProx1["DockedToParent"].GetDataValue()).value) { continue; } if (((BooleanValue)obProx2["DockedToParent"].GetDataValue()).value) { continue; } // Don't look for collisions if they are owned by the same player if (StateDB.physicalObjects[id1].ownerID == StateDB.physicalObjects[id2].ownerID) { continue; } // Don't look for collisions if they are on the same team if (StateDB.physicalObjects[id1].teamName == StateDB.physicalObjects[id2].teamName) { continue; } //Don't look for collisions if they are not hostile if (StateDB.teams.ContainsKey(StateDB.physicalObjects[id1].teamName) && StateDB.teams.ContainsKey(StateDB.physicalObjects[id2].teamName)) { if (!StateDB.teams[StateDB.physicalObjects[id1].teamName].hostility.Contains(StateDB.teams[StateDB.physicalObjects[id2].teamName].id) && !StateDB.teams[StateDB.physicalObjects[id2].teamName].hostility.Contains(StateDB.teams[StateDB.physicalObjects[id1].teamName].id)) {//only continue if both teams are not hostile to one another continue; } } CapabilityValue.Effect eff = null; // check ranges and add objects to target lists for self defense sim CapabilityValue cap1 = ((CapabilityValue)obProx1["Capability"].GetDataValue()); VulnerabilityValue vul1 = ((VulnerabilityValue)obProx1["Vulnerability"].GetDataValue()); CapabilityValue cap2 = ((CapabilityValue)obProx2["Capability"].GetDataValue()); VulnerabilityValue vul2 = ((VulnerabilityValue)obProx2["Vulnerability"].GetDataValue()); //double distance = loc1.ScalerDistanceTo(loc2); eff = SimUtility.FindCapabilityEffect(cap1, vul2); dv = obProx1["TargetsInRange"].GetDataValue(); //AD: TODO need a "TargetsInSensorRange"? which can drive the ViewPro loops if (eff != null && distance <= eff.range && ((StringValue)obProx2["State"].GetDataValue()).value != "Dead") { if (!((StringListValue)dv).strings.Contains(id2)) { ((StringListValue)dv).strings.Add(id2); } } else { if (((StringListValue)dv).strings.Contains(id2)) { ((StringListValue)dv).strings.Remove(id2); } } obProx1["TargetsInRange"].SetDataValue(dv); eff = SimUtility.FindCapabilityEffect(cap2, vul1); dv = obProx2["TargetsInRange"].GetDataValue(); if (eff != null && distance <= eff.range && ((StringValue)obProx1["State"].GetDataValue()).value != "Dead") { if (!((StringListValue)dv).strings.Contains(id1)) { ((StringListValue)dv).strings.Add(id1); } } else { if (((StringListValue)dv).strings.Contains(id1)) { ((StringListValue)dv).strings.Remove(id1); } } obProx2["TargetsInRange"].SetDataValue(dv); // Don't look for collisions if they are dead if (((StringValue)obProx1["State"].GetDataValue()).value == "Dead") { continue; } if (((StringValue)obProx2["State"].GetDataValue()).value == "Dead") { continue; } // Don't look for collisions if they are too small to collide dv = obProx1["Size"].GetDataValue(); objectSize1 = ((DoubleValue)dv).value; if (objectSize1 <= 0.000001) { continue; } dv = obProx2["Size"].GetDataValue(); objectSize2 = ((DoubleValue)dv).value; if (objectSize2 <= 0.000001) { continue; } dv = obProx1["Velocity"].GetDataValue(); vel1.Set((VelocityValue)dv); dv = obProx2["Velocity"].GetDataValue(); vel2.Set((VelocityValue)dv); if (vel1.X == 0 && vel2.X == 0 && vel1.Y == 0 && vel2.Y == 0 && vel1.Z == 0 && vel2.Z == 0) { continue; } next1 = loc1.Add(vel1.Multiply(dTime)); next2 = loc2.Add(vel2.Multiply(dTime)); if (next1.ScalerDistanceTo(next2) < (objectSize1 + objectSize2)) { collision = SimulationEventFactory.BuildEvent(ref simModel, "ObjectCollision"); ((StringValue)collision["ObjectID1"]).value = id1; ((StringValue)collision["ObjectID2"]).value = id2; ((IntegerValue)collision["Time"]).value = time; distClient.PutEvent(collision); } } } /*foreach (string id1 in objectProxies.Keys) * { * foreach (string id2 in objectProxies.Keys) * { * if (id1 == id2) * { * continue; * } * obProx1 = objectProxies[id1]; * obProx2 = objectProxies[id1]; * * dv = obProx1["Location"].GetDataValue(); * loc1.Set((LocationValue)dv); * dv = obProx2["Location"].GetDataValue(); * loc2.Set((LocationValue)dv); * * } * * }*/ }