fixes and missing file

* fix walking on tile that has too many creatures
* add missing file
* some walk rework
This commit is contained in:
Eduardo Bart 2012-05-09 19:19:05 -03:00
parent 6495d74edd
commit 606fc38109
8 changed files with 158 additions and 12 deletions

10
BUGS
View File

@ -5,9 +5,19 @@ modules recursivity makes client crash, it should generate a warning
sometimes minimap desync Z pos sometimes minimap desync Z pos
follow and autowalk doesn't cancel when walking via hotkeys follow and autowalk doesn't cancel when walking via hotkeys
when walking on a tile with too many creatures, the following errors occurrs:
ERROR: [ProtocolGame::parseCreatureHealth] could not get greature
ERROR: [ProtocolGame::parseCreatureHealth] could not get greature
ERROR: [Map::setCentralPosition] invalid creature
ERROR: [Map::setCentralPosition] invalid creature
ERROR: [Map::setCentralPosition] invalid creature
ERROR: [Map::setCentralPosition] invalid creature
== P2 BUGS == P2 BUGS
battle sometimes doesn't clear attacked/followed creatures when they go out of range battle sometimes doesn't clear attacked/followed creatures when they go out of range
when looking from floor 5 in floor 7, sometimes a tile have 2 invisible grounds in floor 6 that should be ignored when looking from floor 5 in floor 7, sometimes a tile have 2 invisible grounds in floor 6 that should be ignored
invisible creatures name offset is incorrect
== P3 BUGS == P3 BUGS
widgets may have been destroyed when adding event in onSetup (UIResizeBorder), generating invalid events widgets may have been destroyed when adding event in onSetup (UIResizeBorder), generating invalid events

View File

@ -290,6 +290,9 @@ void Creature::turn(Otc::Direction direction)
void Creature::walk(const Position& oldPos, const Position& newPos) void Creature::walk(const Position& oldPos, const Position& newPos)
{ {
if(oldPos == newPos)
return;
// get walk direction // get walk direction
Otc::Direction direction = oldPos.getDirectionFromPosition(newPos); Otc::Direction direction = oldPos.getDirectionFromPosition(newPos);
@ -492,6 +495,7 @@ void Creature::setHealthPercent(uint8 healthPercent)
void Creature::setDirection(Otc::Direction direction) void Creature::setDirection(Otc::Direction direction)
{ {
assert(direction != Otc::InvalidDirection);
m_direction = direction; m_direction = direction;
} }

View File

@ -279,8 +279,7 @@ void Game::processInventoryChange(int slot, const ItemPtr& item)
void Game::processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos) void Game::processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos)
{ {
// animate walk // animate walk
if(oldPos.isInRange(newPos, 1, 1)) creature->walk(oldPos, newPos);
creature->walk(oldPos, newPos);
} }
void Game::processCreatureTeleport(const CreaturePtr& creature) void Game::processCreatureTeleport(const CreaturePtr& creature)
@ -480,8 +479,9 @@ void Game::walk(Otc::Direction direction)
return; return;
// only do prewalks to walkable tiles // only do prewalks to walkable tiles
TilePtr fromTile = m_localPlayer->getTile();
TilePtr toTile = g_map.getTile(m_localPlayer->getPosition().translatedToDirection(direction)); TilePtr toTile = g_map.getTile(m_localPlayer->getPosition().translatedToDirection(direction));
if(toTile && toTile->isWalkable()) if(toTile && toTile->isWalkable()/* && fromTile && fromTile->hasThing(m_localPlayer)*/)
m_localPlayer->preWalk(direction); m_localPlayer->preWalk(direction);
else else
m_localPlayer->lockWalk(); m_localPlayer->lockWalk();

View File

