public override Level Eat(Level currentLevel, Creature consumer) { int creatureIndex = currentLevel.creatures.IndexOf(consumer); currentLevel.creatures[creatureIndex].Affect(eatEffect, currentLevel); //Apply effect to the consumer currentLevel.creatures[creatureIndex].inventory.Remove(this); //It's been drunk, it no longer exists; in the future, rewrite to transfer contents to creature's stomach, and leave behind an empty container in inventory return currentLevel; }
public Creature(Creature c) { this.gold = c.gold; this.attack = new DNotation(c.attack); //Deep copy this.turn_energy = c.turn_energy; this.level = c.level; this.xpWorth = c.xpWorth; this.attack = c.attack; this.xp = c.xp; this.xpLevel = c.xpLevel; this.xpBorder = c.xpBorder; this.hp = c.hp; this.hpMax = c.hpMax; this.mp = c.mp; this.mpMax = c.mpMax; this.gp = c.gp; this.killCount = c.killCount; this.seed = c.seed; this.food = c.food; this.isPlayer = c.isPlayer; this.rng = c.rng; this.isAlive = true; this.creatureImage = c.creatureImage; this.speed = c.speed; this.turnsToWait = c.speed; this.mind = c.mind; this.name = c.name; this.smelliness = c.smelliness; this.senseOfSmell = c.senseOfSmell; this.mass = c.mass; this.color = c.color; this.pos = c.pos; this.minDLevel = c.minDLevel; this.armorType = c.armorType; this.weapon = c.weapon; this.strength = c.strength; this.dexterity = c.dexterity; this.constitution = c.constitution; this.intelligence = c.intelligence; this.wisdom = c.wisdom; this.charisma = c.charisma; this.anatomy = new List<BodyPart>(); foreach (BodyPart b in c.anatomy) this.anatomy.Add(new BodyPart(b)); this.inventory = new List<Item>(); foreach (Item i in c.inventory) this.inventory.Add(i); this.wornArmor = new List<Armor>(); foreach (Armor a in c.wornArmor) this.wornArmor.Add(a); this.isDextrous = c.isDextrous; }
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 }
public Creature CreatureAdjacent(Creature thisCreature) { #region Array of positions Vector2[] newPos = new Vector2[10]; newPos[1] = new Vector2(thisCreature.pos.X - 1, thisCreature.pos.Y + 1); //1 newPos[2] = new Vector2(thisCreature.pos.X, thisCreature.pos.Y + 1); //2 newPos[3] = new Vector2(thisCreature.pos.X + 1, thisCreature.pos.Y + 1); //3 newPos[4] = new Vector2(thisCreature.pos.X - 1, thisCreature.pos.Y); //4 newPos[6] = new Vector2(thisCreature.pos.X + 1, thisCreature.pos.Y); //6 newPos[7] = new Vector2(thisCreature.pos.X - 1, thisCreature.pos.Y - 1); //7 newPos[8] = new Vector2(thisCreature.pos.X, thisCreature.pos.Y - 1); //8 newPos[9] = new Vector2(thisCreature.pos.X + 1, thisCreature.pos.Y - 1); //9 #endregion for (int i = 1; i <= 9; i++) { if (i == 5) i++; //Skip position 5 if (IsCreatureAt(newPos[i])) //If there's an adjacent creature { foreach (Creature k in creatures) //Find out which creature it is { if (k.pos == newPos[i]) //When you get a match { return k; //Return it } } } } return null; }
public Stack<byte> AStarPathfind(Creature creature, Vector2 pointA, Vector2 pointB) { Stack<byte> path = new Stack<byte>(); if (ConvertAbsolutePosToRelative(pointA, pointB) > 0) { path.Push((byte)ConvertAbsolutePosToRelative(pointA, pointB)); return path; } if (pointA.X == pointB.X && pointA.Y == pointB.Y) { path.Push(5); return path; } #region Variables //int g = 0; //int h = (int)(Math.Abs(pointB.X - pointA.X) + (int)Math.Abs(pointB.Y - pointA.Y)); bool done = false; AStarTile currentTile = new AStarTile(pointA, new Vector2(-1, -1), 0, 100 * ((int)(Math.Abs(pointB.X - pointA.X) + (int)Math.Abs(pointB.Y - pointA.Y)))); List<AStarTile> openList = new List<AStarTile>(); List<AStarTile> closedList = new List<AStarTile>(); #endregion openList.Add(currentTile); //Add the current tile while (!done) { #region Find new current tile currentTile = openList[0]; //The lowest F cost tile is the current tile openList.RemoveAt(0); //Removed from the open list closedList.Add(currentTile); //And placed in the closed list #endregion if (currentTile.pos == pointB) //If target has been just added to closed list { done = true; } #region Define adjacent vectors Vector2[] adjacent = new Vector2[8]; adjacent[0] = new Vector2(currentTile.pos.X - 1, currentTile.pos.Y + 1); //Adjacent tile at position 1 adjacent[1] = new Vector2(currentTile.pos.X, currentTile.pos.Y + 1); //Adjacent tile at position 2 adjacent[2] = new Vector2(currentTile.pos.X + 1, currentTile.pos.Y + 1); //Adjacent tile at position 3 adjacent[3] = new Vector2(currentTile.pos.X - 1, currentTile.pos.Y); //Adjacent tile at position 4 adjacent[4] = new Vector2(currentTile.pos.X + 1, currentTile.pos.Y); //Adjacent tile at position 6 adjacent[5] = new Vector2(currentTile.pos.X - 1, currentTile.pos.Y - 1); //Adjacent tile at position 7 adjacent[6] = new Vector2(currentTile.pos.X, currentTile.pos.Y - 1); //Adjacent tile at position 8 adjacent[7] = new Vector2(currentTile.pos.X + 1, currentTile.pos.Y - 1); //Adjacent tile at position 9 #endregion #region Process adjacent tiles to Current Tile for (int i = 0; i <= 7; i++) // the adjacent tiles 0-7, all 8 { if (adjacent[i].X < 0 || adjacent[i].X > GRIDW-1 || adjacent[i].Y < 0 || adjacent[i].Y > GRIDH-1) { i++; break; } bool shouldBeOpen = true; bool isAlreadyOpen = false; bool closedDoor = false; //Whether this tile has a door in it. int indexOnOpen = -1; //if (tileArray[(int)adjacent[i].X, (int)adjacent[i].Y].fixtureLibrary.Count > 0) //{ // foreach (Fixture fixture in tileArray[(int)adjacent[i].X, (int)adjacent[i].Y].fixtureLibrary) // { // if (fixture is Door) //If it's a door // { // Door door = (Door)fixture; // if (!door.isOpen) //If the door is closed // closedDoor = true; // } // } //} if (tileArray[(int)adjacent[i].X, (int)adjacent[i].Y] == null) { shouldBeOpen = false; } else if (this.tileArray[(int)adjacent[i].X, (int)adjacent[i].Y].isPassable == false && !(closedDoor && creature.isDextrous)) //If not passable { shouldBeOpen = false; //It's not a candidate if not blocked by door } else //If passable { foreach (AStarTile j in closedList) //For each closedList item { if (j.pos == adjacent[i]) //If a closedList item is the same as the potential tile { shouldBeOpen = false; //Not a candidate } } foreach (Creature c in creatures) if (c.pos == adjacent[i] && adjacent[i] != pointB) //If a creature is in the way shouldBeOpen = false; int openListCount = openList.Count; for (int j = 0; j < openListCount; j++) { if (openList[j].pos == adjacent[i]) //If an openList item is the same as the potential tile { isAlreadyOpen = true; //Mark it as already on the open list indexOnOpen = j; } } } if (shouldBeOpen) //If it should go on the open list { int g = 100; //Weight of tile ***IMPROVE THIS LATER*** int h = 100 * ((int)(Math.Abs(pointB.X - adjacent[i].X) + (int)Math.Abs(pointB.Y - adjacent[i].Y))); //Heuristic guess //int f = g + h; //Definition of f cost AStarTile newTile = new AStarTile(adjacent[i], currentTile.pos, currentTile.g + g, h, g); //Make an official tile for it if (isAlreadyOpen) //If already on the open list { if (newTile.g < openList[indexOnOpen].g) //If this path to the tile is cheaper than its previous g { openList[indexOnOpen] = newTile; //Overwrite its old info with this cheaper info } } else { openList.Insert(AStarSequentialSearch(openList, newTile), newTile); //Insert in openList a sequential search according to f cost //Calculate where this new tile should go with a binary search. ***UNFINISHED*** //AStarBinarySearch(openList, newTile); } } } if (openList.Count == 0) //If no more tiles to look at, there's no path { path.Push(0); return path; } #endregion } #region Trace back to starting tile int oldIndex = -1; int index = 0; while (currentTile.parentpos != new Vector2(-1, -1)) //Until parent is starting tile { int closedListCount = closedList.Count; for (int j = 0; j < closedListCount; j++) { if (closedList[j].pos == currentTile.parentpos) { oldIndex = index; index = j; path.Push((byte)ConvertAbsolutePosToRelative(closedList[index].pos, currentTile.pos)); break; } } currentTile = closedList[index]; } #endregion currentTile = closedList[oldIndex]; openList.Clear(); closedList.Clear(); return path; }
public void SpawnCreature(Creature c, Vector2 pos) { c.pos = pos; for (int y = 0; y < GRIDH; y++) for (int x = 0; x < GRIDW; x++) { tileArray[x, y].scentIdentifier.Add(c.name); //Keep track of this creature's scent now tileArray[x, y].scentMagnitude.Add(0); //Start it at zero scent in the room } creatures.Add(c); }
public void SlayCreature(Creature c) { if (c.revive > 0) //If extra life { c.revive = 0; //Not anymore, sukka if (c.amulet.effect.type == "revive") c.amulet = null; c.hp = c.hpMax; //Full heal c.food = 15000; //Full food c.message.Add("You have a near death experience"); c.constitution--; } else { if (creatures.IndexOf(c) == 0) playerDiedHere = true; else { int count = c.inventory.Count; for (int i = 0; i < count; i++) c.Drop(this, c.inventory[0]); //Drop all items count = c.wornArmor.Count; for (int i = 0; i < count; i++) { tileArray[c.pos.X, c.pos.Y].itemList.Add(c.wornArmor[0]); //Add item to tile c.wornArmor.Remove(c.wornArmor[0]); //From creature } //Drop all armor tileArray[c.pos.X, c.pos.Y].itemList.Add(c.weapon); //Add item to tile c.weapon = null; //Drop the weapon Item corpse = new Item(c.mass, c.mass, c.name + " corpse", c.color, new List<Item>(), new List<string>()); corpse.itemImage = 253; corpse.edible = true; tileArray[c.pos.X, c.pos.Y].itemList.Add(new Item(corpse)); //Gibs for (int y = 1; y < Level.GRIDH; y++) for (int x = 1; x < Level.GRIDW; x++) { tileArray[x, y].scentIdentifier.RemoveAt( creatures.IndexOf(c)); //Remove it from scent tracking tileArray[x, y].scentMagnitude.RemoveAt( creatures.IndexOf(c)); } if (LineOfSight(creatures[0].pos, c.pos)) creatures[0].message.Add("The " + c.name + " dies."); //killedIndex = creatureList.IndexOf(c); } } }
static void Update_Creature(Creature c) { c.message.Clear(); //Monsters shouldn't need to keep messages string action = c.mind.DecideAction(currentLevel, c); //Decide action #region Perform Action #region Move Actions List<String> actionList = new List<String>(); actionList.Add("Move 1"); actionList.Add("Move 2"); actionList.Add("Move 3"); actionList.Add("Move 4"); actionList.Add("Move 5"); actionList.Add("Move 6"); actionList.Add("Move 7"); actionList.Add("Move 8"); actionList.Add("Move 9"); for (int k = 0; k <= 8; k++) { if (action == actionList[k]) { c.Move(currentLevel, k + 1); } } actionList.Clear(); #endregion #region Item Management Actions if (action == "Pick Up") { currentLevel = c.PickUp(currentLevel); } if (action == "Unwield") c.Unwield(); if (action.StartsWith("Wield")) { while (action.StartsWith("Wield")) action = action.Remove(0, 6); //Clip everything but the index Weapon targetItem = (Weapon)c.inventory[int.Parse(action)]; c.Wield(targetItem); } if (action == "Remove") c.RemoveAll(); if (action.StartsWith("Wear")) { while (action.StartsWith("Wear")) action = action.Remove(0, 5); //Clip everything but the index Armor targetItem = (Armor)c.inventory[int.Parse(action)]; c.Wear(targetItem); } if (action.StartsWith("Eat")) //If it starts with "Eat" { action = action.Remove(0, 4); //Clip everything but the index Item targetItem = c.inventory[int.Parse(action)]; c.Eat(currentLevel, targetItem); //Eat the given item } #endregion #region Melee Attack if (action.StartsWith("Attack")) { action = action.Remove(0, 7); currentLevel = c.MeleeAttack(currentLevel, Direction.Parse(action)); } #endregion #endregion }
static void FileL_Level(Vector3 pos) { #region Setup string levelPath = "Saves/" + sessionName.ToString() + "/(" + pos.X.ToString() + ", " + pos.Y.ToString() + ", " + pos.Z.ToString() + ").txt"; //The path to the level Vector2 tilePos = new Vector2(); //The tile position we're working with if (!File.Exists(levelPath)) { GenLevel("Dungeon", false); //Fabricate one return; } #endregion #region Gen base level using (StreamReader read = new StreamReader(levelPath)) { string line = read.ReadLine(); //First entry should be the level type line = line.Remove(0, 7); //Clip off "[TYPE] " string levelType = line; // example: "Dungeon" line = read.ReadLine(); //Next is the seed line = line.Remove(0, 7); //Clip off "[SEED] " levelSeed[pos.X, pos.Y, pos.Z] = int.Parse(line); //Fix the seed to its original GenLevel(levelType, false); //Recreate the originally genned level Creature tempCreature = new Creature(currentLevel.creatures[0]); currentLevel.creatures.Clear(); //We'll fill this in from the load file for (int y = 0; y < Level.GRIDH; y++) for (int x = 0; x < Level.GRIDW; x++) //For all tiles { currentLevel.tileArray[x, y].scentIdentifier.Add(tempCreature.name); //Keep track of this creature's scent now currentLevel.tileArray[x, y].scentMagnitude.Add(0); //Start it at zero scent in the room currentLevel.tileArray[x, y].itemList.Clear(); //Clear out previous items if (!currentLevel.tileArray[x, y].isPassable && currentLevel.tileArray[x, y].fixtureLibrary.Count > 0) { currentLevel.tileArray[x, y].isTransparent = true; //Remove influence of fixtures currentLevel.tileArray[x, y].isPassable = true; } currentLevel.tileArray[x, y].fixtureLibrary.Clear(); } //currentLevel.creatureList.Add(tempCreature); #endregion line = read.ReadLine(); while (line != "[END]") { #region Work on individual tiles if (line.StartsWith("(")) //If it's a tile position { #region Base Tile Data string[] piece = line.Split(','); //Split apart based on commas piece[0] = piece[0].Remove(0, 1); //Remove "(" piece[1] = piece[1].Substring(0, piece[1].Length - 1); //Remove ")" tilePos.X = short.Parse(piece[0]); //Get the X digit tilePos.Y = short.Parse(piece[1]); //Get the Y digit currentLevel.tileArray[tilePos.X, tilePos.Y].itemList.Clear(); //Empty the random gen items. currentLevel.tileArray[tilePos.X, tilePos.Y].fixtureLibrary.Clear(); //Empty the random gen items. #endregion } else if (line.StartsWith("[ARMOR]") || line.StartsWith("[ITEM]") || line.StartsWith("[POTION]") || line.StartsWith("[SCROLL]") || line.StartsWith("[WEAPON]")) //If an item of some sort { #region Item Data string[] piece = line.Split(']'); //Split based on ] piece[0] = piece[0].Remove(0, 1); piece[1] = piece[1].Remove(0, 1); if (piece[1] == "pinecone") //TODO: Bluh hackish improve later { currentLevel.tileArray[tilePos.X, tilePos.Y].itemList.Add(new Item(content.items.Find(item => item.name == "pinecone"))); } else { foreach (Species c in content.bestiary) //For gore { if (piece[1].StartsWith(c.name)) //If it's a creature part { string[] split = piece[1].Split(' '); //Get creature name and part name Item gore; if (split[1] == "corpse") gore = new Item(500f, 500f, $"{c.name} corpse", c.color, new List<Item>(), new List<string>()); else gore = new Item(500f, 500f, $"{c.name} corpse", Color.Crimson, new List<Item>(), new List<string>()); gore.itemImage = 253; //"²" gore.edible = true; currentLevel.tileArray[tilePos.X, tilePos.Y].itemList.Add(gore); break; } } foreach (Item i in content.items) { if (i.name == piece[1]) { currentLevel.tileArray[tilePos.X, tilePos.Y].itemList.Add(i); break; } } } #endregion } else if (line.StartsWith("[CREATURE]") || line.StartsWith("[QUESTGIVER]") || line.StartsWith("[PLAYER]")) { #region Creature Data bool isPlayer = false; int creatureIndex = 0; if (line.StartsWith("[CREATURE]")) line = line.Remove(0, 11); // Clip off the "[CREATURE] " part else if (line.StartsWith("[QUESTGIVER]")) line = line.Remove(0, 13); // Clip off the "[QUESTGIVER] " part else if (line.StartsWith("[PLAYER]")) { isPlayer = true; line = line.Remove(0, 9); //Clip off the "[PLAYER] " part } string[] piece = line.Split(':'); //Split it by ':' foreach (Species c in content.bestiary) //Look for the creature to add { if (piece[0] == c.name) //If the name matches the type of creature generator { if (isPlayer) { Creature p = c.GenerateCreature("monster", content.items, int.Parse(piece[1])); p.hp = int.Parse(piece[2]); p.hpMax = int.Parse(piece[3]); p.xp = int.Parse(piece[4]); p.gold = int.Parse(piece[5]); while (p.xp > p.xpBorder*2) p.xpBorder *= 2; p.inventory.Clear(); p.wornArmor.Clear(); p.weapon = null; p.pos = tilePos; creatureIndex = 0; for (int y = 0; y < Level.GRIDH; y++) for (int x = 0; x < Level.GRIDW; x++) { currentLevel.tileArray[x, y].scentIdentifier.Add(p.name); //Keep track of this creature's scent now currentLevel.tileArray[x, y].scentMagnitude.Add(0); //Start it at zero scent in the room } currentLevel.creatures.Insert(0, p); //Insert player at spot 0 } else { creatureIndex = currentLevel.creatures.Count; if (currentLevel.levelType == "village") { Creature p = c.GenerateCreature("quest giver", content.items, int.Parse(piece[1])); p.inventory.Clear(); p.wornArmor.Clear(); p.weapon = null; currentLevel.SpawnCreature(p, tilePos); } else { Creature p = c.GenerateCreature("monster", content.items, int.Parse(piece[1])); p.inventory.Clear(); p.wornArmor.Clear(); p.weapon = null; currentLevel.SpawnCreature(p, tilePos); } } } } for (int a = 2; a < piece.Length; a++) //Look for items in the inventory to add { if (piece[a] == "pinecone") //Bluh hackish improve later { currentLevel.creatures[creatureIndex].inventory.Add(new Item(content.items.Find(item => item.name == "pinecone"))); } foreach (Species c in content.bestiary) //For gore { if (piece[a].StartsWith(c.name)) //If it's a creature part { string[] split = piece[a].Split(' '); //Get creature name and part name Item gore; if (split[1] == "corpse") gore = new Item(500f, 500f, $"{c.name} corpse", c.color, new List<Item>(), new List<string>()); else gore = new Item(500f, 500f, $"{c.name} corpse", Color.Crimson, new List<Item>(), new List<string>()); gore.itemImage = 253; gore.edible = true; currentLevel.creatures[creatureIndex].inventory.Add(gore); break; } } foreach (Item i in content.items) { if (i.name == piece[a]) { currentLevel.creatures[creatureIndex].inventory.Add(i); } } } #endregion } else if (line.StartsWith("[TRAP]")) { #region Trap Data line = line.Remove(0, 7); //Remove the "[TRAP] " part currentLevel.tileArray[tilePos.X, tilePos.Y].fixtureLibrary.Add(new Trap(new Effect(rngDie.Roll(5), line))); //Add trap #endregion } else if (line.StartsWith("[TREE]")) { #region Tree Data line = line.Remove(0, 7); //Remove the "[TREE] " part string[] piece = line.Split(':'); Tree thisTree = new Tree(rng); thisTree.species = piece[0]; thisTree.fruit = piece[1]; currentLevel.tileArray[tilePos.X, tilePos.Y].isPassable = false; //Fix for tree currentLevel.tileArray[tilePos.X, tilePos.Y].isTransparent = false; //Fix for tree currentLevel.tileArray[tilePos.X, tilePos.Y].fixtureLibrary.Add(thisTree); //Add tree #endregion } else if (line.StartsWith("[DOOR]")) { #region Door Data line = line.Remove(0, 7); string[] dataSplit = line.Split(':'); Tile thisTile = currentLevel.tileArray[tilePos.X, tilePos.Y]; Door thisDoor = new Door(thisTile, bool.Parse(dataSplit[1])); thisTile.fixtureLibrary.Add(thisDoor); if (dataSplit[0] == "open") { thisDoor.Open(thisTile, currentLevel); //Open the door from default closed } else { thisDoor.Close(thisTile, currentLevel); } #endregion } else if (line.StartsWith("[STAIRS]")) { #region Stairs Data line = line.Remove(0, 9); if (line == "down") currentLevel.tileArray[tilePos.X, tilePos.Y].fixtureLibrary.Add(new Stairs(true)); else currentLevel.tileArray[tilePos.X, tilePos.Y].fixtureLibrary.Add(new Stairs(false)); #endregion } #endregion line = read.ReadLine(); } } //read.Dispose(); //read.Close(); //Close this now that we're done with it }
static void Update_PostTurn(Creature c) { c.Wait(currentLevel); if (c.message.Count > 50) c.message.RemoveRange(0, c.message.Count - 50); //Toss excess messages #region Check if a creature should be dead int killedIndex = 0; if (c.ShouldBeDead(currentLevel)) { currentLevel.SlayCreature(c); } if (killedIndex > 0) currentLevel.creatures.RemoveAt(killedIndex); #endregion }
static void Update_Smell(Creature c) { int x = (int)c.pos.X; int y = (int)c.pos.Y; string smelledWhat = String.Empty; for (int i = 0; i < currentLevel.tileArray[x, y].scentMagnitude.Count; i++) if (currentLevel.tileArray[x, y].scentMagnitude[i] > c.senseOfSmell) { smelledWhat = currentLevel.tileArray[x, y].scentIdentifier[i]; } if (smelledWhat != String.Empty) { bool seeSmelled = false; bool ownSmell = false; for (int i = 1; i < currentLevel.creatures.Count; i++) { if (currentLevel.LineOfSight(c.pos, currentLevel.creatures[i].pos) && currentLevel.creatures[i].name == smelledWhat) { seeSmelled = true; //It's the same as something seen } if (smelledWhat == c.name) ownSmell = true; //It's the creature's own smell } if (!seeSmelled && !ownSmell) //If it's an un-obvious smell { int count = c.message.Count; if (count > 0) { //if (currentLevel.creatureList[n].message[count - 1] != "You smell a " + smelledWhat + ".") //Don't spam this // currentLevel.creatureList[n].message.Add("You smell a " + smelledWhat + "."); } } } }
static bool Update_Player(Creature c) { if (currentLevel.playerDiedHere) { if (c.revive > 0) //If extra life { c.revive = 0; //Not anymore, sukka if (c.amulet.effect.type == "revive") { c.message.Add("Your " + c.amulet.name + " disintegrates."); c.amulet = null; } c.hp = c.hpMax; //Full heal c.food = 15000; //Full food c.message.Add("You have a near death experience"); c.constitution--; currentLevel.playerDiedHere = false; } else { c.message.Add("You have died from " + currentLevel.causeOfDeath); c.message.Add("This happened because " + currentLevel.mannerOfDeath); c.message.Add("You have slain " + currentLevel.creatures[0].killCount + " foes"); c.message.Add("You lived to see " + exploredLevels + " areas in your world"); Draw(); while (Update_GetKey() != "Enter") { }; //Wait for Enter FileD_World(); run = false; gameState = GameState.OpeningMenu; return false; } } bool wait = true; Vector2 radius; while (wait) { Draw(); string input = Update_GetKey(); #region Process Input switch (input) { case "1": case "2": case "3": case "4": case "6": case "7": case "8": case "9": return Update_Move(currentLevel.creatures[0], Direction.Parse(input)); case "5": case ".": case "s": return true; //Wait a turn case ">": #region [S] Adventurer: Descend if (currentLevel.tileArray[c.pos.X, c.pos.Y].fixtureLibrary.Count > 0) { //If there's a fixture here if (currentLevel.tileArray[c.pos.X, c.pos.Y].fixtureLibrary[0] is Stairs) { //If that fixture is stairs Stairs stairs = (Stairs)currentLevel.tileArray[c.pos.X, c.pos.Y].fixtureLibrary[0]; //Stairs if (stairs.isDown) { //If those stairs are down stairs mapPos.Z++; //Go down a level c = new Creature(c); //Break reference link GenLevel("dungeon", true); c.pos = currentLevel.creatures[0].pos; //Place the player at the new up stairs position currentLevel.creatures[0] = c; wait = true; } else { c.message.Add("How does one go down up stairs?"); } } } break; #endregion case "<": #region [S] Adventurer: Ascend if (currentLevel.tileArray[c.pos.X, c.pos.Y].fixtureLibrary.Count > 0) { if (currentLevel.tileArray[c.pos.X, c.pos.Y].fixtureLibrary[0] is Stairs) { Stairs stairs = (Stairs)currentLevel.tileArray[c.pos.X, c.pos.Y].fixtureLibrary[0]; //Stairs if (!stairs.isDown) { mapPos.Z--; //Go up a level c = new Creature(c); //Break reference link if (mapPos.Z < 1) { Random thisLevelRNG = new Random(levelSeed[mapPos.X, mapPos.Y, mapPos.Z]); //This level's generator if (thisLevelRNG.Next(0, 100) < 20) { GenLevel("village", true); } else { GenLevel("forest", true); } } else GenLevel("dungeon", true); for (int y = 0; y < Level.GRIDH; y++) for (int x = 0; x < Level.GRIDW; x++) if (currentLevel.tileArray[x, y].fixtureLibrary.Count > 0) if (currentLevel.tileArray[x, y].fixtureLibrary[0].type == "stairs") { stairs = (Stairs)currentLevel.tileArray[x, y].fixtureLibrary[0]; if (stairs.isDown) c.pos = new Vector2(x, y); //Place on down stairs } currentLevel.creatures[0] = c; } else { c.message.Add("How does one go up down stairs?"); } } } break; #endregion case "Escape": gameState = GameState.EscapeMenu; return false; case ",": #region Pick Up c.PickUp(currentLevel); while (c.inventory.Count > 25) { c.message.Add("You drop your " + c.inventory[25] + " to make room."); c.Drop(currentLevel, c.inventory[25]); //Drop item } wait = false; break; #endregion case "c": #region Close Vector2[] position = new Vector2[10]; position[1] = new Vector2((int)c.pos.X - 1, (int)c.pos.Y + 1); position[2] = new Vector2((int)c.pos.X , (int)c.pos.Y + 1); position[3] = new Vector2((int)c.pos.X + 1, (int)c.pos.Y + 1); position[4] = new Vector2((int)c.pos.X - 1, (int)c.pos.Y ); position[6] = new Vector2((int)c.pos.X + 1, (int)c.pos.Y ); position[7] = new Vector2((int)c.pos.X - 1, (int)c.pos.Y - 1); position[8] = new Vector2((int)c.pos.X , (int)c.pos.Y - 1); position[9] = new Vector2((int)c.pos.X + 1, (int)c.pos.Y - 1); for (int dir = 1; dir <= 9; dir++) { if (dir == 5) dir++; //Skip 5 foreach (Fixture f in currentLevel.tileArray[(int)position[dir].X, (int)position[dir].Y].fixtureLibrary) { if (f.type == "door") { Door door = (Door)f; if (door.isOpen) { c.CloseDoor(currentLevel.tileArray[ (int)position[dir].X, (int)position[dir].Y], currentLevel); } } } } break; #endregion case "e": currentLevel.tileArray[c.pos.X, c.pos.Y].engraving = Update_GetString(); //Engrave wait = false; break; case "h": #region Hax dig if (debugMode) { c.message.Add("Choose a direction to dig."); string s = Update_GetKey(); radius = new Vector2(c.pos.X, c.pos.Y); if (s == "1") radius = new Vector2(c.pos.X - 5, c.pos.Y + 5); else if (s == "2") radius = new Vector2(c.pos.X - 0, c.pos.Y + 5); else if (s == "3") radius = new Vector2(c.pos.X + 5, c.pos.Y + 5); else if (s == "4") radius = new Vector2(c.pos.X - 5, c.pos.Y - 0); else if (s == "6") radius = new Vector2(c.pos.X + 5, c.pos.Y - 0); else if (s == "7") radius = new Vector2(c.pos.X - 5, c.pos.Y - 5); else if (s == "8") radius = new Vector2(c.pos.X - 0, c.pos.Y - 5); else if (s == "9") radius = new Vector2(c.pos.X + 5, c.pos.Y - 5); else { c.message.Add("Dig cancelled"); break; } c.message.Add("You release a blast of unnatural energy, tearing through the walls of the dungeon."); currentLevel.DigLine(c.pos, radius); wait = false; } wait = true; break; #endregion case "i": gameState = GameState.InventoryMenu; //Gamestate is now the Inventory Menu return false; case "k": #region Kick/Break c.message.Add("Choose a direction."); input = Update_GetKey(); radius = new Vector2(c.pos.X, c.pos.Y); if (input == "1") radius = new Vector2(c.pos.X - 1, c.pos.Y + 1); else if (input == "2") radius = new Vector2(c.pos.X - 0, c.pos.Y + 1); else if (input == "3") radius = new Vector2(c.pos.X + 1, c.pos.Y + 1); else if (input == "4") radius = new Vector2(c.pos.X - 1, c.pos.Y - 0); else if (input == "6") radius = new Vector2(c.pos.X + 1, c.pos.Y - 0); else if (input == "7") radius = new Vector2(c.pos.X - 1, c.pos.Y - 1); else if (input == "8") radius = new Vector2(c.pos.X - 0, c.pos.Y - 1); else if (input == "9") radius = new Vector2(c.pos.X + 1, c.pos.Y - 1); else { c.message.Add("Cancelled"); break; } bool creatureThere = false; foreach (Creature d in currentLevel.creatures) { if (d.pos == radius) //If a creature is there. { creatureThere = true; } } if (creatureThere) //Stupid foreach limitations { c.MeleeAttack(currentLevel, Direction.Parse(input)); } else if (currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary.Count > 0) { if (currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary[0] is Door) { if (rngDie.Roll(2) == 1) // 1/2 chance { Item stick = new Item(100f, 100f, "stick", Color.Brown, new List<Item>(), new List<string>()); currentLevel.tileArray[radius.X, radius.Y].itemList.Add(new Item(stick)); currentLevel.tileArray[radius.X, radius.Y].itemList.Add(new Item(stick)); currentLevel.tileArray[radius.X, radius.Y].itemList.Add(new Item(stick)); currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary.RemoveAt(0); currentLevel.tileArray[radius.X, radius.Y].isPassable = true; currentLevel.tileArray[radius.X, radius.Y].isTransparent = true; currentLevel.tileArray[radius.X, radius.Y].isDoor = false; c.message.Add("The door splinters apart."); } else { c.message.Add("The door thuds."); } } else if (currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary[0] is Trap) { Trap thisTrap = (Trap)currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary[0]; if (thisTrap.effect.type == "tripwire") { Item rope = new Item(100f, 100f, "rope", Color.Wheat, new List<Item>(), new List<string>()); foreach (Item t in content.items) { if (t.name == "rope") { rope = new Item(t); //Copy an actual rope if possible } } currentLevel.tileArray[radius.X, radius.Y].itemList.Add(new Item(rope)); c.message.Add("You take apart the tripwire."); currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary.RemoveAt(0); } } else if (currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary[0] is Stairs) { c.TakeDamage(1); //Ow. c.message.Add("You kick the hard stairs and hurt your leg."); } else if (currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary[0] is Tree) { Tree thisTree = (Tree)currentLevel.tileArray[radius.X, radius.Y].fixtureLibrary[0]; if (rng.Next(1, 101) > 50) //50% chance { c.TakeDamage(1); //Ow. c.message.Add("You hurt your leg kicking the tree."); } else if (thisTree.fruit != String.Empty && rng.Next(1, 101) > 50) //If it has fruit, 50% chance { currentLevel.tileArray[c.pos.X, c.pos.Y].itemList.Add(new Item(100f, 100f, thisTree.fruit, Color.Lime, new List<Item>(), new List<string>())); //Add a fruit c.message.Add("A " + thisTree.fruit + " drops at your feet."); thisTree.fruit = String.Empty; //No more fruit } } } else { c.message.Add("You kick at nothing."); } break; #endregion case "l": if (debugMode) { if (iCanSeeForever) iCanSeeForever = false; else iCanSeeForever = true; } return false; case "o": #region Open position = new Vector2[10]; position[1] = new Vector2((int)c.pos.X - 1, (int)c.pos.Y + 1); position[2] = new Vector2((int)c.pos.X , (int)c.pos.Y + 1); position[3] = new Vector2((int)c.pos.X + 1, (int)c.pos.Y + 1); position[4] = new Vector2((int)c.pos.X - 1, (int)c.pos.Y ); position[6] = new Vector2((int)c.pos.X + 1, (int)c.pos.Y ); position[7] = new Vector2((int)c.pos.X - 1, (int)c.pos.Y - 1); position[8] = new Vector2((int)c.pos.X , (int)c.pos.Y - 1); position[9] = new Vector2((int)c.pos.X + 1, (int)c.pos.Y - 1); for (int dir = 1; dir <= 9; dir++) { if (dir == 5) dir++; //Skip 5 foreach (Fixture f in currentLevel.tileArray[(int)position[dir].X, (int)position[dir].Y].fixtureLibrary) { if (f.type == "door") { Door door = (Door)f; if (!door.isOpen) { c.OpenDoor(currentLevel.tileArray[(int)position[dir].X, (int)position[dir].Y], currentLevel); } } } } break; #endregion case "v": #region Hax Dive if (debugMode) { c = new Creature(c); //Break reference link c.message.Add("You warp through the floor"); mapPos.Z++;//Go down a level GenLevel("dungeon", true); c.pos = currentLevel.creatures[0].pos; //Place the player at the new up stairs position currentLevel.creatures[0] = c; c.message.Add("Now entering area (" + mapPos.X + ", " + mapPos.Y + ", " + mapPos.Z + ")"); } break; #endregion case "w": if (c.weapon == null) c.message.Add("You are wielding nothing."); else { c.Unwield(); wait = false; } break; case "W": if (c.wornArmor.Count > 0) { c.RemoveAll(); wait = true; } else c.message.Add("You are wearing no armor."); break; case "x": Update_GetPosition(); //Retrieve a position return false; case "X": if (debugMode) //Toggle debug mode { debugMode = false; c.message.Add("You feel the unnatural energy fade."); } else { debugMode = true; c.message.Add("You call upon the power of Kalasen."); } iCanSeeForever = false; //Disable infinisight return false; case "z": gameState = GameState.HealthMenu; return false; default: return false; //If no other appropriate key is pressed, don't use a turn } #endregion } return true; }
static bool Update_Move(Creature c, Directions dir) { bool peacefulAdjacent = false; //Whether the adjacent creature, if any, is peaceful foreach (Creature d in currentLevel.creatures) { if (d is QuestGiver && d.pos == c.pos.AdjacentVector(dir)) { QuestGiver qG = (QuestGiver)d; bool haveItem = false; peacefulAdjacent = true; c.message.Add("You chat with the " + d.name + "."); int inventoryCount = c.inventory.Count; //Bluh foreach for (int itemIndex = 0; itemIndex < inventoryCount; itemIndex++) { Item item = c.inventory[itemIndex]; //There, foreach simulated if (item.name == qG.wantObject) { haveItem = true; c.message.Add(CapitalizeFirst(d.name) + ": I see you have a " + qG.wantObject + ". Trade for a " + qG.giveObject + "? (y/n)"); Draw(); //Draw this to the screen if (Update_GetKey() == "y") { d.inventory.Add(item); //Give away the wanted item c.inventory.Remove(item); int cInventoryCount = c.inventory.Count; //Bluh foreach for (itemIndex = 0; itemIndex < cInventoryCount; itemIndex++) { Item cItem = d.inventory[itemIndex]; c.inventory.Add(cItem); //Recieve giveObject d.inventory.Remove(cItem); } foreach (Item cItem in d.inventory) { if (cItem.name == qG.giveObject) { c.inventory.Add(cItem); } } qG.CycleWantGiveItem(content.items); //Cycle what s/he wants and what he will give c.message.Add(CapitalizeFirst(d.name) + ": You trade your items."); } else { c.message.Add(CapitalizeFirst(d.name) + ": Too bad. Come back if you change your mind."); } break; } } if (!haveItem) //If we don't have the item { c.message.Add(CapitalizeFirst(d.name) + ": Hello adventurer. If you bring me a " + qG.wantObject + ", I'll give you a " + qG.giveObject + "."); } return true; //Talking is not a free action } } if (!peacefulAdjacent) { if (c.CanAttackMelee(currentLevel, dir) && !peacefulAdjacent) { currentLevel = c.MeleeAttack(currentLevel, dir); return true; } else if (!currentLevel.MoveWillBeBlocked(0, dir)) { bool moved = c.Move(currentLevel, (int)dir); Update_MapEdge(c); //Check for hitting map edge return moved; } } return false; }
static void Update_MapEdge(Creature c) { if (c.pos.X <= 1) { Creature player = new Creature(c); //Grab copy of player mapPos.X--; //We've gone to the left if (mapPos.X == -1) { mapPos.X = 99; //Loop around } Random thisLevelRNG = new Random(levelSeed[mapPos.X, mapPos.Y, mapPos.Z]); //This level's generator if (thisLevelRNG.Next(0, 100) < 30) { GenLevel("village", true); } else { GenLevel("forest", true); } player.pos.X = Level.GRIDW - 2; //Now on other end of map currentLevel.creatures[0] = player; //Creature 0 is the player } else if (c.pos.X >= Level.GRIDW - 1) { Creature player = new Creature(c); //Grab copy of player mapPos.X++; //We've gone to the left if (mapPos.X == 100) { mapPos.X = 0; //Loop around } Random thisLevelRNG = new Random(levelSeed[mapPos.X, mapPos.Y, mapPos.Z]); //This level's generator if (thisLevelRNG.Next(0, 100) < 30) { GenLevel("village", true); } else { GenLevel("forest", true); } player.pos.X = 2; //Now on other end of map currentLevel.creatures[0] = player; //Creature 0 is the player } else if (c.pos.Y <= 1) { Creature player = new Creature(c); //Grab copy of player mapPos.Y--; //We've gone to the left if (mapPos.Y == -1) { mapPos.Y = 99; //Loop around } Random thisLevelRNG = new Random(levelSeed[mapPos.X, mapPos.Y, mapPos.Z]); //This level's generator if (thisLevelRNG.Next(0, 100) < 30) { GenLevel("village", true); } else { GenLevel("forest", true); } player.pos.Y = Level.GRIDH - 2; //Now on other end of map currentLevel.creatures[0] = player; //Creature 0 is the player } else if (c.pos.Y >= Level.GRIDH - 1) { Creature player = new Creature(c); //Grab copy of player mapPos.Y++; //We've gone to the left if (mapPos.X == 100) { mapPos.X = 0; //Loop around } Random thisLevelRNG = new Random(levelSeed[mapPos.X, mapPos.Y, mapPos.Z]); //This level's generator if (thisLevelRNG.Next(0, 100) < 30) { GenLevel("village", true); } else { GenLevel("forest", true); } player.pos.Y = 2; //Now on other end of map currentLevel.creatures[0] = player; //Creature 0 is the player } }
static void Update_Hunger(Creature c) { c.food -= 2; //Hunger if (c.food < 0) //If starving { c.hp--; currentLevel.causeOfDeath = "organ failure."; currentLevel.mannerOfDeath = "you were starving."; } }
public void FallMultiple(Creature c) { c.message.Add("IT KEEPS HAPENNING"); }