/[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.63 by reallysoft, Thu May 8 11:54:26 2003 UTC revision 1.64 by dheck, Thu May 8 19:02:14 2003 UTC
# Line 547  bool Stone::move_stone(Direction dir) { Line 547  bool Stone::move_stone(Direction dir) {
547      if (!GetStone(newPos)) {      if (!GetStone(newPos)) {
548          play_sound("st-move");          play_sound("st-move");
549          SetStone(newPos, YieldStone(p));          SetStone(newPos, YieldStone(p));
550          display::GetStatusBar()->set_counter(player::IncMoveCounter());          player::IncMoveCounter();
551    
552          on_move();          on_move();
553          if (Item *it = GetItem(newPos)) it->on_stonehit(this);          if (Item *it = GetItem(newPos)) it->on_stonehit(this);
# Line 1855  PuzzleStone::maybe_move_cluster(Cluster Line 1855  PuzzleStone::maybe_move_cluster(Cluster
1855              SetStone(mc[i], clusterstones[i]);              SetStone(mc[i], clusterstones[i]);
1856      }      }
1857    
1858      display::GetStatusBar()->set_counter(player::IncMoveCounter(c.size()));      player::IncMoveCounter(c.size());
1859  }  }
1860    
1861  bool  bool
# Line 2282  namespace Line 2282  namespace
2282          }          }
2283    
2284          void actor_hit(const StoneContact &sc)          void actor_hit(const StoneContact &sc)
   
2285          {          {
2286            if (sc.actor->get_attrib("blackball"))              if (sc.actor->get_attrib("blackball"))
2287              set_on(!is_on());                  set_on(!is_on());
2288              PerformAction(this, is_on());              PerformAction(this, is_on());
2289              play_sound("st-switch");              play_sound("st-switch");
2290          }          }
# Line 2317  namespace Line 2316  namespace
2316          }          }
2317    
2318          void actor_hit(const StoneContact &sc)          void actor_hit(const StoneContact &sc)
   
