1 /*
2  *  CVS: $Id: EventHandler.java,v 1.12 2004/07/23 14:55:18 marcus Exp $
3  * 
4  *  This file is part of Zuul.
5  *
6  *  Zuul 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 *  Zuul 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.util.ArrayList;
27import java.util.Iterator;
28import java.util.List;
29import java.util.Map;
30import java.util.Random;
31import java.util.Vector;
32
33import org.jzuul.engine.rooms.Room;
34
35/**
36 * Ein EventHandler behandelt {@link Event}. 
37 * EventHandler können einer Klasse, die {@link EventListener} implementiert über die 
38 * Methode setHandler() zugewiesen werden.
39 * 
40 * Es gibt drei Einstiegspunkte für die Behandlung von Events:
41 *  execute(GameObject) wird von Character Objekten und Item Objekten aufgerufen;
42 *  execute(Room) wird von Room Objekten aufgerufen;
43 *  execute()   wird von execute(Room) aufgerufen;
44 * 
45 * Die Methoden rufen sich untereinander selber auf, d.h. von oben nach unten werden
46 * immer weniger echte Aktionen ausgeführt.
47 * 
48 * 
49 * @version $Revision: 1.12 $
50 */
51public class EventHandler {
52    /**
53     * Eine Liste von Strings die bei dem Event vom Spieler ausgegben werden sollen.
54     */
55    protected List playerSayings;
56    /**
57     * Eine Liste von Strings die bei dem Event vom beteiligten NPC ausgegben werden sollen.
58     */
59    protected List npcSayings;
60    /**
61     * Eine Liste von actions, die bei diesem Event ausgeführt werden sollen.
62     */
63    protected List actions;
64    /**
65     * TargetObjects die dem Spieler bei diesem Event zugewiesen werden.
66     */
67    protected TargetList targets;
68    /**
69     * Liste von GameObject Namen, die bei diesem Event dem Player übergeben werden.
70     * 
71     */
72    protected List invobjects;
73    /**
74     * Liste von GameObject Namen, die bei diesem Event dem Raum hinzugefügt werden
75     * 
76     */
77    protected List roomobjects;
78    /**
79     * Liste von GameObject Namen, die bei diesem Event gelöscht werden sollen.
80     * Hierbei wird sowohl im Raum als auch im Inventar des Spielers nachgeschaut.
81     * 
82     */
83    protected List delete;
84    /**
85     * Map von properties, die bei diesem Event geändert werden sollen.
86     */
87    protected Map properties;
88    /**
89     * Legt fest ob das Event RandomSuccess haben soll.
90     * Steuert den Rückgabewert der execute Methode.
91     */
92    protected boolean randomSuccess;
93    
94    private String owner;
95
96    /**
97     * Erstellt einen leeren EventHandler
98     *
99     */
00    public EventHandler() {
01        this.playerSayings = new Vector();
02        this.npcSayings = new Vector();
03        this.actions = new Vector();
04        this.invobjects = new Vector();
05        this.roomobjects = new Vector();
06        this.delete = new Vector();
07        this.randomSuccess = false;
08    }
09
10    /**
11     * Fügt einen Satz zu den bei dem Event ausgegbenen Sätzen hinzu
12     * 
13     * @param sentence  der neue Satz
14     */
15    public void addPlayerSaying(String sentence) {
16        this.playerSayings.add(sentence);
17    }
18
19    /**
20     * Fügt einen Satz zu den bei dem Event ausgegbenen NPC Sätzen hinzu
21     * 
22     * @param sentence  der neue Satz
23     */
24    public void addNpcSaying(String sentence) {
25        Engine.debug("added npc saying: " + sentence, 1);
26        this.npcSayings.add(sentence);
27    }
28    
29    /**
30     * Fügt den Namen einer Aktion zu den bei dem Event ausgeführten Aktionen hinzu
31     * 
32     * @param actionName    der Name einer aktion (z.B. moveRandom)
33     */
34    public void addAction(String actionName) {
35        this.actions.add(actionName);
36    }
37
38    /**
39     * Setzt die TargetList die die TargetObjects enthällt die bei der Aktion dem Spieler hinzugefüht werden
40     * 
41     * @param targets   eine TargetList mit neuen Targets
42     */
43    public void setTargets(TargetList targets) {
44        this.targets = targets;
45    }
46
47
48    /**
49     * Fügt den namen eines GameObjects hinzu, das bei dem Event dem Spieler übergeben werden soll
50     * 
51     * @param objName   der Name eines existierenden GameObjects
52     */
53    public void addInvobject(String objName) {
54        this.invobjects.add(objName);
55    }
56
57    /**
58     * Fügt den Namen eines GameObjects hinzu, das bei dem Event dem aktuellen Raum hinzugefügt werden
59     * soll.
60     * 
61     * @param objName der Name eines existierenden GameObjects
62     */
63    public void addRoomobject(String objName) {
64        this.roomobjects.add(objName);
65    }
66
67    /**
68     * Fügt den Namen eines GameObjects hinzu, das bei dem Event gelöscht werden soll.
69     * 
70     * @param objName   der Name eines existierenden GameObjects
71     */
72    public void addDeletition(String objName) {
73        this.delete.add(objName);
74    }
75
76    /**
77     * Setzt die Map in der zu ändernde Eigenschaften eines GameObjects definiert werden
78     * 
79     * @param properties    eine Map von Eigenschaftsnamen und neuen Werten
80     */
81    public void setPropertyChanges(Map properties) {
82        this.properties = properties;
83    }
84
85    /**
86     * Definiert ob die auslösende Aktion zufällig ist.
87     * 
88     * @param isRandomSuccess   true wenn dem so ist, false sonst
89     */
90    public void setRandomSuccess(boolean isRandomSuccess) {
91        this.randomSuccess = isRandomSuccess;
92    }
93
94    /**
95     * Die Haupmethode für GameObjects.
96     * Wird von den doEvent() Methoden von GameObject aufgerufen, die sich selber 
97     * übergeben.
98     * Falls das übergebene GameObject ein Character Objekt ist wird die Action für
99     * den Charakter ausgeführt und die Sätze von dem Character gesagt. Da Characters
00     * überprüfen ob sie sich im selben Raum wie der Spieler befinden bevor sie etwas sagen
01     * kann hier die Ausgabe auch ins leere verlaufen.
02     * Properties werden in dem übergebenen GameObject geändert.
03     * Danach wird die Methode excecute(Room) mit dem aktuellen Raum des Spielers
04     * aufgerufen.
05     * 
06     * @param obj das GameObject das das Event bekommen hat
07     * @return  true be erfolg, false otherwise
08     */
09    public boolean execute(GameObject obj) {
10        // say and actions like moveRandom etc...
11        if (isCharacter(obj)) {
12            Character cobj = (Character) obj;
13            for (Iterator actionIter = actions.iterator(); actionIter.hasNext();) {
14                String element = (String) actionIter.next();
15                cobj.doAction(element);
16            }
17            for (Iterator sayingIter = npcSayings.iterator(); sayingIter.hasNext();) {
18                String element = (String) sayingIter.next();
19                cobj.say(element);
20            }
21        }
22        if ((this.properties != null) && (properties.size() > 0)) {
23            Engine.player.findGameObject(obj.getName()).setProperties(properties);
24        }
25        return execute(Engine.player.getCurrentRoom());
26    }
27
28    /**
29     * Execute methode ohne Parameter
30     * In dieser Methode wird die TargetList dem Spieler hinzugefügt und
31     * die Objekte die ins Inventar kommen und gelöscht werden bearbeitet,
32     * Die Methode wird von execute(Room) aufgerufen.
33     * 
34     * @return always true
35     */
36    public boolean execute() {
37        // target lists
38        for (Iterator targetIter = targets.targetObjectIterator(); targetIter.hasNext();) {
39            TargetObject element = (TargetObject) targetIter.next();
40            Engine.player.getTargetList().addTargetVerbose(element);
41        }
42
43        //handle game object stuff like roomitems, invitems, delete and properties
44        if (this.invobjects != null) {
45            for (Iterator objIter = invobjects.iterator(); objIter.hasNext();) {
46                String element = (String) objIter.next();
47                Engine.player.getFromPool(element);
48            }
49        }
50
51        if (this.delete != null) {
52            for (Iterator deleteIter = delete.iterator(); deleteIter.hasNext();) {
53                String element = (String) deleteIter.next();
54                Engine.player.findAndDeleteGameObject(element,false);
55            }
56
57        }
58        return true;
59
60    }
61
62    /**
63     * Methode für Räume Hier werden Sätze im Namen des Players gesagt. Die
64     * excute(GameObject) methode löscht gesagt Sätze falls ein Character
65     * übergeben wurde, daher werden hier nur Sätze in Verbindung mit Items
66     * gesagt. Die Sätze werden nur ausgegeben wenn der übergebene Raum auch der
67     * aktuelle Raum des Spielers ist. Danach werden dem Übergebenen Raumobjekt
68     * die eingestellten GameObjects hinzugefügt. Zuletzt wird execute()
69     * aufgerufen, danach entscheidet das Random Success ob die Methode true
70     * oder false zurückgibt. Die Methode wird von der doEvent() Methode von
71     * Räumen direkt aufgerufen.
72     * 
73     * @param r
74     *            ein Room Objekt
75     * @return true if RandomSuccess == false, else random true or false
76     */
77    public boolean execute(Room r) {
78        if (this.roomobjects != null) {
79            for (Iterator roomIter = roomobjects.iterator(); roomIter.hasNext();) {
80                String element = (String) roomIter.next();
81                r.getFromPool(element);
82            }
83        }
84
85        /*
86         * actually, there are two ways this method could be called, either by a GameObject
87         * event handler or by a room event handler. 
88         * If it is called by a GameObject handler it is called with the current room of the
89         * player, otherwise it is called with the room the event is handled in, so the
90         * player sayings belong here:
91         */
92        
93        for (Iterator sayingIter = playerSayings.iterator(); sayingIter.hasNext();) {
94            String element = (String) sayingIter.next();
95            if (Engine.player.getCurrentRoom().equals(r)) {
96                Engine.player.say(element);
97            }
98        }
99
00        execute();
01        
02        if (this.randomSuccess) {
03            if (new Random().nextBoolean()) {
04                return true;
05            } else {
06                return false;
07            }
08        } else {
09            return true;
10        }
11
12    }
13
14    /**
15     * Interne Methode zum überprüfen auf Null
16     * @param  foo ein Object
17     * @return  foo != null
18     */
19    public boolean notNull(Object foo) {
20        return foo != null;
21    }
22    
23    /**
24     * Interne Methode zum überprüfen ob ein GameObject ein Character Objekt ist
25     * 
26     * @param foo   ein GameObject
27     * @return          true falls es ein CharacterObject ist, false sonst
28     */
29    public boolean isCharacter(GameObject foo) {
30        return foo.isCharacter();
31    }
32    
33    public void setOwner(String name) {
34        this.owner = name;
35        if (targets != null) {
36            targets.setCreator(name);
37        }
38    }
39    
40}
41