diff options
Diffstat (limited to 'src')
-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 | } | ||