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
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
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
invisible creatures name offset is incorrect
== P3 BUGS
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)
{
if(oldPos == newPos)
return;
// get walk direction
Otc::Direction direction = oldPos.getDirectionFromPosition(newPos);
@ -492,6 +495,7 @@ void Creature::setHealthPercent(uint8 healthPercent)
void Creature::setDirection(Otc::Direction direction)
{
assert(direction != Otc::InvalidDirection);
m_direction = direction;
}

View File

@ -279,7 +279,6 @@ void Game::processInventoryChange(int slot, const ItemPtr& item)
void Game::processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos)
{
// animate walk
if(oldPos.isInRange(newPos, 1, 1))
creature->walk(oldPos, newPos);
}
@ -480,8 +479,9 @@ void Game::walk(Otc::Direction direction)
return;
// only do prewalks to walkable tiles
TilePtr fromTile = m_localPlayer->getTile();
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);
else
m_localPlayer->lockWalk();

View File

@ -132,15 +132,10 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
if(!thing)
return;
Position oldPos = thing->getPosition();
TilePtr tile = getOrCreateTile(pos);
if(CreaturePtr creature = thing->asCreature()) {
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()) {
if(MissilePtr missile = thing->asMissile()) {
m_floorMissiles[pos.z].push_back(missile);
} else if(AnimatedTextPtr animatedText = thing->asAnimatedText()) {
m_animatedTexts.push_back(animatedText);
@ -169,6 +164,15 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
thing->startAnimation();
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);
}
@ -291,6 +295,19 @@ void Map::setCentralPosition(const Position& centralPosition)
else
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)

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;
}
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)
{
for(uint stackpos = 0; stackpos < m_things.size(); ++stackpos)

View File

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

View File

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