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

Diff of /enigma/src/objects.cc

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

revision 1.75 by dheck, Wed May 14 07:32:59 2003 UTC revision 1.76 by reallysoft, Wed May 14 08:12:39 2003 UTC
# Line 172  Object::double_attrib(const string &name Line 172  Object::double_attrib(const string &name
172      return false;      return false;
173  }  }
174    
175    // Send an impulse to position 'dest' into direction dir.
176    // If 'dest' contains a stone, on_impulse() is called for that stone
177    
178    void
179    Object::send_impulse(const GridPos& dest, Direction dir)
180    {
181        if (Stone *st = GetStone(dest)) {
182            Impulse impulse(this, dest, dir);
183            st->on_impulse(impulse);
184        }
185    }
186    
187  namespace  {  namespace  {
188      const char *vstrf(const char *format, va_list argPtr) {      const char *vstrf(const char *format, va_list argPtr) {
189          static size_t  buf_size = 256;          static size_t  buf_size = 256;
# Line 657  Stone::maybe_push_stone (const StoneCont Line 669  Stone::maybe_push_stone (const StoneCont
669  {  {
670      Direction dir = get_push_direction(sc);      Direction dir = get_push_direction(sc);
671      if (dir != enigma::NODIR) {      if (dir != enigma::NODIR) {
672          SendImpulse(sc.stonepos, dir, sc.actor);          sc.actor->send_impulse(sc.stonepos, dir);
673          return true;          return GetStone(sc.stonepos) == 0; // return true only if stone vanished
674      }      }
675      return false;      return false;
676  }  }
# Line 1716  namespace Line 1728  namespace
1728              return false;              return false;
1729          }          }
1730    
1731          void on_impulse (Direction dir) {          void on_impulse (const Impulse& impulse) {
1732              move_stone(dir);              move_stone(impulse.dir);
1733              Object *sender = ImpulseSender();              if (impulse.sender && 0 == strncmp(impulse.sender->get_kind(), "st-rotator-", 11)) {
1734              if (sender && 0 == strncmp(sender->get_kind(), "st-rotator-", 11)) {                  set_dir(impulse.dir);
                 set_dir(dir);  
1735              }              }
1736              init_model();              init_model();
1737          }          }
# Line 1892  namespace Line 1903  namespace
1903              return get_connections() == 0;              return get_connections() == 0;
1904          }          }
1905    
1906          virtual void on_impulse(Direction dir);          virtual void on_impulse(const Impulse& impulse);
1907    
1908          void init_model();          void init_model();
1909          StoneResponse collision_response(const StoneContact &sc);          StoneResponse collision_response(const StoneContact &sc);
# Line 2100  PuzzleStone::collision_response(const St Line 2111  PuzzleStone::collision_response(const St
2111  }  }
2112    
2113  void  void
2114  PuzzleStone::on_impulse(Direction dir)  PuzzleStone::on_impulse(const Impulse& impulse)
2115  {  {
2116      Cluster c;      Cluster c;
2117      bool    is_complete = find_cluster(c);      bool    is_complete = find_cluster(c);
2118      maybe_move_cluster(c, is_complete, dir);      maybe_move_cluster(c, is_complete, impulse.dir);
2119  }  }
2120    
2121    
# Line 2133  PuzzleStone::actor_hit(const StoneContac Line 2144  PuzzleStone::actor_hit(const StoneContac
2144          }          }
2145      }      }
2146      else if (move_dir != NODIR) {      else if (move_dir != NODIR) {
2147          SendImpulse(get_pos(), move_dir, sc.actor);          sc.actor->send_impulse(get_pos(), move_dir);
2148      }      }
2149  }  }
2150    
# Line 2727  namespace Line 2738  namespace
2738              notify_item();              notify_item();
2739          }          }
2740    
2741          void on_impulse(Direction dir);          void on_impulse(const Impulse& impulse);
2742    
2743          void init_model() {          void init_model() {
2744              char x[20];              char x[20];
# Line 2780  ShogunStone::actor_hit(const StoneContac Line 2791  ShogunStone::actor_hit(const StoneContac
2791  }  }
2792    
2793  void  void
2794  ShogunStone::on_impulse(Direction dir)  ShogunStone::on_impulse(const Impulse& impulse)
2795  {  {
2796      GridPos destpos     = move(get_pos(), dir);      GridPos destpos     = move(get_pos(), impulse.dir);
2797      Holes holes         = get_holes();      Holes holes         = get_holes();
2798      Holes smallest      = smallest_hole(holes);      Holes smallest      = smallest_hole(holes);
2799      ShogunStone *target = 0;      ShogunStone *target = 0;
# Line 3014  namespace Line 3025  namespace
3025    
3026          void change_state(State st);          void change_state(State st);
3027    
3028          virtual void on_impulse(Direction dir) {          virtual void on_impulse(const Impulse& impulse) {
3029              incoming = dir;              incoming = impulse.dir;
3030              change_state(PULSING);              change_state(PULSING);
3031          }          }
3032    
# Line 3052  namespace Line 3063  namespace
3063  void  void
3064  StoneImpulse_Base::change_state(State st)  StoneImpulse_Base::change_state(State st)
3065  {  {
3066    //     warning("StoneImpulse_Base changes State %i -> %i", (int)state, (int)st);
3067      if (st == state) return;      if (st == state) return;
3068    
3069      GridPos p = get_pos();      GridPos p = get_pos();
3070      switch (st) {      switch (st) {
3071      case PULSING:          case IDLE: {
3072          if (state != IDLE)              init_model();
3073              return;             // do not set new state              break;
3074          play_sound("impulse");          }
3075          break;          case PULSING:
3076      case CLOSING:              if (state != IDLE) {
3077          {                  return;         // do not set new state
3078                }
3079                play_sound("impulse");
3080                break;
3081            case CLOSING: {
3082              GridPos targetpos[4];              GridPos targetpos[4];
3083              bool    haveStone[4];              bool    haveStone[4];
3084    
# Line 3074  StoneImpulse_Base::change_state(State st Line 3090  StoneImpulse_Base::change_state(State st
3090              for (int d = int(incoming)+1; d <= int(incoming)+4; ++d) {              for (int d = int(incoming)+1; d <= int(incoming)+4; ++d) {
3091                  int D = d%4;                  int D = d%4;
3092                  if (haveStone[D]) {                  if (haveStone[D]) {
3093                      SendImpulse(targetpos[D], Direction(D), this);                      send_impulse(targetpos[D], Direction(D));
3094                  }                  }
3095              }              }
3096    
3097              incoming = NODIR;   // forget impulse direction              incoming = NODIR;   // forget impulse direction
3098              break;              break;
3099          }          }
     case IDLE:  
         init_model();  
         break;  
3100      }      }
3101      state = st;      state = st;
3102    
# Line 3179  namespace Line 3192  namespace
3192              }              }
3193          }          }
3194    
3195          void on_impulse(Direction dir) {          void on_impulse(const Impulse& impulse) {
3196              if (move_stone(dir)) {              if (move_stone(impulse.dir)) {
3197                  // on_move changes state to PULSING                  Actor *hitman = dynamic_cast<Actor*>(impulse.sender);
3198                  incoming = dir;                  if (hitman && wielded_item_is(hitman, "it-magicwand")) {
3199              }                      return;     // do not change state to PULSING
3200              else {                  }
                 StoneImpulse_Base::on_impulse(dir);  
3201              }              }
3202                StoneImpulse_Base::on_impulse(impulse);
3203          }          }
3204    
3205          void on_move() {          void on_move() {
3206              Actor *hitman = dynamic_cast<Actor*>(ImpulseSender());              // when moved, animation seems to be restarted
3207              if (hitman && wielded_item_is(hitman, "it-magicwand")) {              // and animcb never sets state to IDLE
3208                  // move was initiated by actor with magicwand              change_state(IDLE);
                 return; // dont pulse!  
             }  
   
             if (state != IDLE) change_state(IDLE);  
             change_state(PULSING);  
3209          }          }
3210    
3211          bool is_movable() {          bool is_movable() {
3212              if (state != IDLE)              return true;
                 change_state(IDLE);  
             return state == IDLE;  
3213          }          }
3214      };      };
3215  }  }
# Line 3918  namespace Line 3924  namespace
3924          Turnstile_Pivot_Base(const char *kind) : Stone (kind) {}          Turnstile_Pivot_Base(const char *kind) : Stone (kind) {}
3925    
3926      protected:      protected:
3927          bool rotate(bool clockwise);          bool rotate(bool clockwise, Object *impulse_sender);
3928    
3929          friend class Turnstile_Arm; // uses rotate          friend class Turnstile_Arm; // uses rotate
3930    
# Line 3932  namespace Line 3938  namespace
3938    
3939          void animcb() { set_model(model()); }          void animcb() { set_model(model()); }
3940    
3941          void handleActorsAndItems(bool clockwise);          void handleActorsAndItems(bool clockwise, Object *impulse_sender);
3942    
3943          virtual const char *model() const    = 0;          virtual const char *model() const    = 0;
3944          virtual const char *anim() const     = 0;          virtual const char *anim() const     = 0;
# Line 3967  namespace Line 3973  namespace
3973          virtual Direction get_dir() const = 0;          virtual Direction get_dir() const = 0;
3974    
3975          void actor_hit(const StoneContact &sc);          void actor_hit(const StoneContact &sc);
3976          void on_impulse(Direction dir);          void on_impulse(const Impulse& impulse);
3977    
3978          Turnstile_Pivot_Base *get_pivot() {          Turnstile_Pivot_Base *get_pivot() {
3979              Stone *st = GetStone (move (get_pos(), reverse(get_dir())));              Stone *st = GetStone (move (get_pos(), reverse(get_dir())));
# Line 4029  namespace Line 4035  namespace
4035  // -------------------------------------  // -------------------------------------
4036    
4037  void  void
4038  Turnstile_Arm::on_impulse(Direction dir) {  Turnstile_Arm::on_impulse(const Impulse& impulse) {
4039      enum Action { ROTL, ROTR, stay };      enum Action { ROTL, ROTR, stay };
4040      static Action actions[4][4] = {      static Action actions[4][4] = {
4041          { stay, ROTL, stay, ROTR }, // west arm          { stay, ROTL, stay, ROTR }, // west arm
# Line 4041  Turnstile_Arm::on_impulse(Direction dir) Line 4047  Turnstile_Arm::on_impulse(Direction dir)
4047      Turnstile_Pivot_Base *pivot = get_pivot();      Turnstile_Pivot_Base *pivot = get_pivot();
4048    
4049      if (pivot) {      if (pivot) {
4050          Action a = actions[get_dir()][dir];          Action a = actions[get_dir()][impulse.dir];
4051          if (a != stay) {          if (a != stay) {
4052              pivot->rotate(a == ROTR); // ROTR is clockwise              pivot->rotate(a == ROTR, impulse.sender); // ROTR is clockwise
4053          }          }
4054      }      }
4055      else {      else {
4056          // Move arms not attached to a pivot individually          // Move arms not attached to a pivot individually
4057          move_stone(dir);          move_stone(impulse.dir);
4058      }      }
4059  }  }
4060    
# Line 4123  Turnstile_Pivot_Base::set_arm (Direction Line 4129  Turnstile_Pivot_Base::set_arm (Direction
4129  }  }
4130    
4131  bool  bool
4132  Turnstile_Pivot_Base::rotate(bool clockwise)  Turnstile_Pivot_Base::rotate(bool clockwise, Object *impulse_sender)
4133  {  {
4134      DirectionBits arms       = arms_present();      DirectionBits arms       = arms_present();
4135      bool          can_rotate = true;      bool          can_rotate = true;
# Line 4166  Turnstile_Pivot_Base::rotate(bool clockw Line 4172  Turnstile_Pivot_Base::rotate(bool clockw
4172      }      }
4173    
4174      if (can_rotate) {      if (can_rotate) {
4175          if (dynamic_cast<Actor*>(ImpulseSender()))          if (dynamic_cast<Actor*>(impulse_sender))
4176              play_sound("st-magic");              play_sound("st-magic");
4177          play_sound("st-move");          play_sound("st-move");
4178    
# Line 4174  Turnstile_Pivot_Base::rotate(bool clockw Line 4180  Turnstile_Pivot_Base::rotate(bool clockw
4180    
4181          remove_arms(arms);          remove_arms(arms);
4182          set_arms(enigma::rotate(arms, clockwise));          set_arms(enigma::rotate(arms, clockwise));
4183          handleActorsAndItems(clockwise);          handleActorsAndItems(clockwise, impulse_sender);
4184    
4185          player::IncMoveCounter();          player::IncMoveCounter();
4186      }      }
# Line 4182  Turnstile_Pivot_Base::rotate(bool clockw Line 4188  Turnstile_Pivot_Base::rotate(bool clockw
4188  }  }
4189    
4190  void  void
4191  Turnstile_Pivot_Base::handleActorsAndItems(bool clockwise) {  Turnstile_Pivot_Base::handleActorsAndItems(bool clockwise, Object *impulse_sender) {
4192      GridPos pv_pos = get_pos();      GridPos pv_pos = get_pos();
4193      V2      pv_center(pv_pos.x+.5, pv_pos.y+.5);      V2      pv_center(pv_pos.x+.5, pv_pos.y+.5);
4194    
# Line 4252  Turnstile_Pivot_Base::handleActorsAndIte Line 4258  Turnstile_Pivot_Base::handleActorsAndIte
4258                  enum { STAY, WARP, SHATTER } action = STAY;                  enum { STAY, WARP, SHATTER } action = STAY;
4259    
4260                  if (compatible) {                  if (compatible) {
4261                      bool is_impulse_sender = (*ac == dynamic_cast<Actor*>(ImpulseSender()));                      bool is_impulse_sender = (*ac == dynamic_cast<Actor*>(impulse_sender));
4262    
4263                      if (is_impulse_sender) {                      if (is_impulse_sender) {
4264                          action = WARP;                          action = WARP;
# Line 4296  Turnstile_Pivot_Base::handleActorsAndIte Line 4302  Turnstile_Pivot_Base::handleActorsAndIte
4302    
4303                              for (int d = 0; d<4; ++d) {                              for (int d = 0; d<4; ++d) {
4304                                  if (has_dir(possible_impulses, Direction(d))) {                                  if (has_dir(possible_impulses, Direction(d))) {
4305                                      SendImpulse(ac_target_pos, Direction(d), *ac);                                      (*ac)->send_impulse(ac_target_pos, Direction(d));
4306                                  }                                  }
4307                              }                              }
4308    

Legend:
Removed from v.1.75  
changed lines
  Added in v.1.76

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