fix corpses drawing

This commit is contained in:
Eduardo Bart 2012-02-02 18:10:14 -02:00
parent 2eec08d091
commit 614d34b382
9 changed files with 95 additions and 52 deletions

View File

@ -66,18 +66,16 @@ int MASK_TEXTURE_UNIFORM = 14;
void Creature::draw(const Point& dest, float scaleFactor, bool animate) void Creature::draw(const Point& dest, float scaleFactor, bool animate)
{ {
int scaledTileSize = Otc::TILE_PIXELS * scaleFactor;
Point animationOffset = animate ? m_walkOffset : Point(0,0); Point animationOffset = animate ? m_walkOffset : Point(0,0);
if(m_showVolatileSquare && animate) { if(m_showVolatileSquare && animate) {
g_painter.setColor(m_volatileSquareColor); g_painter.setColor(m_volatileSquareColor);
g_painter.drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 3)*scaleFactor, Size(28*scaleFactor, 28*scaleFactor)), std::max((int)(2*scaleFactor), 1)); g_painter.drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 3)*scaleFactor, Size(28, 28)*scaleFactor), std::max((int)(2*scaleFactor), 1));
} }
if(m_showStaticSquare && animate) { if(m_showStaticSquare && animate) {
g_painter.setColor(m_staticSquareColor); g_painter.setColor(m_staticSquareColor);
g_painter.drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 1)*scaleFactor, Size(scaledTileSize, scaledTileSize)), std::max((int)(2*scaleFactor), 1)); g_painter.drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 1)*scaleFactor, Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS)*scaleFactor), std::max((int)(2*scaleFactor), 1));
} }
g_painter.setColor(Fw::white); g_painter.setColor(Fw::white);
@ -124,13 +122,6 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
for(int h = 0; h < getDimensionHeight(); h++) { for(int h = 0; h < getDimensionHeight(); h++) {
for(int w = 0; w < getDimensionWidth(); w++) { for(int w = 0; w < getDimensionWidth(); w++) {
int spriteId = getSpriteId(w, h, 0, xPattern, yPattern, zPattern, m_walkAnimationPhase);
if(!spriteId)
continue;
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
if(!spriteTex)
continue;
// setup texture outfit mask // setup texture outfit mask
TexturePtr maskTex; TexturePtr maskTex;
if(getLayers() > 1) { if(getLayers() > 1) {
@ -139,10 +130,8 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
} }
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1); outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
Rect drawRect(dest.x + (animationOffset.x - w*Otc::TILE_PIXELS - getDisplacementX())*scaleFactor, internalDraw(dest + (animationOffset - Point(w,h)*Otc::TILE_PIXELS)*scaleFactor,
dest.y + (animationOffset.y - h*Otc::TILE_PIXELS - getDisplacementY())*scaleFactor, scaleFactor, w, h, xPattern, yPattern, zPattern, 0, animationPhase);
scaledTileSize, scaledTileSize);
g_painter.drawTexturedRect(drawRect, spriteTex);
} }
} }
@ -171,8 +160,7 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
if(m_outfit.getCategory() == ThingsType::Effect) if(m_outfit.getCategory() == ThingsType::Effect)
animationPhase = std::min(animationPhase+1, getAnimationPhases()); animationPhase = std::min(animationPhase+1, getAnimationPhases());
for(int layer = 0; layer < getLayers(); layer++) internalDraw(dest + animationOffset*scaleFactor, scaleFactor, 0, 0, 0, animationPhase);
internalDraw(dest + animationOffset*scaleFactor, scaleFactor, 0, 0, 0, layer, animationPhase);
} }
} }

View File

@ -32,9 +32,10 @@ void Effect::draw(const Point& dest, float scaleFactor, bool animate)
if(m_id == 0) if(m_id == 0)
return; return;
int animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / Otc::EFFECT_TICKS_PER_FRAME), getAnimationPhases() - 1); int animationPhase = 0;
for(int layer = 0; layer < getLayers(); layer++) if(animate)
internalDraw(dest, scaleFactor, 0, 0, 0, layer, animate ? animationPhase : 0); animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / Otc::EFFECT_TICKS_PER_FRAME), getAnimationPhases() - 1);
internalDraw(dest, scaleFactor, 0, 0, 0, animationPhase);
} }
void Effect::startAnimation() void Effect::startAnimation()

