items draw rework, npc trade fix

This commit is contained in:
Henrique Santiago 2012-05-13 12:05:17 -03:00
parent 7b512bfa9f
commit 1203756baf
13 changed files with 165 additions and 46 deletions

View File

@ -210,10 +210,10 @@ local function onOpenNpcTrade(items)
newItem.name = item[2] newItem.name = item[2]
newItem.weight = item[3] / 100 newItem.weight = item[3] / 100
if item[4] >= 0 then if item[4] > 0 then
newItem.price = item[4] newItem.price = item[4]
table.insert(tradeItems[BUY], newItem) table.insert(tradeItems[BUY], newItem)
elseif item[5] >= 0 then elseif item[5] > 0 then
newItem.price = item[5] newItem.price = item[5]
table.insert(tradeItems[SELL], newItem) table.insert(tradeItems[SELL], newItem)
else else

View File

@ -13,7 +13,7 @@ SET(BUILD_REVISION "custom" CACHE "Git revision string (intended for releases)"
# set debug as default build type # set debug as default build type
IF(NOT CMAKE_BUILD_TYPE) IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo) SET(CMAKE_BUILD_TYPE Debug)
ENDIF() ENDIF()
# setup compiler options # setup compiler options

View File

@ -83,3 +83,23 @@ void Image::overwriteMask(const Color& maskedColor, const Color& insideColor, co
a = writeColor.a(); a = writeColor.a();
} }
} }
void Image::append(const Point& dest, const ImagePtr& other)
{
if(!other)
return;
uint8* otherPixels = other->getPixelData();
for(int p = 0; p < other->getPixelCount(); ++p) {
int x = p % other->getWidth();
int y = p / other->getWidth();
int pos = ((dest.y + y) * m_size.width() + (dest.x + x)) * 4;
if(otherPixels[p*4+3] == 0xFF) {
m_pixels[pos+0] = otherPixels[p*4+0];
m_pixels[pos+1] = otherPixels[p*4+1];
m_pixels[pos+2] = otherPixels[p*4+2];
m_pixels[pos+3] = otherPixels[p*4+3];
}
}
}

View File

@ -35,6 +35,7 @@ public:
static ImagePtr loadPNG(const std::string& file); static ImagePtr loadPNG(const std::string& file);
void overwriteMask(const Color& maskedColor, const Color& insideColor = Color::white, const Color& outsideColor = Color::alpha); void overwriteMask(const Color& maskedColor, const Color& insideColor = Color::white, const Color& outsideColor = Color::alpha);
void append(const Point& dest, const ImagePtr &other);
std::vector<uint8>& getPixels() { return m_pixels; } std::vector<uint8>& getPixels() { return m_pixels; }
uint8* getPixelData() { return &m_pixels[0]; } uint8* getPixelData() { return &m_pixels[0]; }
@ -43,6 +44,7 @@ public:
int getWidth() { return m_size.width(); } int getWidth() { return m_size.width(); }
int getHeight() { return m_size.height(); } int getHeight() { return m_size.height(); }
int getBpp() { return m_bpp; } int getBpp() { return m_bpp; }
uint8* getPixel(int x, int y) { return &m_pixels[(y * m_size.width() + x) * 4]; }
private: private:
std::vector<uint8> m_pixels; std::vector<uint8> m_pixels;

View File

@ -142,6 +142,7 @@ void Texture::generateMipmaps()
//FIXME: disabled because mipmaps size needs to be in base of 2, //FIXME: disabled because mipmaps size needs to be in base of 2,
// and the current algorithmn does not support that // and the current algorithmn does not support that
//generateSoftwareMipmaps(getPixels()); //generateSoftwareMipmaps(getPixels());
logTraceError("non power of 2.");
} }
} }

View File

@ -133,6 +133,7 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor()); outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
*/ */
m_type->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase);
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++) {
// setup texture outfit mask // setup texture outfit mask
@ -145,7 +146,6 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
*/ */
Point p = dest + (-Point(w,h)*Otc::TILE_PIXELS)*scaleFactor; Point p = dest + (-Point(w,h)*Otc::TILE_PIXELS)*scaleFactor;
m_type->draw(p, scaleFactor, w, h, xPattern, yPattern, zPattern, 0, animationPhase);
if(getLayers() > 1) { if(getLayers() > 1) {
g_painter->setCompositionMode(Painter::CompositionMode_Multiply); g_painter->setCompositionMode(Painter::CompositionMode_Multiply);
@ -190,7 +190,7 @@ void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool ani
if(m_outfit.getCategory() == ThingsType::Effect) if(m_outfit.getCategory() == ThingsType::Effect)
animationPhase = std::min(animationPhase+1, getAnimationPhases()); animationPhase = std::min(animationPhase+1, getAnimationPhases());
m_type->draw(dest, scaleFactor, 0, 0, 0, animationPhase); m_type->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase);
} }
} }

