Minor changes

Adds new method for containers for finding first item of a class
Adds health potions
Allows the user to use potions
This commit is contained in:
Kristian Knarvik 2018-03-20 01:10:30 +01:00
parent 5ac42d8fcb
commit 30ba612e56
18 changed files with 231 additions and 90 deletions

View File

@ -25,7 +25,7 @@ Dette prosjektet inneholder [Semesteroppgave 1](SEM-1.md). Du kan også [lese op
# Fyll inn egne svar/beskrivelse/kommentarer til prosjektet under # Fyll inn egne svar/beskrivelse/kommentarer til prosjektet under
* Levert av: *Kristian Knarvik* (*kkn015*) * Levert av: *Kristian Knarvik* (*kkn015*)
* Del A: [x] helt ferdig, [ ] delvis ferdig * Del A: [x] helt ferdig, [ ] delvis ferdig
* Del B: [ ] helt ferdig, [x] delvis ferdig * Del B: [x] helt ferdig, [x] delvis ferdig
* Del C: [ ] helt ferdig, [X] delvis ferdig * Del C: [ ] helt ferdig, [X] delvis ferdig
* [ ] hele semesteroppgaven er ferdig og klar til retting! * [ ] hele semesteroppgaven er ferdig og klar til retting!
@ -69,15 +69,17 @@ Fordelene er at det er lett å få tak i all nødvendig informasjon, uten å må
Ulempene er at alle IActors og IItem blir veldig sterkt knyttet til IGame. De kan ikke brukes uten å spesifikt opprette et objekt som implementerer IGame først, som forhinder dem i å bli brukt i hvilket som helst annet prosjekt. Ulempene er at alle IActors og IItem blir veldig sterkt knyttet til IGame. De kan ikke brukes uten å spesifikt opprette et objekt som implementerer IGame først, som forhinder dem i å bli brukt i hvilket som helst annet prosjekt.
c) c)
* Game.addItem burde strengt tatt sjekket at en IActor ikke blir plassert på en IActor. * Game.addItem burde strengt tatt sjekket at en IActor ikke blir plassert på en IActor. Det er ganske mye som ikke blir sjekket direkte, fordi en går ut ifra at brukeren vet hva den driver med. Dessverre er det ganske vanskelig å oppdage det sånn i forbifarten, med mindre det skaper en feilmelding.
d) d)
* Strukturen er definitivt mye mer kaotisk enn jeg først hadde trodd. Det er egentlig ganske vanskelig å finne det en er ute etter. I tillegg har jeg endret en del, som igjen endrer oppførselen til noen av de gamle klassene. * Strukturen er definitivt mye mer kaotisk enn jeg først hadde trodd. Det er egentlig ganske vanskelig å finne det en er ute etter. I tillegg har jeg endret en del, som igjen endrer oppførselen til noen av de gamle klassene. Jeg har definitivt opplevd nye måter å gjøre ting på.
# Del C # Del C
## Oversikt over designvalg og hva du har gjort ## Oversikt over designvalg og hva du har gjort
* Oversikt over taster: WASD og piltaster kan brukes til bevegelse. Q for å legge ned ting. E for å plukke opp ting. 1-5 for å velge hvilke ting du ønsker å legge ned eller plukke opp. * Oversikt over taster blir gitt til høyre for spillkartet.
* Main og Game har blitt endret til å tillate spilleren å selv velge når den har utført en tur. Dette har blitt gjort for å kunne ignorere uønskede tastetrykk, og for å tilby spilleren valg. * Main og Game har blitt endret til å tillate spilleren å selv velge når den har utført en tur. Dette har blitt gjort for å kunne ignorere uønskede tastetrykk, og for å tilby spilleren valg.
* Mye har blitt endret siden A og B, så noen ting kan ha blitt fjernet (automatiske gulrøtter har blitt kommentert ut).
* NPC inneholder hjelpemetoder som er felles for alle NPC, men oppfører seg svært ulikt basert på input.
### Tredjepartsfiler ### Tredjepartsfiler
* Bow Fire Arrow Sound (http://soundbible.com, Stephan Schutze, Noncommercial 3.0) * Bow Fire Arrow Sound (http://soundbible.com, Stephan Schutze, Noncommercial 3.0)
@ -85,4 +87,5 @@ d)
* Large Fireball Sound (http://soundbible.com, Mike Koenig, Attribution 3.0) * Large Fireball Sound (http://soundbible.com, Mike Koenig, Attribution 3.0)
* Realistic Punch Sound (http://soundbible.com, Mark DiAngelo, Attribution 3.0) * Realistic Punch Sound (http://soundbible.com, Mark DiAngelo, Attribution 3.0)
* Snow Ball Throw And Splat Sound (http://soundbible.com, Mike Koenig, Attribution 3.0) * Snow Ball Throw And Splat Sound (http://soundbible.com, Mike Koenig, Attribution 3.0)
* Dying Sound (http://soundbible.com, Mike Koenig, Attribution 3.0)

Binary file not shown.

View File

@ -11,7 +11,7 @@ public class AppInfo {
/** /**
* Your name. * Your name.
*/ */
public static final String APP_DEVELOPER = "INF101-student"; public static final String APP_DEVELOPER = "kkn015";
/** /**
* A short description. * A short description.
*/ */
@ -19,8 +19,8 @@ public class AppInfo {
/** /**
* List of extra credits (e.g. for media sources) * List of extra credits (e.g. for media sources)
*/ */
public static final List<String> APP_EXTRA_CREDITS = Arrays.asList(// public static final List<String> APP_EXTRA_CREDITS = Arrays.asList(
/* "Graphics by Foo Bar" */ "Sounds by Mike Koenig, Stephan Schutze and Mark DiAngelo"
); );
/** /**
* Help text. Could be used for an in-game help page, perhaps. * Help text. Could be used for an in-game help page, perhaps.

View File

@ -10,7 +10,7 @@ import inf101.v18.rogue101.shared.NPC;
public class Boss implements INonPlayer { public class Boss implements INonPlayer {
private int hp = getMaxHealth(); private int hp = getMaxHealth();
private Backpack backpack = new Backpack(); private final Backpack backpack = new Backpack();
private ILocation loc; private ILocation loc;
public Boss() { public Boss() {

View File

@ -26,10 +26,10 @@ public class Girl implements INonPlayer {
private int attack; private int attack;
private int defence; private int defence;
private int visibility; private int visibility;
private Backpack backpack = new Backpack(); private final Backpack backpack = new Backpack();
private static final Random random = new Random(); private static final Random random = new Random();
private List<Class<?>> validItems; private List<Class<?>> validItems;
private static final String[] namelist = {"Milk", "Salad"}; private static final String[] namelist = {"Milk", "Salad", "Mikan", "Rima", "Suki", "Miki", "Hinata", "Haruna", "Asuna"};
public Girl() { public Girl() {
setStats(); setStats();
@ -100,6 +100,11 @@ public class Girl implements INonPlayer {
validItems.add(IBuffItem.class); validItems.add(IBuffItem.class);
} }
/**
* Picks a "random" name
*
* @return A random name
*/
private String randomName() { private String randomName() {
return namelist[random.nextInt(namelist.length)] + "-chan"; return namelist[random.nextInt(namelist.length)] + "-chan";
} }

View File

@ -1,4 +1,4 @@
package inf101.v18.rogue101.items; package inf101.v18.rogue101.examples;
import inf101.v18.rogue101.game.IGame; import inf101.v18.rogue101.game.IGame;
import inf101.v18.rogue101.objects.IItem; import inf101.v18.rogue101.objects.IItem;
@ -6,22 +6,6 @@ import inf101.v18.rogue101.objects.IItem;
public class Manga implements IItem { public class Manga implements IItem {
private int hp = getMaxHealth(); private int hp = getMaxHealth();
/*@Override
public boolean draw(ITurtle painter, double w, double h) {
painter.save();
painter.jump(-10);
painter.setInk(Color.BLACK);
painter.draw(getSize());
painter.turn(90);
painter.draw(getSize()/2);
painter.turn(90);
painter.draw(getSize());
painter.turn(90);
painter.draw(getSize()/2);
painter.restore();
return true;
}*/
@Override @Override
public int getCurrentHealth() { public int getCurrentHealth() {
return hp; return hp;

View File

@ -14,7 +14,7 @@ import inf101.v18.rogue101.shared.NPC;
public class Rabbit implements INonPlayer { public class Rabbit implements INonPlayer {
private int food = 0; private int food = 0;
private int hp = getMaxHealth(); private int hp = getMaxHealth();
private static List<Class<?>> validItems = new ArrayList<>(); private static final List<Class<?>> validItems = new ArrayList<>();
static { static {
validItems.add(Carrot.class); validItems.add(Carrot.class);
} }

View File

@ -20,6 +20,7 @@ import inf101.v18.rogue101.Main;
import inf101.v18.rogue101.enemies.Boss; import inf101.v18.rogue101.enemies.Boss;
import inf101.v18.rogue101.enemies.Girl; import inf101.v18.rogue101.enemies.Girl;
import inf101.v18.rogue101.examples.Carrot; import inf101.v18.rogue101.examples.Carrot;
import inf101.v18.rogue101.examples.Manga;
import inf101.v18.rogue101.items.*; import inf101.v18.rogue101.items.*;
import inf101.v18.rogue101.examples.Rabbit; import inf101.v18.rogue101.examples.Rabbit;
import inf101.v18.rogue101.map.GameMap; import inf101.v18.rogue101.map.GameMap;
@ -91,9 +92,9 @@ public class Game implements IGame {
} }
// Prints some helpful information. // Prints some helpful information.
String[] info = {"Controls:", "WASD or arrow keys for movement", "E to pick up an item", "Q to drop an item", "1-0 to choose an item (10=0)", "N to change name", "ENTER to confirm", "R to use a ranged attack", "F to use a magic attack"}; String[] info = {"Controls:", "WASD or arrow keys for movement", "E to pick up an item", "Q to drop an item", "1-0 to choose an item (10=0)", "N to change name", "ENTER to confirm", "R to use a ranged attack", "F to use a magic attack", "C to use a potion"};
for (int i = 0; i < info.length; i++) { for (int i = 0; i < info.length; i++) {
this.printer.printAt(map.getWidth() + 2, 1 + i, info[i]); this.printer.printAt(Main.COLUMN_MAP_END + 2, 1 + i, info[i]);
} }
} }
@ -132,10 +133,6 @@ public class Game implements IGame {
*/ */
private int getAttack() { private int getAttack() {
int damage = currentActor.getAttack() + random.nextInt(20) + 1; int damage = currentActor.getAttack() + random.nextInt(20) + 1;
IWeapon weapon = (IWeapon)currentActor.getItem(IWeapon.class);
if (weapon != null) {
damage += weapon.getWeaponDamage();
}
IBuffItem buff = (IBuffItem)currentActor.getItem(IBuffItem.class); IBuffItem buff = (IBuffItem)currentActor.getItem(IBuffItem.class);
if (buff != null) { if (buff != null) {
damage += buff.getBuffDamage(); damage += buff.getBuffDamage();
@ -167,6 +164,10 @@ public class Game implements IGame {
*/ */
private int getDamage(IItem target) { private int getDamage(IItem target) {
int damage = currentActor.getDamage(); int damage = currentActor.getDamage();
IWeapon weapon = (IWeapon)currentActor.getItem(IWeapon.class);
if (weapon != null) {
damage += weapon.getWeaponDamage();
}
IActor actor = (IActor) target; IActor actor = (IActor) target;
IBuffItem item = (IBuffItem) actor.getItem(IBuffItem.class); IBuffItem item = (IBuffItem) actor.getItem(IBuffItem.class);
if (item != null) { if (item != null) {
@ -181,7 +182,7 @@ public class Game implements IGame {
if (!map.has(loc, target)) { if (!map.has(loc, target)) {
throw new IllegalMoveException("Target isn't there!"); throw new IllegalMoveException("Target isn't there!");
} }
//TODO: Detect the weapon used //TODO: Detect the weapon used, and use its sound
IWeapon weapon = (IWeapon) currentActor.getItem(IWeapon.class); IWeapon weapon = (IWeapon) currentActor.getItem(IWeapon.class);
if (weapon != null) { if (weapon != null) {
NPC.playSound(weapon.getSound()); NPC.playSound(weapon.getSound());
@ -279,14 +280,7 @@ public class Game implements IGame {
map.clean(currentLocation); map.clean(currentLocation);
return false; return false;
} else if (currentActor instanceof IPlayer) { } else if (currentActor instanceof IPlayer) {
if (currentActor.isDestroyed()) { if (!currentActor.isDestroyed()) {
// a dead human player gets removed from the game
//This never actually triggers, because of map.clean();
/*displayMessage("YOU DIE!!!");
map.remove(currentLocation, currentActor);
currentActor = null;
currentLocation = null;*/
} else {
// For the human player, we need to wait for input, so we just return. // For the human player, we need to wait for input, so we just return.
// Further keypresses will cause keyPressed() to be called, and once the human // Further keypresses will cause keyPressed() to be called, and once the human
// makes a move, it'll lose its movement point and doTurn() will be called again // makes a move, it'll lose its movement point and doTurn() will be called again
@ -315,6 +309,7 @@ public class Game implements IGame {
currentLocation = null; currentLocation = null;
actors = new ArrayList<>(); actors = new ArrayList<>();
loadMap("gameover.txt"); loadMap("gameover.txt");
NPC.playSound("audio/Dying-SoundBible.com-1255481835.wav");
} }
/** /**
@ -396,6 +391,7 @@ public class Game implements IGame {
itemFactories.put("B", Boss::new); itemFactories.put("B", Boss::new);
itemFactories.put("s", Staff::new); itemFactories.put("s", Staff::new);
itemFactories.put("b", Bow::new); itemFactories.put("b", Bow::new);
itemFactories.put("H", HealthPotion::new);
} }
@Override @Override

View File

@ -11,7 +11,7 @@ public class Backpack implements IContainer {
/** /**
* A list containing everything in the backpack. * A list containing everything in the backpack.
*/ */
private List<IItem> content = new ArrayList<>(); private final List<IItem> content = new ArrayList<>();
/** /**
* The maximum amount of items allowed in a single backpack. * The maximum amount of items allowed in a single backpack.
*/ */
@ -85,15 +85,20 @@ public class Backpack implements IContainer {
} }
} }
/** @Override
* Removes an element at index i
*
* @param i The index of an element
*/
public void remove(int i) { public void remove(int i) {
content.remove(i); content.remove(i);
} }
/**
* Removes item from the backpack.
*
* @param item The item to remove
*/
public void remove(IItem item) {
content.remove(item);
}
/** /**
* Gets a T at index i, * Gets a T at index i,
* *
@ -127,4 +132,14 @@ public class Backpack implements IContainer {
public boolean isFull() { public boolean isFull() {
return size() >= MAX_SIZE; return size() >= MAX_SIZE;
} }
@Override
public IItem getFirst(Class<?> clazz) {
for (IItem item : content) {
if (clazz.isInstance(item)) {
return item;
}
}
return null;
}
} }

View File

@ -8,8 +8,8 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class Chest implements IContainer, IStatic { public class Chest implements IContainer, IStatic {
private List<IItem> container; private final List<IItem> container;
private int MAX_SIZE = 10; private final int MAX_SIZE = 10;
public Chest() { public Chest() {
this.container = new ArrayList<>(); this.container = new ArrayList<>();
@ -48,6 +48,16 @@ public class Chest implements IContainer, IStatic {
return container.size() >= MAX_SIZE; return container.size() >= MAX_SIZE;
} }
@Override
public IItem getFirst(Class<?> clazz) {
for (IItem item : container) {
if (clazz.isInstance(item)) {
return item;
}
}
return null;
}
@Override @Override
public int getCurrentHealth() { public int getCurrentHealth() {
return 0; return 0;
@ -91,4 +101,9 @@ public class Chest implements IContainer, IStatic {
return false; return false;
} }
} }
@Override
public void remove(int i) {
container.remove(i);
}
} }

View File

@ -0,0 +1,56 @@
package inf101.v18.rogue101.items;
import inf101.v18.rogue101.game.IGame;
import inf101.v18.rogue101.objects.IItem;
public class HealthPotion implements IConsumable {
@Override
public int hpIncrease() {
return 100;
}
@Override
public int attackIncrease() {
return 0;
}
@Override
public int defenceIncrease() {
return 0;
}
@Override
public int getCurrentHealth() {
return 0;
}
@Override
public int getDefence() {
return 0;
}
@Override
public int getMaxHealth() {
return 0;
}
@Override
public String getName() {
return "Healing potion";
}
@Override
public int getSize() {
return 0;
}
@Override
public String getSymbol() {
return "H";
}
@Override
public int handleDamage(IGame game, IItem source, int amount) {
return 0;
}
}

View File

@ -3,7 +3,7 @@ package inf101.v18.rogue101.items;
import inf101.v18.rogue101.objects.IItem; import inf101.v18.rogue101.objects.IItem;
public interface IConsumable extends IItem { public interface IConsumable extends IItem {
void hpIncrease(); int hpIncrease();
void attackIncrease(); int attackIncrease();
void defenceIncrease(); int defenceIncrease();
} }

View File

@ -9,39 +9,54 @@ public interface IContainer extends IItem {
* Retrieves an item from a container in index i * Retrieves an item from a container in index i
* *
* @param i The index of an element * @param i The index of an element
* @return An IItem * @return An IItem
* @throws IndexOutOfBoundsException If the index is out of range. * @throws IndexOutOfBoundsException If the index is out of range.
*/ */
IItem get(int i); IItem get(int i);
/** /**
* Adds an item to a container. * Adds an item to a container.
* *
* @praram item The item to add to the container
* @return True if the container was not full * @return True if the container was not full
* @praram item The item to add to the container
*/ */
boolean addItem(IItem item); boolean addItem(IItem item);
/** /**
* Gets a list with everything inside a container. * Gets a list with everything inside a container.
* *
* @return A list of Objects extending IItem * @return A list of Objects extending IItem
*/ */
List<IItem> getContent(); List<IItem> getContent();
/** /**
* Checks if we can add anything at all to the container. * Checks if we can add anything at all to the container.
* *
* @return True if it has no space left * @return True if it has no space left
*/ */
boolean isFull(); boolean isFull();
/** /**
* Returns the message to show the user upon interacting with the container. * Returns the message to show the user upon interacting with the container.
* *
* @return A message * @return A message
*/ */
default String getInteractMessage() { default String getInteractMessage() {
return "Items in " + getName() + ": "; return "Items in " + getName() + ": ";
} }
}
/**
* Gets the first item from the container of a specified type.
*
* @param clazz The class type to accept
* @return An IItem or null
*/
IItem getFirst(Class<?> clazz);
/**
* Removes an element at index i from the container.
*
* @param i The index of an element
*/
void remove(int i);
}

View File

@ -11,9 +11,10 @@ import inf101.v18.grid.IMultiGrid;
import inf101.v18.grid.MultiGrid; import inf101.v18.grid.MultiGrid;
import inf101.v18.rogue101.Main; import inf101.v18.rogue101.Main;
import inf101.v18.rogue101.examples.Carrot; import inf101.v18.rogue101.examples.Carrot;
import inf101.v18.rogue101.game.IGame;
import inf101.v18.rogue101.game.IllegalMoveException; import inf101.v18.rogue101.game.IllegalMoveException;
import inf101.v18.rogue101.items.Manga; import inf101.v18.rogue101.items.Chest;
import inf101.v18.rogue101.examples.Manga;
import inf101.v18.rogue101.items.Sword;
import inf101.v18.rogue101.objects.IActor; import inf101.v18.rogue101.objects.IActor;
import inf101.v18.rogue101.objects.IItem; import inf101.v18.rogue101.objects.IItem;
import inf101.v18.rogue101.objects.IPlayer; import inf101.v18.rogue101.objects.IPlayer;
@ -73,6 +74,12 @@ public class GameMap implements IGameMap {
if (random.nextInt(100) < 1) { if (random.nextInt(100) < 1) {
this.add(loc, new Manga()); this.add(loc, new Manga());
} }
if (random.nextInt(100) < 5) {
this.add(loc, new Chest());
}
if (random.nextInt(100) < 5) {
this.add(loc, new Sword());
}
} }
} }

View File

@ -8,9 +8,9 @@
############### # # ############### # #
# # # # # #
# S s # # # S s # #
# b @ ######## ######### # b H @ ######## #########
# # #
# # # # # #
# H # #
# # # # # #
# G # # G #
# G # # G #

View File

@ -2,7 +2,6 @@ package inf101.v18.rogue101.objects;
import inf101.v18.grid.GridDirection; import inf101.v18.grid.GridDirection;
import inf101.v18.grid.ILocation; import inf101.v18.grid.ILocation;
import inf101.v18.rogue101.game.Game;
import inf101.v18.rogue101.game.IGame; import inf101.v18.rogue101.game.IGame;
import inf101.v18.rogue101.items.*; import inf101.v18.rogue101.items.*;
import inf101.v18.rogue101.shared.NPC; import inf101.v18.rogue101.shared.NPC;
@ -12,6 +11,8 @@ import java.util.List;
public class Player implements IPlayer { public class Player implements IPlayer {
private int hp = getMaxHealth(); private int hp = getMaxHealth();
private int attack = 50;
private int defence = 30;
private final Backpack equipped = new Backpack(); private final Backpack equipped = new Backpack();
// True if the player wants to pick up something using the digit keys // True if the player wants to pick up something using the digit keys
private boolean dropping = false; private boolean dropping = false;
@ -45,6 +46,8 @@ public class Player implements IPlayer {
turnConsumed = pickUpInit(game); turnConsumed = pickUpInit(game);
} else if (key == KeyCode.Q) { } else if (key == KeyCode.Q) {
turnConsumed = dropInit(game); turnConsumed = dropInit(game);
} else if (key == KeyCode.C) {
turnConsumed = useConsumable(game);
} else if (key.isDigitKey()) { } else if (key.isDigitKey()) {
//Takes care of all digit keys, but we only use the first 5 for picking up and dropping. //Takes care of all digit keys, but we only use the first 5 for picking up and dropping.
int keyValue = Integer.parseInt(key.getName()); int keyValue = Integer.parseInt(key.getName());
@ -102,10 +105,12 @@ public class Player implements IPlayer {
*/ */
private void write(IGame game, KeyCode key) { private void write(IGame game, KeyCode key) {
if (key == KeyCode.BACK_SPACE) { if (key == KeyCode.BACK_SPACE) {
text = text.substring(0, text.length() - 1); if (text.length() > 0) {
game.displayMessage("Please enter your name: " + text); text = text.substring(0, text.length() - 1);
game.displayMessage("Please enter your name: " + text);
}
} else if (key != KeyCode.ENTER) { } else if (key != KeyCode.ENTER) {
text += key.toString(); text += key.impl_getChar(); //Deprecated, but kind of necessary
game.displayMessage("Please enter your name: " + text); game.displayMessage("Please enter your name: " + text);
} else { } else {
name = text.toLowerCase(); name = text.toLowerCase();
@ -133,11 +138,7 @@ public class Player implements IPlayer {
pickUp(game, 0); pickUp(game, 0);
return true; return true;
} else { } else {
StringBuilder msg = new StringBuilder("Items on this tile:"); game.displayMessage("Items on this tile:" + niceList(items, 5));
for (int i = 0; i < Math.min(items.size(), 5); i++) {
msg.append(" [").append(i + 1).append("] ").append(firstCharToUpper(items.get(i).getName()));
}
game.displayMessage(msg.toString());
picking = true; picking = true;
} }
} }
@ -145,6 +146,36 @@ public class Player implements IPlayer {
return false; return false;
} }
/**
* Uses the first consumable from the player's inventory
*
* @param game An IGame object
* @return
*/
private boolean useConsumable(IGame game) {
IConsumable potion = (IConsumable) equipped.getFirst(IConsumable.class);
if (potion != null) {
hp += potion.hpIncrease();
if (hp > getMaxHealth()) {
hp = getMaxHealth();
}
attack += potion.attackIncrease();
defence += potion.defenceIncrease();
equipped.remove(potion);
game.displayMessage("Used " + potion.getName());
return true;
} else {
game.displayMessage("You don't have any potions.");
}
return false;
}
/**
* Lists the contents of a chest, an makes the player ready to loot.
*
* @param game An IGame object
* @param items A list of items on the current tile
*/
private void openChest(IGame game, List<IItem> items) { private void openChest(IGame game, List<IItem> items) {
IContainer container = (IContainer) items.get(0); IContainer container = (IContainer) items.get(0);
items = container.getContent(); items = container.getContent();
@ -152,6 +183,13 @@ public class Player implements IPlayer {
exploringChest = true; exploringChest = true;
} }
/**
* Prints a set number of item names from a list.
*
* @param list The list of items
* @param max The maximum number of items to print
* @return
*/
private String niceList(List<IItem> list, int max) { private String niceList(List<IItem> list, int max) {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
for (int i = 0; i < Math.min(list.size(), max); i++) { for (int i = 0; i < Math.min(list.size(), max); i++) {
@ -173,11 +211,7 @@ public class Player implements IPlayer {
} else if (equipped.size() < 1) { } else if (equipped.size() < 1) {
game.displayMessage("You have nothing to drop"); game.displayMessage("You have nothing to drop");
} else { } else {
StringBuilder msg = new StringBuilder("Items to drop:"); game.displayMessage("Items to drop:" + niceList(equipped.getContent(), equipped.getContent().size()));
for (int i = 0; i < equipped.getContent().size(); i++) {
msg.append(" [").append(i + 1).append("] ").append(firstCharToUpper(equipped.get(i).getName()));
}
game.displayMessage(msg.toString());
dropping = true; dropping = true;
} }
return false; return false;
@ -217,16 +251,20 @@ public class Player implements IPlayer {
if (container != null && i < container.getContent().size()) { if (container != null && i < container.getContent().size()) {
IItem loot = container.getContent().get(i); IItem loot = container.getContent().get(i);
equipped.add(loot); equipped.add(loot);
container.getContent().remove(i); container.remove(i);
game.displayMessage("Looted " + loot.getName()); game.displayMessage("Looted " + loot.getName());
} else {
game.displayMessage("It seems you are trying to loot a chest, without a chest nearby.");
} }
} else { } else {
game.displayMessage("Your inventory is full."); game.displayMessage("Your inventory is full.");
} }
} }
/**
* Gets any static containers on the current tile.
*
* @param game An IGame object
* @return A static container
*/
private IContainer getStaticContainer(IGame game) { private IContainer getStaticContainer(IGame game) {
List<IItem> items = game.getLocalItems(); List<IItem> items = game.getLocalItems();
if (items.size() < 1) { if (items.size() < 1) {
@ -251,8 +289,8 @@ public class Player implements IPlayer {
IContainer container = getStaticContainer(game); IContainer container = getStaticContainer(game);
if (container != null) { if (container != null) {
if (container.addItem(equipped.get(i))) { if (container.addItem(equipped.get(i))) {
game.displayMessage(equipped.get(i).getName() + " stored in " + container.getName());
equipped.remove(i); equipped.remove(i);
game.displayMessage("Item stored in container.");
return; return;
} else { } else {
game.displayMessage(container.getName() + " is full."); game.displayMessage(container.getName() + " is full.");
@ -301,6 +339,12 @@ public class Player implements IPlayer {
} }
} }
/**
* Lets the user move or attack if possible.
*
* @param game An IGame object
* @param dir The direction the player wants to go
*/
private void tryToMove(IGame game, GridDirection dir) { private void tryToMove(IGame game, GridDirection dir) {
ILocation loc = game.getLocation(); ILocation loc = game.getLocation();
if (game.canGo(dir)) { if (game.canGo(dir)) {
@ -315,7 +359,7 @@ public class Player implements IPlayer {
@Override @Override
public int getAttack() { public int getAttack() {
return 50; return attack;
} }
@Override @Override
@ -340,7 +384,7 @@ public class Player implements IPlayer {
@Override @Override
public int getDefence() { public int getDefence() {
return 30; return defence;
} }
@Override @Override
@ -392,10 +436,9 @@ public class Player implements IPlayer {
List<GridDirection> dirs = game.locationDirection(current, neighbour); List<GridDirection> dirs = game.locationDirection(current, neighbour);
IActor actor = game.getMap().getActors(neighbour).get(0); //We assume there is only one actor. IActor actor = game.getMap().getActors(neighbour).get(0); //We assume there is only one actor.
if (actor instanceof INonPlayer && current.gridDistanceTo(neighbour) <= range) { if (actor instanceof INonPlayer && current.gridDistanceTo(neighbour) <= range) {
for (GridDirection dir : dirs) { GridDirection dir = dirs.get(0); //Only ever has one item
game.rangedAttack(dir, actor); game.rangedAttack(dir, actor);
return true; return true;
}
} }
} }
} }

View File

@ -51,6 +51,8 @@ public class GameMapTest {
@Test @Test
public void testNeighboursOutOfBounds() { public void testNeighboursOutOfBounds() {
//This is a bit overkill, but it's meant to distinguish between kind of working and always working.
GameMap gameMap = new GameMap(20, 20); GameMap gameMap = new GameMap(20, 20);
ILocation location = gameMap.getLocation(0, 0); ILocation location = gameMap.getLocation(0, 0);

View File

@ -42,7 +42,7 @@ public class PlayerTest {
assertEquals(loc, game.getLocation()); assertEquals(loc, game.getLocation());
player.keyPressed(game, KeyCode.DOWN); player.keyPressed(game, KeyCode.DOWN);
assertEquals(loc, game.getLocation()); assertEquals(loc, game.getLocation());
}*/ //TODO: Fix error when playing sound }*/ //TODO: Fix error "Toolkit not initialized"
@Test @Test
public void testItem() { public void testItem() {