public void AddAttackTest() { AttackCollectionValue target = new AttackCollectionValue(); AttackCollectionValue.AttackValue attack = new AttackCollectionValue.AttackValue(8, 5, "MyTarget", "MyAttacker", "Missile", 60, false); AttackCollectionValue.AttackValue secondAttack = new AttackCollectionValue.AttackValue(10, 5, "MyTarget", "MyAttacker", "Guns", 80, false); AttackCollectionValue.AttackValue thirdAttack = new AttackCollectionValue.AttackValue(11, 5, "MyTarget", "MyAttacker", "Missile", 60, false); string errorMessage = string.Empty; string errorMessageExpected = string.Empty; // TODO: Initialize to an appropriate value bool expected = true; bool actual; //Add Attack 1 actual = target.AddAttack(attack, out errorMessage); Assert.AreEqual(errorMessageExpected, errorMessage); Assert.AreEqual(expected, actual); //Add Attack 2 actual = target.AddAttack(secondAttack, out errorMessage); Assert.AreEqual(errorMessageExpected, errorMessage); Assert.AreEqual(expected, actual); //Add Attack 3 errorMessageExpected = "Applying 40% instead of 60%, as that's all available"; actual = target.AddAttack(thirdAttack, out errorMessage); Assert.AreEqual(errorMessageExpected, errorMessage); Assert.AreEqual(expected, actual); //Add Attack 4 AttackCollectionValue.AttackValue fourthAttack = new AttackCollectionValue.AttackValue(12, 5, "MyTarget", "MyAttacker", "Missile", 60, false); expected = false; errorMessageExpected = "There is no more available percentage to apply for this capability. Try again later."; actual = target.AddAttack(thirdAttack, out errorMessage); Assert.AreEqual(errorMessageExpected, errorMessage); Assert.AreEqual(expected, actual); string serialized = target.ToXML(); Assert.AreEqual(serialized, LoadableXML); }
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)); }