/[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.55 by reallysoft, Thu May 1 09:17:33 2003 UTC revision 1.56 by reallysoft, Sat May 3 07:16:34 2003 UTC
# Line 536  Stone::collision_sound() Line 536  Stone::collision_sound()
536      return "st-stone";      return "st-stone";
537  }  }
538    
539    bool Stone::move_stone(Direction dir) {
540        GridPos p      = get_pos();
541        GridPos newPos = move(p, dir);
542    
543        if (!GetStone(newPos)) {
544            play_sound("st-move");
545            SetStone(newPos, YieldStone(p));
546            on_move();
547            if (Item *it = GetItem(newPos)) it->on_stonehit(this);
548    
549            return true;
550        }
551        return false;
552    }
553    
554    
555  //----------------------------------------  //----------------------------------------
556  // SimpleStone  // SimpleStone
557  //  //
# Line 1552  namespace Line 1568  namespace
1568    
1569          void alarm() {          void alarm() {
1570              state = MOVING;              state = MOVING;
1571              GridPos p = get_pos();              GridPos p = get_pos();
1572    #if defined(USE_IMPULSES)
1573                if (move_stone(get_dir())) {
1574    #else
1575              if (world::MaybeMoveStone(p, get_dir())) {              if (world::MaybeMoveStone(p, get_dir())) {
1576    #endif // USE_IMPULSES
1577                  // send a message to the stone that's blocking our way                  // send a message to the stone that's blocking our way
1578                  Stone *st = GetStone(move(move(p,get_dir()),get_dir()));                  Stone *st = GetStone(move(move(p,get_dir()),get_dir()));
1579                  if( st)                  if( st) SendMessage(st, "trigger");
                     SendMessage(st, "trigger");  
1580              }              }
1581              state = IDLE;              state = IDLE;
1582          }          }
# Line 1677  namespace Line 1696  namespace
1696          bool on_laserhit(Direction dir) {          bool on_laserhit(Direction dir) {
1697              return get_connections() == 0;              return get_connections() == 0;
1698          }          }
1699    #if defined(USE_IMPULSES)
1700            virtual void on_impulse(Direction dir);
1701    #endif // USE_IMPULSES
1702    
1703          void init_model();          void init_model();
1704          StoneResponse collision_response(const StoneContact &sc);          StoneResponse collision_response(const StoneContact &sc);
# Line 1876  PuzzleStone::collision_response(const St Line 1898  PuzzleStone::collision_response(const St
1898      return STONE_REBOUND;      return STONE_REBOUND;
1899  }  }
1900    
1901    #if defined(USE_IMPULSES)
1902    void
1903    PuzzleStone::on_impulse(Direction dir) {
1904    //     fprintf(stderr, "PuzzleStone::on_impulse(%s)\n", to_suffix(dir).c_str());
1905        Cluster c;
1906        bool    is_complete = find_cluster(c);
1907        maybe_move_cluster(c, is_complete, dir);
1908    }
1909    
1910    void
1911    PuzzleStone::actor_hit(const StoneContact &sc)
1912    {
1913        if (get_connections() == NODIRBIT)
1914            return;
1915    
1916        Actor *a = sc.actor;
1917    
1918        bool move_impulse= (a->get_vel()*sc.normal < -4);
1919        Direction hit_dir=reverse(contact_face(sc));
1920    
1921        if (wielded_item_is(a, "it-magicwand")) {
1922            if (cluster_complete()) {
1923                // make all cluster stones explode
1924                return;
1925            }
1926            else if (hit_dir != NODIR) {
1927                Cluster c;
1928                find_row_or_column_cluster(c, get_pos(), hit_dir);
1929    
1930                bool is_complete = false;
1931    
1932                if (move_impulse)
1933                    maybe_move_cluster(c, is_complete, hit_dir);
1934                else
1935                    rotate_cluster(c);
1936            }
1937        }
1938        else if (move_impulse && hit_dir != NODIR) {
1939            SendImpulse(get_pos(), hit_dir);
1940        }
1941    }
1942    #else
1943  void  void
1944  PuzzleStone::actor_hit(const StoneContact &sc)  PuzzleStone::actor_hit(const StoneContact &sc)
1945  {  {
# Line 1910  PuzzleStone::actor_hit(const StoneContac Line 1974  PuzzleStone::actor_hit(const StoneContac
1974          maybe_move_cluster(c, is_complete, hit_dir);          maybe_move_cluster(c, is_complete, hit_dir);
1975      }      }
1976  }  }
1977    #endif // USE_IMPULSES
1978    
1979    
1980  //----------------------------------------  //----------------------------------------
# Line 2509  namespace Line 2574  namespace
2574              notify_item(false);              notify_item(false);
2575          }          }
2576    
2577    #if defined(USE_IMPULSES)
2578            void on_impulse(Direction dir);
2579    #endif // USE_IMPULSES
2580    
2581          void init_model() {          void init_model() {
2582              char x[20];              char x[20];
2583              sprintf(x, "st-shogun%d", int(get_holes()));              sprintf(x, "st-shogun%d", int(get_holes()));
# Line 2631  ShogunStone::transfer_smallest_hole(Grid Line 2700  ShogunStone::transfer_smallest_hole(Grid
2700      return nh;      return nh;
2701  }  }
2702    
2703    #if defined(USE_IMPULSES)
2704    void
2705    ShogunStone::actor_hit(const StoneContact &sc)
2706    {
2707        Actor     *a            = sc.actor;
2708        bool       move_impulse = (a->get_vel()*sc.normal < -4);
2709        Direction  hit_dir      = reverse(contact_face(sc));
2710    
2711        if (hit_dir == NODIR || !move_impulse)
2712            return;
2713    
2714        SendImpulse(get_pos(), hit_dir);
2715    }
2716    
2717    void
2718    ShogunStone::on_impulse(Direction dir) {
2719    //     fprintf(stderr, "ShogunStone::on_impulse(%s)\n", to_suffix(dir).c_str());
2720        Holes holes    = get_holes();
2721        Holes newholes = transfer_smallest_hole(move(get_pos(), dir));
2722    
2723        if (newholes != holes) {
2724            play_sound("st-move");
2725        }
2726    }
2727    
2728    #else
2729  void  void
2730  ShogunStone::actor_hit(const StoneContact &sc)  ShogunStone::actor_hit(const StoneContact &sc)
2731  {  {
# Line 2648  ShogunStone::actor_hit(const StoneContac Line 2743  ShogunStone::actor_hit(const StoneContac
2743          play_sound("st-move");          play_sound("st-move");
2744      }      }
2745  }  }
2746    #endif // USE_IMPULSES
2747    
2748    
2749  //----------------------------------------  //----------------------------------------
# Line 2854  namespace Line 2950  namespace
2950              else if (state == CLOSING)              else if (state == CLOSING)
2951                  change_state (IDLE);                  change_state (IDLE);
2952          }          }
2953    
2954    #if defined(USE_IMPULSES)
2955            virtual void on_impulse(Direction dir) {
2956    //             fprintf(stderr, "StoneImpulse_Base::on_impulse(%s)\n", to_suffix(dir).c_str());
2957                change_state(PULSING);
2958            }
2959    #endif // USE_IMPULSES
2960      };      };
2961    
2962  }  }
# Line 2867  StoneImpulse_Base::change_state(State st Line 2970  StoneImpulse_Base::change_state(State st
2970      switch (st) {      switch (st) {
2971      case PULSING:      case PULSING:
2972          if (state != IDLE)          if (state != IDLE)
2973              return; // do not set new state              return;             // do not set new state
2974          play_sound("impulse");          play_sound("impulse");
2975          break;          break;
2976      case CLOSING:      case CLOSING:
2977          MaybeMoveStone( move( p, NORTH), NORTH);          {
2978          MaybeMoveStone( move( p, EAST), EAST);  #if defined(USE_IMPULSES)
2979          MaybeMoveStone( move( p, SOUTH), SOUTH);  
2980          MaybeMoveStone( move( p, WEST), WEST);              // @@@ FIXME: Send impulses in a defined order depending
2981          SendMessage (GetStone(move(p, NORTH)), "stoneimpulse");              // on the direction of the initial impulse
2982          SendMessage (GetStone(move(p, EAST)), "stoneimpulse");  
2983          SendMessage (GetStone(move(p, SOUTH)), "stoneimpulse");              GridPos targetpos[4];
2984          SendMessage (GetStone(move(p, WEST)), "stoneimpulse");              bool    haveStone[4];
2985          break;  
2986                for (int d = 0; d < 4; ++d) {
2987                    targetpos[d] = move(p, Direction(d));
2988                    haveStone[d] = GetStone(targetpos[d]) != 0;
2989                }
2990    
2991                for (int d = 0; d < 4; ++d) {
2992                    if (haveStone[d]) {
2993                        SendImpulse(targetpos[d], Direction(d));
2994                    }
2995                }
2996                //         SendImpulse(move(p, NORTH), NORTH);
2997                //         SendImpulse(move(p, EAST), EAST);
2998                //         SendImpulse(move(p, SOUTH), SOUTH);
2999                //         SendImpulse(move(p, WEST), WEST);
3000    #else
3001                MaybeMoveStone( move( p, NORTH), NORTH);
3002                MaybeMoveStone( move( p, EAST), EAST);
3003                MaybeMoveStone( move( p, SOUTH), SOUTH);
3004                MaybeMoveStone( move( p, WEST), WEST);
3005                SendMessage (GetStone(move(p, NORTH)), "stoneimpulse");
3006                SendMessage (GetStone(move(p, EAST)), "stoneimpulse");
3007                SendMessage (GetStone(move(p, SOUTH)), "stoneimpulse");
3008                SendMessage (GetStone(move(p, WEST)), "stoneimpulse");
3009    #endif // USE_IMPULSES
3010                break;
3011            }
3012      case IDLE:      case IDLE:
3013          init_model();          init_model();
3014          break;          break;
# Line 2980  namespace Line 3109  namespace
3109    
3110          // Stone interface:          // Stone interface:
3111    
3112    #if defined(USE_IMPULSES)
3113            void on_impulse(Direction dir) {
3114    //             fprintf(stderr, "MovableImpulseStone::on_impulse(%s)\n", to_suffix(dir).c_str());
3115                if (!move_stone(dir)) {
3116                    change_state(PULSING);
3117                }
3118                // otherwise on_move changes state to PULSING
3119            }
3120            void actor_hit(const StoneContact &sc) {
3121                ActorInfo *ai  = sc.actor->get_actorinfo();
3122                Direction  dir = contact_face(sc);
3123    
3124                if (dir!=enigma::NODIR && ai->vel * sc.normal < -4) {
3125                    SendImpulse(get_pos(), reverse(dir));
3126                }
3127                else {
3128                    change_state(PULSING);
3129                }
3130            }
3131    
3132    #else
3133          void actor_hit(const StoneContact &sc)          void actor_hit(const StoneContact &sc)
3134          {          {
3135              ActorInfo *ai = sc.actor->get_actorinfo();              ActorInfo *ai = sc.actor->get_actorinfo();
# Line 3000  namespace Line 3150  namespace
3150              if (!moved) change_state(PULSING);              if (!moved) change_state(PULSING);
3151          }          }
3152    
3153    #endif // USE_IMPULSES
3154    
3155          void on_move() {          void on_move() {
3156              if (state != IDLE) change_state(IDLE);              if (state != IDLE) change_state(IDLE);
3157              if (state == IDLE) change_state(PULSING);              if (state == IDLE) change_state(PULSING);
# Line 3781  namespace Line 3933  namespace
3933          void animcb() {          void animcb() {
3934              set_model("st-turnstile");              set_model("st-turnstile");
3935          }          }
3936    
3937            void warpItemsInRange(bool clockwise);
3938      };      };
3939    
3940      /*      /*
# Line 3790  namespace Line 3944  namespace
3944          virtual Direction get_dir() const = 0;          virtual Direction get_dir() const = 0;
3945    
3946          void actor_hit(const StoneContact &sc);          void actor_hit(const StoneContact &sc);
3947    #if defined(USE_IMPULSES  )
3948            void on_impulse(Direction dir);
3949    #endif // USE_IMPULSES
3950    
3951          Turnstile_Pivot *get_pivot()          Turnstile_Pivot *get_pivot()
3952          {          {
# Line 3847  namespace Line 4004  namespace
4004      };      };
4005  }  }
4006    
4007    #if defined(USE_IMPULSES)
4008    
4009    void
4010    Turnstile_Pivot::warpItemsInRange(bool clockwise) {
4011        GridPos        pv_pos = get_pos();
4012        V2             pv_center(pv_pos.x+.5, pv_pos.y+.5);
4013        vector<Actor*> actorsInRange;
4014    
4015        if (GetActorsInRange(pv_center, 2.0, actorsInRange)) {
4016            for (vector<Actor*>::iterator ac = actorsInRange.begin(); ac != actorsInRange.end(); ++ac) {
4017                const V2& ac_center = (*ac)->get_pos();
4018                GridPos   ac_pos(ac_center);
4019    
4020    //             fprintf(stderr, "actor detected on position %i/%i\n", ac_pos.x, ac_pos.y);
4021    
4022    //             int x = acpos.x-pvpos.x;
4023    //             int y = acpos.y-pvpos.y;
4024    
4025    //             int xd = -y; // clockwise
4026    //             int yd =  x;
4027    
4028                V2 to_actor    = ac_center-pv_center;
4029                V2 to_newactor = clockwise
4030                    ? V2(-to_actor[1], to_actor[0])
4031                    : V2(to_actor[1], -to_actor[0]);
4032    
4033                V2 new_actor = pv_center+to_newactor;
4034    
4035                world::WarpActor(*ac, new_actor[0], new_actor[1]);
4036            }
4037        }
4038    
4039        // @@@ FIXME: warp items ?
4040    }
4041    
4042    void
4043    Turnstile_Arm::on_impulse(Direction dir) {
4044        enum Action { ROTL, ROTR, NOTHING };
4045        static Action actions[4][4] = {
4046            { NOTHING, ROTL, NOTHING, ROTR }, // west arm
4047            { ROTR, NOTHING, ROTL, NOTHING }, // south arm
4048            { NOTHING, ROTR, NOTHING, ROTL }, // east arm
4049            { ROTL, NOTHING, ROTR, NOTHING } // north arm
4050        };
4051    
4052        Turnstile_Pivot *pivot = get_pivot();
4053    
4054        if (pivot) {
4055            Action a = actions[get_dir()][dir];
4056            GridPos pos = move(get_pos(), dir);
4057            V2 destpos (pos.x + 0.5, pos.y + 0.5);
4058            if (a == ROTL) {
4059                if (pivot->rotate_left ()) {
4060    //                 fprintf(stderr, "rotate-left (actor-warp currently inactive)\n");
4061    //                 world::WarpActor (sc.actor, destpos[0], destpos[1]);
4062                }
4063            }
4064            else if (a == ROTR) {
4065                if (pivot->rotate_right ()) {
4066    //                 fprintf(stderr, "rotate-right (actor-warp currently inactive)\n");
4067    //                 world::WarpActor (sc.actor, destpos[0], destpos[1]);
4068                }
4069            }
4070        }
4071        else {
4072            // Move arms not attached to a pivot individually
4073            move_stone(dir);
4074        }
4075    }
4076    
4077    void
4078    Turnstile_Arm::actor_hit(const StoneContact &sc)
4079    {
4080        ActorInfo *ai = sc.actor->get_actorinfo();
4081        Direction dir = reverse(contact_face(sc));
4082        if (dir!=enigma::NODIR && ai->vel * sc.normal < -4)
4083        {
4084            SendImpulse(get_pos(), dir);
4085        }
4086    }
4087    
4088    #else
4089    
4090  void  void
4091  Turnstile_Arm::actor_hit(const StoneContact &sc)  Turnstile_Arm::actor_hit(const StoneContact &sc)
4092  {  {
# Line 3884  Turnstile_Arm::actor_hit(const StoneCont Line 4124  Turnstile_Arm::actor_hit(const StoneCont
4124      }      }
4125  }  }
4126    
4127    #endif // USE_IMPULSES
4128    
4129  // void  // void
4130  // Turnstile_Pivot::animcb()  // Turnstile_Pivot::animcb()
# Line 3979  Turnstile_Pivot::rotate_left() Line 4220  Turnstile_Pivot::rotate_left()
4220          if (arms & EASTBIT) set_arm (NORTH);          if (arms & EASTBIT) set_arm (NORTH);
4221          if (arms & SOUTHBIT) set_arm (EAST);          if (arms & SOUTHBIT) set_arm (EAST);
4222          if (arms & WESTBIT) set_arm (SOUTH);          if (arms & WESTBIT) set_arm (SOUTH);
4223    
4224    #if defined(USE_IMPULSES)
4225            warpItemsInRange(false);
4226    #endif // USE_IMPULSES
4227      }      }
4228      return can_rotate;      return can_rotate;
4229  }  }
# Line 4019  Turnstile_Pivot::rotate_right() Line 4264  Turnstile_Pivot::rotate_right()
4264          if (arms & EASTBIT) set_arm (SOUTH);          if (arms & EASTBIT) set_arm (SOUTH);
4265          if (arms & SOUTHBIT) set_arm (WEST);          if (arms & SOUTHBIT) set_arm (WEST);
4266          if (arms & WESTBIT) set_arm (NORTH);          if (arms & WESTBIT) set_arm (NORTH);
4267    
4268    #if defined(USE_IMPULSES)
4269            warpItemsInRange(true);
4270    #endif // USE_IMPULSES
4271      }      }
4272      return can_rotate;      return can_rotate;
4273  }  }

Legend:
Removed from v.1.55  
changed lines
  Added in v.1.56

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