public CombatManualComponent(int x, int y,CombatManual manual) { this.cm = manual; this.newAttack = cm.SpecialAttack; this.locationX = x; this.locationY = y; this.PerformDrag(0, 0); this.clickedNumber = 0; }
public void HandleMouseOver(int x, int y) { //Are we mousing over a particular special attack? selectedAttack = null; for (int i = 0; i < saRects.Length; i++) { Rectangle rect = saRects[i]; if (rect.Contains(x, y)) { //Yep! selectedAttack = attacker.SpecialAttacks[i]; } } if (selectedAttack != null) { //Display the details int locationX = x + 5; int locationY = y; int bufferX = 10; int bufferY = 40; saDetailsRect = new Rectangle(locationX, locationY, 200, 140); saNameRect = new Rectangle(locationX, locationY+10, 200, 30); sadBleedIcon = new Rectangle(locationX + bufferX, locationY + bufferY, 30, 30); sadBleedValue = new Rectangle(locationX + bufferX + 30, locationY + bufferY, 30, 30); sadAccuracyIcon = new Rectangle(locationX + bufferX + 60, locationY + bufferY, 30, 30); sadAccuracyValue = new Rectangle(locationX + bufferX + 90, locationY + bufferY, 30, 30); sadStunIcon = new Rectangle(locationX + bufferX + 120, locationY + bufferY, 30, 30); sadStunValue = new Rectangle(locationX + bufferX + 150, locationY + bufferY, 30, 30); //-- sadDamageIcon = new Rectangle(locationX + bufferX + 0, locationY + 30 + bufferY, 30, 30); sadDamageValue = new Rectangle(locationX + bufferX + 30, locationY + 30 + bufferY, 30, 30); ; sadAttacksIcon = new Rectangle(locationX + bufferX + 60, locationY + 30 + bufferY, 30, 30); sadAttacksValue = new Rectangle(locationX + bufferX + 90, locationY + 30 + bufferY, 30, 30); sadPiercingIcon = new Rectangle(locationX + bufferX + 120, locationY + 30 + bufferY, 30, 30); sadPiercingValue = new Rectangle(locationX + bufferX + 150, locationY + 30 + bufferY, 30, 30); //--- sadSunderIcon = new Rectangle(locationX + bufferX, locationY + 60 + bufferY , 30, 30); sadSunderValue = new Rectangle(locationX + bufferX + 30, locationY + 60 + bufferY, 30, 30); sadPushIcon = new Rectangle(locationX + bufferX + 60, locationY + 60 + bufferY, 30, 30); sadPushValue = new Rectangle(locationX + bufferX + 90, locationY + 60 + bufferY, 30, 30); sadTargetsIcon = new Rectangle(locationX + bufferX + 120, locationY + 60 + bufferY, 30, 30); sadTargetsValue = new Rectangle(locationX + bufferX + 150, locationY + 60 + bufferY, 30, 30); } }
/// <summary> /// Attack a particular target using this special attack /// </summary> /// <param name="attacker"></param> /// <param name="target"></param> /// <param name="attack"></param> /// <returns></returns> public static ActionFeedback[] PerformSpecialAttack(Actor attacker, Actor target, SpecialAttack attack) { List<ActionFeedback> feedback = new List<ActionFeedback>(); feedback.Add(new LogFeedback(InterfaceSpriteName.SA1, Color.Blue, "You strike using " + attack.AttackName)); if (target.MapCharacter == null) { return new ActionFeedback[] { }; //Huh ? } //So, first we need to determine how many targets we're going to attack, and how many times List<Actor> targets = new List<Actor>(); targets.Add(target); for (int i = 1; i < attack.Effects.Where(e => e.EffectType == SpecialAttackType.TARGETS).Select(e => e.EffectValue).FirstOrDefault(); i++) { //Go around the attacker and add another target - later we'll need to check if they're hostile foreach (var block in GameState.LocalMap.GetBlocksAroundPoint(attacker.MapCharacter.Coordinate, 1)) { foreach (var character in block.GetItems().Where(gi => gi.IsActive && gi.GetType() == typeof(LocalCharacter))) { Actor newTarget = (character as LocalCharacter).Actor; if (!targets.Contains(newTarget)) { //Add it! targets.Add(newTarget); continue; } } } break; //No more actors } int attacksToMake = attack.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.ATTACKS) == null ? 1 : attack.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.ATTACKS).EffectValue; for (int i = 0; i < attacksToMake; i++) { foreach (var defender in targets) { //Are we alive? if (!defender.IsAlive) { continue; //yeah he's dead jim } else { //Attack! feedback.AddRange(Attack(attacker, defender, AttackLocation.CHEST, attack)); } } } //Phew, now let's set the timeout attack.TimeOutLeft = attack.TimeOut; //Done return feedback.ToArray(); }
/// <summary> /// Performs an attack on a character. Will also give an amount of feedback. Also reduces the health of the defender if the attack hits /// </summary> /// <param name="attacker"></param> /// <param name="defender"></param> /// <param name="location"></param> /// <param name="special">Special attack modifications to make. THIS DOES NOT CONSIDER TARGETS OR ATTACKS </param> /// <returns></returns> public static ActionFeedback[] Attack(Actor attacker, Actor defender, AttackLocation location, SpecialAttack special = null) { List<ActionFeedback> feedback = new List<ActionFeedback>(); if (defender.MapCharacter == null) { return new ActionFeedback[] { }; //What on earth are you doing? } int distance = attacker.MapCharacter.Coordinate - defender.MapCharacter.Coordinate; //This will later be used for ranged attacks if (distance >= 2) { //If the defender is not the character, get thhe defender to walk to the attacked location if (!defender.IsPlayerCharacter) { defender.MissionStack.Push(defender.CurrentMission); //It's not retainable, so if it's preempted by another mission he won't walk back to the attacked location for nothing defender.CurrentMission = new WalkToMission() { isRetainable = false, TargetCoordinate = attacker.MapCharacter.Coordinate }; } } //Do we succeed in the attack? int atk = 0; int def = 0; //The type of dice we roll 3 of to determine weapon damage int weaponDiceRolls = attacker.UnarmedDamageDice; //Default damage int weaponWoundPotential = 0; int weaponStunAmount = 0; if (distance < 2) { if (attacker.Inventory.EquippedItems.ContainsKey(EquipmentLocation.WEAPON) && attacker.Anatomy.RightArm > 0) { //Do we have a weapon and an arm to use it? weaponDiceRolls = attacker.Inventory.EquippedItems[EquipmentLocation.WEAPON].DamageDice; weaponWoundPotential = attacker.Inventory.EquippedItems[EquipmentLocation.WEAPON].WoundPotential; weaponStunAmount = attacker.Inventory.EquippedItems[EquipmentLocation.WEAPON].StunAmount; } } else { //Grab the weapon from the BOW slot if (attacker.Inventory.EquippedItems.ContainsKey(EquipmentLocation.BOW) && attacker.Anatomy.RightArm > 0 && attacker.Anatomy.LeftArm > 0) { weaponDiceRolls = attacker.Inventory.EquippedItems[EquipmentLocation.BOW].DamageDice; weaponWoundPotential = attacker.Inventory.EquippedItems[EquipmentLocation.BOW].WoundPotential; weaponStunAmount = attacker.Inventory.EquippedItems[EquipmentLocation.BOW].StunAmount; } else { //Firing with a destroyed upper body? For shame feedback.Add(new LogFeedback(null, Color.Red, "You are unable to use a ranged weapon under these conditions")); } } DamageType damageType = DamageType.SLASH; if (distance >= 2) { //Ranged damageType = DamageType.PIERCE; } GetStanceEffect(out atk, out def, attacker.CombatStance); //Does the defender have a shield? int shieldBonus = 0; if (defender.Inventory.EquippedItems.ContainsKey(EquipmentLocation.SHIELD) && defender.Anatomy.LeftArm != 0) { shieldBonus = defender.Inventory.EquippedItems[EquipmentLocation.SHIELD].ArmourRating; } int hitChance = 0; if (distance < 2) { //Chance to hit for hand to hand- // Attacker Skill + Brawn - 5 + location penalty + stance effect VS Defender Skill + Agil + stance effect + shield bonus hitChance = attacker.Attributes.HandToHand + attacker.TotalBrawn - 5 + penaltyDict[location] + atk; } else { //Chance to hit for ranged- // Attacker Skill + perc - 5 + location penalty + stance effect - distance*2 VS Defender Skill + Agil + stance effect + shield bonus hitChance = attacker.Attributes.Ranged + attacker.TotalPerc - 5 - distance * 2 + penaltyDict[location] + atk; } if (special != null) { hitChance += special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.ACCURACY) == null ? 0 : special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.ACCURACY).EffectValue; } GetStanceEffect(out atk, out def, defender.CombatStance); int defendChance = defender.Attributes.Dodge + def + shieldBonus; //See what the difference is int difference = hitChance - defendChance; //Now roll a d20 and see whether we hit int diceRoll = random.Next(20) + 1; if (difference + diceRoll > 0) { //We have a hit //The defender will learn something defender.Attributes.IncreaseSkill(SkillName.DODGER); //Are they wearing armour ? if (defender.Inventory.EquippedItems.ContainsKey(EquipmentLocation.BODY)) { defender.Attributes.IncreaseSkill(SkillName.ARMOUR_USER); } //Are they using a shield? if (defender.Inventory.EquippedItems.ContainsKey(EquipmentLocation.SHIELD)) { defender.Attributes.IncreaseSkill(SkillName.BLOCKER); } feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.HIT, diceRoll)); //Calculate the amount of damage we're going to do. Roll 3 dice of a particular kind int weaponDamage = random.Next(weaponDiceRolls + 1) + random.Next(weaponDiceRolls + 1) + random.Next(weaponDiceRolls + 1); Console.WriteLine("Damage Roll : " + weaponDamage); int damage = weaponDamage; if (special != null) { damage += special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.DAMAGE) == null ? 0 : special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.DAMAGE).EffectValue; } if (damage > 1) { //Do we have any defences? if (defender.IsPlayerCharacter && defender.CurrentDefences > 0) { //Break one instead defender.CurrentDefences--; feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DEFENDED, diceRoll)); //And mark it GameState.LocalMap.TemporaryGraphics.Add(new TemporaryGraphic() { Coord = new MapCoordinate(defender.MapCharacter.Coordinate), Graphic = SpriteManager.GetSprite(distance < 2 ? InterfaceSpriteName.SWORD_BLOCKED : InterfaceSpriteName.BOW_BLOCKED), LifeTime = attacker.IsPlayerCharacter ? 2 : 2 }); return feedback.ToArray(); } } //Apply the damage //Is the user wearing any armour? if (location == AttackLocation.CHEST || location == AttackLocation.LEFT_ARM || location == AttackLocation.RIGHT_ARM) { //Determine how much damage we can get through due to pierce int piercing = 0; if (special != null) { piercing = special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.PIERCING) == null ? 0 : special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.PIERCING).EffectValue; } //Use the chest armour if (defender.Inventory.EquippedItems.ContainsKey(EquipmentLocation.BODY)) { int block = defender.Inventory.EquippedItems[EquipmentLocation.BODY].ArmourRating - piercing; damage -= (block > 0 ? block : 0); //Do we damage the armour? int sunder = 0; if (special != null) { sunder = special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.SUNDER) == null ? 0 : special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.SUNDER).EffectValue; } if (sunder > 0 && defender.Inventory.EquippedItems[EquipmentLocation.BODY].ArmourRating > 0) { defender.Inventory.EquippedItems[EquipmentLocation.BODY].ArmourRating -= sunder; if (defender.Inventory.EquippedItems[EquipmentLocation.BODY].ArmourRating < 0) //no negative block { defender.Inventory.EquippedItems[EquipmentLocation.BODY].ArmourRating = 0; } } } } //Other location ? if (location == AttackLocation.HEAD) { //Use the head armour if (defender.Inventory.EquippedItems.ContainsKey(EquipmentLocation.HEAD)) { damage -= defender.Inventory.EquippedItems[EquipmentLocation.HEAD].ArmourRating; } } if (location == AttackLocation.LEGS) { //Use the head armour if (defender.Inventory.EquippedItems.ContainsKey(EquipmentLocation.LEGS)) { damage -= defender.Inventory.EquippedItems[EquipmentLocation.LEGS].ArmourRating; } } if (damage <= 0) { //Bounced off the armour feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.BOUNCE, diceRoll)); GameState.LocalMap.TemporaryGraphics.Add(new TemporaryGraphic() { Coord = new MapCoordinate(defender.MapCharacter.Coordinate), Graphic = SpriteManager.GetSprite(distance < 2 ? InterfaceSpriteName.SWORD_ARMOUR : InterfaceSpriteName.BOW_ARMOUR), LifeTime = attacker.IsPlayerCharacter ? 2 : 2 }); return feedback.ToArray(); } //Do we wound the character? diceRoll = random.Next(10) + 1; int woundRoll = diceRoll + (defender.Attributes.WoundResist - weaponWoundPotential) - 5; int woundBonus = 0; if (special != null) { woundBonus = special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.BLEED) == null ? 0 : special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.BLEED).EffectValue; } woundRoll += woundBonus; if (woundRoll <= 0) { //Yes - open a wound defender.Anatomy.BloodLoss++; defender.Anatomy.BloodLoss += woundBonus; //Yeah, bleed makes you bleed more AND increases chance of bleed. Not entirely sure this won't be overpowered Console.WriteLine("Wounded " + woundRoll); //Log it feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.BLEED, woundRoll)); } //Roll again diceRoll = random.Next(10) + 1; int stunRoll = diceRoll + (defender.Attributes.WoundResist - weaponStunAmount) - 5; int stunBonus = 0; if (special != null) { stunBonus = special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.STUN) == null ? 0 : special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.STUN).EffectValue; } stunRoll += stunBonus; if (stunRoll <= 0) { //Stun him defender.Anatomy.StunAmount++; defender.Anatomy.StunAmount += stunRoll; //Yeah stun makes you more likely to get stunned and makes you stun longer. Not entirely sure this won't be as overpowered as ell Console.WriteLine("Stunned " + stunRoll); } //Any damage bonus ? if (special != null) { damage += special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.DAMAGE) == null ? 0 : special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.DAMAGE).EffectValue; } #region Push if (special != null) { //Do we have a push? int pushAmount = special.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.PUSH) == null ? 0 : special.Effects.First(e => e.EffectType == SpecialAttackType.PUSH).EffectValue; if (distance >= 2) { pushAmount = 0; //No push! } if (pushAmount > 0) { //Shove the target back by the total amount of push. Or try to at least //Let's determine the direction int pushX = 0; int pushY = 0; pushX = attacker.MapCharacter.Coordinate.X - defender.MapCharacter.Coordinate.X ; pushY = attacker.MapCharacter.Coordinate.Y - defender.MapCharacter.Coordinate.Y; for (int i = 0; i < pushAmount; i++) { //PUSH! //Is the tile free? if (GameState.LocalMap.GetBlockAtCoordinate(new MapCoordinate(defender.MapCharacter.Coordinate.X, defender.MapCharacter.Coordinate.Y, 0, MapType.LOCAL)).MayContainItems) { //Yeah push em GameState.LocalMap.GetBlockAtCoordinate(new MapCoordinate(defender.MapCharacter.Coordinate.X + pushX, defender.MapCharacter.Coordinate.Y + pushY, 0, MapType.LOCAL)).ForcePutItemOnBlock(defender.MapCharacter); } else { //Is there an obstacle in the way? if (GameState.LocalMap.GetBlockAtCoordinate(new MapCoordinate(defender.MapCharacter.Coordinate.X, defender.MapCharacter.Coordinate.Y, 0, MapType.LOCAL)).IsSeeThrough) { //No, stop there break; } else { //Ouch! Stop there anyway //Do damage equal to push left damage += pushAmount - i; feedback.Add(new LogFeedback(null, Color.Red, defender.Name + " hits an obstacle")); break; } } } } } #endregion //Apply the damage switch (location) { case AttackLocation.CHEST: defender.Anatomy.Chest -= damage; break; case AttackLocation.HEAD: defender.Anatomy.Head -= damage; break; case AttackLocation.LEFT_ARM: defender.Anatomy.LeftArm -= damage; break; case AttackLocation.LEGS: defender.Anatomy.Legs -= damage; break; case AttackLocation.RIGHT_ARM: defender.Anatomy.RightArm -= damage; break; default: throw new NotImplementedException(location + " has no code prepared for damage"); } GameState.LocalMap.TemporaryGraphics.Add(new TemporaryGraphic() { Coord = new MapCoordinate(defender.MapCharacter.Coordinate), Graphic = SpriteManager.GetSprite(distance < 2 ? InterfaceSpriteName.SWORD_HIT : InterfaceSpriteName.BOW_HIT), LifeTime = attacker.IsPlayerCharacter ? 2 : 2 }); //Damage assessment - Do this properly later switch (location) { case AttackLocation.HEAD: if (defender.Anatomy.Head < 0) { if (defender.Anatomy.Head <= -5) { //Destroyed feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DESTROY, diceRoll)); } else { //Disabled feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DISABLE, diceRoll)); } //Dead feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.KILL, diceRoll)); //Close the interface feedback.Add(new InterfaceToggleFeedback(InternalActionEnum.OPEN_ATTACK, false, defender)); KillCharacter(defender); } break; case AttackLocation.CHEST: if (defender.Anatomy.Chest < 0) { if (defender.Anatomy.Chest <= -5) { //Destroyed feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DESTROY, diceRoll)); } else { //Disabled feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DISABLE, diceRoll)); } //Dead feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.KILL, diceRoll)); feedback.Add(new InterfaceToggleFeedback(InternalActionEnum.OPEN_ATTACK, false, defender)); KillCharacter(defender); } break; case AttackLocation.LEFT_ARM: if (defender.Anatomy.LeftArm < 0) { if (defender.Anatomy.LeftArm <= -5) { //Destroyed feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DESTROY, diceRoll)); } else { //Disabled feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DISABLE, diceRoll)); } } break; case AttackLocation.LEGS: if (defender.Anatomy.Legs < 0) { if (defender.Anatomy.Legs <= -5) { //Destroyed feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DESTROY, diceRoll)); } else { //Disabled feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DISABLE, diceRoll)); } } break; case AttackLocation.RIGHT_ARM: if (defender.Anatomy.RightArm < 0) { if (defender.Anatomy.RightArm <= -5) { //Destroyed feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DESTROY, diceRoll)); } else { //Disabled feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.DISABLE, diceRoll)); } } break; default: throw new NotImplementedException("You've injured an unknown body part " + location); } } else { //We have a miss //The attacker learned something attacker.Attributes.IncreaseSkill(SkillName.FIGHTER); if (distance > 2) { attacker.Attributes.IncreaseSkill(SkillName.ARCHER); } else //Are they armed? if (attacker.Inventory.EquippedItems.ContainsKey(EquipmentLocation.WEAPON)) { switch (attacker.Inventory.EquippedItems[EquipmentLocation.WEAPON].WeaponType.ToUpper()) { case "SWORD": attacker.Attributes.IncreaseSkill(SkillName.SWORDFIGHTER); break; case "AXE": attacker.Attributes.IncreaseSkill(SkillName.AXEFIGHTER); break; case "BOW": attacker.Attributes.IncreaseSkill(SkillName.ARCHER); break; default: throw new NotImplementedException("No skill pertains to the weapon type " + attacker.Inventory.EquippedItems[EquipmentLocation.WEAPON].WeaponType); } } else { //Unarmed then attacker.Attributes.IncreaseSkill(SkillName.BRAWLER); } feedback.Add(LogAction(attacker, defender, location, damageType, LogMessageStatus.MISS, diceRoll)); GameState.LocalMap.TemporaryGraphics.Add(new TemporaryGraphic() { Coord = new MapCoordinate(defender.MapCharacter.Coordinate), Graphic = SpriteManager.GetSprite(distance < 2 ? InterfaceSpriteName.SWORD_BLOCKED : InterfaceSpriteName.BOW_BLOCKED), LifeTime = (attacker.IsPlayerCharacter ? 2 : 2) }); } //We're done return feedback.ToArray(); }
/// <summary> /// Generates a special attack having a particular level /// </summary> /// <param name="level"></param> /// <returns></returns> public static SpecialAttack GenerateSpecialAttack(int level) { //Let's see how many points this counts as int pointTotal = Settings.PointProgression[level - 1]; SpecialAttack attack = new SpecialAttack(); attack.AttackName = GenerateName(); attack.Level = level; attack.PointCost = pointTotal; attack.Effects = new List<Effect>(); Random random = GameState.Random; int attempts = 0; while(pointTotal > 0 && attempts++ < 100) { //Spend! var randomEffect = Settings.EffectCosts.GetRandom(); if (randomEffect.PointCost > pointTotal) { continue; } //Do we have it already? var current = attack.Effects.FirstOrDefault(e => e.EffectType == randomEffect.Type); if (current != null) { int index = 0; //Can we progress? for (index = 0; index < randomEffect.Progressions.Length; index++) { if (randomEffect.Progressions[index] == current.EffectValue) { break; } } //Is that the last one? if (index == randomEffect.Progressions.Length -1) { //Yep. Continue continue; } else { //Nope, we can current.EffectValue = randomEffect.Progressions[index + 1]; pointTotal -= randomEffect.PointCost; } } else { //Nope, create a new one Effect effect = new Effect(); effect.EffectType = randomEffect.Type; effect.EffectValue = randomEffect.Progressions[0]; attack.Effects.Add(effect); pointTotal -= randomEffect.PointCost; } } attack.TimeOutLeft = 0; var timeOut = attack.Effects.FirstOrDefault(e => e.EffectType == SpecialAttackType.TIMEOUT); attack.TimeOut = timeOut == null ? 15 : timeOut.EffectValue; return attack; }
public void Draw(Microsoft.Xna.Framework.Content.ContentManager content, Microsoft.Xna.Framework.Graphics.SpriteBatch batch) { if (font == null) { font = content.Load<SpriteFont>(@"Fonts/TextFeedbackFont"); } var white = SpriteManager.GetSprite(ColourSpriteName.WHITE); batch.Draw(content, white, borderRect, Color.DarkGray); //Draw the background var scrollBackground = SpriteManager.GetSprite(InterfaceSpriteName.PAPER_TEXTURE); batch.Draw(content.Load<Texture2D>(scrollBackground.path), rect, scrollBackground.sourceRectangle, Color.White); batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PAPER_TEXTURE), oldBackground, Color.White); batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PAPER_TEXTURE), newBackground, Color.White); batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PAPER_TEXTURE), slotBackground, Color.White); //The text batch.DrawString(font, newAttack.AttackName, newName, Alignment.Center, Color.Black); batch.DrawString(font, "New Attack", newText, Alignment.Center, Color.White); foreach (var icons in newIcons) { switch (icons.Item1) { case SpecialAttackType.ACCURACY: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.ACCURATE_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.ATTACKS: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.RAPID_STRIKES), icons.Item2, Color.Black); break; case SpecialAttackType.BLEED: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.BLEEDING_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.DAMAGE: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.POWER_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.PIERCING: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.ARMOUR_PIERCING_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.PUSH: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PUSHBACK), icons.Item2, Color.Black); break; case SpecialAttackType.STUN: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.STUNNING_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.SUNDER: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.SUNDER), icons.Item2, Color.Black); break; case SpecialAttackType.TARGETS: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.WHIRLWIND), icons.Item2, Color.Black); break; } } foreach (var details in newDetails) { DRObjects.ActorHandling.SpecialAttacks.Effect effect = newAttack.Effects.FirstOrDefault(e => e.EffectType == details.Item1); string display = "0"; if (effect != null) { display = effect.EffectValue.ToString(); } Color colour = Color.Black; if (oldAttack != null) { int newCompare = newAttack.Effects.Where(e => e.EffectType == details.Item1).Select(e => e.EffectValue).FirstOrDefault(); int oldCompare = oldAttack.Effects.Where(e => e.EffectType == details.Item1).Select(e => e.EffectValue).FirstOrDefault(); if (newCompare > oldCompare) { colour = Color.Green; } else if (newCompare < oldCompare) { colour = Color.Red; } } batch.DrawString(font, display, details.Item2, Alignment.Center, colour); } for (int i = 0; i < slotRectangles.Length; i++) { Rectangle slot = slotRectangles[i]; // batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PAPER_TEXTURE), slotRectangles[i], Color.White); SpriteData sprite = SpriteManager.GetSprite( (InterfaceSpriteName) Enum.Parse(typeof(InterfaceSpriteName),"SA" + (i+1) )); batch.Draw(content,sprite,slotRectangles[i],GameState.PlayerCharacter.SpecialAttacks[i] == null ? Color.Black : Color.White); if (clickedNumber == i) { //Circle! batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.CIRCLE), new Rectangle(slotRectangles[i].X - 10, slotRectangles[i].Y - 10, slotRectangles[i].Width + 20, slotRectangles[i].Height + 20), Color.White); } } if (this.clickedNumber != null) { oldAttack = GameState.PlayerCharacter.SpecialAttacks[this.clickedNumber.Value]; } else { oldAttack = null; } if (oldAttack != null) { //Draw the old attack stuff batch.DrawString(font, oldAttack.AttackName, oldName, Alignment.Center, Color.Black); batch.DrawString(font, "Old Attack", oldText, Alignment.Center, Color.White); foreach (var icons in oldIcons) { switch (icons.Item1) { case SpecialAttackType.ACCURACY: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.ACCURATE_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.ATTACKS: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.RAPID_STRIKES), icons.Item2, Color.Black); break; case SpecialAttackType.BLEED: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.BLEEDING_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.DAMAGE: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.POWER_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.PIERCING: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.ARMOUR_PIERCING_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.PUSH: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PUSHBACK), icons.Item2, Color.Black); break; case SpecialAttackType.STUN: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.STUNNING_STRIKE), icons.Item2, Color.Black); break; case SpecialAttackType.SUNDER: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.SUNDER), icons.Item2, Color.Black); break; case SpecialAttackType.TARGETS: batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.WHIRLWIND), icons.Item2, Color.Black); break; } } foreach (var details in oldDetails) { DRObjects.ActorHandling.SpecialAttacks.Effect effect = oldAttack.Effects.FirstOrDefault(e => e.EffectType == details.Item1); string display = "0"; if (effect != null) { display = effect.EffectValue.ToString(); } batch.DrawString(font, display, details.Item2, Alignment.Center, Color.Black); } } else if (this.clickedNumber != null) { //This means a non-selected one is selected batch.DrawString(font, "Empty Slot", oldName, Alignment.Center, Color.Black); batch.DrawString(font, "Old Attack", oldText, Alignment.Center, Color.White); } if (this.newAttack.SkillLevelRequired <= GameState.PlayerCharacter.Attributes.GetSkill(SkillName.FIGHTER)) { batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PAPER_TEXTURE), learnRect, Color.LightGray); batch.DrawString(font, "LEARN", learnRect, Alignment.Center, Color.DarkGreen); } batch.Draw(content, SpriteManager.GetSprite(InterfaceSpriteName.PAPER_TEXTURE), cancelRect, Color.LightGray); batch.DrawString(font, "CANCEL", cancelRect, Alignment.Center, Color.DarkRed); }
public CombatManual(SpecialAttack attack) { this.SpecialAttack = attack; }