public Level MeleeAttack(Level currentLevel, Directions dir) { if (dir == Directions.NONE) { throw new ArgumentOutOfRangeException("dir", "Attempted to melee attack own location"); } int opponentIndex = -1; #region Attack creature in given direction if (currentLevel.CreatureNAt(pos.AdjacentVector(dir)) >= 0) { opponentIndex = currentLevel.CreatureNAt(pos.AdjacentVector(dir)); var opponent = currentLevel.creatures[opponentIndex]; if (opponent is QuestGiver) { //TODO: Make aggressive } byte chanceToMiss = 10; chanceToMiss += (byte)(15 - dexterity); if (rng.Next(0, 101) < chanceToMiss) { message.Add("You miss the " + currentLevel.creatures[opponentIndex].name + "."); currentLevel.creatures[opponentIndex].message.Add("The " + name + " misses you."); } else { int damage = 1; if (weapon == null) { damage = rngDie.Roll(attack); } else { damage = rngDie.Roll(weapon.damage); } int partIndex = rng.Next(0, currentLevel.creatures[opponentIndex].anatomy.Count); BodyPart part = currentLevel.creatures[opponentIndex].anatomy[partIndex]; foreach (Armor a in wornArmor) { foreach (string s in a.covers) { if (s == part.Name) { //damage -= a.aC; } } } if (damage <= 0) { damage = 0; message.Add("You deal no damage."); } var damageBefore = currentLevel.creatures[opponentIndex].anatomy[partIndex].Injury; currentLevel.creatures[opponentIndex].TakeDamage(damage); var damageAfter = currentLevel.creatures[opponentIndex].anatomy[partIndex].Injury; message.Add("You hit the " + currentLevel.creatures[opponentIndex].name + " in the " + part.Name + " for " + damage + " damage."); currentLevel.creatures[opponentIndex].message.Add("The " + this.name + " hits you in the " + part.Name + " for " + damage + " damage."); if (damageBefore != damageAfter) { switch (damageAfter) { case InjuryLevel.Minor: message.Add($"You wound the {currentLevel.creatures[opponentIndex].name}'s {part.Name}."); break; case InjuryLevel.Broken: message.Add($"You break the {currentLevel.creatures[opponentIndex].name}'s {part.Name}."); break; case InjuryLevel.Mangled: message.Add($"You mangle the {currentLevel.creatures[opponentIndex].name}'s {part.Name}."); break; case InjuryLevel.Destroyed: message.Add($"You obliterate the {currentLevel.creatures[opponentIndex].name}'s {part.Name}."); break; } } if (weapon is Potion) { Potion p = (Potion)weapon; currentLevel.creatures[opponentIndex].inventory.Add(p); p.Eat(currentLevel, currentLevel.creatures[opponentIndex]); //Smash, effect affects the creature message.Add($"The ${p.name} smashes against the ${currentLevel.creatures[opponentIndex].name}"); weapon = null; //Smashed, gone } if (opponentIndex == 0) //If player { currentLevel.causeOfDeath = $"lethal damage to your {part.Name}."; if (weapon == null) { currentLevel.mannerOfDeath = $"you were hit in the {part.Name} by a {name}."; } else { currentLevel.mannerOfDeath = $"you were struck in the {part.Name} by a {weapon.name} wielded by a {name}."; } } } } #endregion #region If Killed Opponent if (currentLevel.creatures[opponentIndex].ShouldBeDead(currentLevel)) { if (opponentIndex == 0) //If it was the player { currentLevel.playerDiedHere = true; } else { Creature c = currentLevel.creatures[opponentIndex]; killCount++; xp += currentLevel.creatures[opponentIndex].xpWorth; if (xp > xpBorder * 2) //AKA 20, 40, 80, 160 { LevelUpForSlayingImp(); } int count = currentLevel.creatures[opponentIndex].inventory.Count; for (int i = 0; i < count; i++) { currentLevel = currentLevel.creatures[opponentIndex].Drop(currentLevel, currentLevel.creatures[opponentIndex].inventory[0]); //Drop on death } this.message.Add("You kill the " + currentLevel.creatures[opponentIndex].name + "."); if (currentLevel.creatures[opponentIndex].name == "dragon") { this.message.Add("You monster."); } Item corpse = new Item(500f, 500f, $"{currentLevel.creatures[opponentIndex].name} corpse", currentLevel.creatures[opponentIndex].color, new List <Item>(), new List <string>() ); corpse.itemImage = 253; //"�" corpse.edible = true; corpse.nutrition = 3000; //For now, default to this currentLevel.tileArray[currentLevel.creatures[opponentIndex].pos.X, currentLevel.creatures[opponentIndex].pos.Y].itemList.Add(new Item(corpse)); //Gibs for (int y = 1; y < Level.GRIDH; y++) { for (int x = 1; x < Level.GRIDW; x++) { currentLevel.tileArray[x, y].scentIdentifier.RemoveAt(opponentIndex); //Remove it from scent tracking currentLevel.tileArray[x, y].scentMagnitude.RemoveAt(opponentIndex); } } currentLevel.creatures.RemoveAt(opponentIndex); //Creature is gone ***Improve with death drop*** } } #endregion return(currentLevel); //Give back the level now that we're done with it }
public void RangeAttack(Level currentLevel, Creature target, Item firedItem) { #region Attack creature in given direction if (target is QuestGiver) { Creature c = (Creature)target; target = new Creature(c); //And then target was a monster message.Add("The " + c.name + " gets angry!"); //And s/he's mad. } byte chanceToMiss = 10; //The chance to miss target chanceToMiss += (byte)(15 - dexterity); //Dex bonus if (rng.Next(0, 101) < chanceToMiss) //If miss { message.Add("You miss the " + target.name + "."); target.message.Add("The " + name + " misses you."); currentLevel.tileArray[targetPos.X, targetPos.Y].itemList.Add(firedItem); //It ends up on selected tile } else { int damage = rngDie.Roll(attack); //Inclusive //damage = (int)((float)damage * ((float)strength / 10f)); //Strength bonus int partIndex = rng.Next(0, target.anatomy.Count); BodyPart part = target.anatomy[partIndex]; foreach (Armor a in wornArmor) { foreach (string s in a.covers) { if (s == part.Name) { damage -= a.aC; } } } //float conBonus = target.constitution / 10f; //damage = (int)((float)damage / conBonus); target.TakeDamage(damage); this.message.Add("You hit the " + target.name + " in the " + part.Name + " for " + damage + " damage."); target.message.Add("The " + this.name + " hits you in the " + part.Name + " for " + damage + " damage."); if (firedItem is Potion) { Potion p = (Potion)firedItem; target.inventory.Add(p); p.Eat(currentLevel, target); //Smash, effect affects the creature this.message.Add("The " + p.name + " smashes against the " + target.name); } else { currentLevel.tileArray[targetPos.X, targetPos.Y].itemList.Add(firedItem); //It ends up on selected tile } if (target == currentLevel.creatures[0]) //If player { currentLevel.causeOfDeath = "lethal damage to your " + part.Name + "."; currentLevel.mannerOfDeath = "you were struck in the " + part.Name + " by a " + firedItem.name + " thrown by a " + name + "."; } inventory.Remove(firedItem); //Remove item from inventory } #endregion #region If Killed Opponent if (target.ShouldBeDead(currentLevel)) { killCount++; if (currentLevel.creatures.IndexOf(target) == 0) //If it was the player { currentLevel.playerDiedHere = true; } else { int count = target.inventory.Count; for (int i = 0; i < count; i++) { currentLevel = target.Drop(currentLevel, target.inventory[0]); //Drop on death } this.message.Add("You kill the " + target.name + "."); if (target.name == "dragon") { this.message.Add("You monster."); } Item corpse = new Item(target.mass, target.mass, $"{target.name} corpse", target.color, new List <Item>(), new List <string>()); corpse.itemImage = 253; corpse.edible = true; corpse.nutrition = 3000; //For now, default to this currentLevel.tileArray[target.pos.X, target.pos.Y].itemList.Add(new Item(corpse)); //Gibs for (int y = 1; y < 40; y++) { for (int x = 1; x < 80; x++) { currentLevel.tileArray[x, y].scentIdentifier.RemoveAt(currentLevel.creatures.IndexOf(target)); //Remove it from scent tracking currentLevel.tileArray[x, y].scentMagnitude.RemoveAt(currentLevel.creatures.IndexOf(target)); } } currentLevel.creatures.RemoveAt(currentLevel.creatures.IndexOf(target)); //Creature is gone ***Improve with death drop*** } } #endregion }