Added a common set of bridge funcs for Leveleditor and Sector to create game objects.
authorRicardo Cruz <rick2@aeiou.pt>
Sun, 19 Dec 2004 16:57:27 +0000 (16:57 +0000)
committerRicardo Cruz <rick2@aeiou.pt>
Sun, 19 Dec 2004 16:57:27 +0000 (16:57 +0000)
Stuff ain't working properly in the level editor, because we miss the following common calls for all game objects:
- activate, get image and get postion.

SVN-Revision: 2258

src/gameobjs_bridge.cpp [new file with mode: 0644]
src/gameobjs_bridge.h [new file with mode: 0644]
src/leveleditor.cpp
src/leveleditor.h
src/sector.cpp

diff --git a/src/gameobjs_bridge.cpp b/src/gameobjs_bridge.cpp
new file mode 100644 (file)
index 0000000..c94076c
--- /dev/null
@@ -0,0 +1,231 @@
+/***************************************************************************
+                          gameobjs_bridge.cpp  -  description
+                             -------------------
+    begin                : Dec, 19 2004
+    copyright            : (C) 2004 by Ricardo Cruz
+    email                : rick2@aeiou.pt
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "gameobjs_bridge.h"
+
+#include "object/coin.h"
+#include "object/block.h"
+#include "object/invisible_block.h"
+#include "object/platform.h"
+#include "object/bullet.h"
+#include "object/rock.h"
+#include "badguy/jumpy.h"
+#include "badguy/snowball.h"
+#include "badguy/bouncing_snowball.h"
+#include "badguy/flame.h"
+#include "badguy/flyingsnowball.h"
+#include "badguy/mriceblock.h"
+#include "badguy/mrbomb.h"
+#include "badguy/dispenser.h"
+#include "badguy/spike.h"
+#include "badguy/spiky.h"
+#include "badguy/nolok_01.h"
+#include "trigger/door.h"
+#include "trigger/sequence_trigger.h"
+#include "trigger/secretarea_trigger.h"
+
+std::string object_type_to_string(int kind)
+{
+switch(kind)
+  {
+  // Game Objects
+  case COIN_OBJECT:
+    return "coin";
+  case INVISIBLE_BLOCK_OBJECT:
+    return "invisible-block";
+  case PLATFORM_OBJECT:
+    return "platform";
+  case ROCK_OBJECT:
+    return "rock";
+  // Bad Guys
+  case JUMPY_BADGUY:
+    return "jumpy";
+  case SNOWBALL_BADGUY:
+    return "snowball";
+  case BOUNCING_SNOWBALL_BADGUY:
+    return "bouncingsnowball";
+  case FLAME_BADGUY:
+    return "flame";
+  case FLYING_SNOWBALL_BADGUY:
+    return "flyingsnowball";
+  case MRICEBLOCK_BADGUY:
+    return "mriceblock";
+  case MRBOMB_BADGUY:
+    return "mrbomb";
+  case DISPENSER_BADGUY:
+    return "dispenser";
+  case SPIKE_BADGUY:
+    return "spike";
+  case SPIKY_BADGUY:
+    return "spiky";
+  case NOLOK_01_BADGUY:
+    return "nolok_01";
+  // Triggers
+  case DOOR_TRIGGER:
+    return "door";
+  default:
+    std::cerr << "Warning: object not recognized.\n";
+    return "";  // should not happen
+  }
+return "";  // avoids warnings
+}
+
+GameObjectsType object_name_to_type(const std::string& name)
+{
+// Game Objects
+if(name == "coin")
+  return COIN_OBJECT;
+else if(name == "invisible-block")
+  return INVISIBLE_BLOCK_OBJECT;
+else if(name == "platform")
+  return PLATFORM_OBJECT;
+else if(name == "rock")
+  return ROCK_OBJECT;
+// Bad Guys
+else if(name == "jumpy")
+  return JUMPY_BADGUY;
+else if(name == "snowball")
+  return SNOWBALL_BADGUY;
+else if(name == "bouncingsnowball")
+  return BOUNCING_SNOWBALL_BADGUY;
+else if(name == "flame")
+  return FLAME_BADGUY;
+else if(name == "flyingsnowball")
+  return FLYING_SNOWBALL_BADGUY;
+else if(name == "mriceblock")
+  return MRICEBLOCK_BADGUY;
+else if(name == "mrbomb")
+  return MRBOMB_BADGUY;
+else if(name == "dispenser")
+  return DISPENSER_BADGUY;
+else if(name == "spike")
+  return SPIKE_BADGUY;
+else if(name == "spiky")
+  return SPIKY_BADGUY;
+else if(name == "nolok_01")
+  return NOLOK_01_BADGUY;
+// Triggers
+else if(name == "door")
+  return DOOR_TRIGGER;
+
+// Object not recognized
+return NOT_RECOGNIZED_GAMEOBJECT;
+}
+
+bool is_object(const std::string& name)
+{
+if(object_name_to_type(name) == NOT_RECOGNIZED_GAMEOBJECT)
+  return false;
+return true;
+}
+
+GameObject* create_object(GameObjectsType kind, const lisp::Lisp& reader)
+{
+switch(kind)
+  {
+  // Game Objects
+  case COIN_OBJECT:
+  case INVISIBLE_BLOCK_OBJECT:
+    std::cerr << "Error: This object doesn't yet supported a Lisp argument.\n";
+    return NULL;
+//    return new Coin(reader);
+//    return new InvisibleBlock(reader);
+  case PLATFORM_OBJECT:
+    return new Platform(reader);
+  case ROCK_OBJECT:
+    return new Rock(reader);
+  // Bad Guys
+  case JUMPY_BADGUY:
+    return new Jumpy(reader);
+  case SNOWBALL_BADGUY:
+    return new SnowBall(reader);
+  case BOUNCING_SNOWBALL_BADGUY:
+    return new BouncingSnowball(reader);
+  case FLAME_BADGUY:
+    return new Flame(reader);
+  case FLYING_SNOWBALL_BADGUY:
+    return new FlyingSnowBall(reader);
+  case MRICEBLOCK_BADGUY:
+    return new MrIceBlock(reader);
+  case MRBOMB_BADGUY:
+    return new MrBomb(reader);
+  case DISPENSER_BADGUY:
+    return new Dispenser(reader);
+  case SPIKE_BADGUY:
+    return new Spike(reader);
+  case SPIKY_BADGUY:
+    return new Spiky(reader);
+  case NOLOK_01_BADGUY:
+    return new Nolok_01(reader);
+  // Triggers
+  case DOOR_TRIGGER:
+    return new Door(reader);
+  default:
+    std::cerr << "Warning: object not recognized.\n";
+    return NULL;  // object not recognized
+  }
+return NULL;  // avoids warnings
+}
+
+GameObject* create_object(GameObjectsType kind, const Vector& pos)
+{
+switch(kind)
+  {
+  // Game Objects
+  case COIN_OBJECT:
+    return new Coin(pos);
+  case INVISIBLE_BLOCK_OBJECT:
+    return new InvisibleBlock(pos);
+  case PLATFORM_OBJECT:
+  case ROCK_OBJECT:
+  case JUMPY_BADGUY:
+  case FLAME_BADGUY:
+  case DISPENSER_BADGUY:
+  case SPIKY_BADGUY:
+    std::cerr << "Error: This object doesn't yet support a position argument.\n";
+    return NULL;
+//    return new Platform(pos);
+//    return new Rock(pos);
+  // Bad Guys
+//    return new Jumpy(pos.x,pos.y,LEFT);
+//    return new Flame(pos.x,pos.y,LEFT);
+//    return new Dispenser(pos.x,pos.y,LEFT);
+//    return new Spiky(pos.x,pos.y,LEFT);
+  case SNOWBALL_BADGUY:
+    return new SnowBall(pos.x,pos.y,LEFT);
+  case BOUNCING_SNOWBALL_BADGUY:
+    return new BouncingSnowball(pos.x,pos.y,LEFT);
+  case FLYING_SNOWBALL_BADGUY:
+    return new FlyingSnowBall(pos.x,pos.y);
+  case MRICEBLOCK_BADGUY:
+    return new MrIceBlock(pos.x,pos.y,LEFT);
+  case MRBOMB_BADGUY:
+    return new MrBomb(pos.x,pos.y,LEFT);
+  case SPIKE_BADGUY:
+    return new Spike(pos,Spike::WEST);
+  case NOLOK_01_BADGUY:
+    return new Nolok_01(pos.x,pos.y);
+  // Triggers
+  case DOOR_TRIGGER:
+    return new Door((int)pos.x,(int)pos.y,"","");
+  default:
+    std::cerr << "Warning: object not recognized.\n";
+    return NULL;  // object not recognized
+  }
+return NULL;  // avoids warnings
+}
diff --git a/src/gameobjs_bridge.h b/src/gameobjs_bridge.h
new file mode 100644 (file)
index 0000000..3f30ee6
--- /dev/null
@@ -0,0 +1,72 @@
+/***************************************************************************
+                          gameobjs_bridge.h  -  description
+                             -------------------
+    begin                : Dec, 19 2004
+    copyright            : (C) 2004 by Ricardo Cruz
+    email                : rick2@aeiou.pt
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef GAMEOBJS_BRIDGE_H
+#define GAMEOBJS_BRIDGE_H
+
+#include <string>
+
+//#include "lisp/parser.h"
+#include "lisp/lisp.h"
+//#include "lisp/writer.h"
+//#include "lisp/list_iterator.h"
+
+//class GameObject;
+#include "object/gameobjs.h"
+
+
+/** This is just a set of functions aim to provide a common way
+    to create new game objects. Game objects that ain't really
+    interactive don't fit in here. */
+
+enum GameObjectsType {
+  // Game Objects
+  COIN_OBJECT,
+  INVISIBLE_BLOCK_OBJECT,
+  PLATFORM_OBJECT,
+  ROCK_OBJECT,
+  // Bad Guys
+  JUMPY_BADGUY,
+  SNOWBALL_BADGUY,
+  BOUNCING_SNOWBALL_BADGUY,
+  FLAME_BADGUY,
+  FLYING_SNOWBALL_BADGUY,
+  MRICEBLOCK_BADGUY,
+  MRBOMB_BADGUY,
+  DISPENSER_BADGUY,
+  SPIKE_BADGUY,
+  SPIKY_BADGUY,
+  NOLOK_01_BADGUY,
+  // Triggers
+  DOOR_TRIGGER,
+
+  TOTAL_GAMEOBJECTS,
+  NOT_RECOGNIZED_GAMEOBJECT
+  };
+
+/* Objects identifiers. */
+std::string object_type_to_string(int kind);
+GameObjectsType object_name_to_type(const std::string& name);
+
+bool is_object(const std::string& name);
+
+/* Calls to return a pointer to a created GameObjects.
+   Don't forget to delete them! */
+GameObject* create_object(GameObjectsType kind, const lisp::Lisp& reader);
+GameObject* create_object(GameObjectsType kind, const Vector& pos);
+
+#endif /*GAMEOBJS_BRIDGE_H*/
index 198c0c2..5ac945c 100644 (file)
@@ -38,6 +38,7 @@
 #include "object/camera.h"
 #include "object/tilemap.h"
 #include "object/background.h"
