bool DrasculaEngine::confirmExit() { byte key = 0; color_abc(kColorRed); updateRoom(); centerText(_textsys[1], 160, 87); updateScreen(); delay(100); while (!shouldQuit()) { key = getScan(); if (key != 0) break; // This gives a better feedback to the user when he is asked to // confirm whether he wants to quit. It now still updates the room and // shows mouse cursor movement. Hopefully it will work in all // locations of the game. updateRoom(); color_abc(kColorRed); centerText(_textsys[1], 160, 87); updateScreen(); } if (key == Common::KEYCODE_ESCAPE || shouldQuit()) { stopMusic(); return false; } return true; }
shared_ptr<IRCRoom> IRCSession::ensureRoom(shared_ptr<IIRCTarget> target, bool update) { if(target == nullptr) { OS_ASSERTFALSE(); return nullptr; } OS_LOCK(m_dataCS); const std::string &name = target->getName(); bool needUpdate = false; shared_ptr<IRCRoom> room; Rooms::const_iterator i = m_rooms.find(name); if(i != m_rooms.end()) { room = i->second; } else { room.reset(OS_NEW IRCRoom(target)); m_rooms[name] = room; needUpdate = true; } OS_ASSERT(room != nullptr); if(needUpdate && update) updateRoom(room, false); return room; }
bool DrasculaEngine::pickupObject() { int obj = pickedObject; checkFlags = 1; updateRoom(); showMenu(); updateScreen(); // Objects with an ID smaller than 7 are the inventory verbs if (pickedObject >= 7) { int n = whichObject(); if (n != 0 && inventoryObjects[n] == 0) { inventoryObjects[n] = obj; takeObject = 0; checkFlags = 0; } } if (checkFlags == 1) { if (checkMenuFlags()) return true; } updateEvents(); if (takeObject == 0) selectVerb(kVerbNone); return false; }
void IRCSession::updateAllRooms(bool force) { OS_LOCK(m_dataCS); for(Rooms::const_iterator i = m_rooms.begin(); i != m_rooms.end(); ++i) { updateRoom(i->second, force); } }
void Drawing::DrawingImpl::setNodes(int amount) { room->clearWaypoints(); QElapsedTimer timer; timer.start(); room->setNodes(amount); stats->lastSetNodes = timer.elapsed(); updateRoom(); }
void DrasculaEngine::gotoObject(int pointX, int pointY) { bool cursorVisible = isCursorVisible(); hideCursor(); if (currentChapter == 5 || currentChapter == 6) { if (hare_se_ve == 0) { curX = roomX; curY = roomY; updateRoom(); updateScreen(); return; } } roomX = pointX; roomY = pointY; startWalking(); for (;;) { updateRoom(); updateScreen(); updateEvents(); if (characterMoved == 0) break; pause(3); } if (walkToObject == 1) { walkToObject = 0; trackProtagonist = trackFinal; } updateRoom(); updateScreen(); // roomNumber -2 is end credits. Do not show cursor there if (cursorVisible && roomNumber != -2) showCursor(); }
void DrasculaEngine::hiccup(int counter) { int y = 0, trackCharacter = 0; if (currentChapter == 3) y = -1; do { counter--; updateEvents(); updateRoom(); if (currentChapter == 3) updateScreen(0, 0, 0, y, 320, 200, screenSurface); else updateScreen(0, 1, 0, y, 320, 198, screenSurface); if (trackCharacter == 0) y++; else y--; if (currentChapter == 3) { if (y == 1) trackCharacter = 1; if (y == -1) trackCharacter = 0; } else { if (y == 2) trackCharacter = 1; if (y == 0) trackCharacter = 0; } pause(3); } while (counter > 0); updateRoom(); updateScreen(); }
/** * Remove an item from the inventory, namely the item in the slot * over which the mouse cursor currently hovers. */ void DrasculaEngine::removeObject() { int obj = 0, n; updateRoom(); n = whichObject(); if (n != 0) { obj = inventoryObjects[n]; inventoryObjects[n] = 0; if (obj != 0) takeObject = 1; } updateEvents(); if (takeObject == 1) chooseObject(obj); }
void LocalDataNetworkObjectDirectory::update() { const auto networkObjects = m_configuration.networkObjects(); const NetworkObject rootObject( NetworkObject::Root ); QVector<NetworkObject::Uid> roomUids; for( const auto& networkObjectValue : networkObjects ) { const NetworkObject networkObject( networkObjectValue.toObject() ); if( networkObject.type() == NetworkObject::Group ) { roomUids.append( networkObject.uid() ); if( m_objects.contains( networkObject ) == false ) { emit objectsAboutToBeInserted( rootObject, m_objects.count(), 1 ); m_objects[networkObject] = QList<NetworkObject>(); emit objectsInserted(); } updateRoom( networkObject ); } } int index = 0; for( auto it = m_objects.begin(); it != m_objects.end(); ) { if( it.key().type() == NetworkObject::Group && roomUids.contains( it.key().uid() ) == false ) { emit objectsAboutToBeRemoved( rootObject, index, 1 ); it = m_objects.erase( it ); emit objectsRemoved(); } else { ++it; ++index; } } }
void IRCSession::processCommandJoin(shared_ptr<IRCCommandJoin> command) { OS_ASSERT(command != nullptr); shared_ptr<IRCRoom> room; { OS_LOCK(m_dataCS); const std::string &channelName = command->getChannel(); shared_ptr<IRCChannel> channel; Rooms::const_iterator i = m_rooms.find(channelName); if(isLocalUser(command->getNick())) channel = ensureChannel(channelName); else channel = findChannel(channelName); if(channel != nullptr) { room = ensureRoom(channel, false); OS_ASSERT(room != nullptr); std::string nickname; IRCUserType userType = ircUserTypeNormal; if(IRCParser::parseNickname(command->getNick(), nickname, userType)) { shared_ptr<IRCRoom::UserDetails> userDetails = room->ensureUser(ensureUser(nickname)); OS_ASSERT(userDetails != nullptr); if(userDetails != nullptr) userDetails->setType(userType); } } } if(room != nullptr) updateRoom(room, false); }
void DrasculaEngine::placeVonBraun(int pointX) { trackVonBraun = (pointX < vonBraunX) ? 0 : 1; vonBraunHasMoved = 1; while (!shouldQuit()) { updateEvents(); updateRoom(); updateScreen(); if (trackVonBraun == 0) { vonBraunX = vonBraunX - 5; if (vonBraunX <= pointX) break; } else { vonBraunX = vonBraunX + 5; if (vonBraunX >= pointX) break; } pause(5); } vonBraunHasMoved = 0; }
bool DrasculaEngine::confirmExit() { byte key; color_abc(kColorRed); updateRoom(); centerText(_textsys[1], 160, 87); updateScreen(); delay(100); for (;;) { key = getScan(); if (key != 0) break; } if (key == Common::KEYCODE_ESCAPE) { stopMusic(); return false; } return true; }
void IRCSession::processCommandEndOfNames(shared_ptr<IRCCommandEndOfNames> command) { OS_ASSERT(command != nullptr); shared_ptr<IRCRoom> room; { OS_LOCK(m_dataCS); Rooms::const_iterator i = m_rooms.find(command->getChannel()); if(i == m_rooms.end()) { OS_ASSERTFALSE(); return; } room = i->second; } OS_ASSERT(room != nullptr); updateRoom(room, false); }
void IRCSession::removeUserFromRoom(const std::string &roomName, const std::string &userName) { shared_ptr<IRCRoom> room; bool force = false; { OS_LOCK(m_dataCS); Rooms::iterator r = m_rooms.find(roomName); if(r == m_rooms.end()) return; room = r->second; if(isLocalUser(userName)) { m_rooms.erase(r); force = true; } else { Users::const_iterator u = m_users.find(userName); if(u == m_users.end()) { OS_ASSERTFALSE(); return; } OS_ASSERT(room != nullptr); room->removeUser(u->second); } } OS_ASSERT(room != nullptr); updateRoom(room, force); }
void DrasculaEngine::converse(int index) { debug(4, "converse(%d)", index); char fileName[20]; sprintf(fileName, "op_%d.cal", index); Common::SeekableReadStream *stream = _archives.open(fileName); if (!stream) error("missing data file %s", fileName); int game1 = kDialogOptionUnselected, game2 = kDialogOptionUnselected, game3 = kDialogOptionUnselected; char phrase1[128], phrase2[128], phrase3[128], phrase4[128]; char sound1[13], sound2[13], sound3[13], sound4[13]; int phrase1_bottom, phrase2_bottom, phrase3_bottom, phrase4_bottom; int answer1, answer2, answer3; breakOut = 0; selectVerb(kVerbNone); TextResourceParser p(stream, DisposeAfterUse::YES); p.parseString(phrase1); p.parseString(phrase2); p.parseString(phrase3); p.parseString(phrase4); p.parseString(sound1); p.parseString(sound2); p.parseString(sound3); p.parseString(sound4); p.parseInt(answer1); p.parseInt(answer2); p.parseInt(answer3); // no need to delete the stream, since TextResourceParser takes ownership // delete stream; if (currentChapter == 2 && !strcmp(fileName, "op_5.cal") && flags[38] == 1 && flags[33] == 1) { Common::strlcpy(phrase3, _text[405], 128); strcpy(sound3, "405.als"); answer3 = 31; } if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[7] == 1) { Common::strlcpy(phrase3, _text[273], 128); strcpy(sound3, "273.als"); answer3 = 14; } if (currentChapter == 6 && !strcmp(fileName, "op_12.cal") && flags[10] == 1) { Common::strlcpy(phrase3, _text[274], 128); strcpy(sound3, "274.als"); answer3 = 15; } cleanupString(phrase1); cleanupString(phrase2); cleanupString(phrase3); cleanupString(phrase4); loadPic("car.alg", backSurface); // TODO code here should limit y position for mouse in dialog menu, // but we can't implement this as there is lack in backend functionality // from 1(top) to 31 color_abc(kColorLightGreen); while (breakOut == 0 && !shouldQuit()) { updateRoom(); if (musicStatus() == 0 && roomMusic != 0) { if (currentChapter == 3 || currentChapter == 5) { playMusic(roomMusic); } else { // chapters 1, 2, 4, 6 if (flags[11] == 0) playMusic(roomMusic); } } updateEvents(); flushKeyBuffer(); phrase1_bottom = 8 * print_abc_opc(phrase1, 2, game1); phrase2_bottom = phrase1_bottom + 8 * print_abc_opc(phrase2, phrase1_bottom + 2, game2); phrase3_bottom = phrase2_bottom + 8 * print_abc_opc(phrase3, phrase2_bottom + 2, game3); phrase4_bottom = phrase3_bottom + 8 * print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionUnselected); if (_mouseY > 0 && _mouseY < phrase1_bottom) { if (game1 == kDialogOptionClicked && _color != kColorWhite) color_abc(kColorWhite); else if (game1 != kDialogOptionClicked && _color != kColorLightGreen) color_abc(kColorLightGreen); print_abc_opc(phrase1, 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); game1 = kDialogOptionClicked; talk(phrase1, sound1); response(answer1); } } else if (_mouseY > phrase1_bottom && _mouseY < phrase2_bottom) { if (game2 == kDialogOptionClicked && _color != kColorWhite) color_abc(kColorWhite); else if (game2 != kDialogOptionClicked && _color != kColorLightGreen) color_abc(kColorLightGreen); print_abc_opc(phrase2, phrase1_bottom + 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); game2 = kDialogOptionClicked; talk(phrase2, sound2); response(answer2); } } else if (_mouseY > phrase2_bottom && _mouseY < phrase3_bottom) { if (game3 == kDialogOptionClicked && _color != kColorWhite) color_abc(kColorWhite); else if (game3 != kDialogOptionClicked && _color != kColorLightGreen) color_abc(kColorLightGreen); print_abc_opc(phrase3, phrase2_bottom + 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); game3 = kDialogOptionClicked; talk(phrase3, sound3); response(answer3); } } else if (_mouseY > phrase3_bottom && _mouseY < phrase4_bottom) { print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionSelected); if (_leftMouseButton == 1) { delay(100); talk(phrase4, sound4); breakOut = 1; } } else if (_color != kColorLightGreen) color_abc(kColorLightGreen); _system->delayMillis(10); updateScreen(); } // while (breakOut == 0) if (currentChapter == 2) loadPic(menuBackground, backSurface); else loadPic(99, backSurface); }
void DrasculaEngine::volumeControls() { if (_lang == kSpanish) loadPic(95, tableSurface); copyRect(1, 56, 73, 63, 177, 97, tableSurface, screenSurface); updateScreen(73, 63, 73, 63, 177, 97, screenSurface); setCursor(kCursorCrosshair); showCursor(); while (!shouldQuit()) { int masterVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType) / 16), 0, 15); int voiceVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 16), 0, 15); int musicVolume = CLIP((_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 16), 0, 15); int masterVolumeY = 72 + 61 - masterVolume * 4; int voiceVolumeY = 72 + 61 - voiceVolume * 4; int musicVolumeY = 72 + 61 - musicVolume * 4; updateRoom(); copyRect(1, 56, 73, 63, 177, 97, tableSurface, screenSurface); copyBackground(183, 56, 82, masterVolumeY, 39, 2 + masterVolume * 4, tableSurface, screenSurface); copyBackground(183, 56, 138, voiceVolumeY, 39, 2 + voiceVolume * 4, tableSurface, screenSurface); copyBackground(183, 56, 194, musicVolumeY, 39, 2 + musicVolume * 4, tableSurface, screenSurface); updateScreen(); updateEvents(); // we're ignoring keypresses, so just empty the keyboard buffer while (getScan()) ; if (rightMouseButton == 1) { delay(100); break; } if (leftMouseButton == 1) { delay(100); if (mouseX > 80 && mouseX < 121) { updateVolume(Audio::Mixer::kPlainSoundType, masterVolumeY); } if (mouseX > 136 && mouseX < 178) { updateVolume(Audio::Mixer::kSpeechSoundType, voiceVolumeY); } if (mouseX > 192 && mouseX < 233) { updateVolume(Audio::Mixer::kMusicSoundType, musicVolumeY); } } } if (_lang == kSpanish) loadPic(974, tableSurface); selectVerb(kVerbNone); updateEvents(); }
void DrasculaEngine::doTalkSequenceCommand(TalkSequenceCommand cmd) { switch (cmd.commandType) { case kPause: pause(cmd.action); break; case kSetFlag: flags[cmd.action] = 1; break; case kClearFlag: flags[cmd.action] = 0; break; case kPickObject: pickObject(cmd.action); break; case kAddObject: addObject(cmd.action); break; case kBreakOut: breakOut = 1; break; case kConverse: converse(cmd.action); break; case kPlaceVB: placeVonBraun(cmd.action); break; case kUpdateRoom: updateRoom(); break; case kUpdateScreen: updateScreen(); break; case kTrackProtagonist: trackProtagonist = cmd.action; break; case kPlaySound: playSound(cmd.action); break; case kFinishSound: finishSound(); break; case kTalkerGeneral: talk(cmd.action); break; case kTalkerDrunk: talk_drunk(cmd.action); break; case kTalkerPianist: talk_pianist(cmd.action); break; case kTalkerBJ: talk_bj(cmd.action); break; case kTalkerVBNormal: talk_vonBraun(cmd.action, kVonBraunNormal); break; case kTalkerVBDoor: talk_vonBraun(cmd.action, kVonBraunDoor); break; case kTalkerIgorSeated: talk_igor(cmd.action, kIgorSeated); break; case kTalkerWerewolf: talk_werewolf(cmd.action); break; case kTalkerMus: talk_mus(cmd.action); break; case kTalkerDrascula: talk_drascula(cmd.action, 1); break; case kTalkerBartender0: talk_bartender(cmd.action, 0); break; case kTalkerBartender1: talk_bartender(cmd.action, 1); break; default: error("doTalkSequenceCommand: Unknown command: %d", cmd.commandType); } }
void Drawing::DrawingImpl::initialize() { #ifdef WIN32 GLenum result = glewInit(); std::string glewVersionString; std::string vertexBufferString; if (result != GLEW_OK) { glewVersionString = "GLEW not correctly supported.\n" + std::string(reinterpret_cast<const char *>(glewGetErrorString(result))); } else { glewVersionString = "GLEW supported.\n" + std::string(reinterpret_cast<const char *>(glewGetString(GLEW_VERSION))); } if (!GLEW_ARB_vertex_buffer_object) { vertexBufferString = "OpenGL VBO not supported."; } else { vertexBufferString = "OpenGL VBO are supported."; } statusText_->setText(QString::fromStdString(glewVersionString + "\n" + vertexBufferString)); if (result != GLEW_OK) { return; } #endif glEnable(GL_DEPTH_TEST); GLdouble vertices[(300 + 1) * 2]; vertices[0] = 0; vertices[1] = 0; for (int i = 0; i < 300; i++) { double angle = 2.0 * M_PI * (1.0 * i) / 300; double drawX = (ROBOT_DIAMETER / 2.5) * std::cos(angle); double drawY = (ROBOT_DIAMETER / 2.5) * std::sin(angle); vertices[(i + 1) * 2] = drawX; vertices[(i + 1) * 2 + 1] = drawY; } glGenBuffersARB(1, &circleVBO); throwErrorFromGLError(); try { glBindBufferARB(GL_ARRAY_BUFFER_ARB, circleVBO); throwErrorFromGLError(); glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof vertices, vertices, GL_STATIC_DRAW); throwErrorFromGLError(); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); throwErrorFromGLError(); } catch (...) { glDeleteBuffers(1, &circleVBO); throw; } { vertices[0] = -3; vertices[1] = -3; vertices[2] = 3; vertices[3] = 3; vertices[4] = -3; vertices[5] = 3; vertices[6] = 3; vertices[7] = -3; } glGenBuffersARB(1, &crossVBO); throwErrorFromGLError(); try { glBindBufferARB(GL_ARRAY_BUFFER_ARB, crossVBO); throwErrorFromGLError(); glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof *vertices * 8, vertices, GL_STATIC_DRAW); throwErrorFromGLError(); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); throwErrorFromGLError(); } catch (...) { glDeleteBuffers(2, &crossVBO); throw; } texture = new Texture(room->image()); updateRoom(); }
void Drawing::DrawingImpl::mouseClick(int x, int y) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, texture->width(), 0, texture->height(), -1.0f, 4.0f); throwErrorFromGLError(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Texture glTranslatef(0.0f, 0.0f, -3.5f); GLdouble modelview[16], projection[16]; glGetDoublev(GL_MODELVIEW_MATRIX, modelview); glGetDoublev(GL_PROJECTION_MATRIX, projection); GLfloat z; glReadPixels(x, viewport[3] - y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z); GLdouble posX, posY, posZ; gluUnProject(x, y, z, modelview, projection, viewport, &posX, &posY, &posZ); throwErrorFromGLError(); x = posX; y = posY; bool changed = false; switch (waypointModification) { case Drawing::WaypointAdd: changed = room->insertWaypoint(Coord2D(x, y)); break; case Drawing::WaypointDelete: changed = delNode(x, y); break; case Drawing::WaypointStart: changed = room->setStartpoint(Coord2D(x, y)); break; case Drawing::WaypointEnd: changed = room->setEndpoint(Coord2D(x, y)); break; default: if (show_[ShowNeighbours]) { Coord2D coord; if (!getCoordFromMouseClick(x, y, coord)) { return; } showNeighbours(coord); } break; } if (changed) { updateRoom(); } }
void Drawing::DrawingImpl::setAlgorithm(Room::Algorithm algorithm) { room->setAlgorithm(algorithm); updateRoom(); }
int main(int argc, char * argv[]) { short int bool = 0; // bool = 0 means (x, y) outdated on redis // used for ttl manipulation and decision making via clock() static double time = 0; static double prevTime = 0; // // some structures used to hold data conveniently struct GridCoord grid; //struct GridCoord holds int x, y and posn // struct Position camPosn; // Position has members .pan, .tilt, .zoom // struct Line posn; // Lines have members .pan, .tilt //// // create a "struct Room" and load its control varibles struct Room room; struct Room * roomp = &room; struct BlackBoard * boardp; boardp = getBoardCoords(); room.boards[0] = *boardp; room.boards[1] = *(boardp + 1); room.boards[2] = *(boardp + 2); room.control = *loadControlInfo();// // create a connection to the Redis server redisContext * c; redisReply * reply; c = redisConnect("127.0.0.1", 6379); if (c->err) { puts("Error Connecting to Redis Server: %s\n"); redisFree(c); return 1; }// else puts("\nConnected to Redis\n"); // initialize the camera values to something simple: // push values onto Redis server, execute command to move cam, set expiration time char buf[256]; // holds string sent to redis server snprintf(buf, 256, "MSET visca:camera:pan %i visca:camera:tilt %i visca:camera:zoom %i",0,0,0); redisCommand(c, buf); redisCommand(c, "lpush visca:command m"); redisCommand(c, "expire visca:command 2"); // // this loop runs continuously: // 1) pulls values from the redis server, places in (struct GridCoord)grid // 2) converts from grid to (P, T) // 3) updates ttl's on blackboards, finds best camera (P, T, Z) frame // 4) pushes new (P, T, Z) values to redis server, execute move command // 5) update grid with current camera position clock(); puts("Setup complete"); while(1) { // 1) pull values from redis server, place in grid: reply = redisCommand(c, "MGET vision:x vision:y vision:bool"); if (reply->type == REDIS_REPLY_ARRAY) { grid.x = atoi(reply->element[0]->str); grid.z = atoi(reply->element[1]->str); //bool = atoi(reply->element[2]->str); }// bool = 1; // if valid x, y exists on redis server if(bool) { // 2) converts from grid to (P, T) posn = coordTrans(grid); // // 3) updates ttl's on blackboards, finds best camera (P, T, Z) frame prevTime = time; time = clock()/CLOCKS_PER_SEC; // time = seconds passed since updateRoom() last called updateRoom(posn, roomp, time - prevTime); // update room with latest speaker pos'n, etc. camPosn = updateCamPosn(roomp); // calculate ideal camera (P, T, Z) // // 4) pushes new (P, T, Z) values to redis server, execute move command // push values onto Redis server: snprintf(buf, 256, "MSET visca:camera:pan %i visca:camera:tilt %i visca:camera:zoom %i", (int)camPosn.pan, (int)camPosn.tilt, (int)camPosn.zoom); // // execute the redis Command to move the camera redisCommand(c, buf); redisCommand(c, "lpush visca:command m"); redisCommand(c, "expire visca:command 5");// // 5) update grid with current camera position grid.posn.pan = camPosn.pan; grid.posn.tilt = camPosn.tilt; grid.posn.zoom = camPosn.zoom; // } // 70,if else //if redis server has invalid x y values (line 74) { /* zoom all the way out: snprintf(buf, 256, "MSET visca:camera:pan 0 visca:camera:tilt 0 visca:camera:zoom 0"); redisCommand(c, buf); redisCommand(c, "lpush visca:command m"); redisCommand(c, "expire visca:command 5"); */ } } //while, 57
void IRCSession::processCommandMode(shared_ptr<IRCCommandMode> command) { OS_ASSERT(command != nullptr); if(command->getTargetType() != ircTargetTypeChannel) return; shared_ptr<IRCRoom> room = findRoom(command->getTarget()); if(room == nullptr) { OS_ASSERTFALSE(); return; } shared_ptr<IRCUser> user; if(command->hasArg()) user = findUser(command->getArg()); shared_ptr<IRCRoom::UserDetails> userDetails; if(user != nullptr) userDetails = room->getUserDetails(user->getID()); const IRCCommandMode::ModeOptions &modes = command->getModeOptions(); for(IRCCommandMode::ModeOptions::const_iterator i = modes.begin(); i != modes.end(); ++i) { switch(i->first) { case ircModeTypeUnknown: break; case ircModeTypeOperator: if(userDetails != nullptr) userDetails->setType(i->second ? ircUserTypeOperator : ircUserTypeNormal); break; case ircModeTypeHalfOperator: if(userDetails != nullptr) userDetails->setType(i->second ? ircUserTypeHalfOperator : ircUserTypeNormal); break; case ircModeTypeVoice: if(userDetails != nullptr) userDetails->setVoice(i->second); break; case ircModeTypeInvisible: if(userDetails != nullptr) userDetails->setInvisible(i->second); break; case ircModeTypeBan: if(userDetails != nullptr) userDetails->setBanned(i->second); break; default: OS_ASSERTFALSE(); break; } } updateRoom(room, false); }