View File

@ -32,7 +32,7 @@ void Effect::draw(const Point& dest, float scaleFactor, bool animate)
int animationPhase = 0; int animationPhase = 0;
if(animate) if(animate)
animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / Otc::EFFECT_TICKS_PER_FRAME), getAnimationPhases() - 1); animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / Otc::EFFECT_TICKS_PER_FRAME), getAnimationPhases() - 1);
m_type->draw(dest, scaleFactor, 0, 0, 0, animationPhase); m_type->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase);
} }
void Effect::startAnimation() void Effect::startAnimation()

View File

@ -181,7 +181,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate)
*/ */
// now we can draw the item // now we can draw the item
m_type->draw(dest, scaleFactor, xPattern, yPattern, zPattern, animationPhase); m_type->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase);
// release draw shader // release draw shader
g_painter->resetShaderProgram(); g_painter->resetShaderProgram();

View File

@ -63,7 +63,7 @@ void Missile::draw(const Point& dest, float scaleFactor, bool animate)
} }
float fraction = m_animationTimer.ticksElapsed() / m_duration; float fraction = m_animationTimer.ticksElapsed() / m_duration;
m_type->draw(dest + m_delta * fraction * scaleFactor, scaleFactor, xPattern, yPattern, 0, 0); m_type->draw(dest + m_delta * fraction * scaleFactor, 0, scaleFactor, xPattern, yPattern, 0, 0);
} }
void Missile::setPath(const Position& fromPosition, const Position& toPosition) void Missile::setPath(const Position& fromPosition, const Position& toPosition)

View File