View File

@ -170,9 +170,8 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
} }
g_painter.setCustomProgram(itemProgram); g_painter.setCustomProgram(itemProgram);
// draw all item layers // now we can draw the item
for(int layer = 0; layer < getLayers(); layer++) internalDraw(dest, scaleFactor, xPattern, yPattern, zPattern, animationPhase);
internalDraw(dest, scaleFactor, xPattern, yPattern, zPattern, layer, animationPhase);
// release draw shader // release draw shader
g_painter.releaseCustomProgram(); g_painter.releaseCustomProgram();

View File

@ -122,9 +122,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
if(!thing) if(!thing)
return; return;
TilePtr tile = getTile(pos); TilePtr tile = getOrCreateTile(pos);
if(!tile)
tile = createTile(pos);
if(CreaturePtr creature = thing->asCreature()) { if(CreaturePtr creature = thing->asCreature()) {
Position oldPos = thing->getPosition(); Position oldPos = thing->getPosition();
@ -225,10 +223,20 @@ const TilePtr& Map::getTile(const Position& pos)
return nulltile; return nulltile;
} }
TilePtr Map::getOrCreateTile(const Position& pos)
{
const TilePtr& tile = getTile(pos);
if(tile)
return tile;
else
return createTile(pos);
}
void Map::cleanTile(const Position& pos) void Map::cleanTile(const Position& pos)
{ {
if(TilePtr tile = getTile(pos)) { if(TilePtr tile = getTile(pos)) {
tile->clean(); tile->clean();
if(tile->canErase())
m_tiles.erase(m_tiles.find(pos)); m_tiles.erase(m_tiles.find(pos));
notificateTileUpdateToMapViews(pos); notificateTileUpdateToMapViews(pos);

View File

@ -46,6 +46,7 @@ public:
// tile related // tile related
TilePtr createTile(const Position& pos); TilePtr createTile(const Position& pos);
const TilePtr& getTile(const Position& pos); const TilePtr& getTile(const Position& pos);
TilePtr getOrCreateTile(const Position& pos);
void cleanTile(const Position& pos); void cleanTile(const Position& pos);
bool removeThing(const ThingPtr& thing); bool removeThing(const ThingPtr& thing);

View File

@ -25,6 +25,7 @@
#include "thingstype.h" #include "thingstype.h"
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include "map.h" #include "map.h"
#include "tile.h"
Thing::Thing() Thing::Thing()
{ {
@ -52,23 +53,30 @@ const TilePtr& Thing::getTile()
return g_map.getTile(m_position); return g_map.getTile(m_position);
} }
void Thing::internalDraw(const Point& dest, float scaleFactor, int xPattern, int yPattern, int zPattern, int layer, int animationPhase) int Thing::getStackpos()
{
const TilePtr& tile = getTile();
if(tile)
return tile->getThingStackpos(asThing());
return -1;
}
void Thing::internalDraw(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; int scaledSize = Otc::TILE_PIXELS * scaleFactor;
for(int h = 0; h < getDimensionHeight(); h++) {
for(int w = 0; w < getDimensionWidth(); w++) {
int spriteId = getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animationPhase); int spriteId = getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animationPhase);
if(!spriteId) if(spriteId) {
continue; Rect drawRect(dest - getDisplacement()*scaleFactor, Size(scaledSize, scaledSize));
g_painter.setColor(Fw::white);
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId); g_painter.drawTexturedRect(drawRect, g_sprites.getSpriteTexture(spriteId));
Rect drawRect(dest.x - (w*Otc::TILE_PIXELS - getDisplacementX())*scaleFactor,
dest.y - (h*Otc::TILE_PIXELS - getDisplacementY())*scaleFactor,
scaledSize, scaledSize);
g_painter.drawTexturedRect(drawRect, spriteTex);
}
} }
} }
void Thing::internalDraw(const Point& dest, float scaleFactor, int xPattern, int yPattern, int zPattern, int animationPhase)
{
for(int l = 0; l < getLayers(); ++l)
for(int w = 0; w < getDimensionWidth(); ++w)
for(int h = 0; h < getDimensionHeight(); ++h)
internalDraw(dest - Point(w,h)*Otc::TILE_PIXELS*scaleFactor, scaleFactor, w, h, xPattern, yPattern, zPattern, l, animationPhase);
}

View File

