AIWander.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /// <reference path="../AI.ts" />
  2. module AIRules {
  3. export var Wander = AI.rules.createAndAddRule({
  4. name : "Wander",
  5. firstPriority : AIRules.PRIORITY_ACTING_ON_IDLE,
  6. conditions : (runner : RulebookRunner<Person>) => {
  7. let person = runner.noun;
  8. return person.AI.wanderer && (Math.random() * 100) > person.AI.wanderChance;
  9. },
  10. code : (runner : RulebookRunner<Person>) => {
  11. let person = runner.noun;
  12. let room = <RoomRandom> person.getRoom();
  13. if (person.AI.wandersOn != undefined) {
  14. // stick to region while wandering
  15. if (person.AI.wandersOn.containsRoom(room)) {
  16. // Alredy in region, so just wander off inside it
  17. let connections = room.connections.slice();
  18. let realConnections = [];
  19. for (let i = 0; i < connections.length; i++) {
  20. if (connections[i] != undefined && person.AI.wandersOn.containsRoom(connections[i])) {
  21. realConnections.push(i);
  22. }
  23. }
  24. let direction = ((new Shuffler(realConnections)).getOne());
  25. return new ActionGo(person, direction);
  26. } else {
  27. // return to region
  28. let regionRooms = person.AI.wandersOn.getRooms().filter((a : Room) => {
  29. if (a instanceof RoomRandom && a.placed) {
  30. return true;
  31. }
  32. });
  33. // Ideally we'd actually make a path to it and check the distance, since mazes can make it be longer than it really is
  34. // But this is quick and dirty enough. And since regions are closely packed, even if this is not really the closest room, the NPC will end up
  35. // entering the region earlier by accident.
  36. regionRooms.sort((a : RoomRandom, b : RoomRandom) => {
  37. let dist = a.getDistanceTo(b);
  38. if (dist != undefined) {
  39. return -dist; // This means that the latest element will be the closest.
  40. } else {
  41. return 0; // This means that the first elements will be unreachable
  42. }
  43. });
  44. let targetRoom = regionRooms.pop();
  45. return new ActionGo(person, targetRoom);
  46. }
  47. } else {
  48. // just wander in random direction
  49. let direction = room.getConnectedDirection();
  50. return new ActionGo(person, direction);
  51. }
  52. }
  53. });
  54. }