2011-08-28 15:17:58 +02:00
|
|
|
/*
|
2012-01-02 17:58:37 +01:00
|
|
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
2011-08-28 15:17:58 +02:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2011-08-15 16:11:24 +02:00
|
|
|
#include "map.h"
|
|
|
|
#include "game.h"
|
2011-08-15 23:02:52 +02:00
|
|
|
#include "localplayer.h"
|
2011-08-29 16:14:21 +02:00
|
|
|
#include "tile.h"
|
2011-09-02 00:00:46 +02:00
|
|
|
#include "item.h"
|
2011-11-08 02:44:30 +01:00
|
|
|
#include "missile.h"
|
2011-12-29 18:45:59 +01:00
|
|
|
#include "statictext.h"
|
2011-12-29 19:18:12 +01:00
|
|
|
|
2011-08-15 16:11:24 +02:00
|
|
|
#include <framework/graphics/graphics.h>
|
|
|
|
#include <framework/graphics/framebuffer.h>
|
2011-12-07 20:54:28 +01:00
|
|
|
#include <framework/graphics/paintershaderprogram.h>
|
|
|
|
#include <framework/graphics/paintershadersources.h>
|
|
|
|
#include <framework/graphics/texture.h>
|
2011-12-29 19:18:12 +01:00
|
|
|
|
2011-08-15 23:02:52 +02:00
|
|
|
Map g_map;
|
|
|
|
|
2011-11-23 05:27:58 +01:00
|
|
|
Map::Map()
|
|
|
|
{
|
2011-11-23 05:33:04 +01:00
|
|
|
setVisibleSize(Size(MAP_VISIBLE_WIDTH, MAP_VISIBLE_HEIGHT));
|
2011-11-23 05:27:58 +01:00
|
|
|
}
|
|
|
|
|
2011-08-21 05:21:35 +02:00
|
|
|
void Map::draw(const Rect& rect)
|
2011-08-15 16:11:24 +02:00
|
|
|
{
|
2011-12-07 20:54:28 +01:00
|
|
|
if(!m_framebuffer) {
|
2011-12-25 00:14:12 +01:00
|
|
|
Size fboSize(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS);
|
|
|
|
m_framebuffer = FrameBufferPtr(new FrameBuffer(fboSize));
|
2011-08-15 16:11:24 +02:00
|
|
|
|
2011-12-07 20:54:28 +01:00
|
|
|
|
2011-12-29 19:18:12 +01:00
|
|
|
m_shaderProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
|
|
|
m_shaderProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
|
|
|
m_shaderProgram->addShaderFromSourceFile(Shader::Fragment, "/game_shaders/map.frag");
|
|
|
|
assert(m_shaderProgram->link());
|
2011-12-07 20:54:28 +01:00
|
|
|
}
|
|
|
|
|
2011-12-07 01:31:55 +01:00
|
|
|
g_painter.setColor(Fw::white);
|
2011-08-15 16:11:24 +02:00
|
|
|
m_framebuffer->bind();
|
|
|
|
|
2011-09-02 00:00:46 +02:00
|
|
|
// draw offsets
|
2011-08-31 01:39:14 +02:00
|
|
|
LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
|
2011-11-23 04:11:49 +01:00
|
|
|
if(localPlayer)
|
|
|
|
m_drawOffset = localPlayer->getWalkOffset();
|
2011-08-31 01:39:14 +02:00
|
|
|
|
2011-09-02 00:02:54 +02:00
|
|
|
//TODO: cache first/last visible floor
|
2011-09-02 00:00:46 +02:00
|
|
|
// draw from bottom floors to top floors
|
|
|
|
int firstFloor = getFirstVisibleFloor();
|
|
|
|
const int lastFloor = MAX_Z-1;
|
|
|
|
for(int iz = lastFloor; iz >= firstFloor; --iz) {
|
2011-09-02 00:02:54 +02:00
|
|
|
// draw tiles like linus pauling's rule order
|
2011-11-23 04:11:49 +01:00
|
|
|
const int numDiagonals = m_size.width() + m_size.height() - 1;
|
2011-09-02 00:00:46 +02:00
|
|
|
for(int diagonal = 0; diagonal < numDiagonals; ++diagonal) {
|
|
|
|
// loop through / diagonal tiles
|
2011-11-23 04:11:49 +01:00
|
|
|
for(int ix = std::min(diagonal, m_size.width() - 1), iy = std::max(diagonal - m_size.width(), 0); ix >= 0 && iy < m_size.height(); --ix, ++iy) {
|
2011-09-02 00:00:46 +02:00
|
|
|
// position on current floor
|
2011-11-23 04:11:49 +01:00
|
|
|
Position tilePos(m_centralPosition.x + (ix - m_centralOffset.x), m_centralPosition.y + (iy - m_centralOffset.y), m_centralPosition.z);
|
2011-09-02 00:00:46 +02:00
|
|
|
// adjust tilePos to the wanted floor
|
|
|
|
tilePos.perspectiveUp(m_centralPosition.z - iz);
|
2011-09-02 02:00:29 +02:00
|
|
|
//TODO: cache visible tiles, m_tiles[] has a high cost (50% fps decrease)
|
|
|
|
if(const TilePtr& tile = m_tiles[tilePos]) {
|
|
|
|
// skip tiles that are behind another tile
|
|
|
|
//if(isCompletlyCovered(tilePos, firstFloor))
|
|
|
|
// continue;
|
2012-01-05 19:34:37 +01:00
|
|
|
tile->draw(positionTo2D(tilePos) - m_drawOffset, rect);
|
2011-09-02 02:00:29 +02:00
|
|
|
}
|
2011-08-15 16:11:24 +02:00
|
|
|
}
|
|
|
|
}
|
2011-11-08 02:44:30 +01:00
|
|
|
|
|
|
|
// after drawing all tiles, draw shots
|
|
|
|
for(const MissilePtr& shot : m_missilesAtFloor[iz]) {
|
2012-01-04 11:26:58 +01:00
|
|
|
Position missilePos = shot->getPos();
|
2012-01-05 19:34:37 +01:00
|
|
|
shot->draw(positionTo2D(missilePos) - m_drawOffset, rect);
|
2011-11-08 02:44:30 +01:00
|
|
|
}
|
2011-08-15 16:11:24 +02:00
|
|
|
}
|
|
|
|
|
2011-12-07 01:31:55 +01:00
|
|
|
m_framebuffer->release();
|
2011-08-20 22:30:41 +02:00
|
|
|
|
2011-12-07 20:54:28 +01:00
|
|
|
|
2011-12-29 19:18:12 +01:00
|
|
|
g_painter.setCustomProgram(m_shaderProgram);
|
2011-12-08 00:43:12 +01:00
|
|
|
g_painter.setColor(Fw::white);
|
|
|
|
m_framebuffer->draw(rect);
|
|
|
|
g_painter.releaseCustomProgram();
|
2011-08-21 05:21:35 +02:00
|
|
|
|
|
|
|
// calculate stretch factor
|
2011-11-23 04:11:49 +01:00
|
|
|
float horizontalStretchFactor = rect.width() / (float)(m_visibleSize.width() * NUM_TILE_PIXELS);
|
|
|
|
float verticalStretchFactor = rect.height() / (float)(m_visibleSize.height() * NUM_TILE_PIXELS);
|
2011-08-21 05:21:35 +02:00
|
|
|
|
|
|
|
// draw player names and health bars
|
2011-09-02 02:00:29 +02:00
|
|
|
//TODO: this must be cached with creature walks
|
2011-11-23 04:11:49 +01:00
|
|
|
for(int x = 0; x < m_visibleSize.width(); ++x) {
|
|
|
|
for(int y = 0; y < m_visibleSize.height(); ++y) {
|
|
|
|
Position tilePos = Position(m_centralPosition.x + (x - m_centralOffset.x + 1), m_centralPosition.y + (y - m_centralOffset.y + 1), m_centralPosition.z);
|
2011-08-31 01:39:14 +02:00
|
|
|
if(const TilePtr& tile = m_tiles[tilePos]) {
|
2011-08-31 22:22:57 +02:00
|
|
|
auto creatures = tile->getCreatures();
|
2011-08-31 01:39:14 +02:00
|
|
|
|
|
|
|
if(creatures.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
for(const CreaturePtr& creature : creatures) {
|
2011-11-23 04:11:49 +01:00
|
|
|
Point p((m_centralOffset.x - 1 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation(),
|
|
|
|
(m_centralOffset.y - 1 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation());
|
2011-08-21 21:09:23 +02:00
|
|
|
|
2011-08-31 01:39:14 +02:00
|
|
|
if(creature != localPlayer) {
|
2011-11-23 04:11:49 +01:00
|
|
|
p += creature->getWalkOffset() - m_drawOffset;
|
2011-08-26 17:44:29 +02:00
|
|
|
}
|
|
|
|
|
2011-11-08 02:44:30 +01:00
|
|
|
creature->drawInformation(rect.x() + p.x*horizontalStretchFactor, rect.y() + p.y*verticalStretchFactor, isCovered(tilePos, firstFloor), rect);
|
2011-08-31 01:39:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-26 12:53:16 +01:00
|
|
|
|
|
|
|
// draw animated text
|
|
|
|
for(auto it = m_animatedTexts.begin(), end = m_animatedTexts.end(); it != end; ++it) {
|
2012-01-04 11:26:58 +01:00
|
|
|
Point pos = positionTo2D((*it)->getPos()) - m_drawOffset;
|
2011-12-26 12:53:16 +01:00
|
|
|
pos.x *= horizontalStretchFactor;
|
|
|
|
pos.y *= verticalStretchFactor;
|
2012-01-05 19:34:37 +01:00
|
|
|
(*it)->draw(rect.topLeft() + pos, rect);
|
2011-12-26 12:53:16 +01:00
|
|
|
}
|
2011-12-29 18:45:59 +01:00
|
|
|
|
|
|
|
// draw static text
|
|
|
|
for(auto it = m_staticTexts.begin(), end = m_staticTexts.end(); it != end; ++it) {
|
2012-01-04 11:26:58 +01:00
|
|
|
Point pos = positionTo2D((*it)->getPos()) - m_drawOffset;
|
2011-12-29 18:45:59 +01:00
|
|
|
pos.x *= horizontalStretchFactor;
|
|
|
|
pos.y *= verticalStretchFactor;
|
2012-01-05 19:34:37 +01:00
|
|
|
(*it)->draw(rect.topLeft() + pos, rect);
|
2011-12-29 18:45:59 +01:00
|
|
|
}
|
2011-08-31 01:39:14 +02:00
|
|
|
}
|
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
void Map::clean()
|
|
|
|
{
|
|
|
|
m_tiles.clear();
|
|
|
|
}
|
|
|
|
|
2011-09-02 00:00:46 +02:00
|
|
|
int Map::getFirstVisibleFloor()
|
2011-08-31 01:39:14 +02:00
|
|
|
{
|
2011-09-02 00:00:46 +02:00
|
|
|
int firstFloor = 0;
|
|
|
|
for(int ix = -1; ix <= 1 && firstFloor < m_centralPosition.z; ++ix) {
|
|
|
|
for(int iy = -1; iy <= 1 && firstFloor < m_centralPosition.z; ++iy) {
|
|
|
|
Position currentPos(m_centralPosition.x + ix, m_centralPosition.y + iy, m_centralPosition.z);
|
|
|
|
if((ix == 0 && iy == 0) || isLookPossible(currentPos)) {
|
|
|
|
Position upperPos = currentPos;
|
|
|
|
Position perspectivePos = currentPos;
|
|
|
|
perspectivePos.perspectiveUp();
|
|
|
|
upperPos.up();
|
|
|
|
while(upperPos.z >= firstFloor) {
|
|
|
|
if(TilePtr tile = m_tiles[upperPos]) {
|
|
|
|
if(ThingPtr firstThing = tile->getThing(0)) {
|
2011-12-02 03:29:05 +01:00
|
|
|
ThingType *type = firstThing->getType();
|
|
|
|
if((type->properties[ThingType::IsGround] || type->properties[ThingType::IsOnBottom]) && !type->properties[ThingType::DontHide]) {
|
2011-09-02 00:00:46 +02:00
|
|
|
firstFloor = upperPos.z + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(TilePtr tile = m_tiles[perspectivePos]) {
|
|
|
|
if(ThingPtr firstThing = tile->getThing(0)) {
|
2011-12-02 03:29:05 +01:00
|
|
|
ThingType *type = firstThing->getType();
|
|
|
|
if((type->properties[ThingType::IsGround] || type->properties[ThingType::IsOnBottom]) && !type->properties[ThingType::DontHide]) {
|
2011-09-02 00:00:46 +02:00
|
|
|
firstFloor = perspectivePos.z + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
perspectivePos.perspectiveUp();
|
|
|
|
upperPos.up();
|
|
|
|
}
|
|
|
|
}
|
2011-08-31 07:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
2011-09-02 00:00:46 +02:00
|
|
|
return firstFloor;
|
|
|
|
}
|
2011-08-26 17:44:29 +02:00
|
|
|
|
2011-09-02 00:00:46 +02:00
|
|
|
bool Map::isLookPossible(const Position& pos)
|
|
|
|
{
|
|
|
|
TilePtr tile = m_tiles[pos];
|
|
|
|
if(tile)
|
|
|
|
return tile->isLookPossible();
|
|
|
|
return true;
|
2011-08-31 01:39:14 +02:00
|
|
|
}
|
2011-08-26 17:44:29 +02:00
|
|
|
|
2011-09-02 02:00:29 +02:00
|
|
|
bool Map::isCovered(const Position& pos, int firstFloor)
|
2011-08-31 01:39:14 +02:00
|
|
|
{
|
|
|
|
Position tilePos = pos;
|
2011-09-02 00:00:46 +02:00
|
|
|
tilePos.perspectiveUp();
|
2011-09-02 02:00:29 +02:00
|
|
|
while(tilePos.z >= firstFloor) {
|
2011-08-31 01:39:14 +02:00
|
|
|
TilePtr tile = m_tiles[tilePos];
|
2011-09-02 00:00:46 +02:00
|
|
|
if(tile && tile->isFullGround())
|
2011-08-31 01:39:14 +02:00
|
|
|
return true;
|
2011-09-02 00:00:46 +02:00
|
|
|
tilePos.perspectiveUp();
|
2011-08-31 01:39:14 +02:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2011-08-21 21:09:23 +02:00
|
|
|
|
2011-09-02 02:00:29 +02:00
|
|
|
bool Map::isCompletlyCovered(const Position& pos, int firstFloor)
|
2011-08-31 01:39:14 +02:00
|
|
|
{
|
|
|
|
Position tilePos = pos;
|
2011-09-02 00:00:46 +02:00
|
|
|
tilePos.perspectiveUp();
|
2011-09-02 02:00:29 +02:00
|
|
|
while(tilePos.z >= firstFloor) {
|
2011-08-31 01:39:14 +02:00
|
|
|
bool covered = true;
|
|
|
|
for(int x=0;x<2;++x) {
|
|
|
|
for(int y=0;y<2;++y) {
|
|
|
|
TilePtr tile = m_tiles[tilePos + Position(-x, -y, 0)];
|
2011-08-31 22:22:57 +02:00
|
|
|
if(!tile || !tile->isFullyOpaque()) {
|
2011-08-31 01:39:14 +02:00
|
|
|
covered = false;
|
|
|
|
break;
|
2011-08-21 21:09:23 +02:00
|
|
|
}
|
|
|
|
}
|
2011-08-21 05:21:35 +02:00
|
|
|
}
|
2011-08-31 01:39:14 +02:00
|
|
|
if(covered)
|
|
|
|
return true;
|
2011-09-02 00:00:46 +02:00
|
|
|
tilePos.perspectiveUp();
|
2011-08-21 05:21:35 +02:00
|
|
|
}
|
2011-08-31 01:39:14 +02:00
|
|
|
return false;
|
2011-08-15 16:11:24 +02:00
|
|
|
}
|
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
|
2011-08-16 07:47:35 +02:00
|
|
|
{
|
2011-08-17 07:04:45 +02:00
|
|
|
if(!thing)
|
|
|
|
return;
|
|
|
|
|
2011-12-27 03:18:15 +01:00
|
|
|
TilePtr tile = getTile(pos);
|
|
|
|
|
|
|
|
if(CreaturePtr creature = thing->asCreature()) {
|
|
|
|
tile->addThing(thing, stackPos);
|
|
|
|
m_creatures[creature->getId()] = creature;
|
|
|
|
}
|
|
|
|
else if(MissilePtr shot = thing->asMissile()) {
|
2012-01-04 11:26:58 +01:00
|
|
|
m_missilesAtFloor[shot->getPos().z].push_back(shot);
|
2011-11-08 02:44:30 +01:00
|
|
|
}
|
2011-12-26 12:53:16 +01:00
|
|
|
else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) {
|
|
|
|
m_animatedTexts.push_back(animatedText);
|
2011-12-29 18:45:59 +01:00
|
|
|
}
|
|
|
|
else if(StaticTextPtr staticText = thing->asStaticText()) {
|
|
|
|
bool mustAdd = true;
|
|
|
|
for(auto it = m_staticTexts.begin(), end = m_staticTexts.end(); it != end; ++it) {
|
|
|
|
StaticTextPtr cStaticText = *it;
|
2012-01-04 11:26:58 +01:00
|
|
|
if(cStaticText->getPos() == pos) {
|
2011-12-29 18:45:59 +01:00
|
|
|
// try to combine messages
|
|
|
|
if(cStaticText->addMessage(staticText->getName(), staticText->getMessageType(), staticText->getFirstMessage())) {
|
|
|
|
mustAdd = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// must add another message and rearrenge current
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mustAdd)
|
|
|
|
m_staticTexts.push_back(staticText);
|
2011-12-26 12:53:16 +01:00
|
|
|
}
|
2011-12-27 03:18:15 +01:00
|
|
|
else {
|
|
|
|
tile->addThing(thing, stackPos);
|
|
|
|
}
|
2011-11-08 02:44:30 +01:00
|
|
|
|
2011-12-27 03:18:15 +01:00
|
|
|
thing->start();
|
2012-01-04 11:26:58 +01:00
|
|
|
thing->setPos(pos);
|
2011-08-17 06:45:55 +02:00
|
|
|
}
|
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
ThingPtr Map::getThing(const Position& pos, int stackPos)
|
2011-08-17 06:45:55 +02:00
|
|
|
{
|
2011-08-31 22:22:57 +02:00
|
|
|
if(const TilePtr& tile = m_tiles[pos])
|
|
|
|
return tile->getThing(stackPos);
|
|
|
|
return nullptr;
|
2011-08-16 14:47:30 +02:00
|
|
|
}
|
|
|
|
|
2012-01-08 16:42:23 +01:00
|
|
|
void Map::removeThingByPos(const Position& pos, int stackPos)
|
2011-08-16 14:47:30 +02:00
|
|
|
{
|
2011-08-31 22:22:57 +02:00
|
|
|
if(TilePtr& tile = m_tiles[pos])
|
2012-01-08 16:42:23 +01:00
|
|
|
tile->removeThingByStackpos(stackPos);
|
2011-08-15 16:11:24 +02:00
|
|
|
}
|
2011-08-16 14:47:30 +02:00
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
void Map::removeThing(const ThingPtr& thing)
|
2011-08-17 07:04:45 +02:00
|
|
|
{
|
|
|
|
if(!thing)
|
|
|
|
return;
|
|
|
|
|
2011-11-08 02:44:30 +01:00
|
|
|
if(MissilePtr shot = thing->asMissile()) {
|
2012-01-04 11:26:58 +01:00
|
|
|
auto it = std::find(m_missilesAtFloor[shot->getPos().z].begin(), m_missilesAtFloor[shot->getPos().z].end(), shot);
|
|
|
|
if(it != m_missilesAtFloor[shot->getPos().z].end()) {
|
|
|
|
m_missilesAtFloor[shot->getPos().z].erase(it);
|
2011-11-08 02:44:30 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2011-12-26 12:53:16 +01:00
|
|
|
else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) {
|
|
|
|
auto it = std::find(m_animatedTexts.begin(), m_animatedTexts.end(), animatedText);
|
|
|
|
if(it != m_animatedTexts.end())
|
|
|
|
m_animatedTexts.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
2011-12-29 18:45:59 +01:00
|
|
|
else if(StaticTextPtr staticText = thing->asStaticText()) {
|
|
|
|
auto it = std::find(m_staticTexts.begin(), m_staticTexts.end(), staticText);
|
|
|
|
if(it != m_staticTexts.end())
|
|
|
|
m_staticTexts.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
2011-11-08 02:44:30 +01:00
|
|
|
|
2012-01-04 11:26:58 +01:00
|
|
|
if(TilePtr& tile = m_tiles[thing->getPos()])
|
2011-08-31 22:22:57 +02:00
|
|
|
tile->removeThing(thing);
|
2011-08-17 07:04:45 +02:00
|
|
|
}
|
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
TilePtr Map::getTile(const Position& pos)
|
2011-08-17 06:45:55 +02:00
|
|
|
{
|
2012-01-04 14:02:35 +01:00
|
|
|
if(!pos.isValid())
|
|
|
|
return nullptr;
|
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
TilePtr& tile = m_tiles[pos];
|
|
|
|
if(!tile)
|
|
|
|
tile = TilePtr(new Tile(pos));
|
|
|
|
return tile;
|
2011-08-17 06:45:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Map::cleanTile(const Position& pos)
|
|
|
|
{
|
|
|
|
if(TilePtr& tile = m_tiles[pos])
|
|
|
|
tile->clean();
|
|
|
|
}
|
|
|
|
|
2011-08-31 22:22:57 +02:00
|
|
|
void Map::addCreature(const CreaturePtr& creature)
|
|
|
|
{
|
|
|
|
m_creatures[creature->getId()] = creature;
|
|
|
|
}
|
|
|
|
|
2011-08-17 06:45:55 +02:00
|
|
|
CreaturePtr Map::getCreatureById(uint32 id)
|
|
|
|
{
|
2012-01-03 01:10:39 +01:00
|
|
|
if(g_game.getLocalPlayer() && (uint32)g_game.getLocalPlayer()->getId() == id)
|
2011-08-17 06:45:55 +02:00
|
|
|
return g_game.getLocalPlayer();
|
|
|
|
return m_creatures[id];
|
|
|
|
}
|
|
|
|
|
|
|
|
void Map::removeCreatureById(uint32 id)
|
|
|
|
{
|
|
|
|
m_creatures.erase(id);
|
|
|
|
}
|
2011-08-31 01:39:14 +02:00
|
|
|
|
|
|
|
void Map::setCentralPosition(const Position& centralPosition)
|
|
|
|
{
|
|
|
|
m_centralPosition = centralPosition;
|
|
|
|
}
|
2011-11-23 04:11:49 +01:00
|
|
|
|
|
|
|
void Map::setVisibleSize(const Size& visibleSize)
|
|
|
|
{
|
|
|
|
m_visibleSize = visibleSize;
|
|
|
|
|
|
|
|
if(m_visibleSize.width() > MAX_WIDTH || m_visibleSize.height() > MAX_HEIGHT)
|
|
|
|
m_visibleSize = Size(MAP_VISIBLE_WIDTH, MAP_VISIBLE_HEIGHT);
|
|
|
|
|
|
|
|
m_centralOffset = Point(std::ceil(m_visibleSize.width() / 2.0), std::ceil(m_visibleSize.height() / 2.0));
|
|
|
|
m_size = m_visibleSize + Size(3, 3);
|
|
|
|
|
2011-12-25 00:14:12 +01:00
|
|
|
if(m_framebuffer) {
|
|
|
|
m_framebuffer->resize(Size(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));
|
|
|
|
}
|
2011-11-23 04:11:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Point Map::positionTo2D(const Position& position)
|
|
|
|
{
|
|
|
|
return Point((m_centralOffset.x - 1 + (position.x - m_centralPosition.x) - (m_centralPosition.z - position.z)) * NUM_TILE_PIXELS,
|
|
|
|
(m_centralOffset.y - 1 + (position.y - m_centralPosition.y) - (m_centralPosition.z - position.z)) * NUM_TILE_PIXELS);
|
|
|
|
}
|