@ -48,6 +48,7 @@ bool ThingsType::load(const std::string& file)
for(int i = 0; i < LastCategory; ++i) { for(int i = 0; i < LastCategory; ++i) {
m_things[i].resize(numThings[i]); m_things[i].resize(numThings[i]);
for(int id = 0; id < numThings[i]; ++id) { for(int id = 0; id < numThings[i]; ++id) {
m_things[i][id].m_category = i;
if(!parseThingType(fin, m_things[i][id])) { if(!parseThingType(fin, m_things[i][id])) {
logError("corrupt or dat file"); logError("corrupt or dat file");
return false; return false;
@ -142,10 +143,13 @@ bool ThingsType::parseThingType(const FileStreamPtr& fin, ThingType& thingType)
return false; return false;
thingType.m_spritesIndex.resize(totalSprites); thingType.m_spritesIndex.resize(totalSprites);
thingType.m_sprites.resize(totalSprites);
for(int i = 0; i < totalSprites; i++) for(int i = 0; i < totalSprites; i++)
thingType.m_spritesIndex[i] = fin->getU16(); thingType.m_spritesIndex[i] = fin->getU16();
thingType.m_textures.resize(thingType.m_dimensions[ThingType::AnimationPhases]);
thingType.m_texturesFramesRects.resize(thingType.m_dimensions[ThingType::AnimationPhases]);
thingType.m_texturesFramesOffsets.resize(thingType.m_dimensions[ThingType::AnimationPhases]);
return true; return true;
} }

View File

@ -21,6 +21,7 @@
*/ */
#include "thingtype.h" #include "thingtype.h"
#include "thingstype.h"
#include "spritemanager.h" #include "spritemanager.h"
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
@ -34,23 +35,20 @@ ThingType::ThingType()
m_properties.fill(false); 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) void ThingType::draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
{ {
int scaledSize = Otc::TILE_PIXELS * scaleFactor; const TexturePtr& texture = getTexture(animationPhase); // rects might not be calculated yet.
int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex];
Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex];
Point displacement(m_parameters[DisplacementX], m_parameters[DisplacementY]); Point displacement(m_parameters[DisplacementX], m_parameters[DisplacementY]);
Rect screenRect(dest - displacement - Point(32 * m_dimensions[Width] * scaleFactor, 32 * m_dimensions[Height] * scaleFactor) + Point(32, 32) + textureOffset,
textureRect.size() * scaleFactor);
Rect drawRect(dest - displacement*scaleFactor, Size(scaledSize, scaledSize));
g_painter->setColor(Color::white); g_painter->setColor(Color::white);
g_painter->drawTexturedRect(drawRect, getSprite(w, h, layer, xPattern, yPattern, zPattern, animationPhase)); g_painter->drawTexturedRect(screenRect, texture, textureRect);
}
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) 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)
@ -63,26 +61,6 @@ void ThingType::drawMask(const Point& dest, float scaleFactor, int w, int h, int
g_painter->drawTexturedRect(drawRect, getSpriteMask(w, h, layer, xPattern, yPattern, zPattern, animationPhase, mask)); 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) 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) if(m_spritesMask.size() == 0)
@ -108,3 +86,103 @@ TexturePtr& ThingType::getSpriteMask(int w, int h, int l, int x, int y, int z, i
return maskTexture; return maskTexture;
} }
TexturePtr& ThingType::getTexture(int animationPhase)
{
TexturePtr& animationPhaseTexture = m_textures[animationPhase];
if(!animationPhaseTexture) {
int textureLayers = m_dimensions[Layers];
if(m_category != ThingsType::Creature) // we dont need layers in texture. they can be 'rendered' now.
textureLayers = 1;
int indexSize = textureLayers * m_dimensions[PatternX] * m_dimensions[PatternY] * m_dimensions[PatternZ];
Size textureSize = getBestDimension(m_dimensions[Width], m_dimensions[Height], indexSize);
ImagePtr fullImage = ImagePtr(new Image(textureSize * 32));
m_texturesFramesRects[animationPhase].resize(indexSize);
m_texturesFramesOffsets[animationPhase].resize(indexSize);
for(int z = 0; z < m_dimensions[PatternZ]; ++z) {
for(int y = 0; y < m_dimensions[PatternY]; ++y) {
for(int x = 0; x < m_dimensions[PatternX]; ++x) {
for(int l = 0; l < m_dimensions[Layers]; ++l) {
int frameIndex = getTextureIndex(l % textureLayers, x, y, z);
Point framePos = Point(frameIndex % (textureSize.width() / m_dimensions[Width]) * m_dimensions[Width],
frameIndex / (textureSize.width() / m_dimensions[Width]) * m_dimensions[Height]) * 32;
for(int h = 0; h < m_dimensions[Height]; ++h) {
for(int w = 0; w < m_dimensions[Width]; ++w) {
uint spriteIndex = getSpriteIndex(w, h, l, x, y, z, animationPhase);
ImagePtr spriteImage = g_sprites.getSpriteImage(m_spritesIndex[spriteIndex]);
if(spriteImage) {
Point spritePos = Point(m_dimensions[Width] - w - 1,
m_dimensions[Height] - h - 1) * 32;
fullImage->append(framePos + spritePos, spriteImage);
}
}
}
Rect drawRect(framePos + Point(m_dimensions[Width], m_dimensions[Height]) * 32, framePos);
for(int x = framePos.x; x < framePos.x + m_dimensions[Width] * 32; ++x) {
for(int y = framePos.y; y < framePos.y + m_dimensions[Height] * 32; ++y) {
uint8 *p = fullImage->getPixel(x,y);
if(p[3] != 0x00) {
drawRect.setTop(std::min(y, (int)drawRect.top()));
drawRect.setLeft(std::min(x, (int)drawRect.left()));
drawRect.setBottom(std::max(y, (int)drawRect.bottom()));
drawRect.setRight(std::max(x, (int)drawRect.right()));
}
}
}
m_texturesFramesRects[animationPhase][frameIndex] = drawRect;
m_texturesFramesOffsets[animationPhase][frameIndex] = drawRect.topLeft() - framePos;
}
}
}
}
animationPhaseTexture = TexturePtr(new Texture(fullImage));
animationPhaseTexture->setSmooth(true);
//if(g_graphics.canUseMipmaps())
//animationPhaseTexture->generateSoftwareMipmaps(fullImage->getPixels());
}
return animationPhaseTexture;
}
Size ThingType::getBestDimension(int w, int h, int count)
{
const int MAX = 16;
int k = 1;
while(k < w)
k<<=1;
w = k;
k = 1;
while(k < h)
k<<=1;
h = k;
int numSprites = w*h*count;
assert(numSprites <= MAX*MAX);
assert(w <= MAX);
assert(h <= MAX);
Size bestDimension = Size(MAX, MAX);
for(int i=w;i<=MAX;i<<=1) {
for(int j=h;j<=MAX;j<<=1) {
Size candidateDimension = Size(i, j);
if(candidateDimension.area() < numSprites)
continue;
if((candidateDimension.area() < bestDimension.area()) ||
(candidateDimension.area() == bestDimension.area() && candidateDimension.width() + candidateDimension.height() < bestDimension.width() + bestDimension.height()))
bestDimension = candidateDimension;
}
}
return bestDimension;
}

