public string DecideAction(Level currentLevel) { int dir = rng.Next(1, 8); if (dir >= 5) { dir++; } if (creature is QuestGiver) { return("Wait"); } #region Array of positions Point2D[] newPos = new Point2D[10]; newPos[1] = new Point2D(creature.pos.X - 1, creature.pos.Y + 1); //1 newPos[2] = new Point2D(creature.pos.X, creature.pos.Y + 1); //2 newPos[3] = new Point2D(creature.pos.X + 1, creature.pos.Y + 1); //3 newPos[4] = new Point2D(creature.pos.X - 1, creature.pos.Y); //4 newPos[6] = new Point2D(creature.pos.X + 1, creature.pos.Y); //6 newPos[7] = new Point2D(creature.pos.X - 1, creature.pos.Y - 1); //7 newPos[8] = new Point2D(creature.pos.X, creature.pos.Y - 1); //8 newPos[9] = new Point2D(creature.pos.X + 1, creature.pos.Y - 1); //9 #endregion #region Gather States while (newPos[dir].X <= 0 || newPos[dir].X >= 80 || newPos[dir].Y <= 0 || newPos[dir].Y >= 40) //While out of bounds { dir = rng.Next(1, 8); if (dir >= 5) { dir++; } } int canAttackMeleeDir = 0; Point2D playerPos = currentLevel.creatures[0].pos; for (int y = 0; y < Level.GRIDH; y++) { for (int x = 0; x < Level.GRIDW; x++) { if (currentLevel.tileArray[x, y].itemList.Count > 0 && currentLevel.LineOfSight(creature.pos, new Point2D(x, y)) && path.Count == 0) { creature.targetPos = new Point2D(x, y); //Item is next target if seen path = currentLevel.AStarPathfind(creature, creature.pos, new Point2D(x, y)); } } } #endregion #region Decide on Action if (currentLevel.tileArray[creature.pos.X, creature.pos.Y].itemList.Count > 0) //If standing over an item { foreach (BodyPart b in creature.anatomy) { if (b.Flags.HasFlag(BodyPartFlags.CanPickUpItem)) //If any part can pick up items { inventoryCheck = true; //We're picking up an item, so we need to see what we can do with it return("Pick Up"); //Pick it up } } } if (ShouldBeHostileTo(currentLevel.creatures.FirstOrDefault(c => c.isPlayer)) && currentLevel.LineOfSight(creature.pos, playerPos)) //If player is newly seen or smelled { targetPos = playerPos; //Keep the last known position in creature's memory canAttackMeleeDir = creature.AdjacentToCreatureDir(currentLevel); if (currentLevel.ConvertAbsolutePosToRelative(creature.pos, targetPos) > 0) //If adjacent { return("Attack " + currentLevel.ConvertAbsolutePosToRelative(creature.pos, targetPos)); } path = currentLevel.AStarPathfind(creature, creature.pos, playerPos); //Path to player return("Move " + path.Pop()); } if (path.Count > 0) //If there's a target { if (targetPos == creature.pos) //If we're standing on it { targetPos = new Point2D(-1, -1); //Forget this target path.Clear(); } else { if (canAttackMeleeDir == path.Peek()) //If there's a creature in our way { return("Attack " + canAttackMeleeDir); //Attack it } if (path.Peek() > 0) { return("Move " + path.Pop()); //Go towards target } else { targetPos = new Point2D(-1, -1); path.Clear(); return("Move " + dir); //Wander } } } foreach (BodyPart b in creature.anatomy) { foreach (Item i in creature.inventory) { if (i is Potion && (b.Injury.HasFlag(InjuryLevel.Mangled) || b.Injury.HasFlag(InjuryLevel.Broken))) //If the creature has a potion and is hurt badly { return("Eat " + creature.inventory.IndexOf(i)); } } } for (int y = 0; y < Level.GRIDH; y++) { for (int x = 0; x < Level.GRIDW; x++) { if (currentLevel.tileArray[x, y].itemList.Count > 0) { if (currentLevel.LineOfSight(creature.pos, new Point2D(x, y))) { foreach (BodyPart b in creature.anatomy) { if (b.Flags.HasFlag(BodyPartFlags.CanPickUpItem)) { targetPos = new Point2D(x, y); path = currentLevel.AStarPathfind(creature, creature.pos, playerPos); //Path to item break; } } } } } } #endregion if (inventoryCheck) { foreach (Item i in creature.inventory) //Look at all the items { if (i is Weapon) { if (creature.weapon == null) { return("Wield " + creature.inventory.IndexOf(i)); } else { if (i.damage.average > creature.weapon.damage.average) { return("Unwield"); } } } if (i is Armor) { if (creature.CanWear((Armor)i)) { return("Wear " + creature.inventory.IndexOf(i)); } } } inventoryCheck = false; //If we've checked everything and can't find a use, don't bother for a while } while (!creature.CanMoveBorder(dir)) { dir = rng.Next(1, 9); if (dir >= 5) { dir++; } } return("Move " + dir); //Default action }