@ -49,6 +49,7 @@ public:
Position getPosition() { return m_position; } Position getPosition() { return m_position; }
int getStackPriority(); int getStackPriority();
const TilePtr& getTile(); const TilePtr& getTile();
int getStackpos();
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); } ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
virtual ItemPtr asItem() { return nullptr; } virtual ItemPtr asItem() { return nullptr; }
@ -82,6 +83,7 @@ public:
bool isHookSouth() { return m_type->properties[ThingType::HookSouth]; } bool isHookSouth() { return m_type->properties[ThingType::HookSouth]; }
bool isHookEast() { return m_type->properties[ThingType::HookEast]; } bool isHookEast() { return m_type->properties[ThingType::HookEast]; }
bool isStackable() { return m_type->properties[ThingType::IsStackable]; } bool isStackable() { return m_type->properties[ThingType::IsStackable]; }
bool isLyingCorpse() { return m_type->properties[ThingType::IsLyingCorpse]; }
bool blocksProjectile() { return m_type->properties[ThingType::BlockProjectile]; } bool blocksProjectile() { return m_type->properties[ThingType::BlockProjectile]; }
bool isFluid() { return m_type->properties[ThingType::IsFluid]; } bool isFluid() { return m_type->properties[ThingType::IsFluid]; }
bool isFluidContainer() { return m_type->properties[ThingType::IsFluidContainer]; } bool isFluidContainer() { return m_type->properties[ThingType::IsFluidContainer]; }
@ -98,10 +100,14 @@ public:
int getAnimationPhases() { return m_type->dimensions[ThingType::AnimationPhases]; } int getAnimationPhases() { return m_type->dimensions[ThingType::AnimationPhases]; }
int getGroundSpeed() { return m_type->parameters[ThingType::GroundSpeed]; } int getGroundSpeed() { return m_type->parameters[ThingType::GroundSpeed]; }
int getElevation() { return m_type->parameters[ThingType::Elevation]; } int getElevation() { return m_type->parameters[ThingType::Elevation]; }
int getSpriteId(int w = 0, int h = 0, int layer = 0, int xPattern = 0, int yPattern = 0, int zPattern = 0, int animation = 0) { return m_type->getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animation); }
int getSpriteId(int w = 0, int h = 0, int layer = 0,
int xPattern = 0, int yPattern = 0, int zPattern = 0,
int animation = 0) { return m_type->getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animation); }
protected: protected:
void internalDraw(const Point& dest, float scaleFactor, int xPattern, int yPattern, int zPattern, int layer, int animationPhase); void internalDraw(const Point& dest, float scaleFactor, int w, int h, int xPattern, int yPattern, int zPattern, int layer, int animationPhase);
void internalDraw(const Point& dest, float scaleFactor, int xPattern, int yPattern, int zPattern, int animationPhase);
Position m_position; Position m_position;
ThingType *m_type; ThingType *m_type;

View File

