package inf101.v18.rogue101.game; import java.util.List; import java.util.Random; import inf101.v18.gfx.gfxmode.ITurtle; import inf101.v18.gfx.textmode.Printer; import inf101.v18.grid.GridDirection; import inf101.v18.grid.ILocation; import inf101.v18.rogue101.map.IMapView; import inf101.v18.rogue101.objects.IItem; import inf101.v18.rogue101.objects.IActor; import inf101.v18.rogue101.objects.INonPlayer; import inf101.v18.rogue101.objects.IPlayer; /** * Game interface *

* The game has a map and a current {@link IActor} (the player or non-player * whose turn it currently is). The game also knows the current location of the * actor. Most methods that deal with the map will use this current location – * they are meant to be used by the current actor for exploring or interacting * with its surroundings. *

* In other words, you should avoid calling most of these methods if you're not * the current actor. You know you're the current actor when you're inside your * {@link IPlayer#keyPressed()} or {@link INonPlayer#doTurn()} method. * * @author anya * */ public interface IGame { /** * Add an item to the current location *

* If the item is an actor, it won't move until the next turn. * * @param item */ void addItem(IItem item); /** * Add a new item (identified by symbol) to the current location *

* If the item is an actor, it won't move until the next turn. * * @param sym */ void addItem(String sym); /** * Perform an attack on the target. *

* Will use your {@link IActor#getAttack()} against the target's * {@link IItem#getDefence()}, and then possiblyu find the damage you're dealing * with {@link IActor#getDamage()} and inform the target using * {@link IItem#handleDamage(IGame, IItem, int)} * * @param dir * Direction * @param target * A target item, which should be in the neighbouring square in the * given direction * @return Your new location if the attack resulted in you moving */ ILocation attack(GridDirection dir, IItem target); /** * @param dir * @return True if it's possible to move in the given direction */ boolean canGo(GridDirection dir); /** * Create a new item based on a text symbol *

* The item won't be added to the map unless you call {@link #addItem(IItem)}. * * @param symbol * @return The new item */ IItem createItem(String symbol); /** * Displays a message in the debug area on the screen (bottom line) * * @param s * A message */ void displayDebug(String s); /** * Displays a message in the message area on the screen (below the map and the * status line) * * @param s * A message */ void displayMessage(String s); /** * Displays a status message in the status area on the screen (right below the * map) * * @param s * A message */ void displayStatus(String s); /** * Displays a message in the message area on the screen (below the map and the * status line) * * @param s * A message * @see String#format(String, Object...) */ void formatDebug(String s, Object... args); /** * Displays a formatted message in the message area on the screen (below the map * and the status line) * * @param s * A message * @see String#format(String, Object...) */ void formatMessage(String s, Object... args); /** * Displays a formatted status message in the status area on the screen (right * below the map) * * @param s * A message * @see String#format(String, Object...) */ void formatStatus(String s, Object... args); /** * Pick up an item *

* This should be used by IActors who want to pick up an item and carry it. The * item will be returned if picking it succeeded (the actor might also * make a mistake and pick up the wrong item!). * * @param item * An item, should be in the current map location * @return The item that was picked up (normally item), or * null if it failed */ IItem pickUp(IItem item); /** * Drop an item *

* This should be used by IActors who are carrying an item and want to put it on * the ground. Check the return value to see if it succeeded. * * @param item * An item, should be carried by the current actor and not already be * on the map * @return True if the item was placed on the map, false means you're still * holding it */ boolean drop(IItem item); /** * Clear the unused graphics area (you can fill it with whatever you want!) */ void clearFreeGraphicsArea(); /** * Clear the unused text area (you can fill it with whatever you want!) */ void clearFreeTextArea(); /** * Get the bounds of the free graphics area. *

* You can fill this with whatever you want, using {@link #getPainter()} and * {@link #clearFreeGraphicsArea()}. * * @return Array of coordinates; ([0],[1]) are the top-left corner, and * ([2],[3]) are the bottom-right corner (exclusive). */ double[] getFreeGraphicsAreaBounds(); /** * Get the bounds of the free text area. *

* You can fill this with whatever you want, using {@link #getPrinter()} and * {@link #clearFreeTextArea()}. *

* You'll probably want to use something like: * *

	 * int[] bounds = getFreeTextArea();
	 * int x = bounds[0];
	 * int y = bounds[1];
	 * game.getPrinter().printAt(x, y++, "Hello");
	 * game.getPrinter().printAt(x, y++, "Do you have any carrot cake?", Color.ORANGE);
	 * 
* * @return Array of column/line numbers; ([0],[1]) is the top-left corner, and * ([2],[3]) is the bottom-right corner (inclusive). */ int[] getFreeTextAreaBounds(); /** * See {@link #getFreeGraphicsAreaBounds()}, {@link #clearFreeGraphicsArea()}. * * @return A Turtle, for painting graphics */ ITurtle getPainter(); /** * See {@link #getFreeTextAreaBounds()}, {@link #clearFreeTextArea()}. * * @return A printer, for printing text */ Printer getPrinter(); /** * @return The height of the map */ int getHeight(); /** * @return A list of the non-actor items at the current map location */ List getLocalItems(); /** * Get the current actor's location. *

* You should only call this from an IActor that is currently doing its move. * * @return Location of the current actor */ ILocation getLocation(); /** * Get the current actor *

* You can check if it's your move by doing game.getActor()==this. * * @return The current actor (i.e., the (IPlayer/INonPlayer) player who's turn it currently is) */ IActor getActor(); /** * Get the neighbouring map location in direction dir *

* Same as getLocation().go(dir) * * @param dir * A direction * @return A location, or null if the location would be outside the * map */ ILocation getLocation(GridDirection dir); /** * @return The map */ IMapView getMap(); /** * @return A list of directions we can move in, for use with * {@link #move(GridDirection)} */ List getPossibleMoves(); /** * Get a list of all locations that are visible from the current location. *

* The location list is sorted so that nearby locations come earlier in the * list. E.g., if l = getVisible() and i < jthen * getLocation().gridDistanceTo(l.get(i)) < getLocation().gridDistanceTo(l.get(j)) * * @return A list of grid cells visible from the {@link #getLocation()} */ List getVisible(); /** * @return Width of the map */ int getWidth(); /** * Move the current actor in the given direction. *

* The new location will be returned. * * @param dir * @return A new location * @throws IllegalMoveException * if moving in that direction is illegal */ ILocation move(GridDirection dir); /** * Perform a ranged attack on the target. *

* Rules for this are up to you! * * @param dir * Direction * @param target * A target item, which should in some square in the given direction * @return Your new location if the attack resulted in you moving (unlikely) */ ILocation rangedAttack(GridDirection dir, IItem target); /** * @return A random generator */ Random getRandom(); /** * Gets the best direction to go from current to neighbour. * If the target is positioned diagonally from the start, the direction requiring the most steps is chosen. * * @param current The location to go from * @param neighbour The location to go to * @return A direction */ GridDirection locationDirection(ILocation current, ILocation neighbour); }