@ -132,15 +132,10 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
if(!thing) if(!thing)
return; return;
Position oldPos = thing->getPosition();
TilePtr tile = getOrCreateTile(pos); TilePtr tile = getOrCreateTile(pos);
if(CreaturePtr creature = thing->asCreature()) { if(MissilePtr missile = thing->asMissile()) {
Position oldPos = thing->getPosition();
tile->addThing(thing, stackPos);
if(oldPos.isValid() && !oldPos.isInRange(pos,1,1))
g_game.processCreatureTeleport(creature);
} else if(MissilePtr missile = thing->asMissile()) {
m_floorMissiles[pos.z].push_back(missile); m_floorMissiles[pos.z].push_back(missile);
} else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) { } else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) {
m_animatedTexts.push_back(animatedText); m_animatedTexts.push_back(animatedText);
@ -169,6 +164,15 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
thing->startAnimation(); thing->startAnimation();
thing->setPosition(pos); thing->setPosition(pos);
if(CreaturePtr creature = thing->asCreature()) {
if(oldPos != pos) {
if(oldPos.isInRange(pos,1,1))
g_game.processCreatureMove(creature, oldPos, pos);
else
g_game.processCreatureTeleport(creature);
}
}
notificateTileUpdateToMapViews(pos); notificateTileUpdateToMapViews(pos);
} }
@ -291,6 +295,19 @@ void Map::setCentralPosition(const Position& centralPosition)
else else
logTraceError("invalid creature"); logTraceError("invalid creature");
} }
// this fixes local player position when the local player is removed fro the map,
// the local player is removed from the map when there are too many creatures on his tile
// so there is not enough stackpos to the server send him
g_eventDispatcher.addEvent([this] {
LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
if(!localPlayer || localPlayer->getPosition() == m_centralPosition)
return;
TilePtr tile = getTile(localPlayer->getPosition());
if(!tile || tile->hasThing(localPlayer))
return;
localPlayer->setPosition(m_centralPosition);
});
} }
std::vector<CreaturePtr> Map::getSpectators(const Position& centerPos, bool multiFloor) std::vector<CreaturePtr> Map::getSpectators(const Position& centerPos, bool multiFloor)

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2010-2012 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 "thingtype.h"
#include "spritemanager.h"
#include <framework/graphics/graphics.h>
#include <framework/graphics/texture.h>
#include <framework/graphics/image.h>
ThingType::ThingType()
{
m_dimensions.fill(0);
m_parameters.fill(0);
m_properties.fill(false);
}
void ThingType::draw(const Point& dest, float scaleFactor, int w, int h, int xPattern, int yPattern, int zPattern, int layer, int animationPhase)
{
int scaledSize = Otc::TILE_PIXELS * scaleFactor;
Point displacement(m_parameters[DisplacementX], m_parameters[DisplacementY]);
Rect drawRect(dest - displacement*scaleFactor, Size(scaledSize, scaledSize));
g_painter->setColor(Color::white);
g_painter->drawTexturedRect(drawRect, getSprite(w, h, layer, xPattern, yPattern, zPattern, animationPhase));
}
void ThingType::draw(const Point& dest, float scaleFactor, int xPattern, int yPattern, int zPattern, int animationPhase)
{
for(int l = 0; l < m_dimensions[Layers]; ++l)
for(int w = 0; w < m_dimensions[Width]; ++w)
for(int h = 0; h < m_dimensions[Height]; ++h)
draw(dest - Point(w,h)*Otc::TILE_PIXELS*scaleFactor, scaleFactor, w, h, xPattern, yPattern, zPattern, l, animationPhase);
}
void ThingType::drawMask(const Point& dest, float scaleFactor, int w, int h, int xPattern, int yPattern, int zPattern, int layer, int animationPhase, ThingType::SpriteMask mask)
{
int scaledSize = Otc::TILE_PIXELS * scaleFactor;
Point displacement(m_parameters[DisplacementX], m_parameters[DisplacementY]);
Rect drawRect(dest - displacement*scaleFactor, Size(scaledSize, scaledSize));
g_painter->drawTexturedRect(drawRect, getSpriteMask(w, h, layer, xPattern, yPattern, zPattern, animationPhase, mask));
}
TexturePtr& ThingType::getSprite(int w, int h, int l, int x, int y, int z, int a)
{
uint index = getSpriteIndex(w,h,l,x,y,z,a);
TexturePtr& spriteTexture = m_sprites[index];
if(!spriteTexture) {
ImagePtr spriteImage = g_sprites.getSpriteImage(m_spritesIndex[index]);
if(!spriteImage)
spriteTexture = g_graphics.getEmptyTexture();
else {
spriteTexture = TexturePtr(new Texture(spriteImage));
spriteTexture->setSmooth(true);
if(g_graphics.canUseMipmaps())
spriteTexture->generateSoftwareMipmaps(spriteImage->getPixels());
}
}
return spriteTexture;
}
TexturePtr& ThingType::getSpriteMask(int w, int h, int l, int x, int y, int z, int a, ThingType::SpriteMask mask)
{
if(m_spritesMask.size() == 0)
m_spritesMask.resize(m_spritesIndex.size());
uint index = getSpriteIndex(w,h,l,x,y,z,a);
TexturePtr& maskTexture = m_spritesMask[index][mask];
if(!maskTexture) {
ImagePtr maskImage = g_sprites.getSpriteImage(m_spritesIndex[index]);
if(!maskImage)
maskTexture = g_graphics.getEmptyTexture();
else {
static Color maskColors[LastMask] = { Color::yellow, Color::red, Color::green, Color::blue };
maskImage->overwriteMask(maskColors[mask]);
maskTexture = TexturePtr(new Texture(maskImage));
maskTexture->setSmooth(true);
if(g_graphics.canUseMipmaps())
maskTexture->generateSoftwareMipmaps(maskImage->getPixels());
}
}
return maskTexture;
}

