public static Tuple <List <AttackOutcome>, List <Effect> > castSpell(Character caster, Character target, Spell s, double spellPower, double defensePower) { Tuple <List <AttackOutcome>, List <Effect> > ret = new Tuple <List <AttackOutcome>, List <Effect> >(new List <AttackOutcome>(), new List <Effect>()); spellPower += EffectHolder.GetValidEffectsByEffect(caster, EffectHolder.EffectType.SpellBonus); foreach (Effect eff in s.SpellEffects.Keys) { Effect effMultiplied = new Effect(eff.effectTypes, eff.effectStrength + s.SpellEffects[eff].Item1 * spellPower, eff.effectLength + (int)Math.Round(s.SpellEffects[eff].Item2 * spellPower), eff.deterioration + s.SpellEffects[eff].Item3 * spellPower); effMultiplied.effectTag = eff.effectTag; ret.Item2.Add(effMultiplied); } foreach (Weapon weap in s.SpellWeapons.Keys) { Weapon save = caster.CombatStuff.CombatWeapon; caster.CombatStuff.CombatWeapon = Utilities.GetWeaponByName(weap.ItemName); AttackOutcome outcome = CombatScripts.RunCombat(caster.MakeDeepCopy(), target, s.SpellWeapons[weap] + spellPower, defensePower, null); outcome.Attacker.CombatStuff.attackResultsForDisplay = new List <List <string> >(); outcome.Defender.CombatStuff.defendResultsForDisplay = new List <List <string> >(); ret.Item1.Add(outcome); caster.CombatStuff.CombatWeapon = save; } return(ret); }
public static void IndexAttacks() { lock (IndexedAttacks) { foreach (AttackOutcome ao in MostRecentAttacks) { while (ao.attackUUID == "" || IndexedAttacks.ContainsKey(ao.attackUUID)) { ao.attackUUID = Utilities.RandomString(8); } AttackOutcome attackcopy = new AttackOutcome(); attackcopy.Attacker = Utilities.GetSameCharWithCurrentState(ao.Attacker); attackcopy.Defender = Utilities.GetSameCharWithCurrentState(ao.Defender); attackcopy.attackRoll = ao.attackRoll; attackcopy.defendRoll = ao.defendRoll; attackcopy.HitLocation = ao.HitLocation; attackcopy.Othertext = ao.Othertext; attackcopy.perception = attackcopy.Attacker.Skills.PerceptionSkill + (int)(attackcopy.Attacker.Statistics.Intelligence / 3.0); IndexedAttacks.Add(ao.attackUUID, new Tuple <AttackOutcome, List <List <double> > >(attackcopy, null)); while (ao.defenceUUID == "" || IndexedAttacks.ContainsKey(ao.defenceUUID)) { ao.defenceUUID = Utilities.RandomString(8); } AttackOutcome defendcopy = new AttackOutcome(); defendcopy.Attacker = Utilities.GetSameCharWithCurrentState(ao.Attacker); defendcopy.Defender = Utilities.GetSameCharWithCurrentState(ao.Defender); defendcopy.attackRoll = ao.attackRoll; defendcopy.defendRoll = ao.defendRoll; defendcopy.HitLocation = ao.HitLocation; defendcopy.Othertext = ao.Othertext; defendcopy.perception = defendcopy.Defender.Skills.PerceptionSkill + (int)(defendcopy.Defender.Statistics.Intelligence / 3.0); IndexedAttacks.Add(ao.defenceUUID, new Tuple <AttackOutcome, List <List <double> > >(defendcopy, null)); } } }
//this is what happens when you click the 'Attack' button. The method name is an inside joke. private void followTheTaco_Click(object sender, EventArgs e) { double offenseRoll = 0.0; double defendRoll = 0.0; Double.TryParse(txtBoxOffensiveRoll.Text, out offenseRoll); Double.TryParse(txtBoxDefensiveRoll.Text, out defendRoll); Character _defender = _canAttack.Find(Ch => Ch.CombatStuff.CombatName == comboBox1.Text); if (_attacker.Weapons.Any(A => A.ItemName == comboBoxAttackerWeapon.Text)) { _attacker.CombatStuff.CombatWeapon = _attacker.Weapons.Find(A => A.ItemName == comboBoxAttackerWeapon.Text); } else { _attacker.CombatStuff.CombatWeapon = Utilities.GetWeaponByName(comboBoxAttackerWeapon.Text); } if (_defender.Weapons.Any(A => A.ItemName == comboBoxDefenderWeapon.Text)) { _defender.CombatStuff.CombatWeapon = _defender.Weapons.Find(A => A.ItemName == comboBoxDefenderWeapon.Text); } else { _defender.CombatStuff.CombatWeapon = Utilities.GetWeaponByName(comboBoxDefenderWeapon.Text); } _outcome = new AttackOutcome(); _outcome.Attacker = _attacker; _outcome.Defender = _defender; _outcome.attackRoll = offenseRoll; _outcome.defendRoll = defendRoll; _parentForm.AddToAttacks(_outcome); SingleAttack frmRemover = this; frmRemover.Hide(); }
private void FOLLOWTHETACO_Click(object sender, EventArgs e) { List <AttackOutcome> followedTacos = new List <AttackOutcome>(); foreach (AttackOutcome tacoToFollow in allAttacks) { AttackOutcome followedTaco = CombatScripts.RunCombat(tacoToFollow.Attacker, tacoToFollow.Defender, tacoToFollow.attackRoll, tacoToFollow.defendRoll, null); followedTaco.Attacker.CombatStuff.AttackNotes = followedTaco.Notes; followedTaco.Defender.CombatStuff.DefendNotes = followedTaco.Notes; followedTacos.Add(followedTaco); } CombatScripts.fatigueCharactersAndRecordCombat(followedTacos); foreach (AttackOutcome Whack in followedTacos) { CombatScripts.applyAttackOutcome(Whack); } EffectHolder.ClearUselessEffects(); CombatHolder.MoveAttackingCharsToHasAttackedChars(); if (CombatHolder._masterOfDeclarations != null) { CombatHolder._masterOfDeclarations.UpdateRTB(); } CombatHolder.updateCombatDeclarations(); AfterCrits frmCreator = new AfterCrits(); frmCreator.Show(); Master_Attacker frmCloser = this; frmCloser.Hide(); }
public static void applyAttackOutcome(AttackOutcome Whack) { Whack.Attacker.CombatStuff.attackResultsForDisplay.Insert(0, Utilities.translateAttackOutcomeToDisplayStrings(Whack, Whack.attackUUID)); Whack.Defender.CombatStuff.defendResultsForDisplay.Insert(0, Utilities.translateAttackOutcomeToDisplayStrings(Whack, Whack.defenceUUID)); Character Whackee = CombatHolder._inCombatChars.Find(Ch => Ch.CombatStuff.CombatName == Whack.Defender.CombatStuff.CombatName); //this can happen in some enchantment cases if (Whackee == null) { return; } Whackee.HitPoints = Whackee.HitPoints - Whack.harm; Effect bleed = new Effect(EffectHolder.EffectType.Regeneration, Whack.bleed * -1, Whack.bleed, -1); bleed.effectTag = EffectHolder.EffectTag.Bleed; Effect trauma = new Effect(EffectHolder.EffectType.Focus, Whack.trauma * -1, Whack.trauma, -1); trauma.effectTag = EffectHolder.EffectTag.Trauma; bool doPermanantImpairment = Whackee.CharTypeTag != "" && Whackee.CharTypeTag != null; Effect impairment = new Effect(EffectHolder.EffectType.OB, Whack.impairment * -1, -1, 0); impairment.effectTypes.Add(EffectHolder.EffectType.DB); impairment.effectTag = EffectHolder.EffectTag.NerveImpairment; Effect disorientation = new Effect(EffectHolder.EffectType.OB, Whack.disorientation * -1, Whack.disorientation, 1); disorientation.effectTypes.Add(EffectHolder.EffectType.DB); disorientation.effectTag = EffectHolder.EffectTag.Disorientation; Effect KO = new Effect(EffectHolder.EffectType.KO, Whack.ko, Whack.ko, 0.02); EffectHolder.CreateEffect(disorientation, Whackee, false); EffectHolder.CreateEffect(bleed, Whackee, false); EffectHolder.CreateEffect(trauma, Whackee, false); EffectHolder.CreateEffect(impairment, Whackee, false); EffectHolder.CreateEffect(KO, Whackee, false); }
public void AddToAttacks(AttackOutcome toAdd) { allAttacks.Add(toAdd); }
private void runSingleAttack() { clearDedPeople(); if (leftSide.Count == 0 || rightSide.Count == 0) { return; } Character attackingChar = new Character(); Character toAttackChar = new Character(); bool thereIsACharThatHasNotAttacked = false; bool thereIsAnAttackingChar = false; ifThisThenLeftAttacksNext = !ifThisThenLeftAttacksNext; foreach (Character c in leftSide.Keys) { if (!leftSide[c]) { thereIsACharThatHasNotAttacked = true; break; } } foreach (Character c in rightSide.Keys) { if (!rightSide[c]) { thereIsACharThatHasNotAttacked = true; break; } } if (!thereIsACharThatHasNotAttacked) { EffectHolder.ProcAndDecayEffectsForSingleChar(rightSide.Keys.Last()); EffectHolder.ProcAndDecayEffectsForSingleChar(leftSide.Keys.Last()); clearDedPeople(); //c# really does make you do it this way. Iteration through a dictionary is hard for some reason List <Character> temp = new List <Character>(); foreach (Character c in leftSide.Keys) { temp.Add(c); } foreach (Character c in temp) { leftSide[c] = false; } temp.Clear(); foreach (Character c in rightSide.Keys) { temp.Add(c); } foreach (Character c in temp) { rightSide[c] = false; } if (leftSide.Count == 0 || rightSide.Count == 0) { return; } } if (ifThisThenLeftAttacksNext) { foreach (Character c in leftSide.Keys) { if (!leftSide[c]) { attackingChar = c; thereIsAnAttackingChar = true; leftSide[c] = true; break; } } toAttackChar = rightSide.Keys.Last(); } else { foreach (Character c in rightSide.Keys) { if (!rightSide[c]) { attackingChar = c; thereIsAnAttackingChar = true; rightSide[c] = true; break; } } toAttackChar = leftSide.Keys.Last(); } if (!thereIsAnAttackingChar) { return; } AttackOutcome ao = CombatScripts.RunCombat(attackingChar, toAttackChar, Math.Round(r.NextDouble() * 20), Math.Round(r.NextDouble() * 20), null); if (ao.Othertext.ToString() == "Hit") { toAttackChar.HitPoints = toAttackChar.HitPoints - ao.harm; Effect bleed = new Effect(EffectHolder.EffectType.Regeneration, ao.bleed * -1, -1, 0); Effect focus = new Effect(EffectHolder.EffectType.Focus, ao.trauma * -1, -1, 0); Effect impairmentOB = new Effect(EffectHolder.EffectType.OB, ao.impairment * -1, -1, 0); Effect impairmentDB = new Effect(EffectHolder.EffectType.DB, ao.impairment * -1, -1, 0); Effect OB = new Effect(EffectHolder.EffectType.OB, ao.disorientation * -1, ao.disorientation, 1); Effect DB = new Effect(EffectHolder.EffectType.DB, ao.disorientation * -1, ao.disorientation, 1); EffectHolder.CreateEffect(OB, toAttackChar, false); EffectHolder.CreateEffect(DB, toAttackChar, false); EffectHolder.CreateEffect(bleed, toAttackChar, false); EffectHolder.CreateEffect(focus, toAttackChar, false); EffectHolder.CreateEffect(impairmentOB, toAttackChar, false); EffectHolder.CreateEffect(impairmentDB, toAttackChar, false); EffectHolder.ClearUselessEffects(); } if (doPrinting) { richTextBoxBig.Text += attackingChar.CombatStuff.CombatName + " -> " + toAttackChar.CombatStuff.CombatName + " " + " " + ao.Othertext.ToString() + "\n"; } clearDedPeople(); }
public static List <List <Double> > CreateDataPoints(AttackOutcome ao, bool doTotalDamage, bool doHarm, bool doBleed, bool doDisorientation, bool doImpairment, bool doTrauma, bool doKO, Utilities.BodyParts?location, int perception) { List <List <Double> > gridOfPoints = new List <List <double> >(); for (double j = ao.defendRoll - perception; j <= ao.defendRoll + perception; j++) { List <double> rowOfPoints = new List <double>(); for (double i = ao.attackRoll - perception; i <= ao.attackRoll + perception; i++) { AttackOutcome oneOutcome = CombatScripts.RunCombat(Utilities.GetSameCharWithCurrentState(ao.Attacker), Utilities.GetSameCharWithCurrentState(ao.Defender), i, j, location); double Damage = 0.0; switch (oneOutcome.Othertext.ToString()) { case "Miss": Damage = -1; break; case "Block": Damage = -2; break; case "Parry": Damage = -3; break; case "Hit": if (doTotalDamage) { Damage += oneOutcome.TotalStrikeAmountFromAllTypes(); } if (doHarm) { Damage += oneOutcome.harm; } if (doBleed) { Damage += oneOutcome.bleed; } if (doDisorientation) { Damage += oneOutcome.disorientation; } if (doImpairment) { Damage += oneOutcome.impairment; } if (doTrauma) { Damage += oneOutcome.trauma; } if (doTrauma) { Damage += oneOutcome.ko; } if (ao.Othertext != Utilities.AttackResultType.Hit) { Damage = 99; } break; default: throw new Exception("WTF did you give me?"); } rowOfPoints.Add(Damage); } gridOfPoints.Add(rowOfPoints); } return(gridOfPoints); }
public static void CalculateCrit(AttackOutcome CritSource) { double harm; double bleed; double heavybleed; double disorientation; double impairment; double trauma; double ko; double harmCumulative = CritSource.TotalStrikeAmountFromAllTypes() * EffectHolder.GetValidEffectsByEffect(CritSource.Attacker, EffectHolder.EffectType.InflictHarm); double bleedCumulative = CritSource.TotalStrikeAmountFromAllTypes() * EffectHolder.GetValidEffectsByEffect(CritSource.Attacker, EffectHolder.EffectType.InflictBleed); double heavybleedCumulative = CritSource.TotalStrikeAmountFromAllTypes() * EffectHolder.GetValidEffectsByEffect(CritSource.Attacker, EffectHolder.EffectType.InflictBleed); double disorientationCumulative = CritSource.TotalStrikeAmountFromAllTypes() * EffectHolder.GetValidEffectsByEffect(CritSource.Attacker, EffectHolder.EffectType.InflictDisorientation); double impairmentCumulative = CritSource.TotalStrikeAmountFromAllTypes() * EffectHolder.GetValidEffectsByEffect(CritSource.Attacker, EffectHolder.EffectType.InflictImpairment); double traumaCumulative = CritSource.TotalStrikeAmountFromAllTypes() * EffectHolder.GetValidEffectsByEffect(CritSource.Attacker, EffectHolder.EffectType.InflictTrauma); double koCumulative = CritSource.TotalStrikeAmountFromAllTypes() * EffectHolder.GetValidEffectsByEffect(CritSource.Attacker, EffectHolder.EffectType.InflictKO); bool locationMatters; foreach (Utilities.DamageType critType in CritSource.DamageTypes.Keys) { switch (critType) { case Utilities.DamageType.Slash: harm = 0.3; bleed = 0.6; heavybleed = 0.3; disorientation = 0.3; impairment = 0.3; trauma = 0.2; ko = 0.2; locationMatters = true; break; case Utilities.DamageType.Pierce: harm = 0.3; bleed = 0.3; heavybleed = 0.6; disorientation = 0.1; impairment = 0.2; trauma = 0.2; ko = 0.1; locationMatters = true; break; case Utilities.DamageType.Crush: harm = 0.2; bleed = 0.0; heavybleed = 0.1; disorientation = 0.4; impairment = 0.4; trauma = 0.4; ko = 0.4; locationMatters = true; break; case Utilities.DamageType.Heat: harm = 0.7; bleed = -0.1; heavybleed = 0.0; disorientation = 0.5; impairment = 0.3; trauma = 0.3; ko = 0.0; locationMatters = true; break; case Utilities.DamageType.Cold: harm = 0.2; bleed = -0.3; heavybleed = -0.3; disorientation = 0.5; impairment = 0.8; trauma = 0.3; ko = 0.3; locationMatters = true; break; case Utilities.DamageType.Shock: harm = 0.6; bleed = 0.0; heavybleed = 0.0; disorientation = 0.4; impairment = 0.5; trauma = 0.6; ko = 0.4; locationMatters = false; break; case Utilities.DamageType.Mental: harm = 0; bleed = 0; heavybleed = 0.1; disorientation = 1.0; impairment = 0.0; trauma = 1.0; ko = 0.3; locationMatters = false; break; case Utilities.DamageType.Impact: harm = 0.8; bleed = 0; heavybleed = 0.1; disorientation = 0.5; impairment = 0.3; trauma = 0.6; ko = 0.6; locationMatters = false; break; case Utilities.DamageType.Soul: harm = 1.0; bleed = 0; heavybleed = 0.0; disorientation = 0.0; impairment = 0.7; trauma = 0.2; ko = 0.4; locationMatters = false; break; default: throw new Exception("No valid Critical Type found."); } if (locationMatters) { switch (CritSource.HitLocation) { case Utilities.BodyParts.Head: harm += 0.2; bleed += 0.0; heavybleed += 0.0; disorientation += 0.2; impairment += 0.1; trauma += 0.2; ko += 0.2; break; case Utilities.BodyParts.Gut: harm += 0.4; bleed += 0.1; heavybleed += 0.2; disorientation += 0.0; impairment += 0.0; trauma += 0.1; ko += 0.1; break; case Utilities.BodyParts.Groin: harm += 0.0; bleed += 0.0; heavybleed += 0.0; disorientation += 0.5; impairment += 0.1; trauma += 0.5; ko += 0.0; break; case Utilities.BodyParts.Chest: harm += 0.3; bleed += 0.1; heavybleed += 0.2; disorientation += 0.0; impairment += 0.0; trauma += 0.0; ko += 0.2; break; case Utilities.BodyParts.Neck: harm += 0.2; bleed += 0.2; heavybleed += 0.4; disorientation += 0.0; impairment += 0.0; trauma += 0.0; ko += 0.3; break; default: harm += 0.0; bleed += 0.1; heavybleed += 0.1; disorientation += 0.0; impairment += 0.2; trauma += 0.0; ko += 0.0; break; } } harmCumulative += harm * CritSource.DamageTypes[critType]; bleedCumulative += bleed * CritSource.DamageTypes[critType]; heavybleedCumulative += heavybleed * CritSource.DamageTypes[critType]; disorientationCumulative += disorientation * CritSource.DamageTypes[critType]; impairmentCumulative += impairment * CritSource.DamageTypes[critType]; traumaCumulative += trauma * CritSource.DamageTypes[critType]; koCumulative += ko * CritSource.DamageTypes[critType]; } //ADD THIS FOR SOME RANDOMNESS /* * harmCumulative = harmCumulative * (_generator.NextDouble() + 0.5); * bleedCumulative = bleedCumulative * (_generator.NextDouble() + 0.5); * heavybleedCumulative = heavybleedCumulative * (_generator.NextDouble() + 0.5); * disorientationCumulative = disorientationCumulative * (_generator.NextDouble() + 0.5); * impairmentCumulative = impairmentCumulative * (_generator.NextDouble() + 0.5); * traumaCumulative = traumaCumulative * (_generator.NextDouble() + 0.5); * koCumulative = koCumulative * (_generator.NextDouble() + 0.5);*/ //adjust the values. changing these lines vastly changes the harm dealt by all attacks, futz with caution //harm is easy to come by, as it has the smallest impact on its own and needs to accumulate to perform its function harmCumulative = harmCumulative * 2; //bleed is easy to get in smallish doses, and scales at a moderate rate bleedCumulative = bleedCumulative / 2; //....until a certain point, when you start hitting arteries and stuff, and it scales rapidly heavybleedCumulative = heavybleedCumulative - 7; //the plus on the right is necessary, because 1 point of disorientation matters very little, since it dissapates at the end of the round disorientationCumulative = (disorientationCumulative / 2) + 0.4; //impairment has to scale slowly and be difficult to achieve, since it will accumulate over combat and seriously hamstrings a fighter impairmentCumulative = (impairmentCumulative / 4) - 0.5; //like disorientation, 1 point of trauma matters very little, unless you held off on your attack for the round traumaCumulative = (traumaCumulative / 4); //even one point of ko is usually fatal, since you are likely to be bleeding, so this needs to be difficult to achieve koCumulative = (koCumulative / 2) - 7.5; Character Whackee = CritSource.Defender; double resistHarm = EffectHolder.GetValidEffectsByEffect(Whackee, EffectHolder.EffectType.ResistHarm); double resistBleed = EffectHolder.GetValidEffectsByEffect(Whackee, EffectHolder.EffectType.ResistBleed); double resistDisorientation = EffectHolder.GetValidEffectsByEffect(Whackee, EffectHolder.EffectType.ResistDisorientation); double resistImpairment = EffectHolder.GetValidEffectsByEffect(Whackee, EffectHolder.EffectType.ResistImpairment); double resistTrauma = EffectHolder.GetValidEffectsByEffect(Whackee, EffectHolder.EffectType.ResistTrauma); double resistKo = EffectHolder.GetValidEffectsByEffect(Whackee, EffectHolder.EffectType.ResistKO); harmCumulative = (harmCumulative - resistHarm) * 5 / (5 + resistHarm); // NOTE bleed and heavybleed both accounted for here bleedCumulative = (Math.Max(0, bleedCumulative) + Math.Max(0, heavybleedCumulative) - resistBleed) * 5 / (5 + resistBleed); disorientationCumulative = (disorientationCumulative - resistDisorientation) * 5 / (5 + resistDisorientation); impairmentCumulative = (impairmentCumulative - resistImpairment) * 5 / (5 + resistImpairment); traumaCumulative = (traumaCumulative - resistTrauma) * 5 / (5 + resistTrauma); koCumulative = (koCumulative - resistKo) * 5 / (5 + resistKo); //round the values properly and send them back, no negative values accepted CritSource.harm = (int)Math.Round(Math.Max(0, harmCumulative)); CritSource.bleed = (int)Math.Round(Math.Max(0, bleedCumulative)); CritSource.disorientation = (int)Math.Round(Math.Max(0, disorientationCumulative)); CritSource.impairment = (int)Math.Round(Math.Max(0, impairmentCumulative)); CritSource.trauma = (int)Math.Round(Math.Max(0, traumaCumulative)); CritSource.ko = (int)Math.Round(Math.Max(0, koCumulative)); }
private List <DataPoint> CreateDataPoints() { List <DataPoint> lstData = new List <DataPoint>(); Random r = new Random(); Double average = 0; Character copy1 = Utilities.GetSameCharWithCurrentState(_char1); Character copy2 = Utilities.GetSameCharWithCurrentState(_char2); for (int i = 1; i < 21; i++) { for (int j = 1; j < 21; j++) { copy1.TemporaryEffects = new List <Effect>(); foreach (Effect ef in _char1.TemporaryEffects) { copy1.TemporaryEffects.Add(ef); } copy2.TemporaryEffects = new List <Effect>(); foreach (Effect ef in _char2.TemporaryEffects) { copy2.TemporaryEffects.Add(ef); } AttackOutcome _outcome = CombatScripts.RunCombat(copy1, copy2, i, j, null); if (!checkBoxDoLocationCheck.Checked) { //_outcome.recalculateWithoutLocation(); } double Red = 0; double Blue = 0; double Green = 0; double Damage = 0.0; if (!checkBoxHarm.Checked && !checkBoxBleed.Checked && !checkBoxDisorientation.Checked && !checkBoxImpairment.Checked && !checkBoxTrauma.Checked && !checkBoxKO.Checked) { Damage = _outcome.TotalStrikeAmountFromAllTypes(); } if (checkBoxHarm.Checked) { Damage += _outcome.harm; } if (checkBoxBleed.Checked) { Damage += _outcome.bleed; } if (checkBoxDisorientation.Checked) { Damage += _outcome.disorientation; } if (checkBoxImpairment.Checked) { Damage += _outcome.impairment; } if (checkBoxTrauma.Checked) { Damage += _outcome.trauma; } if (checkBoxKO.Checked) { Damage += _outcome.ko; } switch (_outcome.Othertext.ToString()) { case "Miss": Red = 0; Blue = 0; Green = 0; break; case "Block": Red = 100; Blue = 100; Green = 100; break; case "Parry": Red = 200; Blue = 200; Green = 200; break; case "Hit": if (Damage < 100) { Red = 255; Blue = 255; Green = 255; } if (Damage < 50) { Red = 200; Blue = 0; Green = 0; } if (Damage < 20) { Red = 200; Blue = 0; Green = 200; } if (Damage < 15) { Red = 0; Blue = 0; Green = 200; } if (Damage < 10) { Red = 0; Blue = 200; Green = 200; } if (Damage < 5) { Red = 0; Blue = 250; Green = 100; } if (Damage < 4) { Red = 50; Blue = 200; Green = 0; } if (Damage < 3) { Red = 100; Blue = 125; Green = 0; } if (Damage < 2) { Red = 200; Blue = 100; Green = 50; } if (Damage < 1) { Red = 225; Blue = 0; Green = 125; } break; default: throw new Exception("WTF did you give me?"); } int iRed = Convert.ToInt32(Math.Floor(Red)); int iBlue = Convert.ToInt32(Math.Floor(Blue)); int iGreen = Convert.ToInt32(Math.Floor(Green)); DataPoint dp = new DataPoint(10, 10, 11 * i, 11 * j, iRed, iGreen, iBlue); lstData.Add(dp); average += Damage; } } lblAverage.Text = "Average Damage: " + Math.Round(average * 10 / 400) / 10; return(lstData); }
public static AttackOutcome RunCombat(Character _attacker, Character _defender, double AttackRoll, double DefendRoll, Utilities.BodyParts?location) { AttackOutcome outcome = new AttackOutcome(); _attacker.CombatStuff.aoForEnchantments = outcome; _defender.CombatStuff.aoForEnchantments = outcome; outcome.attackRoll = AttackRoll; outcome.defendRoll = DefendRoll; //this is to give the option of one-roll combat on the specific input of DefensiveRoll == -999.0 /* * if (DefendRoll == -999.0) * { * DefendRoll = 20 - AttackRoll; * }*/ outcome.Attacker = _attacker; outcome.Defender = _defender; Weapon _attackerSelectedWeapon = _attacker.CombatStuff.CombatWeapon; Weapon _defenderSelectedWeapon = _defender.CombatStuff.CombatWeapon; Shield _attackerSelectedShield = _attacker.CombatStuff.CombatShield; Shield _defenderSelectedShield = _defender.CombatStuff.CombatShield; outcome.Notes.attackerWeaponName = _attackerSelectedWeapon.ItemName; outcome.Notes.defenderWeaponName = _defenderSelectedWeapon.ItemName; outcome.Notes.stun = -1 * EffectHolder.GetValidEffectsByEffect(_defender, EffectHolder.EffectType.Focus); double _attackerWeightFactor = GetWeightFactor(_attacker); double _defenderWeightFactor = GetWeightFactor(_defender); double _attackerStaminaFactor = GetStaminaFactor(_attacker); double _defenderStaminaFactor = GetStaminaFactor(_defender); //primary calculators double offensiveCalculator = (AttackRoll + _attacker.CombatStuff.CombatOB + _attackerSelectedWeapon.OffensiveBonus + _attackerSelectedShield.OffensiveBonus + EffectHolder.GetValidEffectsByEffect(_attacker, EffectHolder.EffectType.OB) + _attackerWeightFactor) * _attackerStaminaFactor; double defensiveCalculator = (DefendRoll + _defender.CombatStuff.CombatDB + _defenderSelectedWeapon.DefensiveBonus + _defenderSelectedShield.DefensiveBonus + EffectHolder.GetValidEffectsByEffect(_defender, EffectHolder.EffectType.DB) + _defenderWeightFactor) * _defenderStaminaFactor; foreach (Armor a in _attacker.Armor) { offensiveCalculator += a.OffensiveBonus; } foreach (Armor a in _defender.Armor) { defensiveCalculator += a.DefensiveBonus; } outcome.Notes.attackroll = AttackRoll; outcome.Notes.attackValue = offensiveCalculator; outcome.Notes.defendRoll = DefendRoll; outcome.Notes.defendValue = defensiveCalculator; EnchantmentUtilities.triggerAllEnchantmentsForChar(_attacker, new EnchantmentParameters() { triggerSource = EnchantmentUtilities.SourceTypes.Attack }); EnchantmentUtilities.triggerAllEnchantmentsForChar(_defender, new EnchantmentParameters() { triggerSource = EnchantmentUtilities.SourceTypes.WasAttacked }); //generate reflex double defenderReflex = CalculateReflex(_defender, defensiveCalculator); //adjust by a percentage if stamina is low defenderReflex = defenderReflex * _defenderStaminaFactor; outcome.Notes.reflex = defenderReflex; //generate blocking difficulty double attackerBlockingDifficulty = _attackerSelectedWeapon.BlockingDifficulty + EffectHolder.GetValidEffectsByEffect(_attacker, EffectHolder.EffectType.BlockingDifficulty) + 0.2 * offensiveCalculator; outcome.Notes.blockingDifficulty = attackerBlockingDifficulty; //apply 25% of blocking difficulty defensiveCalculator -= attackerBlockingDifficulty * 0.25; //generate block double defenderBlock = defensiveCalculator * (_defenderSelectedShield.Coverage + EffectHolder.GetValidEffectsByEffect(_defender, EffectHolder.EffectType.ShieldCoverage)); outcome.Notes.block = defenderBlock; //apply rest of blocking difficulty defensiveCalculator -= attackerBlockingDifficulty * 0.75; //generate parry double defenderParry = defensiveCalculator * _defenderSelectedWeapon.ParryStrength / System.Math.Max(_attackerSelectedWeapon.ParryBreak, 0.01); outcome.Notes.parryBreak = _attackerSelectedWeapon.ParryBreak; outcome.Notes.parryStrength = _defenderSelectedWeapon.ParryStrength; outcome.Notes.parry = defenderParry; outcome.Notes.defendValueAfterBlockingDifficulty = defensiveCalculator; //perform dodge if (defenderReflex > 0) { offensiveCalculator -= defenderReflex; } //if the attack has been reduced to 0, it was dodged if (offensiveCalculator <= 0) { outcome.Othertext = Utilities.AttackResultType.Miss; outcome.HitCaliber = offensiveCalculator; return(outcome); } outcome.Notes.attackAfterReflex = offensiveCalculator; //perform block if (defenderBlock > 0) { offensiveCalculator -= defenderBlock; } //if the attack has been reduced to 0, it was blocked if (offensiveCalculator <= 0) { outcome.Othertext = Utilities.AttackResultType.Block; outcome.HitCaliber = offensiveCalculator; return(outcome); } outcome.Notes.attackAfterBlock = offensiveCalculator; //perform parry if (defenderParry > 0) { offensiveCalculator -= defenderParry; } //if the attack has been reduced to 0, it was parried if (offensiveCalculator <= 0) { outcome.Othertext = Utilities.AttackResultType.Parry; outcome.HitCaliber = offensiveCalculator; return(outcome); } outcome.Notes.attackAfterParry = offensiveCalculator; if (location == null) { Utilities.FindCritLocation(outcome); } else { outcome.HitLocation = (Utilities.BodyParts)location; } //otherwise, attacker hit! do damage/armor calculation Dictionary <Utilities.DamageType, Double> tempDamageValues = new Dictionary <Utilities.DamageType, double>(); foreach (Utilities.DamageType dt in _attackerSelectedWeapon.DamageTypes.Keys) { tempDamageValues.Add(dt, _attackerSelectedWeapon.DamageTypes[dt]); } foreach (Utilities.DamageType dt in Enum.GetValues(typeof(Utilities.DamageType))) { double addedDamage = EffectHolder.GetValidEffectsByEffectAndDamageType(_attacker, EffectHolder.EffectType.WeaponDamage, dt); if (addedDamage != 0) { if (tempDamageValues.ContainsKey(dt)) { tempDamageValues[dt] += addedDamage; } else { tempDamageValues.Add(dt, addedDamage); } } } foreach (Utilities.DamageType dt in tempDamageValues.Keys) { Double strikeAmountForDamageType = offensiveCalculator * tempDamageValues[dt]; outcome.HitStrength = outcome.HitStrength + strikeAmountForDamageType; outcome.Notes.damageBeforeArmor = outcome.HitStrength; //actually percentage of damage that will go through double damageResistance = 1.0 - EffectHolder.GetValidEffectsByEffectAndDamageType(_defender, EffectHolder.EffectType.DamageResistance, null); damageResistance -= EffectHolder.GetValidEffectsByEffectAndDamageType(_defender, EffectHolder.EffectType.DamageResistance, dt); foreach (Armor arm in _defender.Armor) { if (arm.CoveredAreas.Contains(outcome.HitLocation) && arm.DamageResistanceTypes.ContainsKey(dt)) { //subtraction because a lower percentage of the damage will get through damageResistance -= (arm.DamageResistanceTypes[dt]); } } outcome.DamageTypes.Add(dt, Math.Max(0, (strikeAmountForDamageType * damageResistance))); } double generalDamageReduction = EffectHolder.GetValidEffectsByEffectAndDamageType(_defender, EffectHolder.EffectType.DamageReduction, null); double totalDamageBeforeReduction = outcome.TotalStrikeAmountFromAllTypes(); //weird things happen if this is less than or equal to zero if (totalDamageBeforeReduction > 0) { foreach (Utilities.DamageType dt in tempDamageValues.Keys) { //the amount of damage that will be prevented outcome.DamageTypes[dt] -= generalDamageReduction * (outcome.DamageTypes[dt] / totalDamageBeforeReduction); outcome.DamageTypes[dt] -= EffectHolder.GetValidEffectsByEffectAndDamageType(_defender, EffectHolder.EffectType.DamageReduction, dt); foreach (Armor arm in _defender.Armor) { if (arm.CoveredAreas.Contains(outcome.HitLocation) && arm.DamageReductionTypes.ContainsKey(dt)) { outcome.DamageTypes[dt] -= (arm.DamageReductionTypes[dt]); } } if (outcome.DamageTypes[dt] < 0) { outcome.DamageTypes[dt] = 0; } } } outcome.Notes.damageAfterArmor = outcome.TotalStrikeAmountFromAllTypes(); outcome.Othertext = Utilities.AttackResultType.Hit; outcome.HitCaliber = offensiveCalculator; CritCalculator.CalculateCrit(outcome); EnchantmentUtilities.triggerAllEnchantmentsForChar(_attacker, new EnchantmentParameters() { triggerSource = EnchantmentUtilities.SourceTypes.PostAttack }); EnchantmentUtilities.triggerAllEnchantmentsForChar(_defender, new EnchantmentParameters() { triggerSource = EnchantmentUtilities.SourceTypes.PostWasAttacked }); return(outcome); }
private void button1_Click(object sender, EventArgs e) { if (!Utilities.ValidateComboBox(cboBoxChar1.Text)) { return; } if (!Utilities.ValidateComboBox(cboBoxChar2.Text)) { return;/* * if (!Utilities.ValidateComboBox(cboBoxWeapon1.Text)) * return; * if (!Utilities.ValidateComboBox(cboBoxWeapon2.Text)) * return;*/ } Character char1 = Utilities.getCharacterFromXmlOrCombatHolderByString(cboBoxChar1.Text); if (!CombatHolder._inCombatChars.Contains(char1)) { char1.HitPoints = CombatScripts.GetBaseHealth(char1); char1.Stamina = CombatScripts.GetBaseStamina(char1); } Character char2 = Utilities.getCharacterFromXmlOrCombatHolderByString(cboBoxChar2.Text); if (!CombatHolder._inCombatChars.Contains(char1)) { char2.HitPoints = CombatScripts.GetBaseHealth(char2); char2.Stamina = CombatScripts.GetBaseStamina(char2); } Character CharCopy1 = Utilities.GetSameCharWithCurrentState(char1); Character CharCopy2 = Utilities.GetSameCharWithCurrentState(char2); CharCopy1.CombatStuff.CombatOB = Utilities.ParseDoubleFromDangerousString(txtBoxOffensiveBonus.Text); CharCopy1.CombatStuff.CombatWeapon = char1.Weapons.Find(A => A.ItemName == cboBoxWeapon1.Text); CharCopy1.CombatStuff.CombatShield = char1.Shields.Find(A => A.ItemName == cboBoxShield1.Text); if (CharCopy1.CombatStuff.CombatShield == null) { CharCopy1.CombatStuff.CombatShield = new Shield(); } CharCopy2.CombatStuff.CombatDB = Utilities.ParseDoubleFromDangerousString(txtBoxDefensiveBonus.Text); CharCopy2.CombatStuff.CombatWeapon = char2.Weapons.Find(A => A.ItemName == cboBoxWeapon2.Text); CharCopy2.CombatStuff.CombatShield = char2.Shields.Find(A => A.ItemName == cboBoxShield2.Text); if (CharCopy2.CombatStuff.CombatShield == null) { CharCopy2.CombatStuff.CombatShield = new Shield(); } if (checkBoxStartup.Checked) { EnchantmentUtilities.triggerAllEnchantmentsForChar(CharCopy1, new EnchantmentParameters() { triggerSource = EnchantmentUtilities.SourceTypes.CombatEntry }); EnchantmentUtilities.triggerAllEnchantmentsForChar(CharCopy2, new EnchantmentParameters() { triggerSource = EnchantmentUtilities.SourceTypes.CombatEntry }); } _outcome = CombatScripts.RunCombat(Utilities.GetSameCharWithCurrentState(CharCopy1), Utilities.GetSameCharWithCurrentState(CharCopy2), Utilities.ParseDoubleFromDangerousString(txtBoxOffensiveRoll.Text), Utilities.ParseDoubleFromDangerousString(txtBoxDefensiveRoll.Text), null); txtBoxCrit.Text = _outcome.Othertext.ToString(); txtBoxDamage.Text = Convert.ToString(0); lblHitCaliber.Text = Convert.ToString(0); lblHitStrength.Text = Convert.ToString(0); if (_outcome.Othertext.ToString() == "Hit") { lblHitCaliber.Text = "Hit Caliber: " + _outcome.HitCaliber.ToString(); lblHitStrength.Text = "Hit Strength: " + _outcome.HitStrength.ToString(); double damage = _outcome.TotalStrikeAmountFromAllTypes(); txtBoxDamage.Text = Convert.ToString(damage); txtBoxCrit.Text = _outcome.HitLocation.ToString(); AttackOutcome cumulative = new AttackOutcome(); for (int i = 0; i < 1000; i++) { //calculate the same crit every time Utilities.FindCritLocation(_outcome); CritCalculator.CalculateCrit(_outcome); //store it in a different place so it doesnt get reset cumulative.bleed += _outcome.bleed; cumulative.harm += _outcome.harm; cumulative.disorientation += _outcome.disorientation; cumulative.impairment += _outcome.impairment; cumulative.ko += _outcome.ko; cumulative.trauma += _outcome.trauma; } Console.WriteLine("Harm: " + Convert.ToDouble(cumulative.harm) / 1000); Console.WriteLine("Bleed: " + Convert.ToDouble(cumulative.bleed) / 1000); Console.WriteLine("Disorientation: " + Convert.ToDouble(cumulative.disorientation) / 1000); Console.WriteLine("Impairment: " + Convert.ToDouble(cumulative.impairment) / 1000); Console.WriteLine("Trauma: " + Convert.ToDouble(cumulative.trauma) / 1000); Console.WriteLine("KO: " + Convert.ToDouble(cumulative.ko) / 1000); rtbAverageResults.Text = ""; rtbAverageResults.Text += "Harm: " + Convert.ToDouble(cumulative.harm) / 1000 + "\n"; rtbAverageResults.Text += "Bleed: " + Convert.ToDouble(cumulative.bleed) / 1000 + "\n"; rtbAverageResults.Text += "Disorientation: " + Convert.ToDouble(cumulative.disorientation) / 1000 + "\n"; rtbAverageResults.Text += "Impairment: " + Convert.ToDouble(cumulative.impairment) / 1000 + "\n"; rtbAverageResults.Text += "Trauma: " + Convert.ToDouble(cumulative.trauma) / 1000 + "\n"; rtbAverageResults.Text += "KO: " + Convert.ToDouble(cumulative.ko) / 1000 + "\n"; } if (chkBoxGraph.Checked) { AttackChart frmCreator = new AttackChart(Utilities.GetSameCharWithCurrentState(CharCopy1), Utilities.GetSameCharWithCurrentState(CharCopy2)); frmCreator.Show(); } }