void Actor::pushCreatures(Tile* tile) { //We can not use iterators here since we can push a creature to another tile //which will invalidate the iterator. uint32_t removeCount = 0; int32_t creaturesCount = tile->creatures_count(); for(int32_t i = creaturesCount - 1; i >= 0; --i){ for(uint32_t i = 0; i < tile->creatures_count();){ Actor* actor = tile->creatures_get(i)->getActor(); if(actor && actor->isPushable()){ if(pushCreature(actor)){ continue; } else{ actor->changeHealth(-actor->getHealth()); actor->setDropLoot(false); removeCount++; } } ++i; } if(removeCount > 0){ g_game.addMagicEffect(tile->getPosition(), MAGIC_EFFECT_YELLOW_SPARK); } } }
void Monster::pushCreatures(Tile* tile) { //We can not use iterators here since we can push a creature to another tile //which will invalidate the iterator. if(CreatureVector* creatures = tile->getCreatures()) { uint32_t removeCount = 0; for(uint32_t i = 0; i < creatures->size();) { Monster* monster = creatures->at(i)->getMonster(); if(monster && monster->isPushable()) { if(pushCreature(monster)) continue; else { monster->changeHealth(-monster->getHealth()); monster->setDropLoot(false); removeCount++; } } ++i; } if(removeCount > 0) g_game.addMagicEffect(tile->getPosition(), NM_ME_BLOCKHIT); } }
void Monster::pushCreatures(Tile* tile) { CreatureVector* creatures = tile->getCreatures(); if(!creatures) return; bool effect = false; Monster* monster = NULL; for(uint32_t i = 0; i < creatures->size();) { if((monster = creatures->at(i)->getMonster()) && monster->isPushable()) { if(pushCreature(monster)) continue; monster->setDropLoot(LOOT_DROP_NONE); monster->changeHealth(-monster->getHealth()); if(!effect) effect = true; } ++i; } if(effect) g_game.addMagicEffect(tile->getPosition(), MAGIC_EFFECT_BLOCKHIT); }
void shMapLevel::moveWalls (int action) { shFeature *f; int north = (1 == action or -1 == action) ? 1 : 0; int squares[20]; int n = 0; int x, y; int i, j; int seen = 0; int interrupt = 0; int heard = 0; // move the wall y = -1; for (i = 0; i < mFeatures.count (); i++) { f = mFeatures.get (i); if (shFeature::kMovingHWall != f->mType) { continue; } if (action > 0) { /* close in */ if (north and f->mMovingHWall.mBeginY < f->mMovingHWall.mEndY and f->mY < f->mMovingHWall.mEndY) { //if (Hero.canSee (f->mX, f->mY)) // setMemory (f->mX, f->mY, ' '); mVisibility[f->mX][f->mY] = 0; y = f->mY + 1; squares[n++] = f->mX; f->mY++; addMachinery (f->mX, f->mY-1); } else if (!north and f->mMovingHWall.mBeginY > f->mMovingHWall.mEndY and f->mY > f->mMovingHWall.mEndY) { //if (Hero.canSee (f->mX, f->mY)) // setMemory (f->mX, f->mY, ' '); mVisibility[f->mX][f->mY] = 0; y = f->mY - 1; squares[n++] = f->mX; f->mY--; addMachinery (f->mX, f->mY+1); } else { continue; } if (Hero.canSee (f->mX, f->mY)) { interrupt++; seen++; } else if (distance (&Hero, f->mX, f->mY) < 100) { heard++; } } else if (action < 0) { /* reset */ int oldy = f->mY; if (north and f->mMovingHWall.mBeginY < f->mMovingHWall.mEndY and f->mY > f->mMovingHWall.mBeginY) { y = f->mY - 1; shFeature *machinery = getFeature (f->mX, y); if (machinery) removeFeature (machinery); f->mY--; } else if (!north and f->mMovingHWall.mBeginY > f->mMovingHWall.mEndY and f->mY < f->mMovingHWall.mBeginY) { y = f->mY + 1; shFeature *machinery = getFeature (f->mX, y); if (machinery) removeFeature (machinery); f->mY++; } else { continue; } if (Hero.canSee (f->mX, oldy)) interrupt++; } } if (!Hero.getStoryFlag ("walls moving")) { if (seen) { I->p ("The walls are moving!"); Hero.setStoryFlag ("walls moving", 1); } else if (heard and !Hero.getStoryFlag ("walls heard")) { I->p ("You hear a loud rumbling!"); Hero.setStoryFlag ("walls heard", 1); } } // displace objects and creatures if (n) { shuffle (squares, n, sizeof(int)); for (i = 0; i < n; i++) { x = squares[i]; shObjectVector *v = getObjects (x, y); if (v) { int y2 = north ? y + 1 : y - 1; int safe = !isObstacle (x, y2); for (j = 0; j < v->count (); j++) { shObject *obj = v->get (j); if (safe) { putObject (obj, x, y2); } else { delete obj; } } if (Hero.mX == x and Hero.mY == y2) { I->p ("%s pushed into your vicinity.", v->count () > 1 ? "Some objects are" : "An object is"); } delete v; setObjects (x, y, NULL); } shCreature *c = getCreature (x, y); if (c) { if (c->mZ < 0) { if (c->isHero ()) { I->p ("You are sealed below the moving wall!"); I->p ("That's not supposed to be possible!"); I->p ("Please send me a bug report! -cyrus"); } } else { pushCreature (c, north ? kSouth : kNorth); } } } } if (interrupt) Hero.interrupt (); }