View Javadoc

1   package erland.game.tileadventure;
2   
3   import erland.game.component.EPanel;
4   import erland.game.component.ETextField;
5   import erland.game.component.ELabel;
6   import erland.game.component.ENumberSpinner;
7   import erland.game.GameEnvironmentInterface;
8   import erland.game.tileadventure.rect.RectBlockContainerData;
9   import erland.util.ParameterSerializable;
10  
11  import javax.swing.*;
12  import javax.swing.event.ChangeListener;
13  import javax.swing.event.ChangeEvent;
14  import java.awt.*;
15  import java.awt.event.ActionListener;
16  import java.awt.event.ActionEvent;
17  
18  /*
19   * Copyright (C) 2004 Erland Isaksson (erland_i@hotmail.com)
20   *
21   * This program is free software; you can redistribute it and/or
22   * modify it under the terms of the GNU General Public License
23   * as published by the Free Software Foundation; either version 2
24   * of the License, or (at your option) any later version.
25   *
26   * This program is distributed in the hope that it will be useful,
27   * but WITHOUT ANY WARRANTY; without even the implied warranty of
28   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29   * GNU General Public License for more details.
30   *
31   * You should have received a copy of the GNU General Public License
32   * along with this program; if not, write to the Free Software
33   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34   * 
35   */
36  
37  public abstract class TileMapEditor extends MapEditor {
38      /*** Block container for the editor area */
39      protected BlockContainerData cont;
40      /*** Block container for the block select area */
41      protected BlockContainerData contPalette;
42      /*** Blocks in the editor area */
43      protected MapObjectContainerInterface mapBlocks;
44      /*** Blocks in the select block area */
45      protected MapObjectContainerInterface paletteBlocks;
46      /*** Spinner that changes the current level/block edited */
47      protected ENumberSpinner levelNoSpinner;
48      /*** Currently edited level/block number */
49      protected int levelNo = 1;
50      /*** Extended information about the currently edited level/block */
51      protected ParameterSerializable extendedLevelInfo;
52      /*** Spinner that changes the current height level edited */
53      protected ENumberSpinner heightLevelSpinner;
54  
55  
56      public void init(GameEnvironmentInterface environment)
57      {
58          paletteBlocks = null;
59          mapBlocks = null;
60          cont = null;
61          contPalette = null;
62          super.init(environment);
63      }
64      /***
65       * Get the name that is used for a list of the currently edited object type
66       * when it is stored to file, for example "levels"
67       * @return The name of the currently edited object type used in storage
68       */
69      abstract protected String getLevelFileLabel();
70  
71      /***
72       * Get the name that is used for the currently edited object type
73       * when it is stored to file, for example "level"
74       * @return The name of the currently edited object type used in storage
75       */
76      abstract protected String getLevelFileGroupLabel();
77  
78      /***
79       * Get the horizontal number of blocks in main editor area
80       * @return The horizontal number of blocks
81       */
82      abstract protected int getSizeX();
83  
84      /***
85       * Get the vertical number of blocks in the main editor area
86       * @return The vertical number of blocks
87       */
88      abstract protected int getSizeY();
89  
90      /***
91       * Get the height number of blocks in the main editor area
92       * @return The height number of blocks
93       */
94      abstract protected int getSizeZ();
95  
96      /***
97       * Get the horizontal number of blocks in the select block area
98       * @return The horizontal number of blocks
99       */
100     abstract protected int getSelectSizeX();
101     /***
102      * Get the vertical number of blocks in the select block area
103      * @return The vertical number of blocks
104      */
105     abstract protected int getSelectSizeY();
106 
107     /***
108      * Get an image which is based on subimages of all blocks
109      * in the block select area
110      * @return
111      */
112     abstract protected Image getMapBlockImage();
113 
114 
115     protected IrregularBlockContainerInterface getMapContainer()
116     {
117         if(cont==null) {
118             cont = ((TileGameEnvironmentInterface)(getEnvironment().getCustomEnvironment())).createBlockContainer(10,10,getSizeX(),getSizeY(),getSizeZ());
119             cont.setScrollingOffsetY(cont.getPositionY(0,0,cont.getSizeZ()));
120         }
121         return cont;
122     }
123 
124 
125     protected IrregularBlockContainerInterface getPaletteContainer()
126     {
127         if(contPalette==null) {
128             TileGameEnvironmentInterface env = ((TileGameEnvironmentInterface)getEnvironment().getCustomEnvironment());
129             contPalette = env.createRectBlockContainer(getMapContainer().getOffsetX()+340,getMapContainer().getOffsetY(),getSelectSizeX(),getSelectSizeY(),1);
130         }
131         return contPalette;
132     }
133 
134     /***
135      * Get a new block based on the specified block from the select block area
136      * @param blockNo Block number of the block to get
137      * @return A newly created block
138      */
139     protected MapObjectInterface getPaletteBlock(int blockNo)
140     {
141         if(blockNo>getFirstPaletteBlock()) {
142             MapEditorObject b = new MapEditorObject();
143             b.init(getEnvironment());
144             b.setContainer(getPaletteContainer());
145             b.setImage(getMapBlockImage(),blockNo-1);
146             b.setBlockType(blockNo);
147             return b;
148         }else {
149             return null;
150         }
151     }
152 
153     /***
154      * Get block number of the first block in the select block area
155      * @return The block number
156      */
157     protected int getFirstPaletteBlock()
158     {
159         return 0;
160     }
161     /***
162      * Get the number of blocks in the select block area
163      * @return The number of blocks
164      */
165     protected int getNoOfPaletteBlocks()
166     {
167         return -1;
168     }
169     protected MapObjectContainerInterface getPaletteBlocks()
170     {
171         if(paletteBlocks==null) {
172             paletteBlocks = new MapBlockContainer(contPalette.getSizeX(),contPalette.getSizeY(),1);
173             int i=getFirstPaletteBlock();
174             for(int x=0;x<paletteBlocks.getSizeX();x++) {
175                 for(int y=0;y<paletteBlocks.getSizeY();y++) {
176                     if(getNoOfPaletteBlocks()==-1 || i<(getNoOfPaletteBlocks()+getFirstPaletteBlock())) {
177                         MapObjectInterface b = getPaletteBlock(i);
178                         if(b!=null) {
179                             b.setContainer(contPalette);
180                             b.setPos(x,y,0);
181                             paletteBlocks.setBlock(b,x,y,0);
182                         }
183                         i++;
184                     }else {
185                         paletteBlocks.setBlock(null,x,y,0);
186                     }
187                 }
188             }
189         }
190         return paletteBlocks;
191     }
192 
193     protected MapObjectContainerInterface getMapBlocks()
194     {
195         if(mapBlocks==null) {
196             LevelInfoInterface levelInfo = getLevelManager().getLevel(getLevelNo());
197             if(levelInfo==null) {
198                 levelInfo = getLevelManager().createLevel(getLevelNo());
199             }
200             mapBlocks = levelInfo.getObjects();
201             setExtendedLevelInfo(levelInfo.getExtendedInfo());
202         }
203         return mapBlocks;
204     }
205 
206 
207     protected MapObjectInterface cloneBlock(MapObjectInterface block,IrregularBlockContainerInterface cont, int x, int y, int z)
208     {
209         MapObjectInterface b = (MapObjectInterface)block;
210         MapObjectInterface newBlock = null;
211         newBlock = (MapObjectInterface)b.clone();
212         newBlock.setPos(x,y,z);
213         newBlock.setContainer(cont);
214         return newBlock;
215     }
216 
217     protected boolean isEmptyAllowed()
218     {
219         return true;
220     }
221 
222     /***
223      * Get the text that should be shown to the user that indicates
224      * what short of object this editor makes it possible for the
225      * user to edit, for example "Level:"
226      * @return The name of the currently edited object type used in user interface
227      */
228     protected String getLevelLabelText()
229     {
230         return "Level:";
231     }
232 
233     /***
234      * Get the text that should be shown to the user that indicates
235      * which height level of the map that is currently edited, for example "Height:"
236      * If this method returns null, no height spinner will be visible
237      * @return The name of the currently edited object type used in user interface
238      */
239     protected String getHeightLabelText()
240     {
241         return "Height:";
242     }
243 
244     /***
245      * Get the maximum height levels of blocks
246      * @return The maximum numer of height levels of blocks
247      */
248     protected int getMaxHeight()
249     {
250         return mapBlocks!=null?mapBlocks.getSizeZ():0;
251     }
252 
253     /***
254      * Get the maximum allowed number of levels/blocks
255      * @return The maximum numer of levels/blocks
256      */
257     protected int getMaxLevel()
258     {
259         return 10;
260     }
261 
262     /***
263      * Creates buttons for changing currently edited level/blocks
264      * @param panel
265      */
266     protected void initLevelChangeButtons(EPanel panel)
267     {
268         EPanel p = EPanel.create(new FlowLayout());
269         ELabel label = ELabel.create(getLevelLabelText());
270         p.getContainer().add(label.getComponent());
271         levelNoSpinner = ENumberSpinner.create(levelNo,1,getMaxLevel(),1);
272         levelNoSpinner.addActionListener(new ActionListener() {
273             public void actionPerformed(ActionEvent e) {
274                 loadButton();
275             }
276         });
277         p.getContainer().add(levelNoSpinner.getComponent());
278         panel.getContainer().add(p.getComponent());
279     }
280 
281     /***
282      * Creates buttons for changing currently edited height level
283      * @param panel
284      */
285     protected void initHeightChangeButtons(EPanel panel)
286     {
287         EPanel p = EPanel.create(new FlowLayout());
288         ELabel label = ELabel.create(getHeightLabelText());
289         p.getContainer().add(label.getComponent());
290         heightLevelSpinner = ENumberSpinner.create(0,0,getMaxHeight(),1);
291         p.getContainer().add(heightLevelSpinner.getComponent());
292         panel.getContainer().add(p.getComponent());
293     }
294     protected void initButtons(EPanel panel)
295     {
296         initLevelChangeButtons(panel);
297         initHeightChangeButtons(panel);
298     }
299     /***
300      * Get currently edited level/block
301      * @return Block/level number of the currently edited block
302      */
303     protected int getLevelNo()
304     {
305         return levelNoSpinner.getValue();
306     }
307 
308     /***
309      * Get extended information about the currently edited level/block
310      * @return Extended level/block information
311      */
312     protected ParameterSerializable getExtendedLevelInfo()
313     {
314         return extendedLevelInfo;
315     }
316     /***
317      * Set the extended information for the currently edited level/block
318      * @param info Extended level/block information
319      */
320     protected void setExtendedLevelInfo(ParameterSerializable info)
321     {
322         this.extendedLevelInfo = info;
323     }
324 
325     /***
326      * Prepare the map container for save
327      * @param blocks The map container with all the blocks
328      * @return The new or unmodified map container which should be saved
329      */
330     protected MapObjectContainerInterface prepareForSave(MapObjectContainerInterface blocks)
331     {
332         return blocks;
333     }
334     protected void saveButton(MapObjectContainerInterface blocks)
335     {
336         MapObjectContainerInterface saveBlocks = prepareForSave(blocks);
337         getLevelManager().setLevel(getLevelNo(),saveBlocks,getExtendedLevelInfo());
338     }
339 
340     /***
341      * Prepare the map container after loading new map data
342      * @param blocks The map container with all the blocks
343      * @return The new or unmodified map container which should be used
344      */
345     protected MapObjectContainerInterface prepareAfterLoad(MapObjectContainerInterface blocks)
346     {
347         return blocks;
348     }
349 
350     protected void loadButton()
351     {
352         mapBlocks = null;
353         LevelInfoInterface levelInfo = getLevelManager().getLevel(getLevelNo());
354         if(levelInfo!=null) {
355             mapBlocks = prepareAfterLoad(levelInfo.getObjects());
356             setExtendedLevelInfo(levelInfo.getExtendedInfo());
357         }
358         updateBlocks();
359     }
360 
361     protected void updateBlocks() {
362         super.updateBlocks();
363         heightLevelSpinner.setMax(mapBlocks.getSizeZ());
364         heightLevelSpinner.setValue(0);
365     }
366 
367     protected int getMapPosZ() {
368         return heightLevelSpinner.getValue();
369     }
370 
371     /***
372      * Gets the level manager or create a new one if it does not
373      * already exist
374      * @return The LevelManager object which we should use
375      */
376     protected abstract LevelManager getLevelManager();
377 
378     public void drawSelectedFrame(Graphics g, MapObjectInterface selectedBlock) {
379         g.setColor(Color.WHITE);
380         int x1 = selectedBlock.getContainer().getPixelDrawingPositionX(selectedBlock.getPosX(),selectedBlock.getPosY(),selectedBlock.getPosZ());
381         int y1 = selectedBlock.getContainer().getPixelDrawingPositionY(selectedBlock.getPosX(),selectedBlock.getPosY(),selectedBlock.getPosZ());
382         int x2 = selectedBlock.getContainer().getPixelDrawingPositionX(selectedBlock.getPosX(),selectedBlock.getPosY()+1,selectedBlock.getPosZ());
383         int y2 = selectedBlock.getContainer().getPixelDrawingPositionY(selectedBlock.getPosX(),selectedBlock.getPosY()+1,selectedBlock.getPosZ());
384         int x3 = selectedBlock.getContainer().getPixelDrawingPositionX(selectedBlock.getPosX()+1,selectedBlock.getPosY(),selectedBlock.getPosZ());
385         int y3 = selectedBlock.getContainer().getPixelDrawingPositionY(selectedBlock.getPosX()+1,selectedBlock.getPosY(),selectedBlock.getPosZ());
386         int x4 = selectedBlock.getContainer().getPixelDrawingPositionX(selectedBlock.getPosX()+1,selectedBlock.getPosY()+1,selectedBlock.getPosZ());
387         int y4 = selectedBlock.getContainer().getPixelDrawingPositionY(selectedBlock.getPosX()+1,selectedBlock.getPosY()+1,selectedBlock.getPosZ());
388         g.drawLine(x1,y1,x2,y2);
389         g.drawLine(x1,y1,x3,y3);
390         g.drawLine(x4,y4,x2,y2);
391         g.drawLine(x4,y4,x3,y3);
392     }
393 
394     public void drawHoveringFrame(Graphics g, int posX, int posY) {
395         g.setColor(Color.WHITE);
396         int x1 = getMapContainer().getPixelDrawingPositionX(posX,posY,getMapPosZ());
397         int y1 = getMapContainer().getPixelDrawingPositionY(posX,posY,getMapPosZ());
398         int x2 = getMapContainer().getPixelDrawingPositionX(posX,posY+1,getMapPosZ());
399         int y2 = getMapContainer().getPixelDrawingPositionY(posX,posY+1,getMapPosZ());
400         int x3 = getMapContainer().getPixelDrawingPositionX(posX+1,posY,getMapPosZ());
401         int y3 = getMapContainer().getPixelDrawingPositionY(posX+1,posY,getMapPosZ());
402         int x4 = getMapContainer().getPixelDrawingPositionX(posX+1,posY+1,getMapPosZ());
403         int y4 = getMapContainer().getPixelDrawingPositionY(posX+1,posY+1,getMapPosZ());
404         g.drawLine(x1,y1,x2,y2);
405         g.drawLine(x1,y1,x3,y3);
406         g.drawLine(x4,y4,x2,y2);
407         g.drawLine(x4,y4,x3,y3);
408     }
409 }