// ---------------------------------------------------------------------------- void TrackObjectPresentationMesh::reset() { if (m_node->getType()==scene::ESNT_ANIMATED_MESH) { scene::IAnimatedMeshSceneNode *a_node = (scene::IAnimatedMeshSceneNode*)m_node; a_node->setPosition(m_init_xyz); a_node->setRotation(m_init_hpr); a_node->setScale(m_init_scale); a_node->setLoopMode(m_is_looped); a_node->setAnimationEndCallback(NULL); a_node->setCurrentFrame((float)(a_node->getStartFrame())); // trick to reset the animation AND also the timer inside it a_node->OnAnimate(0); a_node->OnAnimate(0); // irrlicht's "setFrameLoop" is a misnomer, it just sets the first and // last frame, even if looping is disabled RandomGenerator rg; int animation_set = 0; if (a_node->getAnimationSetNum() > 0) animation_set = rg.get(a_node->getAnimationSetNum()); a_node->useAnimationSet(animation_set); } } // reset
void Rain::update(float dt) { //const int count = m_materials.size(); for (int m=0; m<RAIN_RING_COUNT; m++) { m_x[m] = m_x[m] + dt*RAIN_DX; m_y[m] = m_y[m] + dt*RAIN_DY; if (m_x[m] > 1.0f) m_x[m] = fmod(m_x[m], 1.0f); if (m_y[m] > 1.0f) m_y[m] = fmod(m_y[m], 1.0f); core::matrix4& matrix = m_node[m]->getChild()->getMaterial(0).getTextureMatrix(0); matrix.setTextureTranslate(m_x[m], m_y[m]); } if (m_lightning) { m_next_lightning -= dt; if (m_next_lightning < 0.0f) { RaceGUIBase* gui_base = World::getWorld()->getRaceGUI(); if (gui_base != NULL) { gui_base->doLightning(); if (m_thunder_sound) m_thunder_sound->play(); } RandomGenerator g; m_next_lightning = 35 + (float)g.get(35); } } } // update
/** Returns a random hue when colorized. */ float getRandomHue() { if (m_hue_settings.empty()) return 0.0f; const unsigned int hue = m_random_hue.get(m_hue_settings.size()); assert(hue < m_hue_settings.size()); return m_hue_settings[hue]; }
/** Picks a random message to be displayed when a kart is hit by a plunger. * \param The kart that was hit (ignored here). * \returns The string to display. */ const core::stringw Plunger::getHitString(const AbstractKart *kart) const { const int PLUNGER_IN_FACE_STRINGS_AMOUNT = 2; RandomGenerator r; switch (r.get(PLUNGER_IN_FACE_STRINGS_AMOUNT)) { //I18N: shown when a player receives a plunger in his face case 0: return _LTR("%0 gets a fancy mask from %1"); //I18N: shown when a player receives a plunger in his face case 1: return _LTR("%1 merges %0's face with a plunger"); default:assert(false); return L""; // avoid compiler warning } } // getHitString
/** Picks a random message to be displayed when a kart is hit by a bowling * ball. This function picks a different message if a kart hit itself. * \param kart The kart that was hit. * \returns The string to display. */ const core::stringw Bowling::getHitString(const AbstractKart *kart) const { RandomGenerator r; if(kart!=m_owner) { const int BOWLING_STRINGS_AMOUNT = 3; switch (r.get(BOWLING_STRINGS_AMOUNT)) { //I18N: shown when hit by bowling ball. %1 is the attacker, %0 is // the victim. case 0 : return _LTR("%0 will not go bowling with %1 again"); //I18N: shown when hit by bowling ball. %1 is the attacker, %0 is // the victim. case 1 : return _LTR("%1 strikes %0"); //I18N: shown when hit by bowling ball. %1 is the attacker, %0 is // the victim. case 2 : return _LTR("%0 is bowled over by %1"); default: assert(false); return L""; // avoid compiler warning } } else { const int SELFBOWLING_STRINGS_AMOUNT = 3; switch (r.get(SELFBOWLING_STRINGS_AMOUNT)) { //I18N: shown when hit by own bowling ball. %s is the kart. case 0 : return _LTR("%s is practicing with a blue, big, spheric yo-yo"); //I18N: shown when hit by own bowling ball. %s is the kart. case 1 : return _LTR("%s is the world master of the boomerang ball"); //I18N: shown when hit by own bowling ball. %s is the kart. case 2 : return _LTR("%s should play (rubber) darts instead of bowling"); default: assert(false); return L""; // avoid compiler warning } // switch } // if kart_hit==owner } // getHitString
/** Picks a random message to be displayed when a kart is hit by the * rubber ball. * \param The kart that was hit (ignored here). * \returns The string to display. */ const core::stringw RubberBall::getHitString(const AbstractKart *kart) const { const int COUNT = 2; RandomGenerator r; switch (r.get(COUNT)) { //I18N: shown when a player is hit by a rubber ball. %1 is the // attacker, %0 is the victim. case 0: return _LTR("%s is being bounced around."); //I18N: shown when a player is hit by a rubber ball. %1 is the // attacker, %0 is the victim. case 1: return _LTR("Fetch the ball, %0!"); default:assert(false); return L""; // avoid compiler warning } } // getHitString
const wchar_t* getPlungerInFaceString() { const int PLUNGER_IN_FACE_STRINGS_AMOUNT = 2; RandomGenerator r; const int id = r.get(PLUNGER_IN_FACE_STRINGS_AMOUNT); switch (id) { //I18N: shown when a player receives a plunger in his face case 0: return _("%0 gets a fancy mask from %1"); //I18N: shown when a player receives a plunger in his face case 1: return _("%1 merges %0's face with a plunger"); default:assert(false); return L""; // avoid compiler warning } }
// ---------------------------------------------------------------------------- void TrackObjectPresentationLOD::reset() { LODNode* ln = dynamic_cast<LODNode*>(m_node); if (ln) { for (scene::ISceneNode* node : ln->getAllNodes()) { scene::IAnimatedMeshSceneNode* a_node = dynamic_cast<scene::IAnimatedMeshSceneNode*>(node); if (a_node) { a_node->setLoopMode(true); a_node->setAnimationEndCallback(NULL); RandomGenerator rg; int animation_set = 0; if (a_node->getAnimationSetNum() > 0) animation_set = rg.get(a_node->getAnimationSetNum()); a_node->useAnimationSet(animation_set); } } } } // reset
void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "tracks") { DynamicRibbonWidget* w2 = dynamic_cast<DynamicRibbonWidget*>(widget); if (w2 == NULL) return; const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER); if (UserConfigParams::logGUI()) Log::info("ArenasScreen", "Clicked on arena %s", selection.c_str()); if (selection == "random_track") { RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups"); assert( tabs != NULL ); bool soccer_mode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER; std::vector<int> curr_group; if (tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER) == ALL_ARENA_GROUPS_ID) { const std::vector<std::string>& groups = track_manager->getAllArenaGroups(); for (unsigned int i = 0; i < groups.size(); i++) { const std::vector<int>& tmp_group = track_manager->getArenasInGroup(groups[i], soccer_mode); // Append to our main vector curr_group.insert(curr_group.end(), tmp_group.begin(), tmp_group.end()); } } // if on tab "all" else { curr_group = track_manager->getArenasInGroup( tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER), soccer_mode ); } // Remove unsupported arena if (m_unsupported_arena.size() > 0) { for (std::set<int>::iterator it = m_unsupported_arena.begin(); it != m_unsupported_arena.end(); ++it) { curr_group.erase(std::remove(curr_group.begin(), curr_group.end(), *it), curr_group.end()); } } RandomGenerator random; const int randomID = random.get((int)curr_group.size()); Track* clicked_track = track_manager->getTrack( curr_group[randomID] ); if (clicked_track != NULL) { TrackInfoScreen::getInstance()->setTrack(clicked_track); TrackInfoScreen::getInstance()->push(); } } else if (selection == "locked") { unlock_manager->playLockSound(); } else if (selection == RibbonWidget::NO_ITEM_ID) { } else { Track* clicked_track = track_manager->getTrack(selection); if (clicked_track != NULL) { TrackInfoScreen::getInstance()->setTrack(clicked_track); TrackInfoScreen::getInstance()->push(); } // clickedTrack != NULL } // if random_track } else if (name == "trackgroups") { buildTrackList(); } else if (name == "back") { StateManager::get()->escapePressed(); } } // eventCallback
//----------------------------------------------------------------------------- bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos) { if (!UserConfigParams::m_random_arena_item) return false; if (!BattleGraph::get()) return false; std::vector<int> used_location; std::vector<int> invalid_location; for (unsigned int i = 0; i < pos.size(); i++) { // Load all starting positions of arena, so no items will be near them int node = BattleGraph::get()->pointToNode(/*cur_node*/-1, Vec3(pos[i].getOrigin()), /*ignore_vertical*/true); assert(node != -1); used_location.push_back(node); invalid_location.push_back(node); } RandomGenerator random; const unsigned int MIN_DIST = int(sqrt(BattleGraph::get()->getNumNodes())); const unsigned int TOTAL_ITEM = MIN_DIST / 2; Log::info("[ItemManager]","Creating %d random items for arena", TOTAL_ITEM); for (unsigned int i = 0; i < TOTAL_ITEM; i++) { int chosen_node = -1; const unsigned int total_node = BattleGraph::get()->getNumNodes(); while(true) { if (used_location.size() - pos.size() + invalid_location.size() == total_node) { Log::warn("[ItemManager]","Can't place more random items! " "Use default item location."); return false; } const int node = random.get(total_node); // Check if tried std::vector<int>::iterator it = std::find(invalid_location.begin(), invalid_location.end(), node); if (it != invalid_location.end()) continue; // Check if near edge if (BattleGraph::get()->isNearEdge(node)) { invalid_location.push_back(node); continue; } // Check if too close bool found = true; for (unsigned int j = 0; j < used_location.size(); j++) { if (!found) continue; Vec3 d = BattleGraph::get() ->getPolyOfNode(used_location[j]).getCenter() - BattleGraph::get()->getPolyOfNode(node).getCenter(); found = d.length_2d() > MIN_DIST; } if (found) { chosen_node = node; invalid_location.push_back(node); break; } else invalid_location.push_back(node); } assert(chosen_node != -1); used_location.push_back(chosen_node); } for (unsigned int i = 0; i < pos.size(); i++) used_location.erase(used_location.begin()); assert (used_location.size() == TOTAL_ITEM); // Hard-coded ratio for now const int BONUS_BOX = 4; const int NITRO_BIG = 2; const int NITRO_SMALL = 1; for (unsigned int i = 0; i < TOTAL_ITEM; i++) { const int j = random.get(10); Item::ItemType type = (j > BONUS_BOX ? Item::ITEM_BONUS_BOX : j > NITRO_BIG ? Item::ITEM_NITRO_BIG : j > NITRO_SMALL ? Item::ITEM_NITRO_SMALL : Item::ITEM_BANANA); Vec3 loc = BattleGraph::get() ->getPolyOfNode(used_location[i]).getCenter(); Item* item = newItem(type, loc, Vec3(0, 1, 0)); BattleGraph::get()->insertItems(item, used_location[i]); } return true; } // randomItemsForArena
/** * Callback handling events from the kart selection menu */ void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name, const int player_id) { // don't allow changing group after someone confirmed if (name == "kartgroups" && !m_game_master_confirmed) { RibbonWidget* tabs = getWidget<RibbonWidget>("kartgroups"); assert(tabs != NULL); DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts"); assert(w != NULL); setKartsFromCurrentGroup(); const std::string &selected_kart_group = tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER); UserConfigParams::m_last_used_kart_group = selected_kart_group; RandomGenerator random; const int num_players = m_kart_widgets.size(); for (int n=0; n<num_players; n++) { // The game master is the one that can change the groups, leave // his focus on the tabs for others, remove focus from kart that // might no more exist in this tab. if (n != PLAYER_ID_GAME_MASTER) GUIEngine::focusNothingForPlayer(n); if (!m_kart_widgets[n].isReady()) { // try to preserve the same kart for each player (except for // game master, since it's the one that can change the // groups, so focus for this player must remain on the tabs) const std::string& selected_kart = m_kart_widgets[n].getKartInternalName(); if (!w->setSelection( selected_kart, n, n != PLAYER_ID_GAME_MASTER)) { // if we get here, it means one player "lost" his kart in // the tab switch if (UserConfigParams::logGUI()) Log::info("KartSelectionScreen", "Player %u" " lost their selection when switching tabs!!!",n); // Select a random kart in this case const int count = (int) w->getItems().size(); if (count > 0) { // FIXME: two players may be given the same kart by // the use of random const int random_id = random.get( count ); // select kart for players > 0 (player 0 is the one // that can change the groups, so focus for player 0 // must remain on the tabs) const bool success = w->setSelection( random_id, n, n != PLAYER_ID_GAME_MASTER ); if (!success) Log::warn("KartSelectionScreen", "setting kart of player %u failed"); } else { Log::warn("KartSelectionScreen", " 0 items " "in the ribbon"); } } } } // end for } else if (name == "karts") { if (m_kart_widgets.size() > unsigned(player_id)) playerConfirm(player_id); } else if (name == "back") { StateManager::get()->escapePressed(); } else { // Transmit to all subwidgets, maybe *they* care about this event const int amount = m_kart_widgets.size(); for (int n=0; n<amount; n++) { m_kart_widgets[n].transmitEvent(widget, name, player_id); } // those events may mean that a player selection changed, so // validate again validateIdentChoices(); validateKartChoices(); } } // eventCallback
void KartSelectionScreen::allPlayersDone() { input_manager->setMasterPlayerOnly(true); RibbonWidget* tabs = getWidget<RibbonWidget>("kartgroups"); assert(tabs != NULL); std::string selected_kart_group = tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER); UserConfigParams::m_last_used_kart_group = selected_kart_group; DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts"); assert( w != NULL ); const PtrVector< StateManager::ActivePlayer, HOLD >& players = StateManager::get()->getActivePlayers(); // ---- Print selection (for debugging purposes) if(UserConfigParams::logGUI()) { Log::info("KartSelectionScreen", "players : %d",players.size()); for (unsigned int n=0; n<players.size(); n++) { Log::info("KartSelectionScreen", " Player %u is %s on %s",n, core::stringc( players[n].getConstProfile()->getName().c_str()).c_str(), players[n].getDevice()->getName().c_str()); } } for (unsigned int n=0; n<players.size(); n++) { StateManager::get()->getActivePlayer(n)->getProfile() ->incrementUseFrequency(); } // ---- Give player info to race manager race_manager->setNumPlayers(players.size()); // ---- Manage 'random kart' selection(s) RandomGenerator random; std::vector<ItemDescription> items = w->getItems(); // remove the 'random' item itself const int item_count = (int) items.size(); for (int n=0; n<item_count; n++) { if (items[n].m_code_name == RANDOM_KART_ID) { items[n].m_code_name = ID_DONT_USE; break; } } // pick random karts const int kart_count = m_kart_widgets.size(); for (int n = 0; n < kart_count; n++) { std::string selected_kart = m_kart_widgets[n].m_kartInternalName; if (selected_kart == RANDOM_KART_ID) { // don't select an already selected kart int random_id; // to prevent infinite loop in case they are all locked int count = 0; bool done = false; do { random_id = random.get(item_count); // valid kart if it can bt used, and is either not locked, // or it's a multiplayer race. if (items[random_id].m_code_name != ID_DONT_USE && (!StringUtils::startsWith(items[random_id].m_code_name, ID_LOCKED) || m_multiplayer) ) { selected_kart = items[random_id].m_code_name; done = true; } items[random_id].m_code_name = ID_DONT_USE; count++; if (count > 100) return; } while (!done); } else { // mark the item as taken for (int i=0; i<item_count; i++) { if (items[i].m_code_name == m_kart_widgets[n].m_kartInternalName) { items[i].m_code_name = ID_DONT_USE; break; } } } race_manager->setPlayerKart(n, selected_kart); // Set per player difficulty if needed if (m_multiplayer && UserConfigParams::m_per_player_difficulty && m_kart_widgets[n].isHandicapped()) race_manager->setPlayerDifficulty(n, PLAYER_DIFFICULTY_HANDICAP); } // ---- Switch to assign mode input_manager->getDeviceManager()->setAssignMode(ASSIGN); StateManager::ActivePlayer *ap = m_multiplayer ? NULL : StateManager::get()->getActivePlayer(0); input_manager->getDeviceManager()->setSinglePlayer(ap); // ---- Go to next screen or return to overworld if (m_from_overworld || m_go_to_overworld_next) { m_from_overworld = false; // valid once m_go_to_overworld_next = false; OverWorld::enterOverWorld(); } else { RaceSetupScreen::getInstance()->push(); } } // allPlayersDone
void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "tracks") { DynamicRibbonWidget* w2 = dynamic_cast<DynamicRibbonWidget*>(widget); if (w2 == NULL) return; const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER); if (UserConfigParams::logGUI()) std::cout << "Clicked on arena " << selection.c_str() << std::endl; if (selection == "random_track") { RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups"); assert( tabs != NULL ); bool soccer_mode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER; std::vector<int> curr_group; if (tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER) == ALL_ARENA_GROUPS_ID) { const std::vector<std::string>& groups = track_manager->getAllArenaGroups(); for (unsigned int i = 0; i < groups.size(); i++) { const std::vector<int>& tmp_group = track_manager->getArenasInGroup(groups[i], soccer_mode); // Append to our main vector curr_group.insert(curr_group.end(), tmp_group.begin(), tmp_group.end()); } } // if on tab "all" else { curr_group = track_manager->getArenasInGroup( tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER), soccer_mode ); } RandomGenerator random; const int randomID = random.get(curr_group.size()); Track* clickedTrack = track_manager->getTrack( curr_group[randomID] ); if (clickedTrack != NULL) { ITexture* screenshot = irr_driver->getTexture( clickedTrack->getScreenshotFile().c_str() ); new TrackInfoDialog(selection, clickedTrack->getIdent(), clickedTrack->getName(), screenshot, 0.8f, 0.7f); } } else if (selection == "locked") { unlock_manager->playLockSound(); } else if (selection == RibbonWidget::NO_ITEM_ID) { } else { Track* clickedTrack = track_manager->getTrack(selection); if (clickedTrack != NULL) { ITexture* screenshot = irr_driver->getTexture( clickedTrack->getScreenshotFile().c_str() ); new TrackInfoDialog(selection, clickedTrack->getIdent(), clickedTrack->getName(), screenshot, 0.8f, 0.7f); } // clickedTrack != NULL } // if random_track } else if (name == "trackgroups") { buildTrackList(); } else if (name == "back") { StateManager::get()->escapePressed(); } } // eventCallback
/** If the configuration of this installation has not been reported for the * current version, collect the hardware statistics and send it to STK's * server. */ void reportHardwareStats() { // Version of the hw report, which is stored in the DB. If new fields // are added, increase this version. Each STK installation will report // its configuration only once (per version number). So if the version // number is increased, a new report will be sent. const int report_version = 1; if(UserConfigParams::m_last_hw_report_version>=report_version) return; while(UserConfigParams::m_random_identifier==0) { RandomGenerator rg; UserConfigParams::m_random_identifier = rg.get(1<<30); user_config->saveConfig(); } Json json; #ifdef WIN32 json.add("os_win", 1); #else json.add("os_win", 0); #endif #ifdef __APPLE__ json.add("os_macosx", 1); #else json.add("os_macosx", 0); #endif #ifdef __linux__ json.add("os_linux", 1); json.add("os_unix", 1); #else json.add("os_linux", 0); json.add("os_unix", 0); #endif #ifdef DEBUG json.add("build_debug", 1); #endif json.add("os_version", getOSVersion()); unsigned int ogl_version = irr_driver->getGLSLVersion(); unsigned int major = ogl_version/100; unsigned int minor = ogl_version - 100*major; std::string version = StringUtils::insertValues("%d.%d", major, minor); json.add("GL_SHADING_LANGUAGE_VERSION", version); std::string vendor, renderer, full_version; irr_driver->getOpenGLData(&vendor, &renderer, &full_version); json.add("GL_VENDOR", vendor ); json.add("GL_RENDERER", renderer ); json.add("GL_VERSION", full_version ); json.add("gfx_drv_ver", "OpenGL "+vendor); std::string card_name = vendor; if(StringUtils::startsWith(card_name, "ATI Technologies Inc.")) card_name="ATI"; else if (StringUtils::startsWith(card_name, "NVIDIA Corporation")) card_name="NVIDIA"; else if(StringUtils::startsWith(card_name, "S3 Graphics")) card_name="S3"; json.add("gfx_card", card_name+" "+renderer); json.add("video_xres", UserConfigParams::m_width ); json.add("video_yres", UserConfigParams::m_height); int mem = getRAM(); if(mem>0) json.add("ram_total", mem); int nr_procs = getNumProcessors(); if(nr_procs>0) json.add("cpu_numprocs", nr_procs); json.add("GL_EXTENSIONS", getGLExtensions()); getGLLimits(&json); json.finish(); // ------------------------------------------------------------------------ /** A small class which sends the HW report to the STK server. On * completion, it will either update the last-submitted-hw-report version, * or log an error message (in which case next time STK is started it * wil try again to log the report). */ class HWReportRequest : public Online::HTTPRequest { private: /** Version number of the hw report. */ int m_version; public: HWReportRequest(int version) : Online::HTTPRequest(/*manage memory*/true, 1) , m_version(version) {} // -------------------------------------------------------------------- /** Callback after the request has been executed. */ virtual void callback() { // If the request contains incorrect data, it will not have a // download error, but return an error string as return value: if(hadDownloadError() || getData()=="<h1>Bad Request (400)</h1>") { Log::error("HW report", "Error uploading the HW report."); if(hadDownloadError()) Log::error("HW report", "%s", getDownloadErrorMessage()); else Log::error("HW report", "%s", getData().c_str()); } else { Log::info("HW report", "Upload successful."); UserConfigParams::m_last_hw_report_version = m_version; // The callback is executed by the main thread, so no need // to worry about locks when writing the file. user_config->saveConfig(); } } // callback }; // HWReportRequest // ------------------------------------------------------------------------ Online::HTTPRequest *request = new HWReportRequest(report_version); request->addParameter("user_id", UserConfigParams::m_random_identifier); request->addParameter("time", StkTime::getTimeSinceEpoch()); request->addParameter("type", "hwdetect"); request->addParameter("version", report_version); request->addParameter("data", json.toString()); request->setURL((std::string)UserConfigParams::m_server_hw_report+"/upload/v1/"); //request->setURL("http://127.0.0.1:8000/upload/v1/"); request->queue(); } // reportHardwareStats
Rain::Rain(Camera *camera, irr::scene::ISceneNode* parent) { m_lightning = camera->getIndex()==0; if (m_lightning) m_thunder_sound = sfx_manager->createSoundSource("thunder"); Material* m = material_manager->getMaterial("rain.png"); assert(m != NULL); RandomGenerator g; m_next_lightning = (float)g.get(35); for (int r=0; r<RAIN_RING_COUNT; r++) { m_x[r] = r/(float)RAIN_RING_COUNT; m_y[r] = r/(float)RAIN_RING_COUNT; scene::SMeshBuffer *buffer = new scene::SMeshBuffer(); buffer->Material.setTexture(0, m->getTexture()); m->setMaterialProperties(&buffer->Material, NULL); buffer->Material.ZWriteEnable = false; buffer->Material.BackfaceCulling = false; m_materials.push_back(&buffer->Material); video::S3DVertex v; v.Color.set(255,255,255,255); // create a cylinder mesh const int VERTICES = 17; for (int vid=0; vid<VERTICES*2; vid+=2) { const float ratio = float(vid) / float(VERTICES-1); const float angle = ratio * 2.0f * M_PI; v.Pos.X = cos(angle)*RAIN_RADIUS[r]; v.Pos.Y = RAIN_Y_TO; v.Pos.Z = sin(angle)*RAIN_RADIUS[r]; // offset the X coord in texturing so you don't see textures from // the different rings lining up v.TCoords.X = ratio*TEXTURE_X_TILES[r] + r/3.0f; v.TCoords.Y = TEXTURE_Y_TILES[r]; buffer->Vertices.push_back(v); v.Pos.Y = RAIN_Y_FROM; v.TCoords.Y = 0.0f; buffer->Vertices.push_back(v); if (vid > 0) { buffer->Indices.push_back(vid-2); buffer->Indices.push_back(vid-1); buffer->Indices.push_back(vid); buffer->Indices.push_back(vid-1); buffer->Indices.push_back(vid); buffer->Indices.push_back(vid+1); } } scene::SMesh* mesh = new scene::SMesh(); mesh->addMeshBuffer(buffer); mesh->recalculateBoundingBox(); m_node[r] = irr_driver->addPerCameraMesh(mesh, camera->getCameraSceneNode(), parent); m_node[r]->setAutomaticCulling(0); mesh->drop(); buffer->drop(); } } // Rain
/** Draws the plunger-in-face if necessary. Does nothing if there is no * plunger in face atm. */ void RaceGUIBase::drawPlungerInFace(const Camera *camera, float dt) { const AbstractKart *kart = camera->getKart(); if (kart->getBlockedByPlungerTime()<=0) { m_plunger_state = PLUNGER_STATE_INIT; return; } const core::recti &viewport = camera->getViewport(); const int screen_width = viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X; if(m_plunger_state == PLUNGER_STATE_INIT) { m_plunger_move_time = 0.0f; m_plunger_offset = core::vector2di(0,0); m_plunger_state = PLUNGER_STATE_SLOW_2; m_plunger_speed = core::vector2df(0, 0); } if(World::getWorld()->getPhase()!=World::IN_GAME_MENU_PHASE) { m_plunger_move_time -= dt; if(m_plunger_move_time < dt && m_plunger_state!=PLUNGER_STATE_FAST) { const float fast_time = 0.3f; if(kart->getBlockedByPlungerTime()<fast_time) { // First time we reach faste state: select random target point // at top of screen and set speed accordingly RandomGenerator random; float movement_fraction = 0.3f; int plunger_x_target = screen_width/2 + random.get((int)(screen_width*movement_fraction)) - (int)(screen_width*movement_fraction*0.5f); m_plunger_state = PLUNGER_STATE_FAST; m_plunger_speed = core::vector2df((plunger_x_target-screen_width/2)/fast_time, viewport.getHeight()*0.5f/fast_time); m_plunger_move_time = fast_time; } else { RandomGenerator random; m_plunger_move_time = 0.1f+random.get(50)/200.0f; // Plunger is either moving or not moving if(m_plunger_state==PLUNGER_STATE_SLOW_1) { m_plunger_state = PLUNGER_STATE_SLOW_2; m_plunger_speed = core::vector2df(0, 0.05f*viewport.getHeight() /m_plunger_move_time ); } else { m_plunger_state = PLUNGER_STATE_SLOW_1; m_plunger_speed = core::vector2df(0, 0.02f*viewport.getHeight() /m_plunger_move_time ); } } // has not reach fast moving state } m_plunger_offset.X += (int)(m_plunger_speed.X * dt); m_plunger_offset.Y += (int)(m_plunger_speed.Y * dt); } const int plunger_size = (int)(0.6f * screen_width); int offset_y = viewport.UpperLeftCorner.Y + viewport.getHeight()/2 - plunger_size/2 - m_plunger_offset.Y; int plunger_x = viewport.UpperLeftCorner.X + screen_width/2 - plunger_size/2; video::ITexture *t=m_plunger_face->getTexture(); plunger_x += (int)m_plunger_offset.X; core::rect<s32> dest(plunger_x, offset_y, plunger_x+plunger_size, offset_y+plunger_size); const core::rect<s32> source(core::position2d<s32>(0,0), t->getOriginalSize()); draw2DImage(t, dest, source, &viewport /* clip */, NULL /* color */, true /* alpha */ ); } // drawPlungerInFace
void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "tracks") { DynamicRibbonWidget* w2 = dynamic_cast<DynamicRibbonWidget*>(widget); if (w2 == NULL) return; const std::string selection = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER); if (UserConfigParams::logGUI()) std::cout << "Clicked on arena " << selection.c_str() << std::endl; if (selection == "random_track") { RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups"); assert( tabs != NULL ); const std::vector<int>& curr_group = track_manager->getArenasInGroup( tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER) ); RandomGenerator random; const int randomID = random.get(curr_group.size()); Track* clickedTrack = track_manager->getTrack( curr_group[randomID] ); if (clickedTrack != NULL) { ITexture* screenshot = irr_driver->getTexture( clickedTrack->getScreenshotFile().c_str() ); new TrackInfoDialog(selection, clickedTrack->getIdent(), clickedTrack->getName(), screenshot, 0.8f, 0.7f); } } else if (selection == "locked") { unlock_manager->playLockSound(); } else if (selection == RibbonWidget::NO_ITEM_ID) { } else { Track* clickedTrack = track_manager->getTrack(selection); if (clickedTrack != NULL) { ITexture* screenshot = irr_driver->getTexture( clickedTrack->getScreenshotFile().c_str() ); new TrackInfoDialog(selection, clickedTrack->getIdent(), clickedTrack->getName(), screenshot, 0.8f, 0.7f); } // clickedTrack != NULL } // if random_track } else if (name == "trackgroups") { buildTrackList(); } else if (name == "back") { StateManager::get()->escapePressed(); } } // eventCallback