diff options
Diffstat (limited to 'src/com/fourisland')
| -rw-r--r-- | src/com/fourisland/frigidearth/MapViewGameState.java | 217 | ||||
| -rw-r--r-- | src/com/fourisland/frigidearth/Mob.java | 1 | ||||
| -rw-r--r-- | src/com/fourisland/frigidearth/mobs/Mouse.java | 1 | ||||
| -rw-r--r-- | src/com/fourisland/frigidearth/mobs/Rat.java | 40 |
4 files changed, 249 insertions, 10 deletions
| diff --git a/src/com/fourisland/frigidearth/MapViewGameState.java b/src/com/fourisland/frigidearth/MapViewGameState.java index 08bb151..67da9ae 100644 --- a/src/com/fourisland/frigidearth/MapViewGameState.java +++ b/src/com/fourisland/frigidearth/MapViewGameState.java | |||
| @@ -5,11 +5,15 @@ | |||
| 5 | package com.fourisland.frigidearth; | 5 | package com.fourisland.frigidearth; |
| 6 | 6 | ||
| 7 | import com.fourisland.frigidearth.mobs.Mouse; | 7 | import com.fourisland.frigidearth.mobs.Mouse; |
| 8 | import com.fourisland.frigidearth.mobs.Rat; | ||
| 8 | import java.awt.Color; | 9 | import java.awt.Color; |
| 9 | import java.awt.Graphics2D; | 10 | import java.awt.Graphics2D; |
| 10 | import java.awt.Point; | 11 | import java.awt.Point; |
| 11 | import java.awt.event.KeyEvent; | 12 | import java.awt.event.KeyEvent; |
| 12 | import java.util.ArrayList; | 13 | import java.util.ArrayList; |
| 14 | import java.util.Arrays; | ||
| 15 | import java.util.Collections; | ||
| 16 | import java.util.Deque; | ||
| 13 | import java.util.List; | 17 | import java.util.List; |
| 14 | 18 | ||
| 15 | /** | 19 | /** |
| @@ -275,10 +279,15 @@ public class MapViewGameState implements GameState | |||
| 275 | rooms.add(room); | 279 | rooms.add(room); |
| 276 | 280 | ||
| 277 | // Place mice in random rooms because yolo | 281 | // Place mice in random rooms because yolo |
| 278 | if (Functions.random(0, 100) < 25) | 282 | int random = Functions.random(0,100); |
| 283 | if (random < 25) | ||
| 279 | { | 284 | { |
| 280 | Mob mob = new Mouse(Functions.random(room.getX()+1, room.getX()+room.getWidth()-2), Functions.random(room.getY()+1, room.getY()+room.getHeight()-2)); | 285 | Mob mob = new Mouse(Functions.random(room.getX()+1, room.getX()+room.getWidth()-2), Functions.random(room.getY()+1, room.getY()+room.getHeight()-2)); |
| 281 | mobs.add(mob); | 286 | mobs.add(mob); |
| 287 | } else if (random < 50) | ||
| 288 | { | ||
| 289 | Mob mob = new Rat(Functions.random(room.getX()+1, room.getX()+room.getWidth()-2), Functions.random(room.getY()+1, room.getY()+room.getHeight()-2)); | ||
| 290 | mobs.add(mob); | ||
| 282 | } | 291 | } |
| 283 | 292 | ||
| 284 | return true; | 293 | return true; |
| @@ -594,19 +603,37 @@ public class MapViewGameState implements GameState | |||
| 594 | return; | 603 | return; |
| 595 | } | 604 | } |
| 596 | 605 | ||
| 597 | // Move mobs randomly | 606 | // Move mobs |
| 598 | for (Mob mob : mobs) | 607 | for (Mob mob : mobs) |
| 599 | { | 608 | { |
| 600 | Direction toDir = null; | 609 | // If the mob is hostile, it should move toward the player IF IT CAN SEE the player |
| 601 | 610 | // Also, if it is adjacent to the player, it should attack | |
| 602 | for (int i=0; i<10; i++) | 611 | if ((mob.hostile) && (canSeePlayer(mob.x, mob.y))) |
| 603 | { | 612 | { |
| 604 | toDir = Direction.getRandomDirection(); | 613 | if (arePointsAdjacent(playerx, playery, mob.x, mob.y)) |
| 605 | Point to = toDir.to(mob.getPosition()); | ||
| 606 | if ((isValidPosition(to.x,to.y)) && (!grid[to.x][to.y].isBlocked()) && (!to.equals(new Point(playerx, playery)))) | ||
| 607 | { | 614 | { |
| 608 | mob.moveInDirection(toDir); | 615 | // Attack! |
| 609 | break; | 616 | } else { |
| 617 | List<Direction> path = findPath(mob.getPosition(), new Point(playerx, playery)); | ||
| 618 | |||
| 619 | if (path != null) | ||
| 620 | { | ||
| 621 | mob.moveInDirection(path.get(0)); | ||
| 622 | } | ||
| 623 | } | ||
| 624 | } else { | ||
| 625 | // If the mob isn't hostile, it should just move around randomly | ||
| 626 | Direction toDir = null; | ||
| 627 | |||
| 628 | for (int i=0; i<10; i++) | ||
| 629 | { | ||
| 630 | toDir = Direction.getRandomDirection(); | ||
| 631 | Point to = toDir.to(mob.getPosition()); | ||
| 632 | if ((isValidPosition(to.x,to.y)) && (!grid[to.x][to.y].isBlocked()) && (!to.equals(new Point(playerx, playery)))) | ||
| 633 | { | ||
| 634 | mob.moveInDirection(toDir); | ||
| 635 | break; | ||
| 636 | } | ||
| 610 | } | 637 | } |
| 611 | } | 638 | } |
| 612 | } | 639 | } |
| @@ -693,4 +720,174 @@ public class MapViewGameState implements GameState | |||
| 693 | 720 | ||
| 694 | messages[MESSAGE_HEIGHT-1] = message; | 721 | messages[MESSAGE_HEIGHT-1] = message; |
| 695 | } | 722 | } |
| 723 | |||
| 724 | private boolean canSeePlayer(int mx, int my) | ||
| 725 | { | ||
| 726 | int dx = playerx - mx; | ||
| 727 | int dy = playery - my; | ||
| 728 | int ax = Math.abs(dx) << 1; | ||
| 729 | int ay = Math.abs(dy) << 1; | ||
| 730 | int sx = (int) Math.signum(dx); | ||
| 731 | int sy = (int) Math.signum(dy); | ||
| 732 | int x = mx; | ||
| 733 | int y = my; | ||
| 734 | |||
| 735 | if (ax > ay) | ||
| 736 | { | ||
| 737 | int t = ay - (ax >> 1); | ||
| 738 | |||
| 739 | do | ||
| 740 | { | ||
| 741 | if (t >= 0) | ||
| 742 | { | ||
| 743 | y += sy; | ||
| 744 | t -= ax; | ||
| 745 | } | ||
| 746 | |||
| 747 | x += sx; | ||
| 748 | t += ay; | ||
| 749 | |||
| 750 | if ((x == playerx) && (y == playery)) | ||
| 751 | { | ||
| 752 | return true; | ||
| 753 | } | ||
| 754 | } while (!grid[x][y].isBlocked()); | ||
| 755 | |||
| 756 | return false; | ||
| 757 | } else { | ||
| 758 | int t = ax - (ay >> 1); | ||
| 759 | |||
| 760 | do | ||
| 761 | { | ||
| 762 | if (t >= 0) | ||
| 763 | { | ||
| 764 | x += sx; | ||
| 765 | t -= ay; | ||
| 766 | } | ||
| 767 | |||
| 768 | y += sy; | ||
| 769 | t += ax; | ||
| 770 | |||
| 771 | if ((x == playerx) && (y == playery)) | ||
| 772 | { | ||
| 773 | return true; | ||
| 774 | } | ||
| 775 | } while (!grid[x][y].isBlocked()); | ||
| 776 | |||
| 777 | return false; | ||
| 778 | } | ||
| 779 | } | ||
| 780 | |||
| 781 | private boolean arePointsAdjacent(int px, int py, int mx, int my) | ||
| 782 | { | ||
| 783 | if (mx == (px-1)) | ||
| 784 | { | ||
| 785 | if (my == (py-1)) return true; | ||
| 786 | if (my == py) return true; | ||
| 787 | if (my == (py+1)) return true; | ||
| 788 | } else if (mx == px) | ||
| 789 | { | ||
| 790 | if (my == (py-1)) return true; | ||
| 791 | if (my == (py+1)) return true; | ||
| 792 | } else if (mx == (px+1)) | ||
| 793 | { | ||
| 794 | if (my == (py-1)) return true; | ||
| 795 | if (my == py) return true; | ||
| 796 | if (my == (py+1)) return true; | ||
| 797 | } | ||
| 798 | |||
| 799 | return false; | ||
| 800 | } | ||
| 801 | |||
| 802 | private List<Direction> findPath(Point from, Point to) | ||
| 803 | { | ||
| 804 | return findPath(from, to, new ArrayList<Point>()); | ||
| 805 | } | ||
| 806 | |||
| 807 | private List<Direction> findPath(Point from, Point to, List<Point> attempts) | ||
| 808 | { | ||
| 809 | /* Iterate over all of the directions and check if moving in that | ||
| 810 | * direction would result in the destination position. If so, the | ||
| 811 | * correct path has been acquired and thus we can return. */ | ||
| 812 | for (Direction d : Direction.values()) | ||
| 813 | { | ||
| 814 | Point loc = d.to(from); | ||
| 815 | if (to.equals(loc)) | ||
| 816 | { | ||
| 817 | List<Direction> moves = new ArrayList<Direction>(); | ||
| 818 | moves.add(d); | ||
| 819 | |||
| 820 | return moves; | ||
| 821 | } | ||
| 822 | } | ||
| 823 | |||
| 824 | /* Calculate the directions to attempt and the order in which to do so | ||
| 825 | * based on proximity to the destination */ | ||
| 826 | List<Direction> ds = new ArrayList<Direction>(); | ||
| 827 | for (Direction d : Direction.values()) | ||
| 828 | { | ||
| 829 | Point loc = d.to(from); | ||
| 830 | if ((isValidPosition(loc.x, loc.y)) && (!grid[loc.x][loc.y].isBlocked())) | ||
| 831 | { | ||
| 832 | ds.add(d); | ||
| 833 | } | ||
| 834 | } | ||
| 835 | |||
| 836 | List<Direction> tempd = new ArrayList<Direction>(); | ||
| 837 | |||
| 838 | if (to.x < from.x) | ||
| 839 | { | ||
| 840 | tempd.add(Direction.West); | ||
| 841 | } else if (to.x > from.x) | ||
| 842 | { | ||
| 843 | tempd.add(Direction.East); | ||
| 844 | } else { | ||
| 845 | if (!ds.contains(Direction.North) || !ds.contains(Direction.South)) | ||
| 846 | { | ||
| 847 | tempd.add(Direction.West); | ||
| 848 | tempd.add(Direction.East); | ||
| 849 | } | ||
| 850 | } | ||
| 851 | |||
| 852 | if (to.y < from.y) | ||
| 853 | { | ||
| 854 | tempd.add(Direction.North); | ||
| 855 | } else if (to.y > from.y) | ||
| 856 | { | ||
| 857 | tempd.add(Direction.South); | ||
| 858 | } else { | ||
| 859 | if (!ds.contains(Direction.West) || !ds.contains(Direction.East)) | ||
| 860 | { | ||
| 861 | tempd.add(Direction.North); | ||
| 862 | tempd.add(Direction.South); | ||
| 863 | } | ||
| 864 | } | ||
| 865 | |||
| 866 | // Remove calculated directions that aren't legal movements | ||
| 867 | tempd.retainAll(ds); | ||
| 868 | |||
| 869 | // Randomize directions so movement is more fluid | ||
| 870 | Collections.shuffle(tempd); | ||
| 871 | |||
| 872 | // Iterate over the suggested directions | ||
| 873 | for (Direction d : tempd) | ||
| 874 | { | ||
| 875 | /* If the position in the suggested direction has not already been | ||
| 876 | * covered, recursively search from the new position */ | ||
| 877 | Point loc = d.to(from); | ||
| 878 | if (!attempts.contains(loc)) | ||
| 879 | { | ||
| 880 | attempts.add(loc); | ||
| 881 | |||
| 882 | List<Direction> moves = findPath(loc, to, attempts); | ||
| 883 | if (moves != null) | ||
| 884 | { | ||
| 885 | moves.add(0, d); | ||
| 886 | return moves; | ||
| 887 | } | ||
| 888 | } | ||
| 889 | } | ||
| 890 | |||
| 891 | return null; | ||
| 892 | } | ||
| 696 | } | 893 | } |
| diff --git a/src/com/fourisland/frigidearth/Mob.java b/src/com/fourisland/frigidearth/Mob.java index b89831c..412c11e 100644 --- a/src/com/fourisland/frigidearth/Mob.java +++ b/src/com/fourisland/frigidearth/Mob.java | |||
| @@ -16,6 +16,7 @@ public abstract class Mob | |||
| 16 | public int x; | 16 | public int x; |
| 17 | public int y; | 17 | public int y; |
| 18 | public int health; | 18 | public int health; |
| 19 | public boolean hostile; | ||
| 19 | 20 | ||
| 20 | public Mob(int x, int y) | 21 | public Mob(int x, int y) |
| 21 | { | 22 | { |
| diff --git a/src/com/fourisland/frigidearth/mobs/Mouse.java b/src/com/fourisland/frigidearth/mobs/Mouse.java index af9fe44..3430a00 100644 --- a/src/com/fourisland/frigidearth/mobs/Mouse.java +++ b/src/com/fourisland/frigidearth/mobs/Mouse.java | |||
| @@ -18,6 +18,7 @@ public class Mouse extends Mob | |||
| 18 | super(x, y); | 18 | super(x, y); |
| 19 | 19 | ||
| 20 | health = 1; | 20 | health = 1; |
| 21 | hostile = false; | ||
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | public char getDisplayCharacter() | 24 | public char getDisplayCharacter() |
| diff --git a/src/com/fourisland/frigidearth/mobs/Rat.java b/src/com/fourisland/frigidearth/mobs/Rat.java new file mode 100644 index 0000000..c2aecd4 --- /dev/null +++ b/src/com/fourisland/frigidearth/mobs/Rat.java | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * To change this template, choose Tools | Templates | ||
| 3 | * and open the template in the editor. | ||
| 4 | */ | ||
| 5 | package com.fourisland.frigidearth.mobs; | ||
| 6 | |||
| 7 | import com.fourisland.frigidearth.Functions; | ||
| 8 | import com.fourisland.frigidearth.Mob; | ||
| 9 | import java.awt.Color; | ||
| 10 | |||
| 11 | /** | ||
| 12 | * | ||
| 13 | * @author hatkirby | ||
| 14 | */ | ||
| 15 | public class Rat extends Mob | ||
| 16 | { | ||
| 17 | public Rat(int x, int y) | ||
| 18 | { | ||
| 19 | super(x, y); | ||
| 20 | |||
| 21 | health = Functions.rollDice(1, 4); | ||
| 22 | hostile = true; | ||
| 23 | } | ||
| 24 | |||
| 25 | public char getDisplayCharacter() | ||
| 26 | { | ||
| 27 | return 'r'; | ||
| 28 | } | ||
| 29 | |||
| 30 | public Color getDisplayColor() | ||
| 31 | { | ||
| 32 | return Color.GRAY; | ||
| 33 | } | ||
| 34 | |||
| 35 | public String getName() | ||
| 36 | { | ||
| 37 | return "Rat"; | ||
| 38 | } | ||
| 39 | |||
| 40 | } | ||
