| Room.java |
1 /*
2 * CVS: $Id: Room.java,v 1.17 2004/07/25 19:07:20 marcus Exp $
3 *
4 * This file is part of JZuul.
5 *
6 * JZuul is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * JZuul is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Zuul; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Copyrigth 2004 by marcus, leh
21 * Initially based on an example by Michael Kolling and David J. Barnes
22 *
23 */
24
25package org.jzuul.engine.rooms;
26
27import java.io.InputStream;
28import java.util.Iterator;
29import java.util.List;
30import java.util.Vector;
31
32import org.jdom.Element;
33import org.jzuul.engine.Directions;
34import org.jzuul.engine.Engine;
35import org.jzuul.engine.Event;
36import org.jzuul.engine.EventHandler;
37import org.jzuul.engine.EventListener;
38import org.jzuul.engine.GameObject;
39import org.jzuul.engine.Helpers;
40import org.jzuul.engine.Inventory;
41import org.jzuul.engine.Messages;
42import org.jzuul.engine.exceptions.GuiNotInitializedException;
43import org.jzuul.engine.exceptions.NoSuchEventException;
44
45/**
46 * Ein normaler Raum
47 *
48 *
49 * @version $Revision: 1.17 $
50 **/
51public class Room implements EventListener {
52 /**
53 * enthält die Beschriebung des Raumes
54 */
55 protected String beschreibung;
56
57 /**
58 * die Beschreibungen für "look"
59 */
60 protected String[] blickrichtungen = new String[Directions.NUMBER_OF_DIRECTIONS];
61
62 /**
63 * Die Raum Objekte die an diesen Raum grenzen
64 */
65 protected Room[] wege = new Room[Directions.NUMBER_OF_DIRECTIONS];
66
67 /**
68 * Der Name des Raumes
69 */
70 protected String name;
71
72 /**
73 * Die EventHandler für diesen Raum
74 */
75 protected EventHandler[] eventHandlers = new EventHandler[Event.COUNT];
76
77 /**
78 * Der Inhalt des Raumes
79 */
80 protected Inventory contents;
81
82 /**
83 * Enthällt den Stream auf das für den Raum definierte Bild
84 */
85 protected InputStream imageStream;
86
87 /**
88 * Konstruktor, erstellt einen Raum OHNE Beschreibung
89 *
90 * @param name der Name des Raumes, ermöglicht den Zugriff innerhalb einer GameMap
91 */
92 public Room(String name) {
93 this(name, ""); //$NON-NLS-1$
94 }
95
96 /**
97 * Erzeuge eine Room Objekt mit einer Beschreibung. Ein Raum
98 * hat anfangs keine Ausgänge.
99 * @param name der Name des Raumes, ermöglicht den Zugriff innerhalb einer GameMap
00 * @param beschreibung enthält eine Beschreibung in der Form
01 * "in einer Küche" oder "auf einem Sportplatz".
02 */
03 public Room(String name, String beschreibung) {
04 this.name = name;
05 this.beschreibung = beschreibung;
06 contents = new Inventory(Inventory.UNLIMITED_INVENTORY);
07 }
08
09 /**
10 * Ermöglicht den Zugriff auf das "Inventar" des Raumes, ein Room Objekt kann unendlich viele Dinge enthalten
11 *
12 * @return das Inventory Objekt des Raumes
13 */
14 public Inventory getContent() {
15 return this.contents;
16 }
17
18 /**
19 * Zugriff auf das Room Objekt unter diesem Room Objekt
20 *
21 * @return das Room Objekt unter dem aktuellen Raum
22 */
23 public Room getDownway() {
24 return getRoomByOrientation(Directions.BELOW);
25 }
26
27 /**
28 * Zugriff auf das Room Objekt über diesem Room Objekt
29 *
30 * @return das Room Objekt under dem aktuellen Room Objekt
31 */
32
33 public Room getUpway() {
34 return getRoomByOrientation(Directions.TOP);
35 }
36
37 /**
38 * Gibt ein Room Objekt in einer gegebenen Himmelsrichtung zurück
39 *
40 * @param direction die Himmelsrichtung
41 * @return den Raum in dieser Himmelsrichtung, null falls dort keiner ist
42 * @see org.jzuul.engine.Directions
43 */
44 public Room getRoomByOrientation(int direction) {
45 if (wege[direction] != null) {
46 return wege[direction];
47 } else {
48 return null;
49 }
50 }
51
52 /**
53 * Gibt due Beschreibung für eine Himmelrichtung zurück (für "look")
54 *
55 * Für d Directions.TOP und Directions.BELOW wird ein default Wert zurückgegeben,
56 *
57 * @param direction Eine mögliche Richtung wie north,east,south und west oder up and down
58 * @return die Beschreibung in dieser Richtung, null wenn es keine Beschreibung gibt.
59 * @see org.jzuul.engine.Directions
60 */
61 public String getWayDescriptionByDirection(int direction) {
62 // watch out, this is the INT version of this method
63 // which will be called by the STRING version of this method
64 Engine.debug("Called for direction " + direction, 1); //$NON-NLS-1$
65 if (Directions.getDirectionName(direction) == null) {
66 return null;
67 }
68 String desc = blickrichtungen[direction];
69 if ((desc != null) && (!desc.equals(""))) { //$NON-NLS-1$
70 return desc;
71 }
72 if (direction == Directions.TOP) {
73 return Messages.getString("ROOM_ROOF"); //$NON-NLS-1$
74 }
75 if (direction == Directions.BELOW) {
76 return Messages.getString("ROOM_BOTTOM"); //$NON-NLS-1$
77 }
78 return null;
79 }
80
81 /**
82 * Liefere die Beschreibung dieses Raums (die dem Konstruktor
83 * übergeben wurde).
84 * @return die Beschreibeung des Raumes
85 */
86 public String getDescription() {
87 if (beschreibung != null) {
88 return beschreibung;
89 } else {
90 return Messages.getString("ROOM_DEFAULT") + Helpers.firstToUpper(getName()); //$NON-NLS-1$
91 }
92 }
93
94 /**
95 * Führt ein Event aus und ruft den defaulHandler auf
96 *
97 * @param id die Event ID
98 * @see org.jzuul.engine.Event
99 */
00 public void doEvent(int id) {
01 if (id >= Event.COUNT || id < 0)
02 throw new IllegalArgumentException("Id is not valid: " + id); //$NON-NLS-1$
03 if (eventHandlers[id] != null) {
04 eventHandlers[id].execute(this);
05 }
06 defaultHandler(id);
07 }
08
09 /**
10 * Default EventHandler für die Fälle Event.PLAYERENTER und Event.PLAYERLEAVE.
11 *
12 * Der Raum gibt diese Events an sein Inventory weiter. Bei einem PLAYERENTER
13 * wird zusätzlich die Beschreibung ausgegeben
14 *
15 * @param eventId die EventId
16 * @see org.jzuul.engine.Event
17 * @see org.jzuul.engine.EventHandler
18 */
19 protected void defaultHandler(int eventId) {
20 // these are the default event handlers: (do we want them overrideable?)
21 switch (eventId) {
22 case Event.PLAYERENTER :
23 this.printBeschreibung();
24 notifyContained(Event.PLAYERENTER);
25 break;
26 case Event.PLAYERLEAVE :
27 notifyContained(Event.PLAYERLEAVE);
28 break;
29 }
30 }
31
32 /**
33 * Gibt die Beschreibung aus
34 *
35 * @throws GuiNotInitializedException wenn Engine.gui == null
36 */
37 public void printBeschreibung() throws GuiNotInitializedException {
38 if (Engine.gui == null) {
39 throw new GuiNotInitializedException("Engine.gui is undefined"); //$NON-NLS-1$
40 }
41
42 Engine.gui.showImage(this.imageStream);
43 Engine.gui.println();
44 Engine.gui.println(Messages.getString("ROOM_YOU_ARE") + this.getDescription()); //$NON-NLS-1$
45 Engine.gui.println();
46 String ausgaenge = getWegeAsString();
47
48 if (ausgaenge.length() > 0) {
49 Engine.gui.printU(Messages.getString("ROOM_WAYS")); //$NON-NLS-1$
50 Engine.gui.println(" " + ausgaenge); //$NON-NLS-1$
51 }
52
53 if (this.getUpway() != null) {
54 Engine.gui.println(Messages.getString("ROOM_STAIRS_UP")); //$NON-NLS-1$
55 }
56 if (this.getDownway() != null) {
57 Engine.gui.println(Messages.getString("ROOM_STAIRS_DOWN")); //$NON-NLS-1$
58 }
59
60 String inhalt = new String();
61 for (Iterator i = contents.gameObjectNamesIterator(); i.hasNext();) {
62 String objName = (String) i.next();
63 inhalt += Helpers.firstToUpper(objName) + " "; //$NON-NLS-1$
64 if (contents.getNumberOfObject(objName) > 1) {
65 inhalt += "(" + contents.getNumberOfObject(objName) + ") "; //$NON-NLS-1$ //$NON-NLS-2$
66 }
67 }
68 if (inhalt.length() > 0) {
69 Engine.gui.printU(Messages.getString("ROOM_INTERESTING_THINGS")); //$NON-NLS-1$
70 Engine.gui.println(" " + inhalt); //$NON-NLS-1$
71 }
72
73 Engine.gui.println();
74 }
75
76 /**
77 * Wandelt die möglichen Wege, also Himmelsrichtungen für die ein
78 * Room Objekt existiert in eine Beschreibung um
79 *
80 * @return die Namen der Himmelsrichtungen für die Room Objekte existieren
81 */
82 public String getWegeAsString() {
83 String retval = new String();
84
85 if (getRoomByOrientation(Directions.NORTH) != null) {
86 retval = "north "; //$NON-NLS-1$
87 }
88 if (getRoomByOrientation(Directions.EAST) != null) {
89 retval += "east "; //$NON-NLS-1$
90 }
91 if (getRoomByOrientation(Directions.SOUTH) != null) {
92 retval += "south "; //$NON-NLS-1$
93 }
94 if (getRoomByOrientation(Directions.WEST) != null) {
95 retval += "west "; //$NON-NLS-1$
96 }
97 return retval;
98
99 }
00
01 /**
02 * Setzt die Beschreibungen für oben und unten
03 *
04 * @param up die neue Beschreibung für Oben
05 * @param down die neue Beschreibung für Unten
06 */
07 public void setDescriptionsUpDown(String up, String down) {
08 blickrichtungen[Directions.TOP] = up;
09 blickrichtungen[Directions.BELOW] = down;
10 }
11
12 /**
13 * Zugriffe auf alle an ein Room Objekt grenzenden Räume
14 *
15 * @return eine Liste von Room Objekten die an den aktuellen Raum grenzen
16 */
17 public List getWays() {
18 Vector v = new Vector();
19 for (int i = 0; i < wege.length; i++) {
20 if (wege[i] != null) {
21 v.add(wege[i]);
22 }
23 }
24 return v;
25 }
26
27 /**
28 * Weist dem Room Objekt eine neues benachbartes Objekt zu
29 *
30 * @param direction die Himmelrichtung
31 * @param raum das Room Objekt
32 * @see org.jzuul.engine.Directions
33 */
34 public void setExitByDirection(int direction, Room raum) {
35 if (wege[direction] == null) {
36 wege[direction] = raum;
37 } else {
38 /*throw new RoomOverwriteException(
39 "Der Room "
40 + this.getName()
41 + " hat schon einen Room in Richtung "
42 + Directions.getDirectionName(direction));
43 */
44 }
45 }
46
47 /**
48 * Setzt die Beschreibung für eine Himmelsrichtung die mit "look"
49 * eingesehen werden kann.
50 *
51 * @param direction die Richtung
52 * @param description die neue Beschreibung
53 * @see org.jzuul.engine.Directions
54 */
55 public void setWayDescription(int direction, String description) {
56 blickrichtungen[direction] = description;
57 }
58
59 /**
60 * Gibt das Room Objekt in einer Himmelsrichtung zurück
61 *
62 * @param orientation der Name eine Himmelsrichtung
63 * @return das Room Objekt in dieser Richtung, null falls keines existiert
64 * @see org.jzuul.engine.Directions
65 */
66 public Room getRoomByOrientation(String orientation) {
67 int dir = Directions.directionToInt(orientation);
68 if (dir > -1) {
69 return wege[dir];
70 } else {
71 return null;
72 }
73 }
74
75 /**
76 * Gibt die Beschreibung einer Himmelsrichtung zurück
77 *
78 * @param direction der Name einer Himmelrichtung
79 * @return die Beschreibung für diese Himmelsrichtung
80 * @see org.jzuul.engine.Directions
81 */
82 public String getWayDescriptionByDirection(String direction) {
83 int dir = Directions.directionToInt(direction);
84 if (dir != Directions.DIRECTION_ERROR) {
85 return getWayDescriptionByDirection(dir);
86 } else {
87 return null;
88 }
89 }
90
91 /**
92 * Zugriff auf den Namen eines Raumes
93 *
94 * @return der Name des Raumes
95 */
96 public String getName() {
97 return name;
98 }
99
00 /**
01 * Wandelt einen Raum und die enthaltenen Objekte in ein JDOM XML Element um
02 *
03 * @return das JDOM XML Element das diesen Raum beschreibt
04 */
05 public Element toElement() {
06 Element roomE = new Element("room"); //$NON-NLS-1$
07
08 roomE.setAttribute("class", this.getClass().toString().substring(6)); //$NON-NLS-1$
09 roomE.setAttribute("name", getName()); //$NON-NLS-1$
10 roomE.addContent(new Element("description").setText(getDescription())); //$NON-NLS-1$
11
12 roomE.addContent(getContent().toElement());
13
14 Element w = waysToElement();
15 if (w.getChildren().size() > 0)
16 roomE.addContent(w);
17
18 Element v = viewsToElement();
19 if (v.getChildren().size() > 0)
20 roomE.addContent(v);
21
22 return roomE;
23 }
24
25 /**
26 * Wandelt die Wege (angrenzende Room Objekte) in ein JDOM XML Element um
27 *
28 * @return ein JDOM XML Element das die Namen der Räume beschreibt, die an diesen Raum grenzen
29 */
30 protected Element waysToElement() {
31 Element waysE = new Element("ways"); //$NON-NLS-1$
32 for (int i = 0; i < Directions.NUMBER_OF_DIRECTIONS; i++) {
33 if (wege[i] != null) {
34 Element wayE = new Element("way"); //$NON-NLS-1$
35 wayE.setAttribute("direction", Directions.getDirectionName(i)); //$NON-NLS-1$
36 wayE.setAttribute("room", wege[i].getName()); //$NON-NLS-1$
37 waysE.addContent(wayE);
38 }
39 }
40 return waysE;
41 }
42
43 /**
44 * Wandelt die Wege (Blickrichtungsbeschreibungen) in ein JDOM XML Element um
45 *
46 * @return ein JDOM XML Element das die Wegbeschreibungen enthällt
47 */
48 protected Element viewsToElement() {
49 Element viewsE = new Element("views"); //$NON-NLS-1$
50
51 int count = 0;
52 for (int i = 0; i < Directions.NUMBER_OF_DIRECTIONS; i++) {
53 if (blickrichtungen[i] != null) {
54 Element viewE = new Element("view"); //$NON-NLS-1$
55 viewE.setAttribute("direction", Directions.getDirectionName(i)); //$NON-NLS-1$
56 viewE.setText(blickrichtungen[i]);
57 viewsE.addContent(viewE);
58 count++;
59 }
60 }
61 return viewsE;
62 }
63
64 /**
65 * Weist dem Raum ein Inventar zu
66 *
67 * @param newInv das neue Inventar
68 */
69 public void setInv(Inventory newInv) {
70 this.contents = newInv;
71 }
72
73 /**
74 * Weist den Raum an, ein GameObject aus dem globalen ObjectPool in sein Inventar zu übernehmen
75 *
76 * @param objName der Name des GameObjects das geholt werden soll
77 */
78 public void getFromPool(String objName) {
79 Engine.debug(objName, 1);
80 GameObject obj = (GameObject) Engine.objectPool.get(objName);
81 this.contents.addGameObject(obj.copy());
82 }
83
84 /**
85 * Leitet ein Event an die enthaltenen GameObjects weiter
86 *
87 * @param id die Id des Events
88 * @see org.jzuul.engine.Event
89 */
90 public void notifyContained(int id) {
91 Vector v = (Vector) this.getContent().getCharacterObjects();
92 for (Iterator i = v.iterator(); i.hasNext();) {
93 ((EventListener) i.next()).doEvent(id);
94 }
95 }
96
97 /**
98 * Setzt den EventHandler für eine Event.
99 *
00 * @param name der Name des Events
01 * @param handler das EventHandler Objekt für dieses Event
02 * @see org.jzuul.engine.EventHandler
03 */
04 public void setHandler(String name, EventHandler handler) {
05 if (name == null || handler == null)
06 throw new IllegalArgumentException("You can not set a handler with a null value"); //$NON-NLS-1$
07 int id = Event.fromString(name);
08 if (id > -1) {
09 this.eventHandlers[id] = handler;
10 } else {
11 throw new NoSuchEventException("The event " + name + " is unknown"); //$NON-NLS-1$ //$NON-NLS-2$
12 }
13 }
14
15 /**
16 * Setzt dem Raum den auf das Bild verweisenden Stream
17 *
18 * @param imageStream ein InputStream der ein Bild enthällt
19 */
20 public void setImageStream(InputStream imageStream) {
21 this.imageStream = imageStream;
22 }
23
24}
25