@ -42,14 +42,14 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
bool animate = drawFlags & Otc::DrawAnimations; bool animate = drawFlags & Otc::DrawAnimations;
// first bottom items // first bottom items
if(drawFlags & Otc::DrawGround || drawFlags & Otc::DrawWalls || drawFlags & Otc::DrawGroundBorders) { if(drawFlags & Otc::DrawGround || drawFlags & Otc::DrawGroundBorders || drawFlags & Otc::DrawCommonItems) {
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom()) if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
break; break;
if((thing->isGround() && drawFlags & Otc::DrawGround) || if((thing->isGround() && drawFlags & Otc::DrawGround) ||
(thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) || (thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) ||
(thing->isOnBottom() && drawFlags & Otc::DrawWalls)) (thing->isOnBottom() && drawFlags & Otc::DrawCommonItems))
thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate); thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate);
drawElevation += thing->getElevation(); drawElevation += thing->getElevation();
@ -58,20 +58,45 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
} }
} }
// now common items in reverse order int redrawPreviousOnTopW = 0;
int redrawPreviousOnTopH = 0;
if(drawFlags & Otc::DrawCommonItems) { if(drawFlags & Otc::DrawCommonItems) {
// now common items in reverse order
for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) { for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
const ThingPtr& thing = *it; const ThingPtr& thing = *it;
if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->asCreature()) if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->asCreature())
break; break;
thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate); thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate);
if(thing->isLyingCorpse()) {
redrawPreviousOnTopW = std::max(thing->getDimensionWidth(), redrawPreviousOnTopW);
redrawPreviousOnTopH = std::max(thing->getDimensionHeight(), redrawPreviousOnTopH);
}
drawElevation += thing->getElevation(); drawElevation += thing->getElevation();
if(drawElevation > Otc::MAX_ELEVATION) if(drawElevation > Otc::MAX_ELEVATION)
drawElevation = Otc::MAX_ELEVATION; drawElevation = Otc::MAX_ELEVATION;
} }
} }
// must redraw previous creatures/ontop above lying corpses
if(redrawPreviousOnTopH > 0 || redrawPreviousOnTopW > 0) {
int onTopRedrawFlags = drawFlags & (Otc::DrawCreatures | Otc::DrawEffects | Otc::DrawWalls);
if(onTopRedrawFlags) {
for(int y=-redrawPreviousOnTopH;y<=0;++y) {
for(int x=-redrawPreviousOnTopW;x<=0;++x) {
if(x == 0 && y == 0)
continue;
const TilePtr& tile = g_map.getTile(m_position.translated(x,y));
if(tile) {
tile->draw(dest + Point(x*Otc::TILE_PIXELS, y*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, onTopRedrawFlags);
}
}
}
}
}
// creatures // creatures
if(drawFlags & Otc::DrawCreatures) { if(drawFlags & Otc::DrawCreatures) {
if(animate) { if(animate) {
@ -106,8 +131,8 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
void Tile::clean() void Tile::clean()
{ {
m_things.clear(); while(!m_things.empty())
m_effects.clear(); removeThing(m_things.front());
} }
void Tile::addWalkingCreature(const CreaturePtr& creature) void Tile::addWalkingCreature(const CreaturePtr& creature)
@ -153,7 +178,7 @@ ThingPtr Tile::addThing(const ThingPtr& thing, int stackPos)
return oldObject; return oldObject;
} }
bool Tile::removeThing(const ThingPtr& thing) bool Tile::removeThing(ThingPtr thing)
{ {
if(!thing) if(!thing)
return false; return false;
@ -406,3 +431,9 @@ bool Tile::limitsFloorsView()
return true; return true;
return false; return false;
} }
bool Tile::canErase()
{
return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty();
}

View File

@ -40,7 +40,7 @@ public:
void removeWalkingCreature(const CreaturePtr& creature); void removeWalkingCreature(const CreaturePtr& creature);
ThingPtr addThing(const ThingPtr& thing, int stackPos = -1); ThingPtr addThing(const ThingPtr& thing, int stackPos = -1);
bool removeThing(const ThingPtr& thing); bool removeThing(ThingPtr thing);
ThingPtr getThing(int stackPos); ThingPtr getThing(int stackPos);
int getThingStackpos(const ThingPtr& thing); int getThingStackpos(const ThingPtr& thing);
ThingPtr getTopThing(); ThingPtr getTopThing();
@ -57,6 +57,7 @@ public:
const std::vector<ThingPtr>& getThings() { return m_things; } const std::vector<ThingPtr>& getThings() { return m_things; }
ItemPtr getGround(); ItemPtr getGround();
int getGroundSpeed(); int getGroundSpeed();
int getThingCount() { return m_things.size() + m_effects.size(); }
bool isWalkable(); bool isWalkable();
bool isFullGround(); bool isFullGround();
bool isFullyOpaque(); bool isFullyOpaque();
@ -67,7 +68,7 @@ public:
bool mustHookEast(); bool mustHookEast();
bool hasCreature(); bool hasCreature();
bool limitsFloorsView(); bool limitsFloorsView();
int getThingCount() { return m_things.size() + m_effects.size(); } bool canErase();
TilePtr asTile() { return std::static_pointer_cast<Tile>(shared_from_this()); } TilePtr asTile() { return std::static_pointer_cast<Tile>(shared_from_this()); }
@ -76,7 +77,7 @@ private:
std::vector<EffectPtr> m_effects; // leave this outside m_things because it has no stackpos. std::vector<EffectPtr> m_effects; // leave this outside m_things because it has no stackpos.
std::vector<ThingPtr> m_things; std::vector<ThingPtr> m_things;
Position m_position; Position m_position;
int m_drawElevation; uint8 m_drawElevation;
}; };
#endif #endif