enigma-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Enigma-cvs] enigma/src actors.cc,1.43,1.44


From: Ralf Westram <address@hidden>
Subject: [Enigma-cvs] enigma/src actors.cc,1.43,1.44
Date: Mon, 20 Oct 2003 17:03:51 +0000

Update of /cvsroot/enigma/enigma/src
In directory subversions:/tmp/cvs-serv21529/src

Modified Files:
        actors.cc 
Log Message:
- warning fixes
- respawning actors search for a free starting position
- added find_respawnpos()



Index: actors.cc
===================================================================
RCS file: /cvsroot/enigma/enigma/src/actors.cc,v
retrieving revision 1.43
retrieving revision 1.44
diff -C2 -d -r1.43 -r1.44
*** actors.cc   20 Oct 2003 08:05:45 -0000      1.43
--- actors.cc   20 Oct 2003 17:03:48 -0000      1.44
***************
*** 28,31 ****
--- 28,32 ----
  #include <cassert>
  #include <iostream>
+ #include <set>
  
  using px::V2;
***************
*** 46,50 ****
  }
  
! void Actor::think(double dtime) {
      GridPos  field(actorinfo.pos);
      Floor *fl = GetFloor(field);
--- 47,51 ----
  }
  
! void Actor::think(double /*dtime*/) {
      GridPos  field(actorinfo.pos);
      Floor *fl = GetFloor(field);
***************
*** 55,59 ****
  }
  
! void Actor::set_respawnpos(const V2& p) 
  {
      respawnpos     = p;
--- 56,60 ----
  }
  
! void Actor::set_respawnpos(const V2& p)
  {
      respawnpos     = p;
***************
*** 65,68 ****
--- 66,186 ----
  }
  