+#include "gameobjs_bridge.h"
 
 LevelEditor::LevelEditor()
 {
@@ -102,7 +103,8 @@ LevelEditor::LevelEditor()
             Vector(32,32), Vector(4,8));
 
   tiles_board->add_button(Button(img_rubber_bt, _("Eraser"), SDLKey(SDLK_DELETE)), 0);
-  for(unsigned int id = 1; id < tile_manager->get_max_tileid(); id++)
+  unsigned int id;
+  for(id = 1; id < tile_manager->get_max_tileid(); id++)
     {
     const Tile* tile = tile_manager->get(id);
     if(!tile)
@@ -115,27 +117,15 @@ LevelEditor::LevelEditor()
     Button button = Button(surface, "", SDLKey(0));
     tiles_board->add_button(button, id);
     }
+  gameobjs_first_id = id;
 
-  #if 0
-  for(int i = 0; i < NUM_BadGuyKinds; i++)
+  for(id = 0; id < TOTAL_GAMEOBJECTS; id++)
     {
-    // filter bomb, since it is only for internal use, not for levels
-    if(i == BAD_BOMB)
-      continue;
-
-    BadGuyKind kind = BadGuyKind(i);
-    BadGuy badguy(kind, 0,0);
-    badguy.activate(LEFT);
-
-    Surface *img = badguy.get_image();
-    tiles_board->add_button(Button(img, "", SDLKey(SDLK_1+i)), -(i+1));
+//    Surface *img = badguy.get_image();
+// FIXME: get image from object. Using the rubber in the meanwhile.
+    tiles_board->add_button(Button(img_rubber_bt, object_type_to_string(id),
+                            SDLKey(SDLK_1+id)), id+gameobjs_first_id);
     }