View File

@ -221,6 +221,11 @@ ThingPtr Tile::getThing(int stackPos)
return nullptr; return nullptr;
} }
bool Tile::hasThing(const ThingPtr& thing)
{
return std::find(m_things.begin(), m_things.end(), thing) != m_things.end();
}
int Tile::getThingStackpos(const ThingPtr& thing) int Tile::getThingStackpos(const ThingPtr& thing)
{ {
for(uint stackpos = 0; stackpos < m_things.size(); ++stackpos) for(uint stackpos = 0; stackpos < m_things.size(); ++stackpos)

View File

@ -42,6 +42,7 @@ public:
ThingPtr addThing(const ThingPtr& thing, int stackPos = -1); ThingPtr addThing(const ThingPtr& thing, int stackPos = -1);
bool removeThing(ThingPtr thing); bool removeThing(ThingPtr thing);
ThingPtr getThing(int stackPos); ThingPtr getThing(int stackPos);
bool hasThing(const ThingPtr& thing);
int getThingStackpos(const ThingPtr& thing); int getThingStackpos(const ThingPtr& thing);
ThingPtr getTopThing(); ThingPtr getTopThing();

View File

@ -446,7 +446,7 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg)
logTraceError("could not remove thing"); logTraceError("could not remove thing");
g_map.addThing(thing, newPos); g_map.addThing(thing, newPos);
g_game.processCreatureMove(creature, oldPos, newPos); //g_game.processCreatureMove(creature, oldPos, newPos);
} }
void ProtocolGame::parseOpenContainer(InputMessage& msg) void ProtocolGame::parseOpenContainer(InputMessage& msg)
@ -1269,7 +1269,6 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
if(emblem != -1) if(emblem != -1)
creature->setEmblem(emblem); creature->setEmblem(emblem);
creature->setPassable(passable); creature->setPassable(passable);
creature->setDirection(direction);
// now that the local player is known, we can schedule login event // now that the local player is known, we can schedule login event
if(creature == m_localPlayer && !m_localPlayer->isKnown()) { if(creature == m_localPlayer && !m_localPlayer->isKnown()) {