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)
{
int scaledTileSize = Otc::TILE_PIXELS * scaleFactor;
Point animationOffset = animate ? m_walkOffset : Point(0,0);
if(m_showVolatileSquare && animate) {
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) {
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);
@ -124,13 +122,6 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
for(int h = 0; h < getDimensionHeight(); h++) {
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
TexturePtr maskTex;
if(getLayers() > 1) {
@ -139,10 +130,8 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
}
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
Rect drawRect(dest.x + (animationOffset.x - w*Otc::TILE_PIXELS - getDisplacementX())*scaleFactor,
dest.y + (animationOffset.y - h*Otc::TILE_PIXELS - getDisplacementY())*scaleFactor,
scaledTileSize, scaledTileSize);
g_painter.drawTexturedRect(drawRect, spriteTex);
internalDraw(dest + (animationOffset - Point(w,h)*Otc::TILE_PIXELS)*scaleFactor,
scaleFactor, w, h, xPattern, yPattern, zPattern, 0, animationPhase);
}
}
@ -171,8 +160,7 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
if(m_outfit.getCategory() == ThingsType::Effect)
animationPhase = std::min(animationPhase+1, getAnimationPhases());
for(int layer = 0; layer < getLayers(); layer++)
internalDraw(dest + animationOffset*scaleFactor, scaleFactor, 0, 0, 0, layer, animationPhase);
internalDraw(dest + animationOffset*scaleFactor, scaleFactor, 0, 0, 0, animationPhase);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@
#include "thingstype.h"
#include <framework/graphics/graphics.h>
#include "map.h"
#include "tile.h"
Thing::Thing()
{
@ -52,23 +53,30 @@ const TilePtr& Thing::getTile()
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;
for(int h = 0; h < getDimensionHeight(); h++) {
for(int w = 0; w < getDimensionWidth(); w++) {
int spriteId = getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animationPhase);
if(!spriteId)
continue;
TexturePtr spriteTex = 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);
}
int spriteId = getSpriteId(w, h, layer, xPattern, yPattern, zPattern, animationPhase);
if(spriteId) {
Rect drawRect(dest - getDisplacement()*scaleFactor, Size(scaledSize, scaledSize));
g_painter.setColor(Fw::white);
g_painter.drawTexturedRect(drawRect, g_sprites.getSpriteTexture(spriteId));
}
}
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; }
int getStackPriority();
const TilePtr& getTile();
int getStackpos();
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
virtual ItemPtr asItem() { return nullptr; }
@ -82,6 +83,7 @@ public:
bool isHookSouth() { return m_type->properties[ThingType::HookSouth]; }
bool isHookEast() { return m_type->properties[ThingType::HookEast]; }
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 isFluid() { return m_type->properties[ThingType::IsFluid]; }
bool isFluidContainer() { return m_type->properties[ThingType::IsFluidContainer]; }
@ -98,10 +100,14 @@ public:
int getAnimationPhases() { return m_type->dimensions[ThingType::AnimationPhases]; }
int getGroundSpeed() { return m_type->parameters[ThingType::GroundSpeed]; }
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:
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;
ThingType *m_type;

View File

@ -42,14 +42,14 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
bool animate = drawFlags & Otc::DrawAnimations;
// 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) {
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
break;
if((thing->isGround() && drawFlags & Otc::DrawGround) ||
(thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) ||
(thing->isOnBottom() && drawFlags & Otc::DrawWalls))
(thing->isOnBottom() && drawFlags & Otc::DrawCommonItems))
thing->draw(dest - drawElevation*scaleFactor, scaleFactor, animate);
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) {
// now common items in reverse order
for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
const ThingPtr& thing = *it;
if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->asCreature())
break;
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();
if(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
if(drawFlags & Otc::DrawCreatures) {
if(animate) {
@ -106,8 +131,8 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags)
void Tile::clean()
{
m_things.clear();
m_effects.clear();
while(!m_things.empty())
removeThing(m_things.front());
}
void Tile::addWalkingCreature(const CreaturePtr& creature)
@ -153,7 +178,7 @@ ThingPtr Tile::addThing(const ThingPtr& thing, int stackPos)
return oldObject;
}
bool Tile::removeThing(const ThingPtr& thing)
bool Tile::removeThing(ThingPtr thing)
{
if(!thing)
return false;
@ -406,3 +431,9 @@ bool Tile::limitsFloorsView()
return true;
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);
ThingPtr addThing(const ThingPtr& thing, int stackPos = -1);
bool removeThing(const ThingPtr& thing);
bool removeThing(ThingPtr thing);
ThingPtr getThing(int stackPos);
int getThingStackpos(const ThingPtr& thing);
ThingPtr getTopThing();
@ -57,6 +57,7 @@ public:
const std::vector<ThingPtr>& getThings() { return m_things; }
ItemPtr getGround();
int getGroundSpeed();
int getThingCount() { return m_things.size() + m_effects.size(); }
bool isWalkable();
bool isFullGround();
bool isFullyOpaque();
@ -67,7 +68,7 @@ public:
bool mustHookEast();
bool hasCreature();
bool limitsFloorsView();
int getThingCount() { return m_things.size() + m_effects.size(); }
bool canErase();
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<ThingPtr> m_things;
Position m_position;
int m_drawElevation;
uint8 m_drawElevation;
};
#endif