2319          {          {
2320            if (sc.actor->get_attrib("whiteball"))              if (sc.actor->get_attrib("whiteball"))
2321              set_on(!is_on());                  set_on(!is_on());
2322              PerformAction(this, is_on());              PerformAction(this, is_on());
2323              play_sound("st-switch");              play_sound("st-switch");
2324          }          }
# Line 2509  namespace Line 2507  namespace
2507  {  {
2508      class ShogunStone : public MovableStone {      class ShogunStone : public MovableStone {
2509          CLONEOBJ(ShogunStone);          CLONEOBJ(ShogunStone);
     public:  
         ShogunStone(const char *kind="st-shogun") : MovableStone(kind) {  
             set_holes(SMALL);  
         }  
     protected:  
         enum Holes { SMALL = 1, MEDIUM = 2, LARGE = 4};  
2510    
2511            enum Holes { SMALL = 1, MEDIUM = 2, LARGE = 4};
2512          void set_holes(Holes h) { set_attrib("holes", h); }          void set_holes(Holes h) { set_attrib("holes", h); }
2513        public:
2514            ShogunStone(int holes=SMALL) : MovableStone("st-shogun") {
2515                set_holes(static_cast<Holes>(holes));
2516            }
2517      private:      private:
2518          Holes get_holes() const;          Holes get_holes() const;
2519          void notify_item(bool disappearing);          void notify_item(bool disappearing);
# Line 2548  namespace Line 2545  namespace
2545    
2546          static Holes smallest_hole(Holes s);          static Holes smallest_hole(Holes s);
2547    
2548          Holes transfer_smallest_hole(GridPos p);          bool transfer_smallest_hole(GridPos p);
2549          void actor_hit(const StoneContact &sc);          void actor_hit(const StoneContact &sc);
2550      };      };
   
 #define DEFSHOGUN(CLASSNAME, KIND, HOLES)               \  
     class CLASSNAME : public ShogunStone {              \  
         CLONEOBJ(CLASSNAME);                            \  
     public:                                             \  
         CLASSNAME() : ShogunStone(KIND) {               \  
             set_holes (static_cast<Holes>(HOLES));      \  
         }                                               \  
     };  
   
     DEFSHOGUN(Shogun_S, "st-shogun-s", 1);  
     DEFSHOGUN(Shogun_M, "st-shogun-m", 2);  
     DEFSHOGUN(Shogun_SM, "st-shogun-sm", 3);  
     DEFSHOGUN(Shogun_L, "st-shogun-l", 4);  
     DEFSHOGUN(Shogun_SL, "st-shogun-sl", 5);  
     DEFSHOGUN(Shogun_ML, "st-shogun-ml", 6);  
     DEFSHOGUN(Shogun_SML, "st-shogun-sml", 7);  
2551  }  }
2552    
2553  ShogunStone::Holes  ShogunStone::Holes
# Line 2600  ShogunStone::notify_item(bool disappeari Line 2580  ShogunStone::notify_item(bool disappeari
2580          }          }
2581          else {          else {
2582              switch (get_holes()) {              switch (get_holes()) {
2583                  case SMALL: SendMessage(it,"shogun1"); break;              case SMALL: SendMessage(it,"shogun1"); break;
2584                  case (MEDIUM | SMALL): SendMessage(it,"shogun2"); break;              case (MEDIUM | SMALL): SendMessage(it,"shogun2"); break;
2585                  case (LARGE | MEDIUM | SMALL): SendMessage(it,"shogun3"); break;              case (LARGE | MEDIUM | SMALL): SendMessage(it,"shogun3"); break;
2586                  default: SendMessage(it, "noshogun"); break;              default: SendMessage(it, "noshogun"); break;
2587              }              }
2588          }          }
2589      }      }
2590  }  }
2591    
2592  ShogunStone::Holes  bool
2593  ShogunStone::transfer_smallest_hole(GridPos p)  ShogunStone::transfer_smallest_hole(GridPos p)
2594  {  {
2595      Holes        h            = get_holes();      Holes h  = get_holes();
2596      Holes        sh           = smallest_hole(h);      Holes sh = smallest_hole(h);
2597      Holes        nh           = h; // predicted hole-state      Holes nh = h; // predicted hole-state
2598      ShogunStone *sst          = 0;  
2599      bool         add2existing = false;      ShogunStone *target = 0;
2600        if (Stone *st = GetStone(p)) {
2601      if (Stone *st=GetStone(p)) {          target = dynamic_cast<ShogunStone*>(GetStone(p));
2602          if ((sst = dynamic_cast<ShogunStone*>(st))) {  
2603              add2existing = true;          /* If the stone at `p' is not a shogun stone or if smallest hole
2604              if (sh >= smallest_hole(sst->get_holes())) { // smallest hole does not fit into target             does not fit into target, do not transfer the smallest hole. */
2605                  sst = 0;          if (!target || sh >= smallest_hole(target->get_holes()))
2606              }              return false;
2607          }      }
2608    
2609        // It's important, to remove the old stone before setting the
2610        // new, (otherwise it is possible to activate two triggers
2611        // with one shogun stone
2612        //  when shifting from one shogun target to a second adjacent shogun target)
2613    
2614        // remove/modify source stone:
2615        nh = Holes(nh & ~sh);
2616        if (nh) {
2617            set_holes(nh);
2618            notify_item(false);
2619            init_model();
2620      }      }
2621      else {      else {
2622          sst = new ShogunStone();          notify_item(true);
2623            KillStone(get_pos());
2624      }      }
2625    
2626      if (sst) {                  // perform move ?      // set/modify target stone:
2627        if (target) {     // add to existing
2628          // it's important, to remove the old stone before setting the new,          target->add_hole(sh);
2629          // (otherwise it is possible to activate two triggers with one shogun stone          play_sound("st-magic");
         //  when shifting from one shogun target to a second adjacent shogun target)  
   
         // remove/modify source stone:  
         nh = Holes(nh & ~sh);  
         if (nh) {  
             set_holes(nh);  
             notify_item(false);  
             init_model();  
         }  
         else {  
             notify_item(true);  
             KillStone(get_pos());  
         }  
   
         // set/modify target stone:  
         if (add2existing) {     // add to existing  
             sst->add_hole(sh);  
             play_sound("st-magic");  
         }  
         else { // create new  
             sst->set_holes(sh);  
             SetStone(p, sst);  
         }  
   
         display::GetStatusBar()->set_counter(player::IncMoveCounter());  
2630      }      }
2631        else  // create new
2632            SetStone(p, new ShogunStone(sh));
2633    
2634      return nh;      player::IncMoveCounter();
2635    
2636        return true;
2637  }  }
2638    
2639  void  void
# Line 2678  ShogunStone::actor_hit(const StoneContac Line 2650  ShogunStone::actor_hit(const StoneContac
2650  }  }
2651    
2652  void  void
2653  ShogunStone::on_impulse(Direction dir) {  ShogunStone::on_impulse(Direction dir)
2654  //     fprintf(stderr, "ShogunStone::on_impulse(%s)\n", to_suffix(dir).c_str());  {
2655      Holes holes    = get_holes();      if (transfer_smallest_hole(move(get_pos(), dir)))
     Holes newholes = transfer_smallest_hole(move(get_pos(), dir));  
   
     if (newholes != holes) {  
2656          play_sound("st-move");          play_sound("st-move");
     }  
2657  }  }
2658    
2659  //----------------------------------------  //----------------------------------------
# Line 4015  Turnstile_Pivot_Base::warpActorsInRange( Line 3983  Turnstile_Pivot_Base::warpActorsInRange(
3983                  }                  }
3984    
3985                  switch (action) {                  switch (action) {
3986                      case WARP:  {                  case WARP:  {
3987                          GridPos ac_target_pos(pv_pos.x+to_x[idx_target], pv_pos.y+to_y[idx_target]);                      GridPos ac_target_pos(pv_pos.x+to_x[idx_target], pv_pos.y+to_y[idx_target]);
3988                          world::WarpActor(*ac, ac_target_pos.x+.5, ac_target_pos.y+.5);                      world::WarpActor(*ac, ac_target_pos.x+.5, ac_target_pos.y+.5);
3989    
3990                          Stone *st = GetStone(ac_target_pos);                      Stone *st = GetStone(ac_target_pos);
3991                          if (!st) break;                      if (!st) break;
3992    
3993                          // destination is blocked                      // destination is blocked
3994    
3995                          Turnstile_Arm *arm = dynamic_cast<Turnstile_Arm*>(st);                      Turnstile_Arm *arm = dynamic_cast<Turnstile_Arm*>(st);
3996                          if (arm && !compatible) { // if blocking stone is turnstile arm -> hit it!                      if (arm && !compatible) { // if blocking stone is turnstile arm -> hit it!
3997                              const int impulse_dir[2][8] = {                          const int impulse_dir[2][8] = {
3998                                  // anticlockwise                              // anticlockwise
3999                                  { SOUTHBIT|WESTBIT, WESTBIT, NORTHBIT|WESTBIT, NORTHBIT,                              { SOUTHBIT|WESTBIT, WESTBIT, NORTHBIT|WESTBIT, NORTHBIT,
4000                                    NORTHBIT|EASTBIT, EASTBIT, SOUTHBIT|EASTBIT, SOUTHBIT },                                NORTHBIT|EASTBIT, EASTBIT, SOUTHBIT|EASTBIT, SOUTHBIT },
4001                                  // clockwise                              // clockwise
4002                                  { NORTHBIT|EASTBIT, EASTBIT, SOUTHBIT|EASTBIT, SOUTHBIT,                              { NORTHBIT|EASTBIT, EASTBIT, SOUTHBIT|EASTBIT, SOUTHBIT,
4003                                    SOUTHBIT|WESTBIT, WESTBIT, NORTHBIT|WESTBIT, NORTHBIT }                                SOUTHBIT|WESTBIT, WESTBIT, NORTHBIT|WESTBIT, NORTHBIT }
4004                              };                          };
4005    
4006                              DirectionBits possible_impulses =                          DirectionBits possible_impulses =
4007                                  static_cast<DirectionBits>(impulse_dir[clockwise][idx_target]);                              static_cast<DirectionBits>(impulse_dir[clockwise][idx_target]);
4008    
4009                              for (int d = 0; d<4; ++d) {                          for (int d = 0; d<4; ++d) {
4010                                  if (has_dir(possible_impulses, Direction(d))) {                              if (has_dir(possible_impulses, Direction(d))) {
4011                                      SendImpulse(ac_target_pos, Direction(d), *ac);                                  SendImpulse(ac_target_pos, Direction(d), *ac);
                                 }  
4012                              }                              }
4013                            }
4014    
4015                              if (GetStone(ac_target_pos) == 0) { // arm disappeared                          if (GetStone(ac_target_pos) == 0) { // arm disappeared
4016                                  break;                              break;
                             }  
4017                          }                          }
                         // fall-through (if arm didn't rotate or other stone was blocking)  
                     }  
                     case SHATTER: {  
                         SendMessage(*ac, "shatter");  
                         break;  
4018                      }                      }
4019                        // fall-through (if arm didn't rotate or other stone was blocking)
4020                    }
4021                    case SHATTER:
4022                        SendMessage(*ac, "shatter");
4023                        break;
4024                  }                  }
4025    
4026                  // @@@ FIXME: it's possible that two actors are moved to the same destination field.                  // @@@ FIXME: it's possible that two actors are moved to the same destination field.
# Line 4184  Turnstile_Pivot_Base::remove_arms (Direc Line 4151  Turnstile_Pivot_Base::remove_arms (Direc
4151  void  void
4152  Turnstile_Pivot_Base::set_arms (DirectionBits arms)  Turnstile_Pivot_Base::set_arms (DirectionBits arms)
4153  {  {
     GridPos p = get_pos();  
4154      if (arms & NORTHBIT) set_arm(NORTH);      if (arms & NORTHBIT) set_arm(NORTH);
4155      if (arms & EASTBIT)  set_arm(EAST);      if (arms & EASTBIT)  set_arm(EAST);
4156      if (arms & SOUTHBIT) set_arm(SOUTH);      if (arms & SOUTHBIT) set_arm(SOUTH);
# Line 4240  Turnstile_Pivot_Base::rotate_left() Line 4206  Turnstile_Pivot_Base::rotate_left()
4206          set_arms(rotate(arms, false));          set_arms(rotate(arms, false));
4207          warpActorsInRange(false);          warpActorsInRange(false);
4208    
4209          display::GetStatusBar()->set_counter(player::IncMoveCounter());          player::IncMoveCounter();
4210      }      }
4211      return can_rotate;      return can_rotate;
4212  }  }
# Line 4278  Turnstile_Pivot_Base::rotate_right() Line 4244  Turnstile_Pivot_Base::rotate_right()
4244          set_arms(rotate(arms, true));          set_arms(rotate(arms, true));
4245          warpActorsInRange(true);          warpActorsInRange(true);
4246    
4247          display::GetStatusBar()->set_counter(player::IncMoveCounter());          player::IncMoveCounter();
4248      }      }
4249      return can_rotate;      return can_rotate;
4250  }  }
# Line 4410  ObjectRepos::ObjectRepos() Line 4376  ObjectRepos::ObjectRepos()
4376      add_templ(new RubberBandStone);      add_templ(new RubberBandStone);
4377    
4378      add_templ(new ShogunStone);      add_templ(new ShogunStone);
4379      add_templ(new Shogun_S);      add_templ("st-shogun-s", new ShogunStone(1));
4380      add_templ(new Shogun_M);      add_templ("st-shogun-m", new ShogunStone(2));
4381      add_templ(new Shogun_SM);      add_templ("st-shogun-sm", new ShogunStone(3));
4382      add_templ(new Shogun_L);      add_templ("st-shogun-l", new ShogunStone(4));
4383      add_templ(new Shogun_SL);      add_templ("st-shogun-sl", new ShogunStone(5));
4384      add_templ(new Shogun_ML);      add_templ("st-shogun-ml", new ShogunStone(6));
4385      add_templ(new Shogun_SML);      add_templ("st-shogun-sml", new ShogunStone(7));
4386    
4387      add_templ(new ActorImpulseStone);      add_templ(new ActorImpulseStone);
4388      add_templ(new ActorImpulseStoneInvisible);      add_templ(new ActorImpulseStoneInvisible);

Legend:
Removed from v.1.63  
changed lines
  Added in v.1.64

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