render walking creatures in the correct way
This commit is contained in:
parent
cf18b0c36f
commit
7b965a27af
|
@ -69,12 +69,12 @@ void Creature::draw(const Point& dest, float scaleFactor)
|
|||
|
||||
if(m_showVolatileSquare) {
|
||||
g_painter.setColor(m_volatileSquareColor);
|
||||
g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 3)*scaleFactor, Size(28*scaleFactor, 28*scaleFactor)), 2*scaleFactor);
|
||||
g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 3)*scaleFactor, Size(28*scaleFactor, 28*scaleFactor)), std::max((int)(2*scaleFactor), 1));
|
||||
}
|
||||
|
||||
if(m_showStaticSquare) {
|
||||
g_painter.setColor(m_staticSquareColor);
|
||||
g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 1)*scaleFactor, Size(scaledTileSize, scaledTileSize)), 2*scaleFactor);
|
||||
g_painter.drawBoundingRect(Rect(dest + (m_walkOffset - getDisplacement() + 1)*scaleFactor, Size(scaledTileSize, scaledTileSize)), std::max((int)(2*scaleFactor), 1));
|
||||
}
|
||||
|
||||
g_painter.setColor(Fw::white);
|
||||
|
@ -134,10 +134,10 @@ void Creature::draw(const Point& dest, float scaleFactor)
|
|||
}
|
||||
else if(m_outfit.getCategory() == ThingsType::Item) {
|
||||
for(int l = 0; l < getLayers(); l++)
|
||||
internalDraw(dest + m_walkOffset * scaleFactor, scaleFactor, l);
|
||||
internalDraw(dest + m_walkOffset, scaleFactor, l);
|
||||
}
|
||||
else if(m_outfit.getCategory() == ThingsType::Effect)
|
||||
internalDraw(dest + m_walkOffset * scaleFactor, scaleFactor, 0);
|
||||
internalDraw(dest + m_walkOffset, scaleFactor, 0);
|
||||
}
|
||||
|
||||
void Creature::drawInformation(const Point& point, bool useGray, const Rect& parentRect)
|
||||
|
@ -276,6 +276,36 @@ void Creature::updateWalkOffset(int totalPixelsWalked)
|
|||
m_walkOffset.x = 32 - totalPixelsWalked;
|
||||
}
|
||||
|
||||
void Creature::updateWalkingTile()
|
||||
{
|
||||
// determine new walking tile
|
||||
TilePtr newWalkingTile;
|
||||
Rect virtualCreatureRect(Otc::TILE_PIXELS + (m_walkOffset.x - getDisplacementX()),
|
||||
Otc::TILE_PIXELS + (m_walkOffset.y - getDisplacementY()),
|
||||
Otc::TILE_PIXELS, Otc::TILE_PIXELS);
|
||||
for(int xi = -1; xi <= 1 && !newWalkingTile; ++xi) {
|
||||
for(int yi = -1; yi <= 1 && !newWalkingTile; ++yi) {
|
||||
Rect virtualTileRect((xi+1)*Otc::TILE_PIXELS, (yi+1)*Otc::TILE_PIXELS, Otc::TILE_PIXELS, Otc::TILE_PIXELS);
|
||||
|
||||
// only render creatures where bottom right is inside tile rect
|
||||
if(virtualTileRect.contains(virtualCreatureRect.bottomRight())) {
|
||||
const TilePtr& tile = g_map.getTile(m_position.translated(xi, yi, 0));
|
||||
if(!tile)
|
||||
continue;
|
||||
newWalkingTile = tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(newWalkingTile != m_walkingTile) {
|
||||
if(m_walkingTile)
|
||||
m_walkingTile->removeWalkingCreature(asCreature());
|
||||
if(newWalkingTile)
|
||||
newWalkingTile->addWalkingCreature(asCreature());
|
||||
m_walkingTile = newWalkingTile;
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::nextWalkUpdate()
|
||||
{
|
||||
// remove any previous scheduled walk updates
|
||||
|
@ -303,6 +333,7 @@ void Creature::updateWalk()
|
|||
// update walk animation and offsets
|
||||
updateWalkAnimation(totalPixelsWalked);
|
||||
updateWalkOffset(totalPixelsWalked);
|
||||
updateWalkingTile();
|
||||
|
||||
// terminate walk
|
||||
if(m_walking && m_walkTimer.ticksElapsed() >= m_walkInterval)
|
||||
|
@ -323,6 +354,11 @@ void Creature::terminateWalk()
|
|||
m_walkTurnDirection = Otc::InvalidDirection;
|
||||
}
|
||||
|
||||
if(m_walkingTile) {
|
||||
m_walkingTile->removeWalkingCreature(asCreature());
|
||||
m_walkingTile = nullptr;
|
||||
}
|
||||
|
||||
m_walking = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,8 +78,6 @@ public:
|
|||
void updateInvisibleAnimation();
|
||||
void updateShield();
|
||||
|
||||
ThingType *getType();
|
||||
|
||||
// walk related
|
||||
void turn(Otc::Direction direction);
|
||||
virtual void walk(const Position& oldPos, const Position& newPos);
|
||||
|
@ -93,6 +91,7 @@ public:
|
|||
protected:
|
||||
virtual void updateWalkAnimation(int totalPixelsWalked);
|
||||
virtual void updateWalkOffset(int totalPixelsWalked);
|
||||
void updateWalkingTile();
|
||||
virtual void nextWalkUpdate();
|
||||
virtual void updateWalk();
|
||||
virtual void terminateWalk();
|
||||
|
@ -116,6 +115,7 @@ protected:
|
|||
|
||||
// walk related
|
||||
Timer m_walkTimer;
|
||||
TilePtr m_walkingTile;
|
||||
int m_walkInterval;
|
||||
int m_walkAnimationInterval;
|
||||
bool m_walking;
|
||||
|
|
|
@ -145,6 +145,7 @@ void LocalPlayer::updateWalk()
|
|||
// update walk animation and offsets
|
||||
updateWalkAnimation(totalPixelsWalked);
|
||||
updateWalkOffset(totalPixelsWalked);
|
||||
updateWalkingTile();
|
||||
|
||||
// terminate walk only when client and server side walk are complated
|
||||
if(m_walking && !m_preWalking && m_walkTimer.ticksElapsed() >= m_walkInterval)
|
||||
|
|
|
@ -304,7 +304,7 @@ std::vector<CreaturePtr> Map::getSpectatorsInRangeEx(const Position& centerPos,
|
|||
continue;
|
||||
|
||||
auto tileCreatures = tile->getCreatures();
|
||||
creatures.insert(creatures.end(), tileCreatures.begin(), tileCreatures.end());
|
||||
creatures.insert(creatures.end(), tileCreatures.rbegin(), tileCreatures.rend());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ bool Map::isAwareOfPosition(const Position& pos)
|
|||
int Map::getFirstAwareFloor()
|
||||
{
|
||||
if(m_centralPosition.z > Otc::SEA_FLOOR)
|
||||
return m_centralPosition.z-2;
|
||||
return m_centralPosition.z-Otc::AWARE_UNDEGROUND_FLOOR_RANGE;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ int Map::getFirstAwareFloor()
|
|||
int Map::getLastAwareFloor()
|
||||
{
|
||||
if(m_centralPosition.z > Otc::SEA_FLOOR)
|
||||
return std::min(m_centralPosition.z+2, (int)Otc::MAX_Z);
|
||||
return std::min(m_centralPosition.z+Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::MAX_Z);
|
||||
else
|
||||
return Otc::SEA_FLOOR;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ MapView::MapView()
|
|||
m_shaderProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
m_shaderProgram->addShaderFromSourceFile(Shader::Fragment, "/game_shaders/map.frag");
|
||||
assert(m_shaderProgram->link());
|
||||
//m_animated = false;
|
||||
}
|
||||
|
||||
void MapView::draw(const Rect& rect)
|
||||
|
@ -60,7 +59,7 @@ void MapView::draw(const Rect& rect)
|
|||
if(isNearView())
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems | Otc::DrawCreatures | Otc::DrawEffects;
|
||||
else if(isMidView())
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems;
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls | Otc::DrawCommonItems | Otc::DrawCreatures;
|
||||
else if(isFarView())
|
||||
tileDrawFlags = Otc::DrawGround | Otc::DrawWalls;
|
||||
else // huge far view
|
||||
|
@ -161,6 +160,10 @@ bool MapView::updateVisibleTilesCache()
|
|||
|
||||
int firstFloor = getFirstVisibleFloor();
|
||||
int lastFloor = getLastVisibleFloor();
|
||||
|
||||
if(lastFloor < firstFloor)
|
||||
lastFloor = firstFloor;
|
||||
|
||||
m_cachedFirstVisibleFloor = firstFloor;
|
||||
m_cachedLastVisibleFloor = lastFloor;
|
||||
Position cameraPosition = getCameraPosition();
|
||||
|
@ -291,7 +294,7 @@ int MapView::getFirstVisibleFloor()
|
|||
|
||||
// limits to underground floors while under sea level
|
||||
if(cameraPosition.z > Otc::SEA_FLOOR)
|
||||
firstFloor = Otc::SEA_FLOOR+1;
|
||||
firstFloor = cameraPosition.z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE;
|
||||
|
||||
// loop in 3x3 tiles around the camera
|
||||
for(int ix = -1; ix <= 1 && firstFloor < cameraPosition.z; ++ix) {
|
||||
|
@ -338,7 +341,7 @@ int MapView::getLastVisibleFloor()
|
|||
|
||||
// view only underground floors when below sea level
|
||||
if(cameraPosition.z > Otc::SEA_FLOOR)
|
||||
return Otc::MAX_Z;
|
||||
return cameraPosition.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE;
|
||||
else
|
||||
return Otc::SEA_FLOOR;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ class MapView : public LuaObject
|
|||
{
|
||||
enum {
|
||||
DEFAULT_FRAMBUFFER_SIZE = 2048,
|
||||
NEAR_VIEW_AREA = 4096,
|
||||
MID_VIEW_AREA = 16384,
|
||||
FAR_VIEW_AREA = 32768
|
||||
NEAR_VIEW_AREA = 64*64,
|
||||
MID_VIEW_AREA = 128*128,
|
||||
FAR_VIEW_AREA = 192*192
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -77,6 +77,8 @@ void Thing::internalDraw(const Point& dest, float scaleFactor, int layer)
|
|||
Rect drawRect((dest.x - w*scaledSize) - getDisplacementX()*scaleFactor,
|
||||
(dest.y - h*scaledSize) - getDisplacementY()*scaleFactor,
|
||||
scaledSize, scaledSize);
|
||||
|
||||
g_painter.setColor(Fw::white);
|
||||
g_painter.drawTexturedRect(drawRect, spriteTex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ Tile::Tile(const Position& position)
|
|||
|
||||
void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
|
||||
{
|
||||
m_drawElevation = 0;
|
||||
int drawElevation = 0;
|
||||
|
||||
// first bottom items
|
||||
if(drawFlags & Otc::DrawGround || drawFlags & Otc::DrawWalls) {
|
||||
|
@ -47,11 +47,11 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
|
|||
break;
|
||||
|
||||
if((drawFlags & Otc::DrawGround && thing->isGround()) || (drawFlags & Otc::DrawWalls))
|
||||
thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor);
|
||||
thing->draw(dest - drawElevation*scaleFactor, scaleFactor);
|
||||
|
||||
m_drawElevation += thing->getElevation();
|
||||
if(m_drawElevation > Otc::MAX_ELEVATION)
|
||||
m_drawElevation = Otc::MAX_ELEVATION;
|
||||
drawElevation += thing->getElevation();
|
||||
if(drawElevation > Otc::MAX_ELEVATION)
|
||||
drawElevation = Otc::MAX_ELEVATION;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,37 +59,28 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
|
|||
if(drawFlags & Otc::DrawCommonItems) {
|
||||
for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
|
||||
const ThingPtr& thing = *it;
|
||||
if(thing->asCreature() || thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround())
|
||||
if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->asCreature())
|
||||
break;
|
||||
thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor);
|
||||
thing->draw(dest - drawElevation*scaleFactor, scaleFactor);
|
||||
|
||||
m_drawElevation += thing->getElevation();
|
||||
if(m_drawElevation > Otc::MAX_ELEVATION)
|
||||
m_drawElevation = Otc::MAX_ELEVATION;
|
||||
drawElevation += thing->getElevation();
|
||||
if(drawElevation > Otc::MAX_ELEVATION)
|
||||
drawElevation = Otc::MAX_ELEVATION;
|
||||
}
|
||||
}
|
||||
|
||||
// we can render creatures in 3x3 range
|
||||
// creatures
|
||||
if(drawFlags & Otc::DrawCreatures) {
|
||||
for(int xi = -1; xi <= 1; ++xi) {
|
||||
for(int yi = -1; yi <= 1; ++yi) {
|
||||
const TilePtr& tile = g_map.getTile(m_position.translated(xi, yi, 0));
|
||||
if(!tile)
|
||||
continue;
|
||||
for(const CreaturePtr& creature : tile->getCreatures()) {
|
||||
int tileSize = Otc::TILE_PIXELS * scaleFactor;
|
||||
Rect creatureRect(dest.x + xi*tileSize + (creature->getWalkOffset().x - creature->getDisplacementX())*scaleFactor,
|
||||
dest.y + yi*tileSize + (creature->getWalkOffset().y - creature->getDisplacementY())*scaleFactor,
|
||||
tileSize, tileSize);
|
||||
Rect thisTileRect(dest.x, dest.y, tileSize, tileSize);
|
||||
for(const CreaturePtr& creature : m_walkingCreatures) {
|
||||
creature->draw(Point(dest.x + ((creature->getPosition().x - m_position.x)*Otc::TILE_PIXELS - drawElevation)*scaleFactor,
|
||||
dest.y + ((creature->getPosition().y - m_position.y)*Otc::TILE_PIXELS - drawElevation)*scaleFactor), scaleFactor);
|
||||
|
||||
// only render creatures where bottom right is inside our rect
|
||||
if(thisTileRect.contains(creatureRect.bottomRight())) {
|
||||
creature->draw(Point(dest.x + xi*tileSize - m_drawElevation*scaleFactor,
|
||||
dest.y + yi*tileSize - m_drawElevation*scaleFactor), scaleFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
|
||||
CreaturePtr creature = (*it)->asCreature();
|
||||
if(creature && !creature->isWalking())
|
||||
creature->draw(dest - drawElevation, scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +94,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
|
|||
if(drawFlags & Otc::DrawWalls) {
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(thing->isOnTop())
|
||||
thing->draw(dest - m_drawElevation, scaleFactor);
|
||||
thing->draw(dest - drawElevation, scaleFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +105,18 @@ void Tile::clean()
|
|||
m_effects.clear();
|
||||
}
|
||||
|
||||
void Tile::addWalkingCreature(const CreaturePtr& creature)
|
||||
{
|
||||
m_walkingCreatures.push_back(creature);
|
||||
}
|
||||
|
||||
void Tile::removeWalkingCreature(const CreaturePtr& creature)
|
||||
{
|
||||
auto it = std::find(m_walkingCreatures.begin(), m_walkingCreatures.end(), creature);
|
||||
if(it != m_walkingCreatures.end())
|
||||
m_walkingCreatures.erase(it);
|
||||
}
|
||||
|
||||
ThingPtr Tile::addThing(const ThingPtr& thing, int stackPos)
|
||||
{
|
||||
if(!thing)
|
||||
|
|
|
@ -33,12 +33,12 @@ public:
|
|||
|
||||
void draw(const Point& dest, float scaleFactor, int drawFlags);
|
||||
|
||||
private:
|
||||
void updateVisibleItemsCache();
|
||||
|
||||
public:
|
||||
void clean();
|
||||
|
||||
void addWalkingCreature(const CreaturePtr& creature);
|
||||
void removeWalkingCreature(const CreaturePtr& creature);
|
||||
|
||||
ThingPtr addThing(const ThingPtr& thing, int stackPos = -1);
|
||||
bool removeThing(const ThingPtr& thing);
|
||||
ThingPtr getThing(int stackPos);
|
||||
|
@ -70,6 +70,7 @@ public:
|
|||
TilePtr asTile() { return std::static_pointer_cast<Tile>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
std::vector<CreaturePtr> m_walkingCreatures;
|
||||
std::vector<EffectPtr> m_effects; // leave this outside m_things because it has no stackpos.
|
||||
std::vector<ThingPtr> m_things;
|
||||
Position m_position;
|
||||
|
|
Loading…
Reference in New Issue