xDyego
Member
Hello everyone, from the help of yours guys to leave the client's minimap in elipsy, rounded, could help me please, I want to make my client more pleasant
draw the minimap and then draw your circle over
If you want it round, you need to make a new ui structure for minimap in cpp.
not in case you know to tell me where I need to edit? or some code to per?
Bro I sent you the code the first time you asked me to show you how it was done
yes shadow, thank you, I have no idea how to do it, so I'm asking for help, are you able to help me implement this in my OTC?
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "minimap.h"
#include "tile.h"
#include "game.h"
#include "shadermanager.h"
#include <framework/graphics/image.h>
#include <framework/graphics/texture.h>
#include <framework/graphics/painter.h>
#include <framework/graphics/image.h>
#include <framework/graphics/framebuffermanager.h>
#include <framework/core/resourcemanager.h>
#include <framework/core/filestream.h>
#include <zlib.h>
Minimap g_minimap;
void MinimapBlock::clean()
{
m_tiles.fill(MinimapTile());
m_texture.reset();
m_mustUpdate = false;
}
void MinimapBlock::update()
{
if(!m_mustUpdate)
return;
ImagePtr image(new Image(Size(MMBLOCK_SIZE, MMBLOCK_SIZE)));
bool shouldDraw = false;
for(int x=0;x<MMBLOCK_SIZE;++x) {
for(int y=0;y<MMBLOCK_SIZE;++y) {
uint8 c = getTile(x, y).color;
uint32 col;
if(c != 255) {
col = Color::from8bit(c).rgba();
shouldDraw = true;
} else
col = Color::alpha.rgba();
image->setPixel(x, y, col);
}
}
if(shouldDraw) {
if(!m_texture) {
m_texture = TexturePtr(new Texture(image, true));
} else {
m_texture->uploadPixels(image, true);
}
} else
m_texture.reset();
m_mustUpdate = false;
}
void MinimapBlock::updateTile(int x, int y, const MinimapTile& tile)
{
if(m_tiles[getTileIndex(x,y)].color != tile.color )
m_mustUpdate = true;
m_tiles[getTileIndex(x,y)] = tile;
}
void Minimap::init()
{
}
void Minimap::terminate()
{
clean();
}
void Minimap::clean()
{
for(int i=0;i<=Otc::MAX_Z;++i)
m_tileBlocks[i].clear();
}
void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scale, const Color& color)
{
if(screenRect.isEmpty())
return;
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
g_painter->saveState();
g_painter->setColor(Color::alpha);
g_painter->drawFilledRect(screenRect);
g_painter->resetColor();
g_painter->setClipRect(screenRect);
if(MMBLOCK_SIZE*scale <= 1 || !mapCenter.isMapPosition()) {
g_painter->restoreSavedState();
return;
}
Point blockOff = getBlockOffset(mapRect.topLeft());
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
Point start = screenRect.topLeft() -(mapRect.topLeft() - blockOff)*scale - off;
//Point padding = (mapRect.topLeft() - blockOff)*scale - off;
for(int y = blockOff.y, ys = start.y;ys<screenRect.bottom();y += MMBLOCK_SIZE, ys += MMBLOCK_SIZE*scale) {
if(y < 0 || y >= 65536)
continue;
for(int x = blockOff.x, xs = start.x;xs<screenRect.right();x += MMBLOCK_SIZE, xs += MMBLOCK_SIZE*scale) {
if(x < 0 || x >= 65536)
continue;
Position blockPos(x, y, mapCenter.z);
if(!hasBlock(blockPos))
continue;
MinimapBlock& block = getBlock(Position(x, y, mapCenter.z));
block.update();
const TexturePtr& tex = block.getTexture();
if(tex) {
Rect src(0, 0, MMBLOCK_SIZE, MMBLOCK_SIZE);
auto size = src.size() * scale;
if(m_elipsify) {
auto shader = g_shaders.getShader("elipsify");
if (shader){
shader->bind();
shader->setUniformValue(ShaderManager::MAP_CENTER_COORD, (float)screenRect.width()/2, (float)screenRect.height()/2);
shader->setUniformValue(ShaderManager::MAP_GLOBAL_COORD, (float)(xs - screenRect.left()), (float)(ys - screenRect.top()));
shader->setUniformValue(ShaderManager::MAP_WALKOFFSET, size.width(), size.height());
shader->setUniformValue(ShaderManager::MAP_ZOOM, scale);
g_painter->setShaderProgram(shader);
}
}
Rect dest(Point(xs,ys), size);
tex->setSmooth(scale < 1.0f);
g_painter->drawTexturedRect(dest, tex, src);
}
//g_painter->drawBoundingRect(Rect(xs,ys, MMBLOCK_SIZE * scale, MMBLOCK_SIZE * scale));
}
}
g_painter->restoreSavedState();
}
Point Minimap::getTilePoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
{
if(screenRect.isEmpty() || pos.z != mapCenter.z)
return Point(-1,-1);
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
Point posoff = (Point(pos.x,pos.y) - mapRect.topLeft())*scale;
return posoff + screenRect.topLeft() - off + (Point(1,1)*scale)/2;
}
Position Minimap::getTilePosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale)
{
if(screenRect.isEmpty())
return Position();
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
Point pos2d = (point - screenRect.topLeft() + off)/scale + mapRect.topLeft();
return Position(pos2d.x, pos2d.y, mapCenter.z);
}
Rect Minimap::getTileRect(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
{
if(screenRect.isEmpty() || pos.z != mapCenter.z)
return Rect();
int tileSize = 32 * scale;
Rect tileRect(0,0,tileSize, tileSize);
tileRect.moveCenter(getTilePoint(pos, screenRect, mapCenter, scale));
return tileRect;
}
Rect Minimap::calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale)
{
int w = screenRect.width() / scale, h = std::ceil(screenRect.height() / scale);
Rect mapRect(0,0,w,h);
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
return mapRect;
}
void Minimap::updateTile(const Position& pos, const TilePtr& tile)
{
MinimapTile minimapTile;
LocalPlayerPtr p = g_game.getLocalPlayer();
if(tile && (p != nullptr && tile->getPosition().z == p->getPosition().z)) {
minimapTile.color = tile->getMinimapColorByte();
minimapTile.flags |= MinimapTileWasSeen;
if(!tile->isWalkable(true))
minimapTile.flags |= MinimapTileNotWalkable;
if(!tile->isPathable())
minimapTile.flags |= MinimapTileNotPathable;
minimapTile.speed = std::min((int)std::ceil(tile->getGroundSpeed() / 10.0f), 255);
}
if(minimapTile != MinimapTile()) {
MinimapBlock& block = getBlock(pos);
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
block.updateTile(pos.x - offsetPos.x, pos.y - offsetPos.y, minimapTile);
block.justSaw();
}
}
const MinimapTile& Minimap::getTile(const Position& pos)
{
static MinimapTile nulltile;
if(pos.z <= Otc::MAX_Z && hasBlock(pos)) {
MinimapBlock& block = getBlock(pos);
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
return block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y);
}
return nulltile;
}
bool Minimap::loadImage(const std::string& fileName, const Position& topLeft, float colorFactor)
{
if(colorFactor <= 0.01f)
colorFactor = 1.0f;
try {
ImagePtr image = Image::load(fileName);
uint8 waterc = Color::to8bit(std::string("#3300cc"));
// non pathable colors
Color nonPathableColors[] = {
std::string("#ffff00"), // yellow
};
// non walkable colors
Color nonWalkableColors[] = {
std::string("#000000"), // oil, black
std::string("#006600"), // trees, dark green
std::string("#ff3300"), // walls, red
std::string("#666666"), // mountain, grey
std::string("#ff6600"), // lava, orange
std::string("#00ff00"), // positon
std::string("#ccffff"), // ice, very light blue
};
for(int y=0;y<image->getHeight();++y) {
for(int x=0;x<image->getWidth();++x) {
Color color = *(uint32*)image->getPixel(x,y);
uint8 c = Color::to8bit(color * colorFactor);
int flags = 0;
if(c == waterc || color.a() == 0) {
flags |= MinimapTileNotWalkable;
c = 255; // alpha
}
if(flags != 0) {
for(Color &col : nonWalkableColors) {
if(col == color) {
flags |= MinimapTileNotWalkable;
break;
}
}
}
if(flags != 0) {
for(Color &col : nonPathableColors) {
if(col == color) {
flags |= MinimapTileNotPathable;
break;
}
}
}
if(c == 255)
continue;
Position pos(topLeft.x + x, topLeft.y + y, topLeft.z);
MinimapBlock& block = getBlock(pos);
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
MinimapTile& tile = block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y);
if(!(tile.flags & MinimapTileWasSeen)) {
tile.color = c;
tile.flags = flags;
block.mustUpdate();
}
}
}
return true;
} catch(stdext::exception& e) {
g_logger.error(stdext::format("failed to load OTMM minimap: %s", e.what()));
return false;
}
}
void Minimap::saveImage(const std::string& fileName, const Rect& mapRect)
{
//TODO
}
bool Minimap::loadOtmm(const std::string& fileName)
{
try {
FileStreamPtr fin = g_resources.openFile(fileName);
if(!fin)
stdext::throw_exception("unable to open file");
fin->cache();
uint32 signature = fin->getU32();
if(signature != OTMM_SIGNATURE)
stdext::throw_exception("invalid OTMM file");
uint16 start = fin->getU16();
uint16 version = fin->getU16();
fin->getU32(); // flags
switch(version) {
case 1: {
fin->getString(); // description
break;
}
default:
stdext::throw_exception("OTMM version not supported");
}
fin->seek(start);
uint blockSize = MMBLOCK_SIZE * MMBLOCK_SIZE * sizeof(MinimapTile);
std::vector<uchar> compressBuffer(compressBound(blockSize));
std::vector<uchar> decompressBuffer(blockSize);
while(true) {
Position pos;
pos.x = fin->getU16();
pos.y = fin->getU16();
pos.z = fin->getU8();
// end of file
if(!pos.isValid())
break;
MinimapBlock& block = getBlock(pos);
ulong len = fin->getU16();
ulong destLen = blockSize;
fin->read(compressBuffer.data(), len);
int ret = uncompress(decompressBuffer.data(), &destLen, compressBuffer.data(), len);
if(ret != Z_OK || destLen != blockSize)
break;
memcpy((uchar*)&block.getTiles(), decompressBuffer.data(), blockSize);
block.mustUpdate();
block.justSaw();
}
fin->close();
return true;
} catch(stdext::exception& e) {
g_logger.error(stdext::format("failed to load OTMM minimap: %s", e.what()));
return false;
}
}
void Minimap::saveOtmm(const std::string& fileName)
{
try {
stdext::timer saveTimer;
FileStreamPtr fin = g_resources.createFile(fileName);
fin->cache();
//TODO: compression flag with zlib
uint32 flags = 0;
// header
fin->addU32(OTMM_SIGNATURE);
fin->addU16(0); // data start, will be overwritten later
fin->addU16(OTMM_VERSION);
fin->addU32(flags);
// version 1 header
fin->addString("OTMM 1.0"); // description
// go back and rewrite where the map data starts
uint32 start = fin->tell();
fin->seek(4);
fin->addU16(start);
fin->seek(start);
uint blockSize = MMBLOCK_SIZE * MMBLOCK_SIZE * sizeof(MinimapTile);
std::vector<uchar> compressBuffer(compressBound(blockSize));
const int COMPRESS_LEVEL = 3;
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
for(auto& it : m_tileBlocks[z]) {
int index = it.first;
MinimapBlock& block = it.second;
if(!block.wasSeen())
continue;
Position pos = getIndexPosition(index, z);
fin->addU16(pos.x);
fin->addU16(pos.y);
fin->addU8(pos.z);
ulong len = blockSize;
int ret = compress2(compressBuffer.data(), &len, (uchar*)&block.getTiles(), blockSize, COMPRESS_LEVEL);
assert(ret == Z_OK);
fin->addU16(len);
fin->write(compressBuffer.data(), len);
}
}
// end of file
Position invalidPos;
fin->addU16(invalidPos.x);
fin->addU16(invalidPos.y);
fin->addU8(invalidPos.z);
fin->flush();
fin->close();
} catch(stdext::exception& e) {
g_logger.error(stdext::format("failed to save OTMM minimap: %s", e.what()));
}
}
uniform float u_Time;
uniform float u_MapZoom;
uniform float u_TimeElapsed;
uniform vec2 u_MapCenterCoord;
uniform vec2 u_WalkOffset;
uniform vec2 u_MapGlobalCoord;
uniform sampler2D u_Tex0;
varying vec2 v_TexCoord;
void main()
{
vec2 size = vec2(158.0,163.0);
vec2 varPos = v_TexCoord*u_WalkOffset;
vec4 col = texture2D(u_Tex0, v_TexCoord);
vec2 dst = u_MapGlobalCoord - u_MapCenterCoord + varPos;
dst /= size;
if(sqrt(dot(dst, dst)) > 0.5){
col.r =0.0;
col.g =0.0;
col.b =0.0;
col.a =0.0;
}
else {
}
gl_FragColor = col;
}
How about reading a little bit up on the language required, this will help you when trying to get code to work.. even if its old code.. even the code was never intended to work with whatever you are working with. Remember C++ will always be C++!I followed the tutorial that Shiva posted, I did everything, I got the errors, but all I got was the mini map is transparent underneath, that's it, it used to be black, now it's transparent, I've tried it and I did not succeed: /