+ namespace {
+ 
+     struct ExaminedLocation : public GridPos {
+     public:
+         ExaminedLocation(GridPos p) : GridPos(p) {}
+ 
+         bool operator<(const ExaminedLocation& other) const {
+             return (x == other.x) ? y<other.y : x<other.x;
+         }
+     };
+ 
+     typedef std::set<ExaminedLocation> ExaminedLocations;
+ 
+     class FreeRespawnLocationFinder {
+         ExaminedLocations checked;
+         ExaminedLocations blocked;
+         ExaminedLocations candidates;
+ 
+         void examine(GridPos p) {
+             if (checked.find(p) == checked.end()) {
+ 
+                 if (Floor *fl = GetFloor(p)) {
+                     const string& k = fl->get_kind();
+                     if (k != "fl-abyss" && k != "fl-water" && k != 
"fl-space") { // good destination floor
+                         if (Stone *st = GetStone(p)) {
+                             if (st->is_movable() || st->is_floating())
+                                 blocked.insert(p);
+                         }
+                         else
+                             candidates.insert(p); // no stone -> good location
+                     }
+                 }
+ 
+                 checked.insert(p); // don't examine position multiple times
+             }
+         }
+ 
+     public:
+         FreeRespawnLocationFinder(GridPos p) {
+             blocked.insert(p);
+             checked.insert(p);
+ 
+             while (candidates.empty()) {
+                 ExaminedLocations curr_blocked;
+                 swap(curr_blocked, blocked);
+ 
+                 if (curr_blocked.empty())
+                     break; // no chance to find a candidate
+ 
+                 for (ExaminedLocations::const_iterator bl = 
curr_blocked.begin(); bl != curr_blocked.end(); ++bl) {
+                     examine(move(*bl, NORTH));
+                     examine(move(*bl, SOUTH));
+                     examine(move(*bl, EAST));
+                     examine(move(*bl, WEST));
+                 }
+             }
+ 
+             if (candidates.empty())
+                 candidates.insert(p); // if no location found -> use original 
respawn position
+         }
+ 
+         GridPos choose() const {
+             assert(!candidates.empty());
+ 
+             ExaminedLocations::const_iterator c = candidates.begin();
+             advance(c, IntegerRand(0, candidates.size()-1));
+ 
+             assert(c != candidates.end());
+ 
+             return *c;
+         }
+ 
+     };
+ }
+ 
+ void
+ Actor::find_respawnpos()
+ {
+     if (!use_respawnpos) {
+         GridPos non_blocking;
+         bool    non_blocking_found = false;
+         bool    blocking_found     = false;
+ 
+         // check all fields that may overlap with respawn position
+         for (int xoff = -1; xoff <= 1; ++xoff) {
+             for (int yoff = -1; yoff <= 1; ++yoff) {
+                 double x = startingpos[0] + xoff*.4;
+                 double y = startingpos[1] + yoff*.4;
+ 
+                 GridPos odest(V2(x, y));
+ 
+                 if (GetStone(odest) != 0) {
+                     blocking_found = true;
+                 }
+                 else {
+                     non_blocking_found = true;
+                     non_blocking       = odest;
+                 }
+             }
+         }
+ 
+         if (blocking_found) {
+             if (non_blocking_found) {
+                 // this only happens when the old startingpos was not
+                 // in the center of a GridPos
+                 startingpos = non_blocking.center();
+             }
+             else {
+                 GridPos                   dest(startingpos);
+                 FreeRespawnLocationFinder unblocked(dest);
+                 GridPos                   new_dest = unblocked.choose();
+ 
+                 startingpos = new_dest.center();
+             }
+         }
+     }
+ }
  
  void Actor::respawn() {
***************
*** 108,114 ****
      if (field != ofield) {
          // Actor entered a new field -> notify floor and item objects
!         if (Floor *fl = GetFloor(field)) 
            fl->actor_enter(this);
!         if (Item *it = GetItem(field)) 
            it->actor_enter(this);
  
--- 226,232 ----
      if (field != ofield) {
          // Actor entered a new field -> notify floor and item objects
!         if (Floor *fl = GetFloor(field))
            fl->actor_enter(this);
!         if (Item *it = GetItem(field))
            it->actor_enter(this);
  
***************
*** 291,296 ****
          };
  
!         enum HaloState { 
!             NOHALO, HALOBLINK, HALONORMAL 
          };
  
--- 409,414 ----
          };
  
!         enum HaloState {
!             NOHALO, HALOBLINK, HALONORMAL
          };
  
***************
*** 379,402 ****
  
  bool BasicBall::is_dead()
! { 
!     return state == DEAD; 
  }
  
  
  bool BasicBall::is_on_floor()
! { 
!     return state == NORMAL || state == SINKING || 
!         state == JUMP_VORTEX || state==APPEARING; 
  }
  
! bool BasicBall::can_drop_items()   
! { 
!     return state == NORMAL || state == SINKING || 
!         state == JUMP_VORTEX || state==JUMPING; 
  }
  
! bool BasicBall::can_pickup_items() 
! { 
!     return state == NORMAL || state == SINKING || state == JUMP_VORTEX; 
  }
  
--- 497,520 ----
  
  bool BasicBall::is_dead()
! {
!     return state == DEAD;
  }
  
  
  bool BasicBall::is_on_floor()
! {
!     return state == NORMAL || state == SINKING ||
!         state == JUMP_VORTEX || state==APPEARING;
  }
  
! bool BasicBall::can_drop_items()
! {
!     return state == NORMAL || state == SINKING ||
!         state == JUMP_VORTEX || state==JUMPING;
  }
  
! bool BasicBall::can_pickup_items()
! {
!     return state == NORMAL || state == SINKING || state == JUMP_VORTEX;
  }
  
***************
*** 440,444 ****
          break;
      case APPEARING:
!       if ((m == "shatter" || m == "drown" || m == "fall") 
            && !has_shield())
        {
--- 558,562 ----
          break;
      case APPEARING:
!       if ((m == "shatter" || m == "drown" || m == "fall")
            && !has_shield())
        {
***************
*** 663,667 ****
  }
  
! void 
  BasicBall::disable_shield()
  {
--- 781,785 ----
  }
  
! void
  BasicBall::disable_shield()
  {
***************
*** 759,763 ****
          void on_hit(Actor *a) {
              if (dynamic_cast<BlackBall*>(a) &&
!                 int_attrib("mouseforce") != 0) 
                  // passive small whiteball do not shatter (see PerOxyd 
Linkgame #60)
              {
--- 877,881 ----
          void on_hit(Actor *a) {
              if (dynamic_cast<BlackBall*>(a) &&
!                 int_attrib("mouseforce") != 0)
                  // passive small whiteball do not shatter (see PerOxyd 
Linkgame #60)
              {





reply via email to

[Prev in Thread] Current Thread [Next in Thread]