Histórico de Curtidas
-
Unknown Beats deu reputação a L3K0T em Fade Tile OTCliente 0.6.6by L3K0T
Fade Tile
Bom galera hoje vou ensina a vocês como deixar seu mapa com a alteração fade tile, exatamente igual ao vídeo do meu canal abaixo, com apenas algumas "alterações" na SOURCE do seu Otclient 0.6.6.
VÍDEO;;
TUTORIALBY L3K0T
1° VÁ EM na source do seu otcliente src\client e abra o mapview.cpp e ache;;
m_optimizedSize = Size(g_map.getAwareRange().horizontal(), g_map.getAwareRange().vertical()) * Otc::TILE_PIXELS; abaixo coloque;;
m_fadeL3K0TTime = 150; ache;;
void MapView::draw(const Rect& rect) { // update visible tiles cache when needed if(m_mustUpdateVisibleTilesCache || m_updateTilesPos > 0) updateVisibleTilesCache(m_mustUpdateVisibleTilesCache ? 0 : m_updateTilesPos); float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS; Position cameraPosition = getCameraPosition(); int drawFlags = 0; if(unlikely(g_map.isForcingAnimations()) || (likely(g_map.isShowingAnimations()) && m_viewMode == NEAR_VIEW)) drawFlags = Otc::DrawAnimations; if(m_viewMode == NEAR_VIEW) drawFlags |= Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawItems | Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawMissiles; else drawFlags |= Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawItems; if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) { m_framebuffer->bind(); if(m_mustCleanFramebuffer) { Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize); g_painter->setColor(Color::black); g_painter->drawFilledRect(clearRect); if(m_drawLights) { m_lightView->reset(); m_lightView->resize(m_framebuffer->getSize()); Light ambientLight; if(cameraPosition.z <= Otc::SEA_FLOOR) { ambientLight = g_map.getLight(); } else { ambientLight.color = 215; ambientLight.intensity = 0; } ambientLight.intensity = std::max<int>(m_minimumAmbientLight*255, ambientLight.intensity); m_lightView->setGlobalLight(ambientLight); } } g_painter->setColor(Color::white); auto it = m_cachedVisibleTiles.begin(); auto end = m_cachedVisibleTiles.end(); for(int z=m_cachedLastVisibleFloor;z>=m_cachedFirstVisibleFloor;--z) { while(it != end) { const TilePtr& tile = *it; Position tilePos = tile->getPosition(); if(tilePos.z != z) break; else ++it; if (g_map.isCovered(tilePos, m_cachedFirstVisibleFloor)) tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags); else tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags, m_lightView.get()); } if(drawFlags & Otc::DrawMissiles) { for(const MissilePtr& missile : g_map.getFloorMissiles(z)) { missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), scaleFactor, drawFlags & Otc::DrawAnimations, m_lightView.get()); } } } m_framebuffer->release(); // generating mipmaps each frame can be slow in older cards //m_framebuffer->getTexture()->buildHardwareMipmaps(); m_mustDrawVisibleTilesCache = false; } altere para;;
void MapView::draw(const Rect& rect) { // update visible tiles cache when needed if(m_mustUpdateVisibleTilesCache || m_updateTilesPos > 0) updateVisibleTilesCache(m_mustUpdateVisibleTilesCache ? 0 : m_updateTilesPos); float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS; Position cameraPosition = getCameraPosition(); int drawFlags = 0; if(unlikely(g_map.isForcingAnimations()) || (likely(g_map.isShowingAnimations()) && m_viewMode == NEAR_VIEW)) drawFlags = Otc::DrawAnimations; if(m_viewMode == NEAR_VIEW) drawFlags |= Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawItems | Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawMissiles; else drawFlags |= Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawItems; if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) { m_framebuffer->bind(); if(m_mustCleanFramebuffer) { Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize); g_painter->setColor(Color::black); g_painter->drawFilledRect(clearRect); if(m_drawLights) { m_lightView->reset(); m_lightView->resize(m_framebuffer->getSize()); Light ambientLight; if(cameraPosition.z <= Otc::SEA_FLOOR) { ambientLight = g_map.getLight(); } else { ambientLight.color = 215; ambientLight.intensity = 0; } ambientLight.intensity = std::max<int>(m_minimumAmbientLight*255, ambientLight.intensity); m_lightView->setGlobalLight(ambientLight); } } g_painter->setColor(Color::white); int ms = stdext::millis(); auto it = m_cachedVisibleTiles.begin(); auto end = m_cachedVisibleTiles.end(); for(int z=m_cachedLastVisibleFloor;z>=m_cachedFirstVisibleFloor;--z) { while(it != end) { const TilePtr& tile = *it; Position tilePos = tile->getPosition(); if(tilePos.z != z) break; else ++it; if (m_mustDrawFadeInTilesCache && ((ms - m_fadeStart) / (float)m_fadeL3K0TTime) < 1.0 && z <= m_fadeCachedLastVisibleFloor) g_painter->setOpacity(((float)((int)(ms - m_fadeStart) % m_fadeL3K0TTime) / (float)m_fadeL3K0TTime)); if (g_map.isCovered(tilePos, m_cachedFirstVisibleFloor)) tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags); else tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags, m_lightView.get()); if (m_mustDrawFadeInTilesCache) g_painter->resetOpacity(); } if(drawFlags & Otc::DrawMissiles) { for(const MissilePtr& missile : g_map.getFloorMissiles(z)) { missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), scaleFactor, drawFlags & Otc::DrawAnimations, m_lightView.get()); } } } if (m_mustDrawFadeOutTilesCache && ((ms - m_fadeStart) / (float)m_fadeL3K0TTime) < 1.0) { g_painter->setOpacity(1.0 - ((float)((int)(ms - m_fadeStart) % m_fadeL3K0TTime) / (float)m_fadeL3K0TTime)); auto f_it = m_cachedFadeTiles.begin(); auto f_end = m_cachedFadeTiles.end(); for (int z = m_fadeCachedLastVisibleFloor; z >= m_fadeCachedFirstVisibleFloor; --z) { while (f_it != f_end) { const TilePtr& tile = *f_it; Position tilePos = tile->getPosition(); if (tilePos.z != z) break; else ++f_it; if (g_map.isCovered(tilePos, m_fadeCachedFirstVisibleFloor)) tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags); else tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags, m_lightView.get()); } } g_painter->setOpacity(1); } m_framebuffer->release(); // generating mipmaps each frame can be slow in older cards //m_framebuffer->getTexture()->buildHardwareMipmaps(); m_mustDrawVisibleTilesCache = false; } float fadeOpacity = 1.0f; if(!m_shaderSwitchDone && m_fadeOutTime > 0) { fadeOpacity = 1.0f - (m_fadeTimer.timeElapsed() / m_fadeOutTime); if(fadeOpacity < 0.0f) { m_shader = m_nextShader; m_nextShader = nullptr; m_shaderSwitchDone = true; m_fadeTimer.restart(); } } if(m_shaderSwitchDone && m_shader && m_fadeInTime > 0) fadeOpacity = std::min<float>(m_fadeTimer.timeElapsed() / m_fadeInTime, 1.0f); Rect srcRect = calcFramebufferSource(rect.size()); Point drawOffset = srcRect.topLeft(); if(m_shader && g_painter->hasShaders() && g_graphics.shouldUseShaders() && m_viewMode == NEAR_VIEW) { Rect framebufferRect = Rect(0,0, m_drawDimension * m_tileSize); Point center = srcRect.center(); Point globalCoord = Point(cameraPosition.x - m_drawDimension.width()/2, -(cameraPosition.y - m_drawDimension.height()/2)) * m_tileSize; m_shader->bind(); m_shader->setUniformValue(ShaderManager::MAP_CENTER_COORD, center.x / (float)framebufferRect.width(), 1.0f - center.y / (float)framebufferRect.height()); m_shader->setUniformValue(ShaderManager::MAP_GLOBAL_COORD, globalCoord.x / (float)framebufferRect.height(), globalCoord.y / (float)framebufferRect.height()); m_shader->setUniformValue(ShaderManager::MAP_ZOOM, scaleFactor); g_painter->setShaderProgram(m_shader); } g_painter->setColor(Color::white); g_painter->setOpacity(fadeOpacity); glDisable(GL_BLEND); #if 0 // debug source area g_painter->saveAndResetState(); m_framebuffer->bind(); g_painter->setColor(Color::green); g_painter->drawBoundingRect(srcRect, 2); m_framebuffer->release(); g_painter->restoreSavedState(); m_framebuffer->draw(rect); #else m_framebuffer->draw(rect, srcRect); #endif g_painter->resetShaderProgram(); g_painter->resetOpacity(); glEnable(GL_BLEND); // this could happen if the player position is not known yet if(!cameraPosition.isValid()) return; float horizontalStretchFactor = rect.width() / (float)srcRect.width(); float verticalStretchFactor = rect.height() / (float)srcRect.height(); // avoid drawing texts on map in far zoom outs if(m_viewMode == NEAR_VIEW) { for(const CreaturePtr& creature : m_cachedFloorVisibleCreatures) { if(!creature->canBeSeen()) continue; PointF jumpOffset = creature->getJumpOffset() * scaleFactor; Point creatureOffset = Point(16 - creature->getDisplacementX(), - creature->getDisplacementY() - 2); Position pos = creature->getPosition(); Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset; p += (creature->getDrawOffset() + creatureOffset) * scaleFactor - Point(stdext::round(jumpOffset.x), stdext::round(jumpOffset.y)); p.x = p.x * horizontalStretchFactor; p.y = p.y * verticalStretchFactor; p += rect.topLeft(); int flags = 0; if(m_drawNames){ flags = Otc::DrawNames; } if(m_drawHealthBars) { flags |= Otc::DrawBars; } creature->drawInformation(p, g_map.isCovered(pos, m_cachedFirstVisibleFloor), rect, flags); } } // lights are drawn after names and before texts if(m_drawLights) m_lightView->draw(rect, srcRect); if(m_viewMode == NEAR_VIEW && m_drawTexts) { for(const StaticTextPtr& staticText : g_map.getStaticTexts()) { Position pos = staticText->getPosition(); // ony draw static texts from current camera floor, unless yells //if(pos.z != cameraPosition.z && !staticText->isYell()) // continue; if(pos.z != cameraPosition.z && staticText->getMessageMode() == Otc::MessageNone) continue; Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset; p.x = p.x * horizontalStretchFactor; p.y = p.y * verticalStretchFactor; p += rect.topLeft(); staticText->drawText(p, rect); } for(const AnimatedTextPtr& animatedText : g_map.getAnimatedTexts()) { Position pos = animatedText->getPosition(); /* // only draw animated texts from visible floors if(pos.z < m_cachedFirstVisibleFloor || pos.z > m_cachedLastVisibleFloor) continue; // dont draw animated texts from covered tiles if(pos.z != cameraPosition.z && g_map.isCovered(pos, m_cachedFirstVisibleFloor)) continue; */ if(pos.z != cameraPosition.z) continue; Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset; p.x = p.x * horizontalStretchFactor; p.y = p.y * verticalStretchFactor; p += rect.topLeft(); animatedText->drawText(p, rect); } } } ache;;
void MapView::updateVisibleTilesCache(int start) { if(start == 0) { m_cachedFirstVisibleFloor = calcFirstVisibleFloor(); m_cachedLastVisibleFloor = calcLastVisibleFloor(); assert(m_cachedFirstVisibleFloor >= 0 && m_cachedLastVisibleFloor >= 0 && m_cachedFirstVisibleFloor <= Otc::MAX_Z && m_cachedLastVisibleFloor <= Otc::MAX_Z); if(m_cachedLastVisibleFloor < m_cachedFirstVisibleFloor) m_cachedLastVisibleFloor = m_cachedFirstVisibleFloor; m_cachedFloorVisibleCreatures.clear(); m_cachedVisibleTiles.clear(); m_mustCleanFramebuffer = true; m_mustDrawVisibleTilesCache = true; m_mustUpdateVisibleTilesCache = false; m_updateTilesPos = 0; } else m_mustCleanFramebuffer = false; // there is no tile to render on invalid positions Position cameraPosition = getCameraPosition(); if(!cameraPosition.isValid()) return; bool stop = false; // clear current visible tiles cache m_cachedVisibleTiles.clear(); m_mustDrawVisibleTilesCache = true; m_updateTilesPos = 0; // cache visible tiles in draw order // draw from last floor (the lower) to first floor (the higher) for(int iz = m_cachedLastVisibleFloor; iz >= m_cachedFirstVisibleFloor && !stop; --iz) { if(m_viewMode <= FAR_VIEW) { const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1; // loop through / diagonals beginning at top left and going to top right for(int diagonal = 0; diagonal < numDiagonals && !stop; ++diagonal) { // loop current diagonal tiles int advance = std::max<int>(diagonal - m_drawDimension.height(), 0); for(int iy = diagonal - advance, ix = advance; iy >= 0 && ix < m_drawDimension.width() && !stop; --iy, ++ix) { // only start really looking tiles in the desired start if(m_updateTilesPos < start) { m_updateTilesPos++; continue; } // avoid rendering too much tiles at once if((int)m_cachedVisibleTiles.size() > MAX_TILE_DRAWS && m_viewMode >= HUGE_VIEW) { stop = true; break; } // position on current floor //TODO: check position limits Position tilePos = cameraPosition.translated(ix - m_virtualCenterOffset.x, iy - m_virtualCenterOffset.y); // adjust tilePos to the wanted floor tilePos.coveredUp(cameraPosition.z - iz); if(const TilePtr& tile = g_map.getTile(tilePos)) { // skip tiles that have nothing if(!tile->isDrawable()) continue; // skip tiles that are completely behind another tile if(g_map.isCompletelyCovered(tilePos, m_cachedFirstVisibleFloor)) continue; m_cachedVisibleTiles.push_back(tile); } m_updateTilesPos++; } } } else { // cache tiles in spiral mode static std::vector<Point> m_spiral; if(start == 0) { m_spiral.resize(m_drawDimension.area()); int width = m_drawDimension.width(); int height = m_drawDimension.height(); int tpx = width/2 - 2; int tpy = height/2 - 2; int count = 0; Rect area(0, 0, m_drawDimension); m_spiral[count++] = Point(tpx+1,tpy+1); for(int step = 1; tpx >= 0 || tpy >= 0; ++step, --tpx, --tpy) { int qs = 2*step; Rect lines[4] = { Rect(tpx, tpy, qs, 1), Rect(tpx + qs, tpy, 1, qs), Rect(tpx + 1, tpy + qs, qs, 1), Rect(tpx, tpy + 1, 1, qs), }; for(int i=0;i<4;++i) { int sx = std::max<int>(lines[i].left(), area.left()); int ex = std::min<int>(lines[i].right(), area.right()); int sy = std::max<int>(lines[i].top(), area.top()); int ey = std::min<int>(lines[i].bottom(), area.bottom()); for(int qx=sx;qx<=ex;++qx) for(int qy=sy;qy<=ey;++qy) m_spiral[count++] = Point(qx, qy); } } } for(m_updateTilesPos = start; m_updateTilesPos < (int)m_spiral.size(); ++m_updateTilesPos) { // avoid rendering too much tiles at once if((int)m_cachedVisibleTiles.size() > MAX_TILE_DRAWS) { stop = true; break; } const Point& p = m_spiral[m_updateTilesPos]; Position tilePos = cameraPosition.translated(p.x - m_virtualCenterOffset.x, p.y - m_virtualCenterOffset.y); tilePos.coveredUp(cameraPosition.z - iz); if(const TilePtr& tile = g_map.getTile(tilePos)) { if(tile->isDrawable()) m_cachedVisibleTiles.push_back(tile); } } } } if(!stop) { m_updateTilesPos = 0; m_spiral.clear(); } if(start == 0 && m_viewMode <= NEAR_VIEW) m_cachedFloorVisibleCreatures = g_map.getSightSpectators(cameraPosition, false); } altere para;;
void MapView::updateVisibleTilesCache(int start) { int m_oldCachedFirstVisibleFloor = m_cachedFirstVisibleFloor; int m_oldCachedLastVisibleFloor = m_cachedLastVisibleFloor; bool m_mustUpdateFadeTilesCache = false; if(start == 0) { m_cachedFirstVisibleFloor = calcFirstVisibleFloor(); m_cachedLastVisibleFloor = calcLastVisibleFloor(); if (m_drawFadeEffect && m_oldCachedFirstVisibleFloor != m_cachedFirstVisibleFloor) m_mustUpdateFadeTilesCache = true; assert(m_cachedFirstVisibleFloor >= 0 && m_cachedLastVisibleFloor >= 0 && m_cachedFirstVisibleFloor <= Otc::MAX_Z && m_cachedLastVisibleFloor <= Otc::MAX_Z); if(m_cachedLastVisibleFloor < m_cachedFirstVisibleFloor) m_cachedLastVisibleFloor = m_cachedFirstVisibleFloor; m_cachedFloorVisibleCreatures.clear(); m_cachedVisibleTiles.clear(); m_mustCleanFramebuffer = true; m_mustDrawVisibleTilesCache = true; m_mustUpdateVisibleTilesCache = false; m_updateTilesPos = 0; } else m_mustCleanFramebuffer = false; // there is no tile to render on invalid positions Position cameraPosition = getCameraPosition(); if(!cameraPosition.isValid()) return; bool stop = false; // clear current visible tiles cache m_cachedVisibleTiles.clear(); m_mustDrawVisibleTilesCache = true; m_updateTilesPos = 0; // cache fade visible tiles // draw from first floor that is currently visible (the higher) to the last seen visible floor // effect is only present in view mode lower than FAR_VIEW. if (m_viewMode <= FAR_VIEW && m_mustUpdateFadeTilesCache) { m_cachedFadeTiles.clear(); if (m_oldCachedFirstVisibleFloor < m_cachedFirstVisibleFloor) { m_fadeCachedLastVisibleFloor = m_cachedFirstVisibleFloor-1; // The lowest floor will be the highest floor in cache, at least one floor above it. m_fadeCachedFirstVisibleFloor = m_oldCachedFirstVisibleFloor; // The highest floor will be the old highest visible floor. m_mustDrawFadeOutTilesCache = true; m_mustDrawFadeInTilesCache = false; } else { m_fadeCachedLastVisibleFloor = m_oldCachedFirstVisibleFloor - 1; // The lowest floor will be the highest floor in cache, at least one floor above it. m_fadeCachedFirstVisibleFloor = m_cachedFirstVisibleFloor; // The highest floor will be the old highest visible floor. m_mustDrawFadeOutTilesCache = false; m_mustDrawFadeInTilesCache = true; } if (m_lastCameraFloor != cameraPosition.z) { m_lastCameraFloor = cameraPosition.z; m_fadeStart = 0; } else { m_fadeStart = stdext::millis(); } for (int iz = m_fadeCachedLastVisibleFloor; iz >= m_fadeCachedFirstVisibleFloor; --iz) { const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1; // loop through / diagonals beginning at top left and going to top right for (int diagonal = 0; diagonal < numDiagonals; ++diagonal) { // loop current diagonal tiles int advance = std::max<int>(diagonal - m_drawDimension.height(), 0); for (int iy = diagonal - advance, ix = advance; iy >= 0 && ix < m_drawDimension.width(); --iy, ++ix) { // position on current floor // TODO: check position limits Position tilePos = cameraPosition.translated(ix - m_virtualCenterOffset.x, iy - m_virtualCenterOffset.y); // adjust tilePos to the wanted floor tilePos.coveredUp(cameraPosition.z - iz); if (const TilePtr& tile = g_map.getTile(tilePos)) { //skip tiles that have nothing if (!tile->isDrawable()) continue; //skip tiles that are completely behind another tile if (g_map.isCompletelyCovered(tilePos, m_fadeCachedFirstVisibleFloor)) continue; m_cachedFadeTiles.push_back(tile); } } } } } // cache visible tiles in draw order // draw from last floor (the lower) to first floor (the higher) for(int iz = m_cachedLastVisibleFloor; iz >= m_cachedFirstVisibleFloor && !stop; --iz) { if(m_viewMode <= FAR_VIEW) { const int numDiagonals = m_drawDimension.width() + m_drawDimension.height() - 1; // loop through / diagonals beginning at top left and going to top right for(int diagonal = 0; diagonal < numDiagonals && !stop; ++diagonal) { // loop current diagonal tiles int advance = std::max<int>(diagonal - m_drawDimension.height(), 0); for(int iy = diagonal - advance, ix = advance; iy >= 0 && ix < m_drawDimension.width() && !stop; --iy, ++ix) { // only start really looking tiles in the desired start if(m_updateTilesPos < start) { m_updateTilesPos++; continue; } // avoid rendering too much tiles at once if((int)m_cachedVisibleTiles.size() > MAX_TILE_DRAWS && m_viewMode >= HUGE_VIEW) { stop = true; break; } // position on current floor //TODO: check position limits Position tilePos = cameraPosition.translated(ix - m_virtualCenterOffset.x, iy - m_virtualCenterOffset.y); // adjust tilePos to the wanted floor tilePos.coveredUp(cameraPosition.z - iz); if(const TilePtr& tile = g_map.getTile(tilePos)) { // skip tiles that have nothing if(!tile->isDrawable()) continue; // skip tiles that are completely behind another tile if(g_map.isCompletelyCovered(tilePos, m_cachedFirstVisibleFloor)) if (m_mustDrawFadeInTilesCache && tilePos.z < m_fadeCachedLastVisibleFloor + 1) continue; m_cachedVisibleTiles.push_back(tile); } m_updateTilesPos++; } } } else { // cache tiles in spiral mode static std::vector<Point> m_spiral; if(start == 0) { m_spiral.resize(m_drawDimension.area()); int width = m_drawDimension.width(); int height = m_drawDimension.height(); int tpx = width/2 - 2; int tpy = height/2 - 2; int count = 0; Rect area(0, 0, m_drawDimension); m_spiral[count++] = Point(tpx+1,tpy+1); for(int step = 1; tpx >= 0 || tpy >= 0; ++step, --tpx, --tpy) { int qs = 2*step; Rect lines[4] = { Rect(tpx, tpy, qs, 1), Rect(tpx + qs, tpy, 1, qs), Rect(tpx + 1, tpy + qs, qs, 1), Rect(tpx, tpy + 1, 1, qs), }; for(int i=0;i<4;++i) { int sx = std::max<int>(lines[i].left(), area.left()); int ex = std::min<int>(lines[i].right(), area.right()); int sy = std::max<int>(lines[i].top(), area.top()); int ey = std::min<int>(lines[i].bottom(), area.bottom()); for(int qx=sx;qx<=ex;++qx) for(int qy=sy;qy<=ey;++qy) m_spiral[count++] = Point(qx, qy); } } } for(m_updateTilesPos = start; m_updateTilesPos < (int)m_spiral.size(); ++m_updateTilesPos) { // avoid rendering too much tiles at once if((int)m_cachedVisibleTiles.size() > MAX_TILE_DRAWS) { stop = true; break; } const Point& p = m_spiral[m_updateTilesPos]; Position tilePos = cameraPosition.translated(p.x - m_virtualCenterOffset.x, p.y - m_virtualCenterOffset.y); tilePos.coveredUp(cameraPosition.z - iz); if(const TilePtr& tile = g_map.getTile(tilePos)) { if(tile->isDrawable()) m_cachedVisibleTiles.push_back(tile); } } } } if(!stop) { m_updateTilesPos = 0; m_spiral.clear(); } if(start == 0 && m_viewMode <= NEAR_VIEW) m_cachedFloorVisibleCreatures = g_map.getSightSpectators(cameraPosition, false); } ache;;
void MapView::updateGeometry(const Size& visibleDimension, const Size& optimizedSize) { int tileSize = 0; Size bufferSize; int possiblesTileSizes[] = {1,2,4,8,16,32}; for(int candidateTileSize : possiblesTileSizes) { bufferSize = (visibleDimension + Size(3,3)) * candidateTileSize; if(bufferSize.width() > g_graphics.getMaxTextureSize() || bufferSize.height() > g_graphics.getMaxTextureSize()) break; tileSize = candidateTileSize; if(optimizedSize.width() < bufferSize.width() - 3*candidateTileSize && optimizedSize.height() < bufferSize.height() - 3*candidateTileSize) break; } if(tileSize == 0) { g_logger.traceError("reached max zoom out"); return; } Size drawDimension = visibleDimension + Size(3,3); Point virtualCenterOffset = (drawDimension/2 - Size(1,1)).toPoint(); Point visibleCenterOffset = virtualCenterOffset; ViewMode viewMode = m_viewMode; if(m_autoViewMode) { if(tileSize >= 32 && visibleDimension.area() <= NEAR_VIEW_AREA) viewMode = NEAR_VIEW; else if(tileSize >= 16 && visibleDimension.area() <= MID_VIEW_AREA) viewMode = MID_VIEW; else if(tileSize >= 8 && visibleDimension.area() <= FAR_VIEW_AREA) viewMode = FAR_VIEW; else viewMode = HUGE_VIEW; if(viewMode >= FAR_VIEW) m_multifloor = false; else m_multifloor = true; } // draw actually more than what is needed to avoid massive recalculations on huge views /* if(viewMode >= HUGE_VIEW) { Size oldDimension = drawDimension; drawDimension = (m_framebuffer->getSize() / tileSize); virtualCenterOffset += (drawDimension - oldDimension).toPoint() / 2; } m_viewMode = viewMode; m_visibleDimension = visibleDimension; m_drawDimension = drawDimension; m_tileSize = tileSize; m_virtualCenterOffset = virtualCenterOffset; m_visibleCenterOffset = visibleCenterOffset; m_optimizedSize = optimizedSize; m_framebuffer->resize(bufferSize); requestVisibleTilesCacheUpdate(); } altere para;;
void MapView::updateGeometry(const Size& visibleDimension, const Size& optimizedSize) { int tileSize = 0; Size bufferSize; int possiblesTileSizes[] = {1,2,4,8,16,32}; for(int candidateTileSize : possiblesTileSizes) { bufferSize = (visibleDimension + Size(3,3)) * candidateTileSize; if(bufferSize.width() > g_graphics.getMaxTextureSize() || bufferSize.height() > g_graphics.getMaxTextureSize()) break; tileSize = candidateTileSize; if(optimizedSize.width() < bufferSize.width() - 3*candidateTileSize && optimizedSize.height() < bufferSize.height() - 3*candidateTileSize) break; } if(tileSize == 0) { g_logger.traceError("reached max zoom out"); return; } Size drawDimension = visibleDimension + Size(3,3); Point virtualCenterOffset = (drawDimension/2 - Size(1,1)).toPoint(); Point visibleCenterOffset = virtualCenterOffset; ViewMode viewMode = m_viewMode; if(m_autoViewMode) { if(tileSize >= 32 && visibleDimension.area() <= NEAR_VIEW_AREA) viewMode = NEAR_VIEW; else if(tileSize >= 16 && visibleDimension.area() <= MID_VIEW_AREA) viewMode = MID_VIEW; else if(tileSize >= 8 && visibleDimension.area() <= FAR_VIEW_AREA) viewMode = FAR_VIEW; else viewMode = HUGE_VIEW; if(viewMode >= FAR_VIEW) m_multifloor = false; else m_multifloor = true; } m_viewMode = viewMode; m_visibleDimension = visibleDimension; m_drawDimension = drawDimension; m_tileSize = tileSize; m_virtualCenterOffset = virtualCenterOffset; m_visibleCenterOffset = visibleCenterOffset; m_optimizedSize = optimizedSize; m_framebuffer->resize(bufferSize); requestVisibleTilesCacheUpdate(); } Agora em mapview.h
ache:;;
stdext::boolean<true> m_shaderSwitchDone; abaixo adicione;;
//efeito mapa by l3k0t stdext::boolean<true> m_drawFadeEffect; stdext::boolean<false> m_mustDrawFadeOutTilesCache; stdext::boolean<false> m_mustDrawFadeInTilesCache; std::vector<TilePtr> m_cachedFadeTiles; int m_fadeCachedFirstVisibleFloor; int m_lastCameraFloor; int m_fadeCachedLastVisibleFloor; ticks_t m_fadeStart; int m_fadeL3K0TTime;
Feito isso é só salvar e compilar com as alterações no modo REBUILDER e bom uso.
Ajudei?? REP+
Créditos:
Criadores do PokezRing
ReyHammer (criador original)
-
Unknown Beats deu reputação a Mathias Kenfi em [Loot Channel] -- Tutorial como adicionar Loot ChannelTópico atualizado!
-
Unknown Beats deu reputação a Diego Rulez em Google Cloud PlataformIntrodução
O que eu quero falar aqui não é a parte técnica de segurança, desempenho e outros pontos. Quero falar sobre o dia a dia de alguém que pretende ser um administrador e que acabou de começar um projeto. Mesmo que você seja leigo e tenha dificuldades com a "tela preta" do Linux onde você digita os comandos, ainda assim vale a pena optar pelo Linux logo de primeira pelos seguintes motivos:
Quando você for inaugurar seu servidor você vai querer que ele tenha uma boa estabilidade e não fique travando ou sendo derrubado e você vai conseguir isso apenas utilizando Linux, então pra que aprender a montar tudo no Windows se depois, de qualquer forma, você vai ter que aprender Linux? Todo conhecimento é válido, mas você estaria atrasando seu lado fazendo isso. Visual Studio, complementos, bibliotecas. Antes de compilar sua source para Windows você vai precisar fazer o download, instalar e preparar o seu ambiente de trabalho e isso vai te custar muito tempo visto que são programas pesados, que demoram para serem baixados e instalados e que precisam de configurações muito especificas para compilar sem erros. Se você pode fazer isso tudo em 5 minutos e sem erros no Linux, porque insistir no Windows?
Google Cloud Platform
Ativando os créditos
Criando o VPS
Liberando as Portas
Criando um acesso
Enviar arquivos para o VPS
A parte de compilação da source, instalar o site e abrir o server ficará para o próximo tópico, visto que, é possível aplicar em qualquer VPS e não somente do Google.
Se deseja instalar um site e fazer a compilação da source clique aqui
Se você tiver qualquer dúvida em relação a esse tutorial não fique acuado em perguntar, irei responder todas as dúvidas no tópico.
Não respondo PM, porém também estou no Discord do TibiaKing e posso ajuda-los por lá.
-
Unknown Beats deu reputação a Diego Rulez em Instalando Site e Compilando Source (Ubuntu 20.04)Nesse tutorial vou explicar como instalar tudo que é necessário para rodar qualquer site. Também ensino como compilar as sources OTX2 e TFS-1.3. Utilizarei a versão mais atual do Ubuntu, a versão 20.04.
Iniciando
Ao executar os comandos, algumas vezes será perguntado se você deseja continuar. Por padrão sempre aperte a tecla Y e em seguida a tecla ENTER do teclado, se houver algum ponto em que você precisara agir diferente eu irei indicar o que e onde fazer.
sudo apt update sudo apt upgrade sudo apt install zip sudo apt install nano
Instalando e Configurando NGINX
sudo apt install nginx sudo nano /etc/nginx/sites-available/default Nesse arquivo deve ser adicionado a chamada index.php e deve ser removido o sinal # em algumas linhas. Vou deixar em vermelho as modificações que deverão ser feitas no arquivo. Após terminar a edição aperte CTRL+X, aperte Y, aperte ENTER (tudo isso para salvar o arquivo).
server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; # Add index.php to the list if you are using PHP index index.php index.html index.htm index.nginx-debian.html; server_name example.com www.example.com; # pass PHP scripts to FastCGI server # location ~ \.php$ { include snippets/fastcgi-php.conf; # # # With php-fpm (or other unix sockets): fastcgi_pass unix:/var/run/php/php7.1-fpm.sock; # # With php-cgi (or other tcp sockets): # fastcgi_pass 127.0.0.1:9000; } } E agora, vamos reiniciar o serviço para que entre em vigor todas as alterações.
sudo systemctl restart nginx.service Para testar se ocorreu tudo certo com a instalação, insira o IP do seu VPS no navegador. Se obtiver uma tela de Boas Vindas como na imagem abaixo. Só vá para o próximo passo se estiver tudo certo até aqui.
Instalando MariaDB
sudo apt install mariadb-server
Instalando PHP
sudo apt-get install php-fpm
Instalando phpMyAdmin
Ao executar esse comando, vai aparecer uma tela indicando para você selecionar o apache2 ou lighttpd, porém não selecione nenhuma opção, apenas aperte TAB e depois ENTER.
Na próxima tela terá duas opções YES ou NO, aperte a tecla TAB para marcar a opção NO e depois aperte ENTER para prosseguir.
sudo apt-get install phpmyadmin Após isso, execute o comando a seguir e em sequencia entre no site http://ipNumericoDoSeuServer/phpmyadmin
sudo ln -s /usr/share/phpmyadmin /var/www/html
Será nescessário criar um acesso, pois qualquer outra senha que você tenha definido anteriormente provavelmente não irá funcionar. Não esqueça de substituir as informações em evidencia pelas suas.
sudo mysql -u root CREATE USER 'DIGITE UM LOGIN'@'localhost' IDENTIFIED BY 'DIGITE UMA SENHA'; GRANT ALL PRIVILEGES ON *.* TO 'DIGITE NOVAMENTE SEU LOGIN'@'localhost'; FLUSH PRIVILEGES; Após isso, acesse: 0.0.0.0/phpmyadmin. Onde você vai trocar o 0.0.0.0 pelo IP do seu VPS.
Lembra da senha que você escolheu na instalação do MariaDB? É aqui que você vai usa-la. O usuário é root e a senha é que você escolheu. Depois clique em Banco de Dados e em seguida digite um nome para o banco de dados e clique em criar.
Agora clique em importar, selecione a database e clique em executar.
Transfira os arquivos do seu site para o diretório /var/www/html. Preste muita atenção nessa parte, pois os arquivos do site já devem estar dentro da pasta html, não pode ficar algo como /var/www/html/site. Após isso, abra o arquivo config.php do website que você deseja utilizar e coloque as informações sobre o banco de dados: nome, root, senha.
Compilando a Source TFS 1.3
Entre no repositório do forgottenserver clique aqui
Faça o download para seu PC e extraia o arquivo. Renomeie a pasta extraída para otserv e abra o famoso arquivo config.lua. Configure essa parte de acordo com seus dados, também adicione a última linha.
ip = "digita o ip do VPS" -- MySQL mysqlHost = "127.0.0.1" mysqlUser = "root" mysqlPass = "digite a senha que você escolheu na instalação do Maria DB" mysqlDatabase = "digite o nome da database que você escolheu quando criou a database" mysqlPort = 3306 mysqlSock = "" passwordType = "sha1" Salve o arquivo e depois zipe a paste com a compactação .zip e envie para o diretório /home em seu VPS. Após isso, só executar em sequencia os comandos a seguir que estará compilado.
apt-get install git cmake build-essential liblua5.2-dev libgmp3-dev libmariadb-dev-compat libboost-filesystem-dev libboost-system-dev libboost-iostreams-dev libpugixml-dev libcrypto++-dev cd /home unzip otserv.zip cd otserv mkdir build && cd build cmake .. make -j 2 mv tfs.. && cd .. Para abrir o fechar o servidor respectivamente, você vai usar:
./tfs killall -9 tfs
Compilando a Source OTX 2
Entre no repositório do OTX2 clique aqui
Faça o download para seu PC e extraia o arquivo. Renomeie a pasta extraída para otserv e abra o famoso arquivo config.lua. Configure essa parte de acordo com seus dados, também adicione a última linha.
ip = "digita o ip do VPS" -- MySQL mysqlHost = "127.0.0.1" mysqlUser = "root" mysqlPass = "digite a senha que você escolheu na instalação do Maria DB" mysqlDatabase = "digite o nome da database que você escolheu quando criou a database" mysqlPort = 3306 mysqlSock = "" encryptionType = "sha1" Salve o arquivo e depois zipe a paste com a compactação .zip e envie para o diretório /home em seu VPS. Após isso, só executar em sequencia os comandos a seguir que estará compilado.
apt-get install subversion autoconf build-essential pkg-config libboost-dev libgmp3-dev libxml2-dev liblua5.1-0-dev libmariadbclient-dev-compat ccache libboost-filesystem-dev libboost-regex-dev libboost-system-dev libboost-thread-dev screen libssl-dev libboost-iostreams-dev cd /home/ unzip otserv.zip cd otserv && cd sources sh ./autogen.sh && ./configure --enable-server-diag --enable-mysql --enable-root-permission && make -j mv theotxserver .. && cd .. Para abrir o fechar o servidor respectivamente, você vai usar:
./theotxserver killall -9 theotxserver -
Unknown Beats deu reputação a L3K0T em Anunciar quem Matou um MonstroL3KOT tfs: 1.3
Bom esse sistema é bem simples, ele anuncia pro servidor todo ao matar um tal monstro especifico.
1° vai em otserv\data\creaturescripts\scripts copia um arquivo.lua, renomeia para monsterkill.lua e add dentro;;;
function onDeath(monster, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) local monstro = "Diablo" if monster:getName() == monstro then Game.broadcastMessage("O Jogador "..killer:getName().." matou o Boss " ..monster:getName().. "! ") end return true end
Em creaturescripts.xml add
<event type="death" name="monsterkill" script="monsterkill.lua"/>
Abra o xml do monstro que você quer que apareça a mensagem global depois de mata-lo e add lá no final depois de loot;;
<script> <event name="monsterkill" /> </script> feito isso, salve tudo e pronto!!! Sucesso e jamais desista do seus projetos.
ajuda sandada para @Faysal creditos: L3K0T and @Faysal
-
Unknown Beats deu reputação a chavoz em Shiny Charm PokemonOla Amigos,
Eu vi que ninguém ainda publicou o sistema Shiny Charm. Muitos servidores já o possuem. Eu crio um para o meu. Eu os compartilho.
Voces precisam da função onSpawn em creaturescript, na atualidade axo que devem ter todos em seu servidor.
Tambem precisa a funcao getSpectators, eu tenia adicionada nas sources default do meu distro (TFS 0.4)
Edite seu spawn.lua. nas primeras lineas
local shinysSpawn = { "Dodrio", "Rhydon", "Ariados", "Politoed", "Espeon", "Umbreon", "Stantler", "Mr. Mime", "Crobat", "Magmar", "Venusaur", "Charizard", "Blastoise", "Butterfree", "Beedrill", "Pidgeot", "Rattata", "Raticate" } local function doShiny(cid) if not isCreature(cid) then return true end local name2, pos2 = "Shiny ".. getCreatureName(cid), getThingPos(cid) doRemoveCreature(cid) doSendMagicEffect(pos2, 18) local shi = doCreateMonster(name2, pos2, false, true) setSto(shi, 74469, 1) end function onSpawn(cid) local name = getCreatureName(cid) if not isSummon(cid) and pokes[name] then if isInArray(shinysSpawn, name) then if getSto(cid, 74469)<=0 and getSto(cid, 22546)<=0 and getSto(cid, 637500)<=0 and getSto(cid,"golden")<=0 then if math.random(1, 120) == 1 then local list = getSpectators(getThingPos(cid), 20, 20, false) for i = 1, #list do if isPlayer(list[i]) and (getSto(list[i],13081)>=1 or getSto(list[i],13082)>=1) then sendMsg(list[i],27,"[Shiny Charm] Acaba de nacer un Shiny "..name.."! No fue por causa de Shiny Charm!") end end doShiny(cid) return true else --check for Charms local ch=1 local list = getSpectators(getThingPos(cid), 20, 20, false) for i = 1, #list do if isPlayer(list[i]) and (getSto(list[i],13081)>=1 or getSto(list[i],13082)>=1) then ch = ch + 1 if getSto(list[i],13082)>=1 then ch = ch+1 end--2x super if math.random(1, 120) <=ch then doShiny(cid) sendMsg(list[i],27,"[Shiny Charm] Felicidades grande aventurero! Nacio un Shiny "..name.." cerca tuyo por causa de tu Shiny Charm!") return true end end end ------ end end end Explicação: Basicamente, esta edição é o que está perguntando se há jogadores ao redor do Pokemon selvagem no nascimento. Se houver algum, peça para cada um deles se eles tiverem um feitiço brilhante Normal ou Especial. Se houver algum, então existe a possibilidade de que, se falhar na primeira vez que fique brilhante, ele pede novamente para cada jogador que encontrar.
O encanto brilhante dos jogadores pode ser acumulado, se houver 3 jogadores ao redor de um Charizard (exemplo), haverá mais chances de ele se tornar Brilhante (já que ele passa pelo ciclo 3 vezes).
Eu espero que você entenda.
Edits: voce pode mudar aki no siguiente texto, 20, 20 e a distancia em SQM que o pokemon vai procurar jogadores (no mesmo andar na uma hunt).
13081 e 13082 sao storages do shiny charm e shiny charm Especial (doble chance do normal)
(1, 120) o rate do aparicao do Shiny selvagem. local ch = 1 e rate extra do shiny charm normal, e ch=ch+1 sumaria o doble do normal (2). Se o random do 1,120 e menor o iguai que ch, entao shiny selvagen aparece.
local ch=1 local list = getSpectators(getThingPos(cid), 20, 20, false) for i = 1, #list do if isPlayer(list[i]) and (getSto(list[i],13081)>=1 or getSto(list[i],13082)>=1) then ch = ch + 1 if getSto(list[i],13082)>=1 then ch = ch+1 end--2x super if math.random(1, 120) <=ch then
Peço desculpas pelo meu português, a verdade é que não sou Br, sou chileno. Eu envio uma saudação a todos!
Créditos: Chavoz (eu)
Voce pode publicar o sistema no outros forum, mais lembre dos Creditos pfv!
Eu convido você a experimentar meu servidor do Pokemon, ta Online. O site é Pokexmortal.com. Tenho sistemas varios como Market, Pokebar, Cast, Etc.
-
Unknown Beats deu reputação a L3K0T em Erro com lot do monstroabra seu config.lua e ache
monsterLootMessage mude para
monsterLootMessage = 3 ache
monsterLootMessageType mude para
monsterLootMessageType = 25
-
Unknown Beats deu reputação a Beeny em Extraindo sprite (pokepro, otpoke, etc)eae, se n me engano esse rolê não funciona no gla/pxg. mas, tem outros jeitos de pegar lá tb
links:
ninjaripper - https://gamebanana.com/tools/download/5638
dds converter - http://www.softsea.com/download/DDS-Converter.html
scan:
ninja ripper - https://www.virustotal.com/gui/file/60541e6a43661f0ee2e70c0a7cedb86d44a874e5376949db7a2e1f604fa5cdf1/detection
dds - https://www.virustotal.com/gui/file/611d6bbb534b8a3210b2ca1e7954d6abc3055c6f2995833fbb04b6093f418263/detection
-
Unknown Beats deu reputação a L3K0T em First to Speak Summon System - talkactionsL3K0TTFS 04 e TFS 0.3.6
Olá galera, hoje vim trazer um sistema chamado "First to Speak Summon" mais pera ai L3K0T, como funciona? Bom ele sumonar um monstro numa posição setada por sua preferencia, também verifica uma posxyz que você pode setar também e assim falar o comando "!fss"... mais pera ai L3K0T oque tem de diferente??? ... calma ... esse comando só pode ser pronunciado por 1 player somente, no caso se alguém falar o comando depois de você... não irá sumonar até que o tempo pra falar novamente acabe "configurado" e BORA PRO TUTORIAL???
TUTORIAL;;
1° vai na pasta Servidor\data\talkactions\scripts copia um arquivo.lua e renomeia para fss e dentro coloque;;
local t = { sto = 565674, --Storage global; temp = 300, --Tempo para falar em milesimo 300 = 5 minutos // segundos o comando; monstro = "Demon", --Nome monstrinho que vá nascer; localmapa = {x=1569, y=214, z=7}, --Posição aonde o monstrinho vai nascer; pisomapa = {x=1565, y=215, z=7}, --Posição aonde o player precisa estar para falar o comando de sua preferencia; msgsucesso = "monstro foi criado!!!", --Mensagem que manda ao player ao criar o monstrinho; msgsono = "Demon Está dormindo zzzZZZ", --Mensagem ao tentar usar o comando com intervalo de espera do comando; msgnull = "Está acordado corra lá", --Mensagem quando o monstro acordar } function onSay(cid, words, param, channel) local tp = getThingPos(cid) --verficação --inicio if tp.x == t.pisomapa.x and tp.y == t.pisomapa.y and tp.z == t.pisomapa.z then --verificação if getPlayerStorageValue(cid, t.sto) > os.time() then --verificação tempo doPlayerSendTextMessage(cid, 27, t.msgsono) return true end for _, cid in ipairs(getPlayersOnline()) do --verificação players global setPlayerStorageValue(cid, t.sto, os.time() + t.temp) --seta storage end doCreateMonster(t.monstro, t.localmapa) doPlayerSendTextMessage(cid, 27, t.msgsucesso) else --fora do tile if getPlayerStorageValue(cid, t.sto) > os.time() then --verificação tempo doPlayerSendTextMessage(cid, 27, t.msgsono) return true end if getPlayerStorageValue(cid, t.sto) < os.time() then --verificação tempo doPlayerSendTextMessage(cid, 27, t.msgnull) return true end end --fim script BY L3K0T return true end tag xml;;
<talkaction words="!fss" event="script" value="fss.lua"/> feito isso salva tudinho e use da melhor forma que achar.
Video;;
Créditos: @L3K0T
-
Unknown Beats recebeu reputação de Belmont em (Resolvido)Baú de quest pode ser movidon seria só configurar no item editor pra n deixar o baú "imovivel"?
-
Unknown Beats deu reputação a LeoTK em Skills/Magic Level Max 250 Limite / + Skills StagesSalve galera bom demorou mas consegui trazer esse conteúdo para vocês com ajuda de diversos amigos créditos no final do tópico.
Bom vamos lá é um conjunto de configurações + script que vai permitir todas as skills do servidor ficar limitada até 250
Primeiramente vamos até o config.lua do servidor e deixa a Rate Magic em 0.01
Ficando assim
rateMagic = 0.01 Logo depois disso vamos ao vocation.xml e procure por
manamultiplier="1.2" Use o notepad++ Aperte ctrl + H para substituir todos os manamultiplier="1.2" por manamultiplier="1.0"
manamultiplier="1.0" Essa modificação vai permitir a sua magic level chegar a 250
Depois faça isso com as demais skills Club / Sword / Axe / Distance / Shield / Fishing - Mude todos para 1.0
Depois disso agora vamos instalar os scripts para criar limites para as skills não bugarem e também vamos configurar a rate do magic level para não bugar também
Vá em data/creaturescripts/creaturescripts.xml e adicione essas tags
<!-- Skills Block / Stages Skills --> <event type="advance" name="skillblock" event="script" value="skillblock.lua"/> <event type="login" name="skillblock2" event="script" value="skillblock2.lua"/> <event type="death" name="skillblock3" event="script" value="skillblock3.lua"/> <event type="advance" name="skillblock4" event="script" value="skillblock4.lua"/> <event type="login" name="skillblock6" event="script" value="skillblock6.lua"/> Agora abra o login.lua e adicione isso
registerCreatureEvent(cid, "skillblock") registerCreatureEvent(cid, "skillblock2") registerCreatureEvent(cid, "skillblock3") registerCreatureEvent(cid, "skillblock4")
Crie o arquivo skillblock.lua e adicione isso dentro
Lembre-se coloque um numero anterior ao limite ou seja o limite de fist e 250 mas no maxLevel esta 254
Crie o Arquivo skillblock2.lua e adicione isso dentro
Crie o Arquivo skillblock3.lua e adicione isso dentro
Crie o Arquivo skillblock4.lua e adicione isso dentro
Crie o Arquivo skillblock5.lua e adicione isso dentro
Crie um Arquivo skillblock6.lua e adicione isso dentro
Algumas imagens mostrando funcionando no meu caso eu configurei para enviar a mensagem em uma channel caso se interessar nesse sistema basta seguir o link Clicando Aqui
Créditos:
@movie
@Coltera
@lordzetros
@Yan Liima
@aspira
Night Wolf
-
Unknown Beats deu reputação a L3K0T em Saiba todas as funções do seu TFSComo diz o titulo? você pode gerar suas funções do seu tfs em um arquivo texto, para fazer isso é só ir na lib 050 e adicionar isso no final, depois é só ligar o seu servidor e assim todas funções do seu server vai aparecer no arquivo txt. "Isso é bom pra resolver problemas de scripts e trabalhar de forma melhor, com a manipulação do mesmo."
function getLuaFunctions() local str = "" for f,k in pairs(_G) do if type(k) == 'function' then str = str..f..',' elseif type(k) == 'table' then for d,o in pairs(k) do if type(o) == 'function' then if f ~= '_G' and d ~= "_G" and f ~= 'package' then str = str..f.."."..d..',' end elseif type(o) == 'table' then for m,n in pairs(o) do if type(n) == 'function' then if d == "_M" and m ~= "_M" and f ~= "_G" and f ~= 'package' then str = str..f.."."..m.."," elseif f ~= '_G' and m ~= "_G" and d ~= "_G" and f ~= 'package' then str = str..f.."."..d..'.'..m..',' end elseif type(n) == 'table' then for x,p in pairs(n) do if type(p) == 'function' then if m == "_M" and d ~= "_M" and f ~= "_G" and f ~= 'package' then str = str..f.."."..d..'.'..x..',' elseif m == "_M" and d == "_M" and f ~= "_G" and f ~= 'package' then str = str..f.."."..x..',' elseif m ~= "_M" and d == "_M" and f ~= "_G" and f ~= 'package' then str = str..f..'.'..m..'.'..x..',' elseif f ~= '_G' and m ~= "_G" and d ~= "_G" and f ~= 'package' then str = str..f.."."..d..'.'..m..'.'..x..',' end end end end end end end end end return string.explode(str,',') end local k = getLuaFunctions() local file__ = io.open('funcoes do seu servidor.txt','w') table.sort(k) for i=1,#k do if k[i] ~= "" then file__:write((i-1)..' - '..k[i]..'\n') end end file__:close() Créditos: Mock
-
Unknown Beats deu reputação a .HuRRiKaNe em Teleport com limiteO script determina quantos jogadores podem utilizar uma área por vez!
Preview:
m data/movements/scripts crie um arquivo com o nome tplimit.lua e dentro coloque:
local c = { limit = 5, -- Limite de jogadores msgCancel = 'Tp bloqueado. Maximo de jogadores atingido', -- Mensagem quando o limite de jogadores estiver atingido area = { From = {x = 1069, y = 1027, z = 6}, -- Coordenada maxima superior esquerda To = {x = 1071, y = 1030, z = 7}, -- Coordenada minima inferior direita }, pos = {x = 1070, y = 1030, z = 7}, -- Coordenada onde será teletransportado local function getPlayersInArea(fromPos, toPos) local t = {} for _, cid in ipairs(getPlayersOnline()) do if isInRange(getThingPos(cid), fromPos, toPos) then table.insert(t, cid) end end return t end function onStepIn(cid, item, fromPos, toPos) if isPlayer(cid) then if table.getn(getPlayersInArea(c.area.From, c.area.To)) < c.limit then doSendMagicEffect(fromPos, CONST_ME_TELEPORT) doTeleportThing(cid, c.pos) doSendMagicEffect(getThingPos(cid), CONST_ME_TELEPORT) else doPlayerSendCancel(cid, c.msgCancel) doTeleportThing(cid, toPos, false) end end return true end
Em movements.xml adicione a tag:
<movevent type="StepIn" uniqueid="ID" event="script" value="tplimit.lua"/>
Créditos:
Belerofonte
-
Unknown Beats deu reputação a L3K0T em UPDATE 3: Moveitem + Antipush + Anti-Crash Elf Bot - Bug Fixes - TFS 0.4 11/04/2024TUTORIAL BY L3K0T PT~EN
Olá pessoal, trago a vocês uma atualização que fiz no sistema, contendo 3 novas funcionalidades de movimentação de itens e uma proteção contra Elf Bot. Estas adições foram cuidadosamente implementadas para aperfeiçoar a experiência de jogo e manter a integridade do seu servidor.
As novas funcionalidades têm a função vital de impedir que jogadores deixem itens indesejados em locais inapropriados, como na entrada de sua casa, em cima de seus depósitos ou em teleportes. Agora, apenas proprietários, subproprietários e convidados têm permissão para manipular itens nesses locais.
Este pacote de atualização foi meticulosamente revisado para evitar abusos por parte de jogadores mal-intencionados e garantir um ambiente de jogo justo e equilibrado para todos os usuários.
Iniciando o Tutorial
1Abra o arquivo "creatureevents.cpp" com o editor de sua preferência. Eu pessoalmente recomendo o Notepad++.
Em creatureevents.cpp:
return "onPrepareDeath"; Adicione abaixo:
case CREATURE_EVENT_MOVEITEM: return "onMoveItem"; case CREATURE_EVENT_MOVEITEM2: return "onMoveItem2";
Em:
return "cid, deathList"; Adicione abaixo:
case CREATURE_EVENT_MOVEITEM: return "moveItem, frompos, topos, cid"; case CREATURE_EVENT_MOVEITEM2: return "cid, item, count, toContainer, fromContainer, fromPos, toPos";
Em:
m_type = CREATURE_EVENT_PREPAREDEATH; Adicione abaixo:
else if(tmpStr == "moveitem") m_type = CREATURE_EVENT_MOVEITEM; else if(tmpStr == "moveitem2") m_type = CREATURE_EVENT_MOVEITEM2;
Procure por:
bool CreatureEvents::playerLogout(Player* player, bool forceLogout) { //fire global event if is registered bool result = true; for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it) { if((*it)->getEventType() == CREATURE_EVENT_LOGOUT && (*it)->isLoaded() && !(*it)->executeLogout(player, forceLogout) && result) result = false; } return result; } Adicione abaixo:
uint32_t CreatureEvents::executeMoveItems(Creature* actor, Item* item, const Position& frompos, const Position& pos) { // fire global event if is registered for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it) { if((*it)->getEventType() == CREATURE_EVENT_MOVEITEM) { if(!(*it)->executeMoveItem(actor, item, frompos, pos)) return 0; } } return 1; }
Em:
bool CreatureEvents::playerLogin(Player* player) { //fire global event if is registered bool result = true; for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it) { if((*it)->getEventType() == CREATURE_EVENT_LOGIN && (*it)->isLoaded() && !(*it)->executeLogin(player) && result) result = false; } if (result) { for(CreatureEventList::iterator it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it) { CreatureEvent* event = *it; if(event->isLoaded() && ( event->getRegister() == "player" || event->getRegister() == "all") ) player->registerCreatureEvent(event->getName()); } } return result; } Adicione Abaixo:
uint32_t CreatureEvent::executeMoveItem(Creature* actor, Item* item, const Position& frompos, const Position& pos) { //onMoveItem(moveItem, frompos, position, cid) if(m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); if(m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(pos); std::stringstream scriptstream; env->streamThing(scriptstream, "moveItem", item, env->addThing(item)); env->streamPosition(scriptstream, "position", frompos, 0); env->streamPosition(scriptstream, "position", pos, 0); scriptstream << "local cid = " << env->addThing(actor) << std::endl; scriptstream << m_scriptData; bool result = true; if(m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); } m_interface->releaseEnv(); return result; } else { #ifdef __DEBUG_LUASCRIPTS__ char desc[35]; sprintf(desc, "%s", player->getName().c_str()); env->setEventDesc(desc); #endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(pos); lua_State* L = m_interface->getState(); m_interface->pushFunction(m_scriptId); LuaInterface::pushThing(L, item, env->addThing(item)); LuaInterface::pushPosition(L, frompos, 0); LuaInterface::pushPosition(L, pos, 0); lua_pushnumber(L, env->addThing(actor)); bool result = m_interface->callFunction(4); m_interface->releaseEnv(); return result; } } else { std::clog << "[Error - CreatureEvent::executeMoveItem] Call stack overflow." << std::endl; return 0; } } uint32_t CreatureEvent::executeMoveItem2(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack) { //onMoveItem2(cid, item, count, toContainer, fromContainer, fromPos, toPos) if(m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); if(m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(player->getPosition()); std::stringstream scriptstream; scriptstream << "local cid = " << env->addThing(player) << std::endl; env->streamThing(scriptstream, "item", item, env->addThing(item)); scriptstream << "local count = " << count << std::endl; env->streamThing(scriptstream, "toContainer", toContainer, env->addThing(toContainer)); env->streamThing(scriptstream, "fromContainer", fromContainer, env->addThing(fromContainer)); env->streamPosition(scriptstream, "fromPos", fromPos, fstack); env->streamPosition(scriptstream, "toPos", toPos, 0); scriptstream << m_scriptData; bool result = true; if(m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); } m_interface->releaseEnv(); return result; } else { #ifdef __DEBUG_LUASCRIPTS__ char desc[30]; sprintf(desc, "%s", player->getName().c_str()); env->setEvent(desc); #endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(player->getPosition()); lua_State* L = m_interface->getState(); m_interface->pushFunction(m_scriptId); lua_pushnumber(L, env->addThing(player)); LuaInterface::pushThing(L, item, env->addThing(item)); lua_pushnumber(L, count); LuaInterface::pushThing(L, toContainer, env->addThing(toContainer)); LuaInterface::pushThing(L, fromContainer, env->addThing(fromContainer)); LuaInterface::pushPosition(L, fromPos, fstack); LuaInterface::pushPosition(L, toPos, 0); //lua_pushnumber(L, env->addThing(actor)); bool result = m_interface->callFunction(7); m_interface->releaseEnv(); return result; } } else { std::clog << "[Error - CreatureEvent::executeMoveItem] Call stack overflow." << std::endl; return 0; } }
Agora em em creatureevents.h:
CREATURE_EVENT_PREPAREDEATH, Adicione abaixo:
CREATURE_EVENT_MOVEITEM, CREATURE_EVENT_MOVEITEM2
Em:
uint32_t executePrepareDeath(Creature* creature, DeathList deathList); Adicione abaixo:
uint32_t executeMoveItem(Creature* actor, Item* item, const Position& frompos, const Position& pos); uint32_t executeMoveItem2(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack);
Em:
bool playerLogout(Player* player, bool forceLogout); Abaixo adicone também
uint32_t executeMoveItems(Creature* actor, Item* item, const Position& frompos, const Position& pos); uint32_t executeMoveItem2(Player* player, Item* item, uint8_t count, const Position& fromPos, const Position& toPos, Item* toContainer, Item* fromContainer, int16_t fstack);
Agora em em game.cpp:
if(!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere)) { player->sendCancelMessage(RET_CANNOTTHROW); return false; } ReturnValue ret = internalMoveItem(player, fromCylinder, toCylinder, toIndex, item, count, NULL); if(ret == RET_NOERROR) return true; player->sendCancelMessage(ret); return false; } Altere para:
if (!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere)) { player->sendCancelMessage(RET_CANNOTTHROW); return false; } bool success = true; CreatureEventList moveitemEvents = player->getCreatureEvents(CREATURE_EVENT_MOVEITEM2); for (CreatureEventList::iterator it = moveitemEvents.begin(); it != moveitemEvents.end(); ++it) { Item* toContainer = toCylinder->getItem(); Item* fromContainer = fromCylinder->getItem(); if (!(*it)->executeMoveItem2(player, item, count, fromPos, toPos, (toContainer ? toContainer : 0), (fromContainer ? fromContainer : 0), fromStackpos) && success) success = false; } if (!success) return false; if (g_config.getBool(ConfigManager::ANTI_PUSH)) { std::string antiPushItems = g_config.getString(ConfigManager::ANTI_PUSH_ITEMS); IntegerVec tmpVec = vectorAtoi(explodeString(antiPushItems, ",")); if (tmpVec[0] != 0) { for (IntegerVec::iterator it = tmpVec.begin(); it != tmpVec.end(); ++it) { if (item->getID() == uint32_t(*it) && player->hasCondition(CONDITION_EXHAUST, 1)) { player->sendTextMessage(MSG_STATUS_SMALL, "Please wait a few seconds to move this item."); return false; } } } } int32_t delay = g_config.getNumber(ConfigManager::ANTI_PUSH_DELAY); if (Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_EXHAUST, delay, 0, false, 1)) player->addCondition(condition); if (!g_creatureEvents->executeMoveItems(player, item, mapFromPos, mapToPos)) return false; ReturnValue ret = internalMoveItem(player, fromCylinder, toCylinder, toIndex, item, count, NULL); if (ret != RET_NOERROR) { player->sendCancelMessage(ret); return false; } player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::ACTIONS_DELAY_INTERVAL) - 10); return true; }
Agora em configmanager.h
ADMIN_ENCRYPTION_DATA Adicione abaixo:
ANTI_PUSH_ITEMS,
em:
STAMINA_DESTROY_LOOT, Adicione abaixo:
ANTI_PUSH_DELAY,
em:
ADDONS_PREMIUM, Adicione abaixo:
ANTI_PUSH
Agora você pode compilar a Source.
Configurando no servidor:
Abra seu config.lua do servidor e adicione isso dentro qualquer lugar:
-- Anti-Push useAntiPush = true antiPushItems = "2148,2152,2160,3976" antiPushDelay = 500
Navegue até o diretório 'creaturescripts' e localize o arquivo 'login.lua'.
em resgistros de eventos adicione:
login.lua
registerCreatureEvent(cid, "MoveItem") registerCreatureEvent(cid, "MoveItem2")
Agora abra o aquivo creaturescript .xml
<event type="moveitem" name="MoveItem" event="script" value="houseprotecao.lua"/> <event type="moveitem2" name="MoveItem2" event="script" value="moveitem2.lua"/>
Crie um novo arquivo lua em scripts com o nome houseprotecao.lua e adicione isso:
function onMoveItem(moveItem, frompos, position, cid) if position.x == CONTAINER_POSITION then return true end local house = getHouseFromPos(frompos) or getHouseFromPos(position) --correção 100% if type(house) == "number" then local owner = getHouseOwner(house) if owner == 0 then return false, doPlayerSendCancel(cid, "Isso não é Possível.") end if owner ~= getPlayerGUID(cid) then local sub = getHouseAccessList(house, 0x101):explode("\n") local guest = getHouseAccessList(house, 0x100):explode("\n") local isInvited = false if (#sub > 0) and isInArray(sub, getCreatureName(cid)) then isInvited = true end if (#guest > 0) and isInArray(guest, getCreatureName(cid)) then isInvited = true end if not isInvited then return false, doPlayerSendCancel(cid, "Desculpe, você não está invitado.") end end end return true end
Crie um novo arquivo lua em scripts com o nome moveitem2.lua e adicione isso abaixo:
local depottiles = {} --piso pra n jogar local depots = {2589} --id dos dps local group = 3 --id dos group 6 é todos. local function checkIfThrow(pos,topos) if topos.x == 0xffff then return false end local thing = getThingFromPos(pos) if isInArray(depottiles,thing.itemid) then if not isInArea(topos,{x=pos.x-1,y=pos.y-1,z=pos.z},{x=pos.x+1,y=pos.y+1, z=pos.z}) then return true end else for i = 1, #depots do if depots[i] == getTileItemById(topos,depots[i]).itemid or getTileInfo(topos).actionid == 7483 then return true end end end return false end function onMoveItem2(cid, item, count, toContainer, fromContainer, fromPos, toPos) if isPlayer(cid) then local pos = getThingPos(cid) if getPlayerGroupId(cid) > group then return true end if checkIfThrow({x=pos.x,y=pos.y,z=pos.z,stackpos=0},toPos) then doPlayerSendCancel(cid,"Não jogue item ai!!") doSendMagicEffect(getThingPos(cid),CONST_ME_POFF) return false end end return true end
ajudei?? REP+
CRÉDITOS:
@L3K0T
Fir3element
Summ
Wise
GOD Wille
Yan Lima
-
Unknown Beats deu reputação a Belmont em Ajuda? Criar teleport ao matar o pokemon/monstro@Vitinbrdopk Tenta assim:
Em data/creaturescripts/script crie um arquivo chamado tpmonster e jogue isto dentro
local config = { message = "Parabens! O teleport vai fechar em 20 segundos", timeToRemove = 30, -- Tempo em segundos teleportId = 1387, -- Não mexa bosses = { ["Nome do Monstro"] = { x = 000, y = 000, z = 00 }, -- Posição para onde o teleporte vai levar } } local function removal(position) doRemoveThing(getTileItemById(position, config.teleportId).uid, 1) return TRUE end function onDeath(cid, corpse, killer) registerCreatureEvent(cid, "tpmonster") local position = getCreaturePosition(cid) for name, pos in pairs(config.bosses) do if name == getCreatureName(cid) then teleport = doCreateTeleport(config.teleportId, pos, position) doCreatureSay(cid, config.message, TALKTYPE_ORANGE_1) addEvent(removal, config.timeToRemove * 1000, position) doSendMagicEffect(position,10) end end return TRUE end Registra em creaturescripts.xml desta forma:
<event type="death" name="tpmonster" script="tpmonster.lua"/> Agora vá em data/monsters encontre o arquivo do monstro que deseja que abra um portal assim que morrer, e adicione este código
<script <event name="tpmonster/> </script>
Para adicionar outros monstros, só é trocar o tpmonster, para tpmonster1 em todos os arquivos, e assim sucessivamente.
-
Unknown Beats deu reputação a principe sharingan em Estatua ou porta de Teleport.Bom galera é o seguinte, eu tentei criar um NPC que teleporta por X item. Mas sempre dava um erro quando vai adiciona-lo no mapa. Ai resolvi fazer uma Script que quando você clica na Estatua, porta, parede ou coisa do tipo você é teleportado se tiver X Item.
( PS: Quando vc é teleportado o item não é removido de sua bag. Você cotinua com o item, como se fosse uma permissão !! )
Bom, vamos deixar de papo furado, e vamos ao que interessa. Vai em: data/actions/scripts crie um arquivo .lua com o nome que você quiser e cole isso:
Agora vá em actions.xml e cole essa tag:
Action ID
Nome do arquivo que você criou em: data/actions/scripts
-
Unknown Beats deu reputação a henriquesafadao em [Pedido ] Passivas personalizada para poketibialib,pokemon moves \/ Obs: Veja onde vai coloca.
creaturescripts,scripts,exp.Lua ,,, Procurar por PASSIVAS ou nome de alguma passiva existente na sua base é adicione em baixo da passiva que você acha \/
Pra finalizar vá em lib,configuration vai ate o último passiva é adiciona a nova \/
Pronto basta adiciona no pokemon ex:> passive1 = {name = "NOME DA PASSIVA", level = 1, cd = 0, dist = 6, target = 0, f = 30, t = "fighting"},
},
-
Unknown Beats recebeu reputação de L3K0T em Deixando as Sprites mais Rápida no OTclientConsegui mano, valeu!!
-
Unknown Beats deu reputação a L3K0T em (Resolvido)Tela preta após compilar otclientTENTA DA "REBUILD" PRA COMPILAR A SOURCE NÃO CLICA EM BUILDER OLHA A SETA NA IMAGEM DO CODEBLOCK
ou tenta por isso no game things do otclient em otclient-0.6.6\modules\game_things abre game_things.lua
ache
function load() local version = g_game.getClientVersion() em baixo coloca
g_game.enableFeature(GameSpritesU32) e salva abra o cliente e ve se tá normal.
-
Unknown Beats deu reputação a L3K0T em Deixando as Sprites mais Rápida no OTclientBom galera hoje vou ensinar a vocês como acelerar as Sprites do seu jogo pra ficar como do Tíbia Global, assista o vídeo abaixo que você vai entender.
Primeiramente vá na source do seu OTClient 0.6.6 "otclient-0.6.6\src\client"ou superior e abre o game.cpp depois de aberto procure.
if(version >= 1050) mude para
if(version <= 1050) Salve e Agora vá em const.h e procure.
INVISIBLE_TICKS_PER_FRAME = 500, ITEM_TICKS_PER_FRAME = 500, mude para
INVISIBLE_TICKS_PER_FRAME = 100, ITEM_TICKS_PER_FRAME = 100,
Feito isso salve e da Rebuild no compilador do otcliente que voce usa "recompilação limpa"
Depois de compilar vá no seu Object Builder e compile seu cliente pra "Improved Animations"
pronto, agora só usar
ATENÇÃO
USE SOMENTE EM CASO DE ERROS DO OTCLIENT, CASO NÃO LER SEU CLIENTE;
ache
function load() local version = g_game.getClientVersion() em baixo coloca
g_game.enableFeature(GameSpritesU32)
-
Unknown Beats deu reputação a Cat em Deixando as Sprites mais Rápida no OTclientVlw pelo conteúdo @L3K0T
muito boa sua iniciativa de trazer video-tutoriais, espero ver mais deles por aqui, obrigado mesmo!
-
Unknown Beats deu reputação a L3K0T em Deixando as Sprites mais Rápida no OTclientrecompila usando a opção REBUILD
-
Unknown Beats deu reputação a L3K0T em Deixando as Sprites mais Rápida no OTclientvo passar o meu minGW ai se troca o seu, pelo meu a pasta do disco C
https://www.mediafire.com/file/oc6w2t6cf40vhcd/MinGW.rar/file
scan: https://www.virustotal.com/gui/file/42e501946ac775387e6a7491ac7f3ae6c72b1a5e4ef742d55637b0476a1e5ad2/detection
-
Unknown Beats recebeu reputação de
ADM Flowem Compile ClienteSim, eu compilo poketibia também e uso o vs2013 community
As libs estão no tutorial porém baixe esse Boost aqui e troque pelo o que vem na pasta libs pra não dá erro:
https://www.sendspace.com/file/k5hwxf
scan: https://www.virustotal.com/gui/file/8a519208ae63e3954784c7a3e3c89ab6fe75e4bcd174f12280575779a62c84be/detection
Tutorial:
-
Unknown Beats recebeu reputação de Cat em (Resolvido)Tela preta após compilar otclientAí pessoal acabei de compilar o Otc sem mudar anda demais e ficou tudo bugado ?
Segui esse tutorial aqui: