/[enigma]/enigma/src/stones_simple.cc
ViewVC logotype

Diff of /enigma/src/stones_simple.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.53.2.1 by dheck, Fri Sep 19 17:40:15 2003 UTC revision 1.53.2.2 by dheck, Mon Sep 22 02:51:09 2003 UTC
# Line 329  namespace Line 329  namespace
329      };      };
330  }  }
331    
332    
333  //----------------------------------------  //----------------------------------------
334  // SwapStone  // SwapStone
335  //----------------------------------------  //----------------------------------------
   
 /** \page st-swap Swap Stone  
   
 This stone can exchange its position with other neighboring stones  
 if it is hit hard enough.  In a way, this makes swap stones a kind  
 of "movable stone", except that they can be only exchanged with  
 other stones and may not be moved on empty fields.  
   
 \subsection swape Example  
 \verbatim  
 set_stone("st-swap", 10,10)  
 \endverbatim  
   
 \image html st-swap.png  
 */  
336  namespace  namespace
337  {  {
338      class SwapStone : public Stone, public TimeHandler {      class SwapStone : public Stone, public TimeHandler {
339      public:      public:
340          SwapStone()          SwapStone();
             : Stone("st-swap")  
             , state(IDLE)  
             , in_exchange_with(0)  
             , move_dir(NODIR)  
         {}  
   
341      private:      private:
   
342          // Object interface          // Object interface
343          SwapStone *clone();          SwapStone *clone();
344          void       dispose();          void       dispose();
# Line 369  namespace Line 348  namespace
348          void on_removal();          void on_removal();
349    
350          // Stone interface          // Stone interface
351          void on_impulse(const Impulse& impulse);          void on_impulse (const Impulse &impulse);
352          bool is_removable() { return state == IDLE; }          bool is_removable() { return state == IDLE; }
353          void actor_hit(const StoneContact &sc);          void actor_hit (const StoneContact &sc);
354          void actor_inside(Actor *a) { SendMessage(a, "shatter"); }          void actor_inside(Actor *a) { SendMessage(a, "shatter"); }
355    
356          // TimeHandler interface          // TimeHandler interface
# Line 381  namespace Line 360  namespace
360          enum State { IDLE, COME, GO } state;          enum State { IDLE, COME, GO } state;
361          YieldedGridStone *in_exchange_with;          YieldedGridStone *in_exchange_with;
362          Direction         move_dir;          Direction         move_dir;
   
363      };      };
364    }
365    
366      SwapStone *SwapStone::clone() {  SwapStone::SwapStone()
367          SwapStone *other        = new SwapStone(*this);  : Stone("st-swap"),
368          other->in_exchange_with = 0;    state(IDLE),
369          return other;    in_exchange_with(0),
370      }    move_dir(NODIR)
371    {}
372    
373      void SwapStone::dispose() {  SwapStone *
374          if (state == COME && in_exchange_with != 0) {  SwapStone::clone()
375              in_exchange_with->dispose();  {
376              delete in_exchange_with;      SwapStone *other        = new SwapStone(*this);
377          }      other->in_exchange_with = 0;
378          delete this;      return other;
379    }
380    
381    void SwapStone::dispose()
382    {
383        if (state == COME && in_exchange_with != 0) {
384            in_exchange_with->dispose();
385            delete in_exchange_with;
386      }      }
387        delete this;
388    }
389    
390      void SwapStone::on_removal() {  void SwapStone::on_removal()
391          if (state == COME) {  {
392              g_timer.remove_alarm(this);      if (state == COME) {
393          }          g_timer.remove_alarm(this);
394      }      }
395    }
396    
397      void SwapStone::alarm() {  /* Animation finished; put the "swapped" stone to its new position. */
398          assert(state == COME);  void SwapStone::alarm()
399    {
400        GridPos oldPos = move(get_pos(), reverse(move_dir));
401    
402          state = IDLE;      // Set the swapped stone (this also kills the old (inactive) swap stone)
403          init_model();      in_exchange_with->set_stone(oldPos);
404          play_sound("st-move");      delete in_exchange_with;
405        in_exchange_with = 0;
406    
407          GridPos oldPos = move(get_pos(), reverse(move_dir));      state = IDLE;
408          KillStone(oldPos);      init_model();
409        play_sound("st-move");
410    }
411    
412          assert(in_exchange_with);  void
413          in_exchange_with->set_stone(oldPos);  SwapStone::on_impulse(const Impulse& impulse)
414          delete in_exchange_with;  {
415          in_exchange_with = 0;      if (state == IDLE) {
416      }          GridPos oldp = get_pos();
417            GridPos newp = move(oldp, impulse.dir);
418    
419      void SwapStone::on_impulse(const Impulse& impulse) {          if (!IsLevelBorder(newp)) {
420          if (state == IDLE) {              Stone *other = GetStone(newp);
421              GridPos oldp = get_pos();              if (other && other->is_removable()) {
422              GridPos newp = move(oldp, impulse.dir);                  SwapStone *newStone = new SwapStone;
423                    newStone->state            = COME;
424              if (!IsLevelBorder(newp)) {                  newStone->in_exchange_with = new YieldedGridStone(other); // yields 'other'
425                  Stone *other = GetStone(newp);                  newStone->move_dir         = impulse.dir;
                 if (other && other->is_removable()) {  
                     SwapStone *newStone = clone();  
   
                     newStone->state            = COME;  
                     newStone->in_exchange_with = new YieldedGridStone(other); // yields 'other'  
                     newStone->move_dir         = impulse.dir;  
426    
427                      g_timer.set_alarm(newStone, 0.1, false);                  g_timer.set_alarm(newStone, 0.1, false);
428    
429                      SetStone(newp, newStone);                  SetStone(newp, newStone);
430    
431                      state    = GO;                  state    = GO;
432                      move_dir = impulse.dir;                  move_dir = impulse.dir;
433                      init_model();                  init_model();
434    
435                      play_sound ("st-move");                  play_sound ("st-move");
436                      player::IncMoveCounter(1);                  player::IncMoveCounter(1);
                 }  
437              }              }
438          }          }
439      }      }
440    }
441    
442      void SwapStone::actor_hit(const StoneContact &sc) {  void
443          Direction dir = get_push_direction (sc);  SwapStone::actor_hit(const StoneContact &sc)
444          if (dir != NODIR) {  {
445              send_impulse(get_pos(), dir);      Direction dir = get_push_direction (sc);
446          }      if (dir != NODIR) {
447            send_impulse(get_pos(), dir);
448      }      }
449    }
450    
451      void SwapStone::init_model() {  void SwapStone::init_model()
452          const char *model = 0;  {
453          switch (state) {      static char *models_come[] = { "st-swap-w", "st-swap-s", "st-swap-e", "st-swap-n" };
454              case IDLE: model = "st-swap"; break;      static char *models_go[] =   { "st-swap-e", "st-swap-n", "st-swap-w", "st-swap-s" };
             case COME:  {  
                 const char *models[] = { "st-swap-w", "st-swap-s", "st-swap-e", "st-swap-n" };  
                 model = models[move_dir];  
                 break;  
             }  
             case GO:  {  
                 const char *models[] = { "st-swap-e", "st-swap-n", "st-swap-w", "st-swap-s" };  
                 model = models[move_dir];  
                 break;  
             }  
         }  
455    
456          set_model(model);      const char *model = 0;
457        switch (state) {
458        case IDLE: model = "st-swap"; break;
459        case COME: model = models_come[move_dir]; break;
460        case GO:   model = models_go[move_dir]; break;
461      }      }
462    
463        set_model(model);
464  }  }
465    
466    
467  //----------------------------------------  //----------------------------------------
468  // BlockStone  // BlockStone
469  //----------------------------------------  //----------------------------------------
# Line 1721  namespace Line 1709  namespace
1709  {  {
1710      class ActorImpulseBase : public Stone {      class ActorImpulseBase : public Stone {
1711      public:      public:
1712          ActorImpulseBase(const char *kind) : Stone(kind), state(IDLE) {}          ActorImpulseBase(const char *kind) : Stone(kind), state(IDLE) {
1713    //             set_attrib("force", Value());
1714            }
1715    
1716      protected:      protected:
1717          virtual void actor_hit (const StoneContact &sc) {          virtual void actor_hit (const StoneContact &sc) {
1718              if (state == IDLE) {              if (state == IDLE) {
                 // normal points from stone-center _to_ actor.  
1719                  // actor_hit is called before reflect, but the force added below                  // actor_hit is called before reflect, but the force added below
1720                  // is applied to actor after the reflection.                  // is applied to actor after the reflection.
1721    
1722                  V2     normal   = normalize(sc.actor->get_pos() - get_pos().center());                  double forcefac = enigma::BumperForce;
1723                  double forcefac = 800;                  double_attrib("force", &forcefac);
                 V2     forcevec = normal*forcefac;  
   
 //                 {  
 //                     ActorInfo *ai        = sc.actor->get_actorinfo();  
 //                     double     vel_abs   = length(ai->vel);  
 //                     double     force_abs = length(forcevec);  
 //                     warning("actor_hit (vel=%f=[%f/%f], force=%f=[%f/%f] mass=%f)",  
 //                             vel_abs, ai->vel[0], ai->vel[1],  
 //                             force_abs, forcevec[0], forcevec[1],  
 //                             ai->mass);  
 //                 }  
1724    
1725                  sc.actor->add_force (forcevec);                  V2 vec = normalize(sc.actor->get_pos() - get_pos().center());
1726                    sc.actor->add_force (vec * forcefac);
1727    
1728                  play_sound("impulse");                  play_sound("impulse");
1729                  set_anim("st-actorimpulse-anim");                  set_anim("st-actorimpulse-anim");
# Line 1764  namespace Line 1743  namespace
1743          enum State { IDLE, PULSING, BROKEN };          enum State { IDLE, PULSING, BROKEN };
1744          State state;          State state;
1745      };      };
 }  
1746    
1747    
 //----------------------------------------  
 // ActorImpulseStone  
 //----------------------------------------  
 namespace  
 {  
1748      class ActorImpulseStone : public ActorImpulseBase {      class ActorImpulseStone : public ActorImpulseBase {
1749          CLONEOBJ(ActorImpulseStone);          CLONEOBJ(ActorImpulseStone);
1750      public:      public:
1751          ActorImpulseStone() : ActorImpulseBase("st-actorimpulse") {}          ActorImpulseStone() : ActorImpulseBase("st-actorimpulse") {}
1752      };      };
 }  
1753    
1754    
 //----------------------------------------  
 // ActorImpulseStone Invisible  
 //----------------------------------------  
 namespace  
 {  
1755      class ActorImpulseStoneInvisible : public ActorImpulseBase {      class ActorImpulseStoneInvisible : public ActorImpulseBase {
1756          CLONEOBJ(ActorImpulseStoneInvisible);          CLONEOBJ(ActorImpulseStoneInvisible);
1757      public:      public:
# Line 1792  namespace Line 1759  namespace
1759    
1760          void actor_hit(const StoneContact& sc) {          void actor_hit(const StoneContact& sc) {
1761              if (player::wielded_item_is(sc.actor, "it-brush")) {              if (player::wielded_item_is(sc.actor, "it-brush")) {
1762                  GridPos  p  = get_pos();                  Stone *st = MakeStone("st-actorimpulse");
1763                  KillStone(p);                  SetStone(get_pos(), st);
                 SetStone(p, MakeStone("st-actorimpulse"));  
                 Stone   *st = GetStone(p);  
1764                  st->actor_hit(sc);                  st->actor_hit(sc);
1765              }              }
1766              else {              else
1767                  ActorImpulseBase::actor_hit(sc);                  ActorImpulseBase::actor_hit(sc);
             }  
1768          }          }
1769      };      };
1770  }  }

Legend:
Removed from v.1.53.2.1  
changed lines
  Added in v.1.53.2.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26