1 /*
2  *  CVS: $Id: Player.java,v 1.14 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 * 
22 */
23
24package org.jzuul.engine;
25
26import java.text.MessageFormat;
27
28import org.jdom.Element;
29import org.jzuul.engine.exceptions.NoSuchEventException;
30import org.jzuul.engine.gui.GuiInterface;
31import org.jzuul.engine.rooms.*;
32
33/**
34 * Die Playerklasse, die den Container für den Spieler darstellt. Ein Spieler speichert nicht nur seine gegenwärtige Position
35 * sondern auch alle Dinge die aufgehoben worden sind.
36 * 
37 * 
38 * @version $Revision: 1.14 $
39 */
40public class Player implements EventListener {
41    /**
42     * Der Raum in dem sich der Spieler aufhält
43     */
44    private Room currentRoom;
45    
46    /**
47     * Das Inventory Objekt des Spielers
48     */
49    private Inventory inv;
50    
51    /**
52     * Der Raum in dem sich der Spieler vorher aufgehalten hat (für "go back")
53     */
54    private Room lastRoom;
55    
56    /**
57     * Der Name des Spielers, default ist Player
58     */
59    private String name = Messages.getString("PLAYER_DEFAULT_NAME"); //$NON-NLS-1$
60    
61    /**
62     * Die TargetList des Spielers (für "todo")
63     */
64    private TargetList targets;
65    
66    /**
67     * Die EventHandler des Spielers
68     */
69    private EventHandler[] eventHandlers = new EventHandler[Event.COUNT];
70    
71    /**
72     * Die Nummer des Spielers für Multiplayer, default ist 0
73     */
74    private int number = 0;
75
76    /**
77     * Konstruktor
78     */
79    public Player() {
80        inv = new Inventory(10);
81        targets = new TargetList();
82    }
83    
84    /**
85     * Erstellt einen Spieler mit einer Nummer (multiplayer)
86     * 
87     * @param number    die Nummer des Spielers
88     */
89    public Player(int number) {
90        this();
91        this.number = number;
92    }
93    
94    public boolean findAndDeleteGameObject(String itemName) {
95        return findAndDeleteGameObject(itemName,true);
96    }
97
98    /**
99     * Diese Methode sucht das Item itemName in der Reihenfolge Inventar, Room und löscht dieses.
00     * 
01     * @param itemName
02     * @return true on success and false on failure
03     */
04    public boolean findAndDeleteGameObject(String itemName,boolean verbose) {
05        Engine.debug("Find and delete game Object:" + itemName,1); //$NON-NLS-1$
06        if (this.getInv().containsGameObject(itemName)) {
07            return this.getInv().deleteGameObject(itemName);
08        }
09        else
10            if (currentRoom.getContent().containsGameObject(itemName)) {
11                return currentRoom.getContent().deleteGameObject(itemName);
12            }
13            else {
14                if (verbose) {
15                    Object[] formatArgs = { itemName };
16                    this.say(MessageFormat.format(Messages.getString("PLAYER_FIND_FAILED"),formatArgs)); //$NON-NLS-1$
17                }
18                return false;
19            }
20    }
21    
22    /**
23     * Diese Methode sucht das GameObject objName in der Reihenfolge Inventar, Room und gibt  das GameObject
24     * zurück. Wenn das GameObject nicht gefunden wird gibt es null zurück 
25     * 
26     * @param objName
27     * @return GameObject with objName on success, null on failure
28     */
29    public GameObject findGameObject(String objName) {
30        if (this.getInv().containsGameObject(objName)) {
31            return this.getInv().getGameObject(objName);
32        }
33        if (currentRoom.getContent().containsGameObject(objName)) {
34            return currentRoom.getContent().getGameObject(objName);
35        }
36        return null;
37    }
38
39    /**
40     * Gibt den aktuellen Room zurück
41     * @return Room in dem sich der Spieler aufhält
42     */
43    public Room getCurrentRoom() {
44        return currentRoom;
45    }
46
47    /**
48     * Gibt das Inventar des Spielers zurück
49     * @return Inventar
50     */
51    public Inventory getInv() {
52        return inv;
53    }
54    
55    /**
56     * Setzt das Inventar eines Spielers
57     * 
58     * @param inv Das neuen Inventar des Spielers
59     */
60    public void setInv(Inventory inv) {
61            this.inv=inv;
62    }
63
64    /**
65     * Diese Methode verwandelt einen Gegenstand in einen anderen. Da Gegenstände
66     * über ihre Namen identifiziert werden muss man einen neuen Namen einsetzen.  
67     * 
68     * @param item
69     * @param newName
70     * @return true on success and false on failure
71     * @deprecated  Wird im Moment nicht mehr benutzt
72     */
73    public boolean mutateItem(Item item, String newName) {
74        this.findAndDeleteGameObject(item.getName());
75        item.setName(newName);
76        this.getInv().addGameObject(item);
77        return true;
78    }
79
80    /**
81     * Ausgabe...
82     * @param something     was ausgegeben werden soll
83     */
84    public void say(String something) {
85        Engine.gui.println(name + ": " + something, GuiInterface.RED); //$NON-NLS-1$
86    }
87
88    /**
89     * Setzt den Room in dem sich der Player befindet und löst die Events
90     * Event.PLAYERLEAVE und Event.PLAYERENTER aus
91     * @param currentRoom - tja... 
92     */
93    public void setCurrentRoom(Room currentRoom) {
94        // first time ?
95        if (this.currentRoom == null) {
96            this.currentRoom = currentRoom;
97            return;
98        }
99        this.currentRoom.doEvent(Event.PLAYERLEAVE);
00        this.saveLastRoom();
01        this.currentRoom = currentRoom;
02        currentRoom.doEvent(Event.PLAYERENTER);
03    }
04
05    /**
06     * Macht ein Backup des aktuellen Raumes
07     */
08    public void saveLastRoom() {
09        this.lastRoom = currentRoom;
10    }
11    
12    /**
13     * Setzt den letzten Room auf null zurück
14     */
15    public void resetLastRoom() {
16        this.lastRoom = null;
17    }
18    
19    
20    /**
21     * Zugriff auf das das Backup das mit saveLastRoom genacht wurde
22     * 
23     * @return der Room in dem man vorher war
24     */
25    public Room getLastRoom() {
26        return this.lastRoom;
27    }
28
29    /**
30     * Wandelt den Spieler und sein Inventar in ein JDOM Element um
31     * 
32     * @return  das JDOM XML ELement das den Spieler beschreibt
33     */
34    public Element toElement() {
35        Element playerE = new Element("player"); //$NON-NLS-1$
36        playerE.setAttribute("position", currentRoom.getName()); //$NON-NLS-1$
37        playerE.setAttribute("map", Engine.map.getName()); //$NON-NLS-1$
38        playerE.setAttribute("name", getName()); //$NON-NLS-1$
39        
40        playerE.addContent(inv.toElement());
41        playerE.addContent(targets.toElementList());
42        return playerE;
43    }
44
45    /**
46     * Fügt in das Inventar des Spielers eine Objekt aus dem globalen ObjectPool ein
47     * 
48     * @param objName   der Name des Objektes das geholt werden soll
49     */
50    public void getFromPool(String objName) {
51        GameObject obj =  (GameObject)Engine.objectPool.get(objName);
52        this.inv.addGameObject(obj.copy());
53    }
54    
55    /**
56     * Setzt den Namen des Spielers
57     * 
58     * @param name  der neuen Name des Spielers
59     */
60    public void setName(String name) {
61        this.name = name;
62    }
63    
64    /**
65     * Zugriff auf den Namen des Spielers
66     * 
67     * @return  der aktuelle Name des Spielers
68     */
69    public String getName() {
70        return this.name;
71    }
72    
73    /**
74     * Weist dem Spieler eine neue TargetList zu
75     * 
76     * @param targets   die neue TargetList für den Spieler
77     */
78    public void setTargetList(TargetList targets) {
79        this.targets = targets;
80    }
81
82    /**
83     * Zugriff auf die TargetList des Spielers
84     * 
85     * @return  die aktuelle TargetList des Spielers
86     */
87    public TargetList getTargetList() {
88            return this.targets;
89    }
90    
91    /**
92     * Setzt einen EventHandler für ein Event
93     * 
94     * @param name  der Name des Events
95     * @param handler   der dazugehörige EventHandler
96     * @see org.jzuul.engine.Event
97     * @see org.jzuul.engine.EventHandler
98     */
99    public void setHandler(String name, EventHandler handler) {
00        if (name == null || handler == null) throw new IllegalArgumentException("You can not set a handler with a null value"); //$NON-NLS-1$
01        int id = Event.fromString(name);
02        if (id > -1) {
03            this.eventHandlers[id] = handler;
04        } else {
05              throw new NoSuchEventException("The event " + name + " is unknown"); //$NON-NLS-1$ //$NON-NLS-2$
06        }
07    }
08    
09    /**
10     * Führt ein Event aus
11     * 
12     * @param eventId   die Id des Events
13     * @see org.jzuul.engine.Event
14     * @see org.jzuul.engine.EventHandler
15     */
16    public void doEvent(int eventId) {
17        if (eventId >= Event.COUNT || eventId < 0) throw new IllegalArgumentException("Id is not valid: " + eventId); //$NON-NLS-1$
18        if (eventHandlers[eventId] != null) {
19            eventHandlers[eventId].execute();
20        }
21    }
22    
23    /**
24     * Gibt die Nummer des Spielers zurück
25     * 
26     * @return  die Nummer des spielers
27     */
28    public int getNumber() {
29        return this.number;
30    }
31    
32    /**
33     * Setzt die Nummer des Spielers
34     * 
35     * @param number    die neue Nummer für den Spieler
36     */
37    public void setNumber(int number) {
38        this.number = number;
39    }
40    
41    /**
42     * Erstellt eine 1 zu 1 Kopie des Spielers inklusive aller enthaltenen Objekte.
43     * 
44     * @return  eine unabhängige Kopie des Spielers
45     */
46    public Player copy() {
47        Player newPlayer = new Player();
48        newPlayer.setCurrentRoom(this.getCurrentRoom());
49        newPlayer.setName(this.getName());
50        newPlayer.setInv(this.inv.copy());
51        newPlayer.eventHandlers = this.eventHandlers;
52        newPlayer.setTargetList(this.targets.copy());
53        newPlayer.setNumber(this.getNumber());
54        return newPlayer;
55        
56    }
57    
58    
59}
60