View File

@ -24,8 +24,8 @@
#define THINGATTRIBUTES_H #define THINGATTRIBUTES_H
#include "declarations.h" #include "declarations.h"
#include <framework/graphics/declarations.h> #include <framework/graphics/declarations.h>
#include <framework/graphics/coordsbuffer.h>
struct ThingType struct ThingType
{ {
@ -108,18 +108,20 @@ struct ThingType
ThingType(); ThingType();
void draw(const Point& dest, float scaleFactor, int w, int h, int xPattern, int yPattern, int zPattern, int layer, int animationPhase); void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase);
void draw(const Point& dest, float scaleFactor, int xPattern, int yPattern, int zPattern, int animationPhase);
void drawMask(const Point& dest, float scaleFactor, int w, int h, int xPattern, int yPattern, int zPattern, int layer, int animationPhase, SpriteMask mask); void drawMask(const Point& dest, float scaleFactor, int w, int h, int xPattern, int yPattern, int zPattern, int layer, int animationPhase, SpriteMask mask);
TexturePtr& getSprite(int w, int h, int l, int x, int y, int z, int a); TexturePtr& getSprite(int w, int h, int l, int x, int y, int z, int a);
TexturePtr& getSpriteMask(int w, int h, int l, int x, int y, int z, int a, SpriteMask mask); TexturePtr& getSpriteMask(int w, int h, int l, int x, int y, int z, int a, SpriteMask mask);
TexturePtr& getTexture(int animationPhase);
bool getProperty(Property property) { return m_properties[property]; } bool getProperty(Property property) { return m_properties[property]; }
int getParameter(Parameter param) { return m_parameters[param]; } int getParameter(Parameter param) { return m_parameters[param]; }
int getDimension(Dimension dimension) { return m_dimensions[dimension]; } int getDimension(Dimension dimension) { return m_dimensions[dimension]; }
private: private:
Size getBestDimension(int w, int h, int count);
uint getSpriteIndex(int w, int h, int l, int x, int y, int z, int a) { uint getSpriteIndex(int w, int h, int l, int x, int y, int z, int a) {
uint index = ((((((a % m_dimensions[ThingType::AnimationPhases]) uint index = ((((((a % m_dimensions[ThingType::AnimationPhases])
* m_dimensions[ThingType::PatternZ] + z) * m_dimensions[ThingType::PatternZ] + z)
@ -128,17 +130,28 @@ private:
* m_dimensions[ThingType::Layers] + l) * m_dimensions[ThingType::Layers] + l)
* m_dimensions[ThingType::Height] + h) * m_dimensions[ThingType::Height] + h)
* m_dimensions[ThingType::Width] + w; * m_dimensions[ThingType::Width] + w;
assert(index < m_sprites.size()); assert(index < m_spritesIndex.size());
return index; return index;
} }
uint getTextureIndex(int l, int x, int y, int z) {
return ((l
* m_dimensions[ThingType::PatternZ] + z)
* m_dimensions[ThingType::PatternY] + y)
* m_dimensions[ThingType::PatternX] + x;
}
int m_category;
std::array<int, LastDimension> m_dimensions; std::array<int, LastDimension> m_dimensions;
std::array<int, LastParameter> m_parameters; std::array<int, LastParameter> m_parameters;
std::array<bool, LastProperty> m_properties; std::array<bool, LastProperty> m_properties;
std::vector<int> m_spritesIndex; std::vector<int> m_spritesIndex;
std::vector<TexturePtr> m_sprites;
std::vector<std::array<TexturePtr, LastMask>> m_spritesMask; std::vector<std::array<TexturePtr, LastMask>> m_spritesMask;
std::vector<TexturePtr> m_textures;
std::vector<std::vector<Rect> > m_texturesFramesRects;
std::vector<std::vector<Point> > m_texturesFramesOffsets;
friend class ThingsType; friend class ThingsType;
}; };

View File

@ -53,6 +53,7 @@ void UIItem::drawSelf()
g_painter->setColor(Color(231, 231, 231)); g_painter->setColor(Color(231, 231, 231));
m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight); m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight);
} }
// debug, show item id
//m_font->drawText(Fw::tostring(m_item->getId()), m_rect, Fw::AlignBottomRight); //m_font->drawText(Fw::tostring(m_item->getId()), m_rect, Fw::AlignBottomRight);
} }
} }