[Top][All Lists]
[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)
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Enigma-cvs] enigma/src actors.cc,1.43,1.44,
Ralf Westram <address@hidden> <=
- Prev by Date:
[Enigma-cvs] enigma/src floors.cc, 1.2, 1.3 items.cc, 1.89, 1.90 stones_simple.cc, 1.56, 1.57 world.cc, 1.74, 1.75
- Next by Date:
[Enigma-cvs] enigma/src objects.hh,1.52,1.53
- Previous by thread:
[Enigma-cvs] enigma/src floors.cc, 1.2, 1.3 items.cc, 1.89, 1.90 stones_simple.cc, 1.56, 1.57 world.cc, 1.74, 1.75
- Next by thread:
[Enigma-cvs] enigma/src objects.hh,1.52,1.53
- Index(es):