int doDispelMagic(Creature* player, cmd* cmnd, SpellData* spellData, const char* spell, int numDispel) { Creature* target=0; int chance=0; if(spellData->how == CastType::CAST && player->getClass() != CreatureClass::MAGE && player->getClass() != CreatureClass::LICH && player->getClass() != CreatureClass::CLERIC && player->getClass() != CreatureClass::DRUID && !player->isStaff() ) { player->print("Only mages, liches, clerics, and druids may cast that spell.\n"); return(0); } if(cmnd->num == 2) { target = player; broadcast(player->getSock(), player->getParent(), "%M casts a %s spell on %sself.", player, spell, player->himHer()); player->print("You cast a %s spell on yourself.\n", spell); player->print("Your spells begin to dissolve away.\n"); player->doDispelMagic(numDispel); } else { if(player->noPotion( spellData)) return(0); cmnd->str[2][0] = up(cmnd->str[2][0]); target = player->getParent()->findPlayer(player, cmnd, 2); if(!target) { // dispel-magic on an exit cmnd->str[2][0] = low(cmnd->str[2][0]); Exit* exit = findExit(player, cmnd, 2); if(exit) { player->printColor("You cast a %s spell on the %s^x.\n", spell, exit->getCName()); broadcast(player->getSock(), player->getParent(), "%M casts a %s spell on the %s^x.", player, spell, exit->getCName()); if(exit->flagIsSet(X_PORTAL)) Move::deletePortal(player->getRoomParent(), exit); else exit->doDispelMagic(player->getRoomParent()); return(0); } player->print("You don't see that player here.\n"); return(0); } if(player->isPlayer() && player->getRoomParent()->isPkSafe() && (!player->isCt()) && !target->flagIsSet(P_OUTLAW)) { player->print("That spell is not allowed here.\n"); return(0); } if(!target->isEffected("petrification")) { if(!player->canAttack(target)) return(0); } else { player->print("You cast a %s spell on %N.\n%s body returns to flesh.\n", spell, target, target->upHisHer()); if(mrand(1,100) < 50) { target->print("%M casts a %s spell on you.\nYour body returns to flesh.\n", player, spell); broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts a %s spell on %N.\n%s body returns to flesh.\n", player, spell, target, target->upHisHer()); target->removeEffect("petrification"); return(1); } else { target->print("%M casts a dispel-magic spell on you.\n", player); broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts a dispel-magic spell on %N.\n",player, target); return(0); } } chance = 50 - (10*(bonus((int) player->intelligence.getCur()) - bonus((int) target->intelligence.getCur()))); chance += (spellData->level - target->getLevel())*10; chance = MIN(chance, 90); if((target->isEffected("resist-magic")) && target->isPlayer()) chance /=2; if( player->isCt() || (mrand(1,100) <= chance && !target->chkSave(SPL, player, 0))) { player->print("You cast a %s spell on %N.\n", spell, target); logCast(player, target, spell); broadcast(player->getSock(), target->getSock(), player->getParent(), "%M casts a %s spell on %N.", player, spell, target); target->print("%M casts a %s spell on you.\n", player, spell); target->print("Your spells begin to dissolve away.\n"); target->doDispelMagic(numDispel); for(Monster* pet : target->pets) { if(pet) { if(player->isCt() || !pet->chkSave(SPL, player, 0)) { player->print("Your spell bansished %N's %s!\n", target, pet->getCName()); target->print("%M's spell banished your %s!\n%M fades away.\n", player, pet->getCName(), pet); gServer->delActive(pet); pet->die(pet->getMaster()); } } } } else { player->printColor("^yYour spell fails against %N.\n", target); target->print("%M tried to cast a dispel-magic spell on you.\n", player); broadcast(player->getSock(), target->getSock(), player->getParent(), "%M tried to cast a dispel-magic spell on %N.", player, target); return(0); } } return(1); }
/** * Process mouse activity */ void MouseHandler::mouseHandler() { debugC(2, kDebugMouse, "mouseHandler"); Status &gameStatus = _vm->getGameStatus(); Istate inventState = _vm->_inventory->getInventoryState(); if ((gameStatus._viewState != kViewPlay) && (inventState != kInventoryActive)) return; int16 cx = getMouseX(); int16 cy = getMouseY(); // gameStatus._cx = cx; // Save cursor coords // gameStatus._cy = cy; // Don't process if outside client area if ((cx < 0) || (cx > kXPix) || (cy < kDibOffY) || (cy > kViewSizeY + kDibOffY)) return; int16 objId = -1; // Current source object // Process cursor over an object or icon if (inventState == kInventoryActive) { // Check inventory icon bar first objId = _vm->_inventory->processInventory(kInventoryActionGet, cx, cy); } else { if (cy < 5 && cy > 0) { _vm->_topMenu->runModal(); } } if (!gameStatus._gameOverFl) { if (objId == -1) // No match, check rest of view objId = _vm->_object->findObject(cx, cy); if (objId >= 0) { // Got a match // Display object name next to cursor (unless CURSOR_NOCHAR) // Note test for swapped hero name const char *name = _vm->_text->getNoun(_vm->_object->_objects[(objId == kHeroIndex) ? _vm->_heroImage : objId]._nounIndex, kCursorNameIndex); if (name[0] != kCursorNochar) cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE); // Process right click over object in view or iconbar if (_rightButtonFl) processRightClick(objId, cx, cy); } // Process cursor over an exit hotspot if (objId == -1) { int i = findExit(cx, cy, *_vm->_screenPtr); if (i != -1 && _hotspots[i]._viewx >= 0) { objId = kExitHotspot; cursorText(_vm->_text->getTextMouse(kMsExit), cx, cy, U_FONT8, _TBRIGHTWHITE); } } } // Left click over icon, object or to move somewhere if (_leftButtonFl) processLeftClick(objId, cx, cy); // Clear mouse click states resetLeftButton(); resetRightButton(); }
Building::Building(const string& filename){ //...............................................Ouverture de l'image: Image Level; if (!Level.loadFromFile(filename)) exit(-1); const Uint8* map = Level.getPixelsPtr(); //..............................................Construction de map_ : Vector2u size = Level.getSize(); length_ = size.y; width_ = size.x; map_ = new int[length_*width_]; for (int i=0; i<length_; i++){ for (int j=0; j<width_; j++){ int r = map[j*4 + size.x*4*i]; map_[j+width_*i] = 1-r%254; } } cout << filename << " successfully loaded." << endl; cout << "Height: " << length_ << endl; cout << "Width: " << width_ << endl; //.............................................. recherche des murs : unsigned int start = 0; bool state = false; for (int i=0; i<length_; i++){//horizontaux for (int j=0; j<width_; j++){ if (map_[j+width_*i] and not state){ start = j; state = true; } if (state and (not map_[j+width_*i] or j==width_-1)){ if (j-1-start){ RectangleShape wall(Vector2f(Building::ZOOM*(j-start+(j==width_-1)),Building::ZOOM)); wall.setPosition(Building::ZOOM*start, Building::ZOOM*i); walls_.push_back( wall ); } state = false; } } } for (int j=0; j<width_; j++){//verticaux for (int i=0; i<length_; i++){ if (map_[j+width_*i] and not state){ start = i; state = true; } if (state and (not map_[j+width_*i] or i==length_-1)){ if (i-1-start){ RectangleShape wall(Vector2f(Building::ZOOM,Building::ZOOM*(i-start+(i==length_-1)))); wall.setPosition(Building::ZOOM*j, Building::ZOOM*start); walls_.push_back( wall ); } state = false; } } } //..........................................repérage des angles de mur int s; xborders_.push_back(0.5); yborders_.push_back(0.5); for (int x=0; x<width_; x++){ for (int y=0; y<length_; y++){ s = 0; for (int i=-1; i<=1; i++){ for (int j=-1; j<=1; j++){ if (x+i<0 or y+j<0 or x+i==width_ or y+j==length_) continue; if (map_[y*width_+x] and (i+j)*(i+j)==1) s += map_[(y+j)*width_+x+i]; } } if ( s>0 and s!=2){ if(find(xborders_.begin(),xborders_.end(),x+0.5)==xborders_.end()) xborders_.push_back(x+0.5); if(find(yborders_.begin(),yborders_.end(),y+0.5)==yborders_.end()) yborders_.push_back(y+0.5); } } } cout << "number of x edges: " << int(xborders_.size()) << " ( "; for (unsigned int i=0; i<xborders_.size(); i++){ if (Building::SHOWWALLS){ RectangleShape wall(Vector2f(1,Building::ZOOM*length_)); wall.setPosition(Building::ZOOM*xborders_[i], 0); wall.setFillColor(Color::Red); walls_.push_back( wall ); } cout << xborders_[i]; cout << " "; } sort(yborders_.begin(), yborders_.end()); cout << ") meters\nnumber of y edges: " << int(yborders_.size()) << " ( "; for (unsigned int i=0; i<yborders_.size(); i++){ if (Building::SHOWWALLS){ RectangleShape wall(Vector2f(Building::ZOOM*width_,1)); wall.setPosition(0,Building::ZOOM*yborders_[i]); wall.setFillColor(Color::Red); walls_.push_back( wall ); } cout << yborders_[i]; cout << " "; } cout << ") meters\n"; //......................................... Recherche de la sortie : vector<int> xmin_; vector<int> xmax_; vector<int> ymin_; vector<int> ymax_; for( unsigned int i=0; i<xborders_.size()-1; i++){ for( unsigned int j=0; j<yborders_.size()-1; j++){ xmin_.push_back(xborders_[i]); xmax_.push_back(xborders_[i+1]); ymin_.push_back(yborders_[j]); ymax_.push_back(yborders_[j+1]); } } int w = 2*xborders_.size()-1; int l = 2*yborders_.size()-1; int* nodemap_ = new int[w*l]; for(int j=0; j<l; j++){ for(int i=0; i<w; i++){ nodemap_[ i+w*j ] = 0; if (not (i%2)) nodemap_[ i+w*j] = 1; if (not (j%2)) nodemap_[ i+w*j] = 1; } } for(unsigned int i=0; i<xmin_.size(); i++){ vector<int> directions; if (not map_[ymin_[i]*width_+xmin_[i]+1]) directions.push_back(0); if (not map_[(1+ymin_[i])*width_+xmax_[i]]) directions.push_back(1); if (not map_[(ymax_[i])*width_+xmin_[i]+1]) directions.push_back(2); if (not map_[(1+ymin_[i])*width_+xmin_[i]]) directions.push_back(3); int y = i%(yborders_.size()-1); int x = i/int(yborders_.size()-1); for(unsigned int j=0; j<directions.size(); j++){ int a = directions[j]; if (a==0) nodemap_[(y+1)*2*w+2*x-2*w+1] = 0; if (a==1) nodemap_[(y+1)*2*w+2*x-w+2] = 0; if (a==2) nodemap_[(y+1)*2*w+2*x+1] = 0; if (a==3) nodemap_[(y+1)*2*w+2*x-w] = 0; } } will_tab = new int[w*l]; for(unsigned int i=0; i<xmin_.size(); i++){ int Y = i%(yborders_.size()-1); int X = i/int(yborders_.size()-1); int x = 2*X+1; int y = 2*Y+1; pair<int, int> start (x,y); vector<pair<int, int>> path_to_exit = findExit(start, nodemap_, w, l); pair<int, int> a = path_to_exit[0]; pair<int, int> b = path_to_exit[1]; int dir = ((b.first-a.first)>0)+3*((b.first-a.first)<0)+2*((b.second-a.second)>0); will_tab[Y*(xborders_.size()-1)+X] = dir; } delete[] nodemap_; nodemap_ = nullptr; //..............................................Création des piétons : cout << "placing pedestrians..." << endl; int N = Building::NPEDEST; Pedest::RMIN = Pedest::RMIN + Pedest::MOOD; Pedest::RMAX = Pedest::RMAX + Pedest::MOOD; people_ = new Pedest[N]; for (int i=0; i<N; i++){ unsigned int posX = rand()%width_; unsigned int posY = rand()%length_; while (this->map(posX, posY)){ posX = rand()%width_; posY = rand()%length_; } people_[i] = Pedest(posX, posY, Building::ZOOM); } cout << Building::NPEDEST << " pedestrians randomly placed in this floor.\n" << endl; }
/** Process a left mouse click over: * 1. An icon - show description * 2. An object - walk to and show description * 3. An icon scroll arrow - scroll the iconbar * 4. Nothing - attempt to walk there * 5. Exit - walk to exit hotspot */ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int16 cy) { debugC(1, kDebugMouse, "ProcessLeftClick(%d, %d, %d)", objId, cx, cy); int16 i, x, y; Object *obj; Status &gameStatus = _vm->getGameStatus(); if (gameStatus._storyModeFl || _vm->_hero->_pathType == kPathQuiet) // Make sure user has control return; switch (objId) { case -1: // Empty space - attempt to walk there _vm->_route->startRoute(kRouteSpace, 0, cx, cy); break; case kLeftArrow: // A scroll arrow - scroll the iconbar case kRightArrow: // Scroll the iconbar and display results _vm->_inventory->processInventory((objId == kLeftArrow) ? kInventoryActionLeft : kInventoryActionRight); _vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, kInvDy, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix); _vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, kInvDy, kXPix, _vm->_screen->getBackBuffer(), 0, kDibOffY, kXPix); _vm->_screen->displayList(kDisplayAdd, 0, kDibOffY, kXPix, kInvDy); break; case kExitHotspot: // Walk to exit hotspot i = findExit(cx, cy, *_vm->_screenPtr); x = _hotspots[i]._viewx; y = _hotspots[i]._viewy; if (x >= 0) { // Hotspot refers to an exit // Special case of immediate exit if (_jumpExitFl) { // Get rid of iconbar if necessary if (_vm->_inventory->getInventoryState() != kInventoryOff) _vm->_inventory->setInventoryState(kInventoryUp); _vm->_scheduler->insertActionList(_hotspots[i]._actIndex); } else { // Set up route to exit spot if (_hotspots[i]._direction == Common::KEYCODE_RIGHT) x -= kHeroMaxWidth; else if (_hotspots[i]._direction == Common::KEYCODE_LEFT) x += kHeroMaxWidth; if (!_vm->_route->startRoute(kRouteExit, i, x, y)) Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there } // Get rid of any attached icon _vm->_screen->resetInventoryObjId(); } break; default: // Look at an icon or object obj = &_vm->_object->_objects[objId]; // Over iconbar - immediate description if ((_vm->_inventory->getInventoryState() == kInventoryActive) && (cy < kInvDy + kDibOffY)) { _vm->_object->lookObject(obj); } else { bool foundFl = false; // TRUE if route found to object switch (obj->_viewx) { // Clicked over viewport object case -1: // Walk to object position if (_vm->_object->findObjectSpace(obj, &x, &y)) foundFl = _vm->_route->startRoute(kRouteLook, objId, x, y); if (!foundFl) // Can't get there, immediate description _vm->_object->lookObject(obj); break; case 0: // Immediate description _vm->_object->lookObject(obj); break; default: // Walk to view point if possible if (!_vm->_route->startRoute(kRouteLook, objId, obj->_viewx, obj->_viewy)) { if (_vm->_hero->_cycling == kCycleInvisible) // If invisible do _vm->_object->lookObject(obj); // immediate decription else Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there } break; } } break; } }