-  #endif
-
-  #if 0
-  tiles_board->add_button(Button(img_trampoline[0].get_frame(0), _("Trampoline"), SDLKey(0)), OBJ_TRAMPOLINE);
-  tiles_board->add_button(Button(img_flying_platform->get_frame(0), _("Flying Platform"), SDLKey(0)), OBJ_FLYING_PLATFORM);
-  #endif
 
   tiles_layer = new ButtonGroup(Vector(12, screen->h-64), Vector(80,20), Vector(1,3));
   tiles_layer->add_button(Button(img_foreground_bt, _("Edtit foreground tiles"),
@@ -608,11 +598,12 @@ if(sector)
       if(selection[0][0] == 0 && selection.size() == 1)
           context.draw_surface(img_rubber_bt, Vector(event.button.x - 8,
           event.button.y - 8), LAYER_GUI-2);
-      else if(selection[0][0] < 0)
+      else if(selection[0][0] >= gameobjs_first_id || selection[0][0] < 0)
         {
+// FIXME: this should draw an object image near cursor
+#if 0
         int id = selection[0][0];
 
-#if 0
         if(id == OBJ_TRAMPOLINE)
           context.draw_surface(img_trampoline[0].get_frame(0), Vector(event.button.x - 8,
           event.button.y - 8), LAYER_GUI-2);
@@ -620,14 +611,12 @@ if(sector)
           context.draw_surface(img_flying_platform->get_frame(0), Vector(event.button.x - 8,
           event.button.y - 8), LAYER_GUI-2);
         else
-#endif
         if(id == OBJ_DOOR)
           /*context.draw_surface(door->get_frame(0), Vector(event.button.x - 8,
           event.button.y - 8), LAYER_GUI-2);*/
           ;
         else
           {
-#if 0
           BadGuyKind kind = BadGuyKind((-id)-1);
           BadGuy badguy(kind, 0,0);
           badguy.activate(LEFT);
@@ -635,8 +624,8 @@ if(sector)
 
           context.draw_surface(img, Vector(event.button.x - 8,
           event.button.y - 8), LAYER_GUI-2);
-#endif
           }
+#endif
         }
       else
         {
@@ -791,12 +780,6 @@ foregrounds = solids = backgrounds = 0;
 /* Point foregrounds, backgrounds, solids to its layer */
 for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); i++)
   {
-#if 0
-  BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
-  if(badguy)
-    badguy->activate(LEFT);
-#endif
-
   TileMap* tilemap = dynamic_cast<TileMap*> (*i);
   if(tilemap)
     {
@@ -866,22 +849,12 @@ void LevelEditor::change(int x, int y, int newtile, int layer)
     y = (int)(y * (zoom*32) / 32);
   }
 
-  if(newtile < 0)  // add object
+  if(newtile >= gameobjs_first_id)  // add object
   {
     // remove an active tile or object that might be there
     change(x, y, 0, LAYER_TILES);
 
-#if 0
-    if(newtile == OBJ_TRAMPOLINE)
-      sector->add_object(new Trampoline(x, y));
-    else if(newtile == OBJ_FLYING_PLATFORM)
-      sector->add_object(new FlyingPlatform(x, y));
-    else
-      if(newtile == OBJ_DOOR)
-        sector->add_object(new Door(x, y));
-      else
-        sector->add_bad_guy(x, y, BadGuyKind((-newtile)-1), true);
-#endif
+    create_object((GameObjectsType)(newtile-gameobjs_first_id),Vector(x,y));
 
     sector->update_game_objects();
   } else if(cur_layer == LAYER_FOREGROUNDTILES) {
@@ -891,13 +864,12 @@ void LevelEditor::change(int x, int y, int newtile, int layer)
     // we /32 in order to round numbers
     for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
         i < sector->gameobjects.end(); i++) {
+// FIXME: if there is a game objs in here, remove it!
 #if 0
       BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
       if(badguy)
         if((int)badguy->base.x/32 == x/32 && (int)badguy->base.y/32 == y/32)
           sector->gameobjects.erase(i);
-#endif
-#if 0
       Trampoline* trampoline = dynamic_cast<Trampoline*> (*i);
       if(trampoline)
       {
@@ -908,8 +880,6 @@ void LevelEditor::change(int x, int y, int newtile, int layer)
       if(flying_platform)
         if((int)flying_platform->base.x/32 == x/32 && (int)flying_platform->base.y/32 == y/32)
           sector->gameobjects.erase(i);
-#endif
-#if 0
       Door* door = dynamic_cast<Door*> (*i);
       if(door)
         if((int)door->get_area().x/32 == x/32 && (int)door->get_area().y/32 == y/32)
index 5867d88..5fef880 100644 (file)
@@ -137,7 +137,7 @@ private:
   Surface *img_previous_level_bt, *img_next_level_bt, *img_previous_sector_bt, *img_next_sector_bt;
 
   ButtonGroup *tiles_board, *tiles_layer, *level_options;
-  int cur_layer;
+  int gameobjs_first_id, cur_layer;
 
   std::vector <std::vector <int> > selection;
   Vector selection_ini, selection_end;
index d3e7514..310d64f 100644 (file)
@@ -67,6 +67,7 @@
 #include "trigger/door.h"
 #include "trigger/sequence_trigger.h"
 #include "trigger/secretarea_trigger.h"
+#include "gameobjs_bridge.h"
 
 Sector* Sector::_current = 0;
 
@@ -120,41 +121,14 @@ Sector::parse_object(const std::string& name, const lisp::Lisp& reader)
     CloudParticleSystem* partsys = new CloudParticleSystem();
     partsys->parse(reader);
     return partsys;
-  } else if(name == "door") {
-    return new Door(reader);
   } else if(name == "secretarea") {
     return new SecretAreaTrigger(reader);
   } else if(name == "sequencetrigger") {
     return new SequenceTrigger(reader);
-  } else if(name == "platform") {
-    return new Platform(reader);
-  } else if(name == "jumpy" || name == "money") {
-    return new Jumpy(reader);
-  } else if(name == "snowball") {
-    return new SnowBall(reader);
-  } else if(name == "bouncingsnowball") {
-    return new BouncingSnowball(reader);
-  } else if(name == "flame") {
-    return new Flame(reader);
-  } else if(name == "flyingsnowball") {
-    return new FlyingSnowBall(reader);
-  } else if(name == "mriceblock") {
-    return new MrIceBlock(reader);
-  } else if(name == "mrbomb") {
-    return new MrBomb(reader);
-  } else if(name == "dispenser") {
-    return new Dispenser(reader);
-  } else if(name == "spike") {
-    return new Spike(reader);
-  } else if(name == "spiky") {
-    return new Spiky(reader);
-  } else if(name == "nolok_01") {
-    return new Nolok_01(reader);
-  } else if(name == "rock") {
-    return new Rock(reader);
-  }
-
-  std::cerr << "Unknown object type '" << name << "'.\n";
+  } else if(is_object(name)) {
+    return create_object(object_name_to_type(name), reader);
+  } else
+    std::cerr << "Unknown object type '" << name << "'.\n";
   return 0;
 }